Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(repository): add environment prefix key #78

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/models/server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class Server {
/// Basic authentication password (Use only v5)
final String? basicAuthPassword;

/// Session manager (Use only v5)
/// Session manager (Use only v6)
final SessionManager sm;

Server({
Expand All @@ -42,7 +42,7 @@ class Server {
this.basicAuthUser,
this.basicAuthPassword,
SessionManager? sm,
}) : sm = sm ?? SessionManager(SecureStorageRepository(), address);
}) : sm = sm ?? SessionManager(SecureStorageRepository(address: address));

Server copyWith({
String? address,
Expand Down
79 changes: 26 additions & 53 deletions lib/repository/database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -143,22 +143,18 @@
});

// Load sensitive data from secure storage
final passCode = await _secureStorage.getValue('passCode');
final passCode = await _secureStorage.passCode;
appConfig = AppDbData.withSecrets(appConfig!, passCode);

// _secureStorage.readAll()
logger.d((await _secureStorage.readAll()).toString());
logger.d((await _secureStorage.readEnvironmentData()).toString());

if (servers != null && servers!.isNotEmpty) {
for (int i = 0; i < servers!.length; i++) {
final server = servers![i];
final token =
await _secureStorage.getValue('${server.address}_token');
final basicAuthUser = await _secureStorage
.getValue('${server.address}_basicAuthUser');
final basicAuthPassword = await _secureStorage
.getValue('${server.address}_basicAuthPassword');
final sid = await _secureStorage.getValue('${server.address}_sid');
final token = await _secureStorage.token;
final basicAuthUser = await _secureStorage.basicAuthUser;
final basicAuthPassword = await _secureStorage.basicAuthPassword;
final sid = await _secureStorage.sid;

servers![i] = ServerDbData.withSecrets(
server,
Expand Down Expand Up @@ -210,33 +206,21 @@
Future<bool?> saveServerQuery(Server server) async {
try {
if (server.token != null) {
await _secureStorage.saveValue(
'${server.address}_token',
server.token!,
);
await _secureStorage.saveToken(server.token);

Check warning on line 209 in lib/repository/database.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/database.dart#L209

Added line #L209 was not covered by tests
}
if (server.basicAuthUser != null) {
await _secureStorage.saveValue(
'${server.address}_basicAuthUser',
server.basicAuthUser!,
);
await _secureStorage.saveBasicAuthUser(server.basicAuthUser);

Check warning on line 212 in lib/repository/database.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/database.dart#L212

Added line #L212 was not covered by tests
}
if (server.basicAuthPassword != null) {
await _secureStorage.saveValue(
'${server.address}_basicAuthPassword',
server.basicAuthPassword!,
);
await _secureStorage.saveBasicAuthPassword(server.basicAuthPassword);

Check warning on line 215 in lib/repository/database.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/database.dart#L215

Added line #L215 was not covered by tests
}

final password = await server.sm.password;
if (password != null) {
await _secureStorage.saveValue('${server.address}_password', password);
await _secureStorage.savePassword(password);

Check warning on line 220 in lib/repository/database.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/database.dart#L220

Added line #L220 was not covered by tests
}
if (server.sm.sid != null) {
await _secureStorage.saveValue(
'${server.address}_sid',
server.sm.sid ?? '',
);
await _secureStorage.saveSid(server.sm.sid);

Check warning on line 223 in lib/repository/database.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/database.dart#L223

Added line #L223 was not covered by tests
}

await _dbInstance.transaction((txn) async {
Expand Down Expand Up @@ -278,29 +262,20 @@
Future<bool> editServerQuery(Server server) async {
try {
if (server.token != null) {
await _secureStorage.saveValue(
'${server.address}_token',
server.token!,
);
await _secureStorage.saveToken(server.token);

Check warning on line 265 in lib/repository/database.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/database.dart#L265

Added line #L265 was not covered by tests
}
if (server.basicAuthUser != null) {
await _secureStorage.saveValue(
'${server.address}_basicAuthUser',
server.basicAuthUser!,
);
await _secureStorage.saveBasicAuthUser(server.basicAuthUser);

Check warning on line 268 in lib/repository/database.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/database.dart#L268

Added line #L268 was not covered by tests
}
if (server.basicAuthPassword != null) {
await _secureStorage.saveValue(
'${server.address}_basicAuthPassword',
server.basicAuthPassword!,
);
await _secureStorage.saveBasicAuthPassword(server.basicAuthPassword);

Check warning on line 271 in lib/repository/database.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/database.dart#L271

Added line #L271 was not covered by tests
}
final password = await server.sm.password;
if (password != null) {
await _secureStorage.saveValue('${server.address}_password', password);
await _secureStorage.savePassword(password);

Check warning on line 275 in lib/repository/database.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/database.dart#L275

Added line #L275 was not covered by tests
}
if (server.sm.sid != null) {
await _secureStorage.saveValue('${server.address}_sid', server.sm.sid!);
await _secureStorage.saveSid(server.sm.sid);

Check warning on line 278 in lib/repository/database.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/database.dart#L278

Added line #L278 was not covered by tests
}

return await _dbInstance.transaction((txn) async {
Expand Down Expand Up @@ -412,12 +387,12 @@
/// `false` if it fails.
Future<bool> removeServerQuery(String address) async {
try {
await _secureStorage.deleteValue('${address}_token');
await _secureStorage.deleteValue('${address}_basicAuthUser');
await _secureStorage.deleteValue('${address}_basicAuthPassword');
await _secureStorage.deleteValue('${address}_password');
await _secureStorage.deleteValue('${address}_sid');
logger.d((await _secureStorage.readAll()).toString());
await _secureStorage.saveToken(null);
await _secureStorage.saveBasicAuthUser(null);
await _secureStorage.saveBasicAuthPassword(null);
await _secureStorage.savePassword(null);
await _secureStorage.saveSid(null);
logger.d((await _secureStorage.readEnvironmentData()).toString());

Check warning on line 395 in lib/repository/database.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/database.dart#L390-L395

Added lines #L390 - L395 were not covered by tests

return await _dbInstance.transaction((txn) async {
await txn.delete('servers', where: 'address = ?', whereArgs: [address]);
Expand All @@ -440,7 +415,7 @@
/// `false` if it fails.
Future<bool> deleteServersDataQuery() async {
try {
await _secureStorage.clearAll();
await _secureStorage.deleteEnvironmentData();
return await _dbInstance.transaction((txn) async {
await txn.delete(
'servers',
Expand Down Expand Up @@ -506,12 +481,10 @@
try {
if (column == 'passCode') {
if (value == null) {
await _secureStorage.deleteValue('passCode');
return true;
return await _secureStorage.savePassCode(null);
}

await _secureStorage.saveValue('passCode', value.toString());
return true;
return await _secureStorage.savePassCode(value.toString());
}

return await _dbInstance.transaction((txn) async {
Expand Down Expand Up @@ -540,7 +513,7 @@
/// `false` if it fails.
Future<bool> restoreAppConfigQuery() async {
try {
await _secureStorage.deleteValue('passCode');
await _secureStorage.savePassCode(null);
return await _dbInstance.transaction((txn) async {
await txn.update(
'appConfig',
Expand Down
167 changes: 153 additions & 14 deletions lib/repository/secure_storage.dart
Original file line number Diff line number Diff line change
@@ -1,33 +1,172 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

/// Secure storage repository
///
/// This class is used to store and retrieve sensitive data securely.
///
/// Parameters:
/// - [secureStorage]: FlutterSecureStorage instance: Secure storage instance
/// - [address]: String: Server address. Default is 'http://localhost:80'
/// - [environment]: String: Environment name. Default is 'prd'
class SecureStorageRepository {
final FlutterSecureStorage _secureStorage;
final String _address;
final String _environment;

SecureStorageRepository({FlutterSecureStorage? secureStorage})
: _secureStorage = secureStorage ?? const FlutterSecureStorage();
Future<String?> get sid async {
return await _readValue(_sidKey);
}

Future<String?> get password async {
return await _readValue(_passwordKey);

Check warning on line 21 in lib/repository/secure_storage.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/secure_storage.dart#L20-L21

Added lines #L20 - L21 were not covered by tests
}

Future<String?> get token async {
return await _readValue(_tokenKey);

Check warning on line 25 in lib/repository/secure_storage.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/secure_storage.dart#L24-L25

Added lines #L24 - L25 were not covered by tests
}

Future<String?> get basicAuthUser async {
return await _readValue(_basicAuthUserKey);

Check warning on line 29 in lib/repository/secure_storage.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/secure_storage.dart#L28-L29

Added lines #L28 - L29 were not covered by tests
}

Future<String?> get basicAuthPassword async {
return await _readValue(_basicAuthPasswordKey);

Check warning on line 33 in lib/repository/secure_storage.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/secure_storage.dart#L32-L33

Added lines #L32 - L33 were not covered by tests
}

Future<String?> get passCode async {
return await _readValue(_passCodeKey);
}

String get _sidKey => '${_environment}_${_address}_sid';
String get _passwordKey => '${_environment}_${_address}_password';
String get _tokenKey => '${_environment}_${_address}_token';
String get _basicAuthUserKey => '${_environment}_${_address}_basicAuthUser';
String get _basicAuthPasswordKey =>
'${_environment}_${_address}_basicAuthPassword';

Check warning on line 45 in lib/repository/secure_storage.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/secure_storage.dart#L42-L45

Added lines #L42 - L45 were not covered by tests
String get _passCodeKey => '${_environment}_passCode';

SecureStorageRepository({
FlutterSecureStorage? secureStorage,
String? address,
String? environment,
}) : _secureStorage = secureStorage ?? const FlutterSecureStorage(),
_address = address ?? 'http://localhost',
_environment = environment ?? 'prd';

Future<bool> saveSid(String? sid) async {
return await _writeValue(_sidKey, sid);

Check warning on line 57 in lib/repository/secure_storage.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/secure_storage.dart#L56-L57

Added lines #L56 - L57 were not covered by tests
}

// Save a value securely
Future<void> saveValue(String key, String value) async {
await _secureStorage.write(key: key, value: value);
Future<bool> savePassword(String? password) async {
return await _writeValue(_passwordKey, password);
}

// Retrieve a value securely
Future<String?> getValue(String key) async {
return await _secureStorage.read(key: key);
Future<bool> saveToken(String? token) async {
return await _writeValue(_tokenKey, token);

Check warning on line 65 in lib/repository/secure_storage.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/secure_storage.dart#L64-L65

Added lines #L64 - L65 were not covered by tests
}

// Delete a value
Future<void> deleteValue(String key) async {
await _secureStorage.delete(key: key);
Future<bool> saveBasicAuthUser(String? basicAuthUser) async {
return await _writeValue(_basicAuthUserKey, basicAuthUser);

Check warning on line 69 in lib/repository/secure_storage.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/secure_storage.dart#L68-L69

Added lines #L68 - L69 were not covered by tests
}

// Clear all values
Future<void> clearAll() async {
await _secureStorage.deleteAll();
Future<bool> saveBasicAuthPassword(String? basicAuthPassword) async {
return await _writeValue(_basicAuthPasswordKey, basicAuthPassword);

Check warning on line 73 in lib/repository/secure_storage.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/secure_storage.dart#L72-L73

Added lines #L72 - L73 were not covered by tests
}

Future<bool> savePassCode(String? passCode) async {
return await _writeValue(_passCodeKey, passCode);
}

/// Read all environment data
///
/// This method reads all values stored in the secure storage for a specific environment.
Future<Map<String, String>> readEnvironmentData({String? environment}) async {
try {
final allData = await _secureStorage.readAll();
final environmentData = Map<String, String>.fromEntries(
allData.entries
.where((entry) => entry.key.startsWith(environment ?? _environment))
.map(
(entry) => MapEntry(
entry.key,
entry.value,

Check warning on line 92 in lib/repository/secure_storage.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/secure_storage.dart#L90-L92

Added lines #L90 - L92 were not covered by tests
),
),
);
return environmentData;
} catch (e) {
return {};

Check warning on line 98 in lib/repository/secure_storage.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/secure_storage.dart#L98

Added line #L98 was not covered by tests
}
}

/// Delete all environment data
///
/// This method deletes all values stored in the secure storage for a specific environment.
Future<bool> deleteEnvironmentData({String? environment}) async {

Check warning on line 105 in lib/repository/secure_storage.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/secure_storage.dart#L105

Added line #L105 was not covered by tests
try {
final allData = await _secureStorage.readAll();
final environmentKeys = allData.keys
.where((key) => key.startsWith(environment ?? _environment))
.toList();

Check warning on line 110 in lib/repository/secure_storage.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/secure_storage.dart#L107-L110

Added lines #L107 - L110 were not covered by tests

for (final key in environmentKeys) {
await _secureStorage.delete(key: key);

Check warning on line 113 in lib/repository/secure_storage.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/secure_storage.dart#L112-L113

Added lines #L112 - L113 were not covered by tests
}
return true;
} catch (e) {
return false;
}
}

/// Read all values
///
/// This method reads all values stored in the secure storage.
Future<Map<String, String>> readAll() async {
Map<String, String> allValues = await _secureStorage.readAll();
return allValues;
}

/// Delete all values
///
/// This method deletes all values stored in the secure storage.
Future<bool> deleteAll() async {

Check warning on line 132 in lib/repository/secure_storage.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/secure_storage.dart#L132

Added line #L132 was not covered by tests
try {
await _secureStorage.deleteAll();

Check warning on line 134 in lib/repository/secure_storage.dart

View check run for this annotation

Codecov / codecov/patch

lib/repository/secure_storage.dart#L134

Added line #L134 was not covered by tests
return true;
} catch (e) {
return false;
}
}

/// Read a value, if the key does not exist, return null
Future<String?> _readValue(String key) async {
try {
return await _secureStorage.read(key: key);
} catch (e) {
return null;
}
}

/// Write a value, if the value is null, delete the key
Future<bool> _writeValue(String key, String? value) async {
try {
if (value == null) {
return await _deleteValue(key);
}
await _secureStorage.write(key: key, value: value);
return true;
} catch (e) {
return false;
}
}

/// Delete a value
Future<bool> _deleteValue(String key) async {
try {
await _secureStorage.delete(key: key);
return true;
} catch (e) {
return false;
}
}
}
Loading
Loading