kopia lustrzana https://gitlab.com/mysocialportal/relatica
141 wiersze
3.9 KiB
Dart
141 wiersze
3.9 KiB
Dart
import 'dart:collection';
|
|
import 'dart:convert';
|
|
|
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
import 'package:result_monad/result_monad.dart';
|
|
|
|
import '../globals.dart';
|
|
import '../models/auth/basic_credentials.dart';
|
|
import '../models/auth/credentials_intf.dart';
|
|
import '../models/auth/oauth_credentials.dart';
|
|
import '../models/auth/profile.dart';
|
|
import '../models/exec_error.dart';
|
|
|
|
const _storageAccountName = 'social.myportal.relatica.secure_storage';
|
|
|
|
class SecretsService {
|
|
static const _basicProfilesKey = 'basic_profiles';
|
|
static const _oauthProfilesKey = 'oauth_profiles';
|
|
|
|
final _cachedProfiles = <Profile>{};
|
|
|
|
List<Profile> get profiles =>
|
|
UnmodifiableListView(List.from(_cachedProfiles));
|
|
|
|
final _secureStorage = const FlutterSecureStorage(
|
|
iOptions: IOSOptions(
|
|
accountName: _storageAccountName,
|
|
accessibility: KeychainAccessibility.first_unlock,
|
|
),
|
|
mOptions: MacOsOptions(
|
|
accountName: _storageAccountName,
|
|
groupId: macOsGroupId,
|
|
),
|
|
);
|
|
|
|
FutureResult<List<Profile>, ExecError> initialize() async {
|
|
return await loadProfiles();
|
|
}
|
|
|
|
FutureResult<List<Profile>, ExecError> clearCredentials() async {
|
|
try {
|
|
await _secureStorage.delete(key: _basicProfilesKey);
|
|
await _secureStorage.delete(key: _oauthProfilesKey);
|
|
profiles.clear();
|
|
return Result.ok(profiles);
|
|
} catch (e) {
|
|
return Result.error(ExecError(
|
|
type: ErrorType.localError,
|
|
message: e.toString(),
|
|
));
|
|
}
|
|
}
|
|
|
|
FutureResult<List<Profile>, ExecError> addOrUpdateProfile(
|
|
Profile profile) async {
|
|
try {
|
|
_cachedProfiles.remove(profile);
|
|
_cachedProfiles.add(profile);
|
|
return await saveCredentials();
|
|
} catch (e) {
|
|
return Result.error(ExecError(
|
|
type: ErrorType.localError,
|
|
message: e.toString(),
|
|
));
|
|
}
|
|
}
|
|
|
|
FutureResult<List<Profile>, ExecError> removeProfile(Profile profile) async {
|
|
try {
|
|
_cachedProfiles.remove(profile);
|
|
return await saveCredentials();
|
|
} catch (e) {
|
|
return Result.error(ExecError(
|
|
type: ErrorType.localError,
|
|
message: e.toString(),
|
|
));
|
|
}
|
|
}
|
|
|
|
FutureResult<List<Profile>, ExecError> loadProfiles() async {
|
|
try {
|
|
await _loadJson(_basicProfilesKey, BasicCredentials.fromJson);
|
|
await _loadJson(_oauthProfilesKey, OAuthCredentials.fromJson);
|
|
return Result.ok(profiles);
|
|
} catch (e) {
|
|
return Result.error(ExecError(
|
|
type: ErrorType.localError,
|
|
message: e.toString(),
|
|
));
|
|
}
|
|
}
|
|
|
|
FutureResult<List<Profile>, ExecError> saveCredentials() async {
|
|
try {
|
|
await _saveJson<BasicCredentials>(_basicProfilesKey);
|
|
await _saveJson<OAuthCredentials>(_oauthProfilesKey);
|
|
return Result.ok(profiles);
|
|
} catch (e) {
|
|
return Result.error(ExecError(
|
|
type: ErrorType.localError,
|
|
message: e.toString(),
|
|
));
|
|
}
|
|
}
|
|
|
|
Future<void> _loadJson(
|
|
String key,
|
|
ICredentials Function(Map<String, dynamic>) fromJson,
|
|
) async {
|
|
final jsonString = await _secureStorage.read(key: key);
|
|
if (jsonString == null || jsonString.isEmpty) {
|
|
return;
|
|
}
|
|
final profiles = (jsonDecode(jsonString) as List<dynamic>)
|
|
.map((json) => Profile.fromJson(json, fromJson))
|
|
.toList();
|
|
_cachedProfiles.addAll(profiles);
|
|
}
|
|
|
|
FutureResult<bool, ExecError> _saveJson<T>(
|
|
String key,
|
|
) async {
|
|
final json = _cachedProfiles
|
|
.where((p) => p.credentials is T)
|
|
.map((p) => p.toJson())
|
|
.toList();
|
|
final jsonString = jsonEncode(json);
|
|
await _secureStorage.write(key: key, value: jsonString);
|
|
final pulledResult = await _secureStorage.read(key: key);
|
|
if (pulledResult == jsonString) {
|
|
return Result.ok(true);
|
|
}
|
|
|
|
return buildErrorResult(
|
|
type: ErrorType.localError,
|
|
message:
|
|
'For key $key value read from secure storage did not match value to secure storage',
|
|
);
|
|
}
|
|
}
|