change password generator

pull/32/head
Kherel 2021-08-18 11:36:40 +02:00
parent 8ea1b28d73
commit 1202e4ad53
10 changed files with 273 additions and 252 deletions

View File

@ -7,7 +7,7 @@ import 'package:selfprivacy/logic/api_maps/api_map.dart';
import 'package:selfprivacy/logic/models/hetzner_server_info.dart';
import 'package:selfprivacy/logic/models/server_details.dart';
import 'package:selfprivacy/logic/models/user.dart';
import 'package:selfprivacy/utils/password_generator2.dart';
import 'package:selfprivacy/utils/password_generator.dart';
class HetznerApi extends ApiMap {
bool hasLoger;
@ -73,30 +73,26 @@ class HetznerApi extends ApiMap {
required User rootUser,
required String domainName,
}) async {
var dbPassword = getRandomString(40);
const chars =
'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890';
var dbStorageName = getRandomString(6, chars);
var client = await getClient();
Response dbCreateResponse = await client.post(
'/volumes',
data: {
"size": 10,
"name": dbStorageName,
"name": StringGenerators.dbStorageName(),
"labels": {"labelkey": "value"},
"location": "fsn1",
"automount": false,
"format": "ext4"
},
);
var dbPassword = StringGenerators.dbPassword();
var dbId = dbCreateResponse.data['volume']['id'];
var data = jsonDecode(
'''{"name":"$domainName","server_type":"cx11","start_after_create":false,"image":"ubuntu-20.04", "volumes":[$dbId], "networks":[], "user_data":"#cloud-config\\nruncmd:\\n- curl https://git.selfprivacy.org/ilchub/selfprivacy-nixos-infect/raw/branch/master/nixos-infect | PROVIDER=hetzner NIX_CHANNEL=nixos-21.05 DOMAIN=$domainName LUSER=${rootUser.login} PASSWORD=${rootUser.password} HASHED_PASSWORD=${rootUser.hashPassword.hash} SALT=${rootUser.hashPassword.salt} CF_TOKEN=$cloudFlareKey DB_PASSWORD=$dbPassword bash 2>&1 | tee /tmp/infect.log","labels":{},"automount":true, "location": "fsn1"}'''
);
'''{"name":"$domainName","server_type":"cx11","start_after_create":false,"image":"ubuntu-20.04", "volumes":[$dbId], "networks":[], "user_data":"#cloud-config\\nruncmd:\\n- curl https://git.selfprivacy.org/ilchub/selfprivacy-nixos-infect/raw/branch/master/nixos-infect | PROVIDER=hetzner NIX_CHANNEL=nixos-21.05 DOMAIN=$domainName LUSER=${rootUser.login} PASSWORD=${rootUser.password} HASHED_PASSWORD=${rootUser.hashPassword.hash} SALT=${rootUser.hashPassword.salt} CF_TOKEN=$cloudFlareKey DB_PASSWORD=$dbPassword bash 2>&1 | tee /tmp/infect.log","labels":{},"automount":true, "location": "fsn1"}''');
Response serverCreateResponse = await client.post(
'/servers',

View File

@ -4,8 +4,8 @@ import 'package:cubit_form/cubit_form.dart';
import 'package:selfprivacy/logic/cubit/jobs/jobs_cubit.dart';
import 'package:selfprivacy/logic/models/jobs/job.dart';
import 'package:selfprivacy/logic/models/user.dart';
import 'package:selfprivacy/utils/password_generator.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:selfprivacy/utils/password_generator.dart';
class UserFormCubit extends FormCubit {
UserFormCubit({
@ -32,7 +32,7 @@ class UserFormCubit extends FormCubit {
);
password = FieldCubit(
initalValue: isEdit ? user!.password : genPass(),
initalValue: isEdit ? user!.password : StringGenerators.userPassword(),
validations: [
RequiredStringValidation('validations.required'.tr()),
ValidationModel<String>((s) => passwordRegExp.hasMatch(s),
@ -56,7 +56,7 @@ class UserFormCubit extends FormCubit {
late FieldCubit<String> password;
void genNewPassword() {
password.externalSetValue(genPass());
password.externalSetValue(StringGenerators.userPassword());
}
final JobsCubit jobsCubit;

View File

@ -34,21 +34,3 @@ class UsersCubit extends Cubit<UsersState> {
emit(UsersState(users));
}
}
// final initMockUsers = <User>[
// User(login: 'Heartbreaking.Goose', password: genPass()),
// User(login: 'Alma.lawson', password: genPass()),
// User(login: 'Bee.gees', password: genPass()),
// User(login: 'Bim.jennings', password: genPass()),
// User(login: 'Debra.holt', password: genPass()),
// User(login: 'Georgia.young', password: genPass()),
// User(login: 'Kenzi.lawson', password: genPass()),
// User(login: 'Le.jennings', password: genPass()),
// User(login: 'Kirill.Zh', password: genPass()),
// User(login: 'Tina.Bolton', password: genPass()),
// User(login: 'Rebekah.Lynn', password: genPass()),
// User(login: 'Aleena.Armstrong', password: genPass()),
// User(login: 'Rosemary.Williams', password: genPass()),
// User(login: 'Sullivan.Nixon', password: genPass()),
// User(login: 'Aleena.Armstrong', password: genPass()),
// ];

View File

@ -1,6 +1,6 @@
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:selfprivacy/utils/password_generator2.dart';
import 'package:selfprivacy/utils/password_generator.dart';
import '../user.dart';
@ -9,7 +9,7 @@ class Job extends Equatable {
Job({
String? id,
required this.title,
}) : id = id ?? getRandomString(5);
}) : id = id ?? StringGenerators.simpleId();
final String title;
final String id;

View File

@ -4,6 +4,7 @@ import 'package:crypt/crypt.dart';
import 'package:equatable/equatable.dart';
import 'package:selfprivacy/utils/color_utils.dart';
import 'package:hive/hive.dart';
import 'package:selfprivacy/utils/password_generator.dart';
part 'user.g.dart';
@ -25,7 +26,10 @@ class User extends Equatable {
Color get color => stringToColor(login);
Crypt get hashPassword => Crypt.sha512(password);
Crypt get hashPassword => Crypt.sha512(
password,
salt: StringGenerators.passwordSalt(),
);
String toString() {
return login;

View File

@ -1,138 +1,99 @@
import 'dart:math';
var generator = PasswordGenerator();
Random _rnd = Random();
String genPass() {
generator.generate(8);
return generator.getGeneratedValue();
}
///Generates a password.
///
///The password [_generatedValue] is of a specified length, including letters [_letterGen] of mixed cases,
///numbers [_numGen], and symbols[_symGen] depending on user choice.
class PasswordGenerator {
late bool _letterGen;
late bool _numGen;
late bool _symGen;
late String _generatedValue;
///Constructor.
///
///[_letterGen] is true to make password generation possible from the opening of the application, and
///[_generatedValue] is intialized to the value below so the text containing it can be first generated
///upon users request
PasswordGenerator() {
_letterGen = true;
_numGen = true;
_symGen = false;
_generatedValue = "Press Generate";
}
///Call to generate a value, of [n] length
void generate(int n) {
//Discards the old value
_generatedValue = "";
///Cannot generate a value without any character types selected
if (!_letterGen && !_numGen && !_symGen) {
_generatedValue = "No character type selected";
return;
}
///'Randomly' selectes caracter type to generate and append [toAppend] to [_generatedValue]
// ignore: unnecessary_statements
for (n; n > 0; n--) {
String? toAppend;
var random = new Random();
///loops until a valid character is generated, meaning the user has to check the character value
///to be generated. 'Randomly' picks a character type.
while (toAppend == null) {
int selector = random.nextInt(3);
if (selector == 0) {
toAppend = _generateLetter();
} else if (selector == 1) {
toAppend = _generateNumber();
} else {
toAppend = _generateSymbol();
}
}
_generatedValue += toAppend;
toAppend = null;
}
}
///Generates a letter when called.
String _generateLetter() {
if (!_letterGen) return '';
///Finds the integer value for the range between a-z and A-Z, with [base] UTF-16 value for lowercase letters and
///[baseUpper] UTF-16 value for uppercase letters
int base = "a".codeUnitAt(0);
int baseUpper = "A".codeUnitAt(0);
int maxRand = ("z".codeUnitAt(0) - base) + 1;
Random random = new Random();
///Randomly selects between upper and lower case generation, randomly generates value from [maxRand], then adding base,
///which creates a UTF-16 encoded character to be converted into a string of one character between a-z/A-Z.
///This string is then returned.
if (random.nextInt(2) == 0) {
return String.fromCharCodes([random.nextInt(maxRand) + base]);
} else {
return String.fromCharCodes([random.nextInt(maxRand) + baseUpper]);
}
}
///Generates a number when called
String? _generateNumber() {
if (!_numGen) return null;
///Finds the integer value for the range between 0-9
int base = "0".codeUnitAt(0);
int maxRand = ("9".codeUnitAt(0) - base) + 1;
Random random = new Random();
///Randomly generates value from [maxRand], then adding base, which creates a UTF-16 encoded character to be converted into a
///string of one character between 0-9. This string is then returned.
return String.fromCharCodes([random.nextInt(maxRand) + base]);
}
///Generates a symbol when called
String? _generateSymbol() {
if (!_symGen) return null;
///Finds the integer value for the range between symbols !-.
///(note) which includes symbols !"#$%&'()*+,=.
int base = "!".codeUnitAt(0);
int maxRand = (".".codeUnitAt(0) - base) + 1;
Random random = new Random();
///Randomly generates value from [maxRand], then adding base, which creates a UTF-16 encoded character to be
///converted into a string of one character between !-. . This string is then returned.
return String.fromCharCodes([random.nextInt(maxRand) + base]);
}
///Toggles letter generation
void checkLetterGen(bool value) {
_letterGen = value;
}
///Toggles number generation
void checkNumGen(bool value) {
_numGen = value;
}
///Toggles symbol generation
void checkSymGen(bool value) {
_symGen = value;
}
///Returns the generated value to be used by generator app
String getGeneratedValue() {
return _generatedValue;
}
typedef StringGeneratorFunction = String Function();
class StringGenerators {
static const letters = 'abcdefghijklmnopqrstuvwxyz';
static const numbers = '1234567890';
static const symbols = '_';
static String getRandomString(
int length, {
hasLowercaseLetters = false,
hasUppercaseLetters = false,
hasNumbers = false,
hasSymbols = false,
isStrict = false,
}) {
var chars = '';
if (hasLowercaseLetters) chars += letters;
if (hasUppercaseLetters) chars += letters.toUpperCase();
if (hasNumbers) chars += numbers;
if (hasSymbols) chars += symbols;
assert(chars.isNotEmpty, 'chart empty');
if (!isStrict) {
return genString(length, chars);
}
var res = '';
var loose = length;
if (hasLowercaseLetters) {
loose -= 1;
res += genString(1, letters);
}
if (hasUppercaseLetters) {
loose -= 1;
res += genString(1, letters.toUpperCase());
}
if (hasNumbers) {
loose -= 1;
res += genString(1, numbers.toUpperCase());
}
if (hasSymbols) {
loose -= 1;
res += genString(1, symbols);
}
res += genString(loose, chars);
var shuffledlist = res.split('')..shuffle();
return shuffledlist.join();
}
static String genString(int length, String chars) {
return String.fromCharCodes(
Iterable.generate(
length,
(_) => chars.codeUnitAt(
_rnd.nextInt(chars.length),
),
),
);
}
static StringGeneratorFunction userPassword = () => getRandomString(
8,
hasLowercaseLetters: true,
hasUppercaseLetters: true,
hasNumbers: true,
isStrict: true,
);
static StringGeneratorFunction passwordSalt = () => getRandomString(
8,
hasLowercaseLetters: true,
);
static StringGeneratorFunction simpleId = () => getRandomString(
5,
hasLowercaseLetters: true,
);
static StringGeneratorFunction dbPassword = () => getRandomString(
40,
hasLowercaseLetters: true,
hasUppercaseLetters: true,
hasNumbers: true,
hasSymbols: true,
);
static StringGeneratorFunction dbStorageName = () => getRandomString(
6,
hasLowercaseLetters: true,
hasUppercaseLetters: true,
hasNumbers: true,
);
}

View File

@ -1,14 +0,0 @@
import 'dart:math';
const _chars =
'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890_';
Random _rnd = Random();
String getRandomString(int length, [chars = _chars]) => String.fromCharCodes(
Iterable.generate(
length,
(_) => chars.codeUnitAt(
_rnd.nextInt(chars.length),
),
),
);

View File

@ -28,7 +28,7 @@ packages:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.2.0"
async:
dependency: transitive
description:
@ -37,12 +37,12 @@ packages:
source: hosted
version: "2.6.1"
basic_utils:
dependency: "direct dev"
dependency: "direct main"
description:
name: basic_utils
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
version: "3.4.0"
bloc:
dependency: transitive
description:
@ -63,7 +63,7 @@ packages:
name: build
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
version: "2.0.3"
build_config:
dependency: transitive
description:
@ -84,7 +84,7 @@ packages:
name: build_resolvers
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
version: "2.0.4"
build_runner:
dependency: "direct dev"
description:
@ -112,7 +112,7 @@ packages:
name: built_value
url: "https://pub.dartlang.org"
source: hosted
version: "8.1.0"
version: "8.1.2"
characters:
dependency: transitive
description:
@ -140,7 +140,7 @@ packages:
name: cli_util
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.0"
version: "0.3.3"
clock:
dependency: transitive
description:
@ -168,7 +168,7 @@ packages:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0"
version: "3.0.1"
coverage:
dependency: transitive
description:
@ -196,7 +196,7 @@ packages:
name: cubit_form
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.16"
version: "1.0.18"
cupertino_icons:
dependency: "direct main"
description:
@ -210,7 +210,7 @@ packages:
name: dart_style
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
version: "2.0.3"
dio:
dependency: "direct main"
description:
@ -259,7 +259,7 @@ packages:
name: extended_masked_text
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.1"
version: "2.3.0"
fake_async:
dependency: transitive
description:
@ -306,14 +306,14 @@ packages:
name: flutter_bloc
url: "https://pub.dartlang.org"
source: hosted
version: "7.0.1"
version: "7.1.0"
flutter_launcher_icons:
dependency: "direct dev"
description:
name: flutter_launcher_icons
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.0"
version: "0.9.1"
flutter_localizations:
dependency: transitive
description: flutter
@ -325,14 +325,14 @@ packages:
name: flutter_markdown
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.2"
version: "0.6.4"
flutter_secure_storage:
dependency: "direct main"
description:
name: flutter_secure_storage
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.0"
version: "4.2.1"
flutter_test:
dependency: "direct dev"
description: flutter
@ -426,7 +426,7 @@ packages:
name: io
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
version: "1.0.3"
ionicons:
dependency: "direct main"
description:
@ -454,7 +454,7 @@ packages:
name: json_serializable
url: "https://pub.dartlang.org"
source: hosted
version: "4.1.3"
version: "4.1.4"
logging:
dependency: transitive
description:
@ -552,14 +552,14 @@ packages:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.0.2"
path_provider_macos:
dependency: transitive
description:
name: path_provider_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.0.2"
path_provider_platform_interface:
dependency: transitive
description:
@ -573,7 +573,7 @@ packages:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
version: "2.0.3"
pedantic:
dependency: transitive
description:
@ -601,14 +601,14 @@ packages:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.0.1"
pointycastle:
dependency: transitive
description:
name: pointycastle
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.2"
version: "3.3.0"
pool:
dependency: transitive
description:
@ -629,7 +629,7 @@ packages:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.1"
version: "4.2.3"
provider:
dependency: "direct main"
description:
@ -706,14 +706,14 @@ packages:
name: shared_preferences_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.0.2"
shared_preferences_macos:
dependency: transitive
description:
name: shared_preferences_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.0.2"
shared_preferences_platform_interface:
dependency: transitive
description:
@ -727,21 +727,21 @@ packages:
name: shared_preferences_web
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.0.1"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.0.2"
shelf:
dependency: transitive
description:
name: shelf
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.4"
version: "1.2.0"
shelf_packages_handler:
dependency: transitive
description:
@ -755,7 +755,7 @@ packages:
name: shelf_static
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
version: "1.1.0"
shelf_web_socket:
dependency: transitive
description:
@ -774,14 +774,14 @@ packages:
name: source_gen
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
version: "1.0.3"
source_helper:
dependency: transitive
description:
name: source_helper
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.2.1"
source_map_stack_trace:
dependency: transitive
description:
@ -886,42 +886,42 @@ packages:
name: url_launcher
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.6"
version: "6.0.9"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.0.1"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.0.1"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
version: "2.0.4"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
version: "2.0.2"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.0.1"
vector_math:
dependency: transitive
description:
@ -942,35 +942,35 @@ packages:
name: wakelock
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.2"
version: "0.5.3+3"
wakelock_macos:
dependency: transitive
description:
name: wakelock_macos
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.0+1"
version: "0.1.0+2"
wakelock_platform_interface:
dependency: transitive
description:
name: wakelock_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.1+1"
version: "0.2.1+2"
wakelock_web:
dependency: transitive
description:
name: wakelock_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0+1"
version: "0.2.0+2"
wakelock_windows:
dependency: transitive
description:
name: wakelock_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.0"
version: "0.1.0+1"
watcher:
dependency: transitive
description:
@ -998,7 +998,7 @@ packages:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.1"
version: "2.2.5"
xdg_directories:
dependency: transitive
description:
@ -1021,5 +1021,5 @@ packages:
source: hosted
version: "3.1.0"
sdks:
dart: ">=2.13.0 <3.0.0"
flutter: ">=2.0.0"
dart: ">=2.13.4 <3.0.0"
flutter: ">=2.2.3"

View File

@ -4,8 +4,8 @@ publish_to: 'none'
version: 0.1.3+5
environment:
sdk: '>=2.12.0 <3.0.0'
flutter: ">=2.0.0"
sdk: '>=2.13.4 <3.0.0'
flutter: ">=2.2.3"
dependencies:
flutter:
@ -16,9 +16,9 @@ dependencies:
dio: ^4.0.0-beta7
easy_localization: ^3.0.0
either_option: ^2.0.1-dev.1
equatable: ^2.0.0
equatable: ^2.0.3
fl_chart: ^0.35.0
flutter_bloc: ^7.0.0
flutter_bloc: ^7.1.0
flutter_markdown: ^0.6.0
flutter_secure_storage: ^4.1.0
get_it: ^6.0.0
@ -35,11 +35,11 @@ dependencies:
unicons: ^1.0.2
url_launcher: ^6.0.2
wakelock: ^0.5.0+2
basic_utils: ^3.4.0
dev_dependencies:
flutter_test:
sdk: flutter
basic_utils: ^3.0.0-nullsafety.1
build_runner: ^1.11.5
flutter_launcher_icons: ^0.9.0
hive_generator: ^1.0.0

View File

@ -1,30 +1,122 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility that Flutter provides. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:selfprivacy/main.dart';
import 'package:selfprivacy/utils/password_generator.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(MyApp());
group('StringGenerators', () {
group('Basic', () {
test('assert chart empty', () {
expect(() {
StringGenerators.getRandomString(8);
}, throwsAssertionError);
});
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
test('only lowercase string', () {
var length = 8;
var generatedString =
StringGenerators.getRandomString(length, hasLowercaseLetters: true);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
expect(generatedString, isNot(matches(regExpNewLines)));
expect(generatedString, isNot(matches(regExpWhiteSpaces)));
expect(generatedString, isNot(matches(regExpNumbers)));
expect(generatedString, isNot(matches(regExpUppercaseLetters)));
expect(generatedString, isNot(matches(regExpSymbols)));
expect(generatedString.length, equals(length));
expect(generatedString, matches(regExpLowercaseLetters));
});
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
test('only uppercase string', () {
var length = 8;
var generatedString = StringGenerators.getRandomString(length,
hasLowercaseLetters: false, hasUppercaseLetters: true);
expect(generatedString, isNot(matches(regExpNewLines)));
expect(generatedString, isNot(matches(regExpWhiteSpaces)));
expect(generatedString, isNot(matches(regExpNumbers)));
expect(generatedString, isNot(matches(regExpLowercaseLetters)));
expect(generatedString, isNot(matches(regExpSymbols)));
expect(generatedString.length, equals(length));
expect(generatedString, matches(regExpUppercaseLetters));
});
test('only numbers string', () {
var length = 8;
var generatedString = StringGenerators.getRandomString(length,
hasLowercaseLetters: false,
hasUppercaseLetters: false,
hasNumbers: true);
expect(generatedString, isNot(matches(regExpNewLines)));
expect(generatedString, isNot(matches(regExpWhiteSpaces)));
expect(generatedString, isNot(matches(regExpUppercaseLetters)));
expect(generatedString, isNot(matches(regExpLowercaseLetters)));
expect(generatedString, isNot(matches(regExpSymbols)));
expect(generatedString.length, equals(length));
expect(generatedString, matches(regExpNumbers));
});
test('only symbols string', () {
var length = 8;
var generatedString = StringGenerators.getRandomString(
length,
hasLowercaseLetters: false,
hasUppercaseLetters: false,
hasNumbers: false,
hasSymbols: true,
);
expect(generatedString, isNot(matches(regExpNewLines)));
expect(generatedString, isNot(matches(regExpWhiteSpaces)));
expect(generatedString, isNot(matches(regExpUppercaseLetters)));
expect(generatedString, isNot(matches(regExpLowercaseLetters)));
expect(generatedString, isNot(matches(regExpNumbers)));
expect(generatedString.length, equals(length));
expect(generatedString, matches(regExpSymbols));
});
});
group('Strict mode', () {
test('All', () {
var length = 5;
var generatedString = StringGenerators.getRandomString(length,
hasLowercaseLetters: true,
hasUppercaseLetters: true,
hasNumbers: true,
hasSymbols: true,
isStrict: true);
expect(generatedString, isNot(matches(regExpNewLines)));
expect(generatedString, isNot(matches(regExpWhiteSpaces)));
expect(generatedString, matches(regExpLowercaseLetters));
expect(generatedString, matches(regExpUppercaseLetters));
expect(generatedString, matches(regExpNumbers));
expect(generatedString, matches(regExpSymbols));
expect(generatedString.length, equals(length));
});
test('Lowercase letters and numbers', () {
var length = 3;
var generatedString = StringGenerators.getRandomString(length,
hasLowercaseLetters: true,
hasUppercaseLetters: false,
hasNumbers: true,
hasSymbols: false,
isStrict: true);
expect(generatedString, isNot(matches(regExpNewLines)));
expect(generatedString, isNot(matches(regExpWhiteSpaces)));
expect(generatedString, isNot(matches(regExpUppercaseLetters)));
expect(generatedString, isNot(matches(regExpSymbols)));
expect(generatedString, matches(regExpLowercaseLetters));
expect(generatedString, matches(regExpNumbers));
expect(generatedString.length, equals(length));
});
});
});
}
var regExpNewLines = RegExp(r"[\n\r]+");
var regExpWhiteSpaces = RegExp(r"[\s]+");
var regExpUppercaseLetters = RegExp(r"[A-Z]");
var regExpLowercaseLetters = RegExp(r"[a-z]");
var regExpNumbers = RegExp(r"[0-9]");
var regExpSymbols = RegExp(r'(?:_|[^\w\s])+');