-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
TW-2220: Add new func to mapping Fed server data from well-know
- Loading branch information
Showing
16 changed files
with
530 additions
and
30 deletions.
There are no files selected for viewing
12 changes: 12 additions & 0 deletions
12
lib/data/datasource/federation_configurations_datasource.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import 'package:fluffychat/data/model/federation_server/federation_configuration.dart'; | ||
|
||
abstract class FederationConfigurationsDatasource { | ||
Future<FederationConfigurations> getFederationConfigurations(String userId); | ||
|
||
Future<void> saveFederationConfigurations( | ||
String userId, | ||
FederationConfigurations federationConfiguration, | ||
); | ||
|
||
Future<void> deleteFederationConfigurations(String userId); | ||
} |
68 changes: 68 additions & 0 deletions
68
lib/data/datasource_impl/federation_configurations_datasource_impl.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import 'package:fluffychat/data/datasource/federation_configurations_datasource.dart'; | ||
import 'package:fluffychat/data/hive/dto/federation_configurations_hive_obj.dart'; | ||
import 'package:fluffychat/data/hive/hive_collection_federation_database.dart'; | ||
import 'package:fluffychat/data/model/federation_server/federation_configuration.dart'; | ||
import 'package:fluffychat/di/global/get_it_initializer.dart'; | ||
import 'package:fluffychat/domain/exception/federation_configuration_not_found.dart'; | ||
import 'package:matrix/matrix.dart'; | ||
|
||
class HiveFederationConfigurationsDatasourceImpl | ||
implements FederationConfigurationsDatasource { | ||
@override | ||
Future<FederationConfigurations> getFederationConfigurations( | ||
String userId, | ||
) async { | ||
final hiveCollectionFederationDatabase = | ||
await getIt.getAsync<HiveCollectionFederationDatabase>(); | ||
final cachedFederationConfigurations = | ||
await hiveCollectionFederationDatabase.federationConfigurationsBox | ||
.get(userId); | ||
if (cachedFederationConfigurations != null) { | ||
final federationConfigurationsHiveObj = | ||
FederationConfigurationsHiveObj.fromJson( | ||
copyMap( | ||
cachedFederationConfigurations, | ||
), | ||
); | ||
|
||
return FederationConfigurations( | ||
fedServerInformation: federationConfigurationsHiveObj | ||
.federationServerInformation | ||
.toFederationServerInformation(), | ||
identityServerInformation: | ||
federationConfigurationsHiveObj.identityServerUrl != null | ||
? IdentityServerInformation( | ||
baseUrl: Uri.parse( | ||
federationConfigurationsHiveObj.identityServerUrl!, | ||
), | ||
) | ||
: null, | ||
); | ||
} | ||
throw FederationConfigurationNotFound(); | ||
} | ||
|
||
@override | ||
Future<void> saveFederationConfigurations( | ||
String userId, | ||
FederationConfigurations federationConfiguration, | ||
) async { | ||
final hiveCollectionFederationDatabase = | ||
await getIt.getAsync<HiveCollectionFederationDatabase>(); | ||
return hiveCollectionFederationDatabase.federationConfigurationsBox.put( | ||
userId, | ||
FederationConfigurationsHiveObj.fromFederationConfigurations( | ||
federationConfiguration, | ||
).toJson(), | ||
); | ||
} | ||
|
||
@override | ||
Future<void> deleteFederationConfigurations(String userId) async { | ||
final hiveCollectionFederationDatabase = | ||
getIt.get<HiveCollectionFederationDatabase>(); | ||
return hiveCollectionFederationDatabase.federationConfigurationsBox.delete( | ||
userId, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import 'package:equatable/equatable.dart'; | ||
import 'package:fluffychat/data/hive/dto/federation_server_information_hive_obj.dart'; | ||
import 'package:fluffychat/data/model/federation_server/federation_configuration.dart'; | ||
import 'package:json_annotation/json_annotation.dart'; | ||
|
||
part 'federation_configurations_hive_obj.g.dart'; | ||
|
||
@JsonSerializable(explicitToJson: true) | ||
class FederationConfigurationsHiveObj with EquatableMixin { | ||
final FederationServerInformationHiveObj federationServerInformation; | ||
|
||
final String? identityServerUrl; | ||
|
||
FederationConfigurationsHiveObj({ | ||
required this.federationServerInformation, | ||
required this.identityServerUrl, | ||
}); | ||
|
||
factory FederationConfigurationsHiveObj.fromFederationConfigurations( | ||
FederationConfigurations federationConfigurations, | ||
) { | ||
return FederationConfigurationsHiveObj( | ||
federationServerInformation: | ||
FederationServerInformationHiveObj.fromFederationServerInformation( | ||
federationConfigurations.fedServerInformation, | ||
), | ||
identityServerUrl: federationConfigurations | ||
.identityServerInformation?.baseUrl | ||
.toString(), | ||
); | ||
} | ||
|
||
factory FederationConfigurationsHiveObj.fromJson(Map<String, dynamic> json) => | ||
_$FederationConfigurationsHiveObjFromJson(json); | ||
|
||
Map<String, dynamic> toJson() => | ||
_$FederationConfigurationsHiveObjToJson(this); | ||
|
||
@override | ||
List<Object?> get props => [ | ||
federationServerInformation, | ||
identityServerUrl, | ||
]; | ||
} |
40 changes: 40 additions & 0 deletions
40
lib/data/hive/dto/federation_server_information_hive_obj.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import 'package:equatable/equatable.dart'; | ||
import 'package:fluffychat/data/model/federation_server/federation_server_information.dart'; | ||
import 'package:json_annotation/json_annotation.dart'; | ||
|
||
part 'federation_server_information_hive_obj.g.dart'; | ||
|
||
@JsonSerializable(explicitToJson: true) | ||
class FederationServerInformationHiveObj with EquatableMixin { | ||
final List<String>? baseUrls; | ||
|
||
FederationServerInformationHiveObj({ | ||
required this.baseUrls, | ||
}); | ||
|
||
factory FederationServerInformationHiveObj.fromJson( | ||
Map<String, dynamic> json, | ||
) => | ||
_$FederationServerInformationHiveObjFromJson(json); | ||
|
||
Map<String, dynamic> toJson() => | ||
_$FederationServerInformationHiveObjToJson(this); | ||
|
||
FederationServerInformation toFederationServerInformation() { | ||
return FederationServerInformation( | ||
baseUrls: baseUrls?.map((e) => Uri.parse(e)).toList(), | ||
); | ||
} | ||
|
||
factory FederationServerInformationHiveObj.fromFederationServerInformation( | ||
FederationServerInformation fedServerInformation, | ||
) { | ||
return FederationServerInformationHiveObj( | ||
baseUrls: | ||
fedServerInformation.baseUrls?.map((e) => e.toString()).toList(), | ||
); | ||
} | ||
|
||
@override | ||
List<Object?> get props => [baseUrls]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
import 'dart:convert'; | ||
import 'dart:io'; | ||
|
||
import 'package:fluffychat/utils/matrix_sdk_extensions/flutter_hive_collections_database.dart'; | ||
import 'package:fluffychat/utils/platform_infos.dart'; | ||
import 'package:flutter/foundation.dart'; | ||
import 'package:flutter/services.dart'; | ||
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; | ||
import 'package:hive/hive.dart'; | ||
import 'package:matrix/matrix.dart'; | ||
import 'package:path_provider/path_provider.dart'; | ||
|
||
class HiveCollectionFederationDatabase { | ||
final String name; | ||
final String? path; | ||
final HiveCipher? key; | ||
|
||
late BoxCollection _collection; | ||
|
||
String get _federationConfigurationsBoxName => | ||
'federation_configurations_box'; | ||
late CollectionBox<Map> federationConfigurationsBox; | ||
|
||
HiveCollectionFederationDatabase(this.name, this.path, {this.key}); | ||
|
||
static Future<HiveCollectionFederationDatabase> databaseBuilder() async { | ||
Logs().d('Open Hive for Federation...'); | ||
HiveAesCipher? hiverCipher; | ||
try { | ||
// Workaround for secure storage is calling Platform.operatingSystem on web | ||
if (kIsWeb || PlatformInfos.isIOS) { | ||
// ignore: unawaited_futures | ||
throw MissingPluginException(); | ||
} | ||
|
||
const secureStorage = FlutterSecureStorage(); | ||
final containsEncryptionKey = await secureStorage.read( | ||
key: FlutterHiveCollectionsDatabase.cipherStorageKey, | ||
) != | ||
null; | ||
if (!containsEncryptionKey) { | ||
// do not try to create a buggy secure storage for new Linux users | ||
if (Platform.isLinux) throw MissingPluginException(); | ||
final key = Hive.generateSecureKey(); | ||
await secureStorage.write( | ||
key: FlutterHiveCollectionsDatabase.cipherStorageKey, | ||
value: base64UrlEncode(key), | ||
); | ||
} | ||
|
||
// workaround for if we just wrote to the key and it still doesn't exist | ||
final rawEncryptionKey = await secureStorage.read( | ||
key: FlutterHiveCollectionsDatabase.cipherStorageKey, | ||
); | ||
if (rawEncryptionKey == null) throw MissingPluginException(); | ||
|
||
hiverCipher = HiveAesCipher(base64Url.decode(rawEncryptionKey)); | ||
} on MissingPluginException catch (_) { | ||
const FlutterSecureStorage() | ||
.delete(key: FlutterHiveCollectionsDatabase.cipherStorageKey) | ||
.catchError((_) {}); | ||
Logs().i('Hive encryption is not supported on this platform'); | ||
} catch (e, s) { | ||
const FlutterSecureStorage() | ||
.delete(key: FlutterHiveCollectionsDatabase.cipherStorageKey) | ||
.catchError((_) {}); | ||
Logs().w('Unable to init Hive encryption', e, s); | ||
} | ||
|
||
final db = HiveCollectionFederationDatabase( | ||
'hive_collections_federation', | ||
await _findDatabasePath(), | ||
key: hiverCipher, | ||
); | ||
try { | ||
await db.open(); | ||
} catch (e, s) { | ||
Logs().w('Unable to open Federation Hive.', e, s); | ||
const FlutterSecureStorage() | ||
.delete(key: FlutterHiveCollectionsDatabase.cipherStorageKey); | ||
await db.clear().catchError((_) {}); | ||
await Hive.deleteFromDisk(); | ||
rethrow; | ||
} | ||
Logs().d('Hive for Federation is ready'); | ||
return db; | ||
} | ||
|
||
static Future<String> _findDatabasePath({ | ||
String? path = 'federation_db', | ||
}) async { | ||
if (!kIsWeb) { | ||
Directory directory; | ||
try { | ||
if (Platform.isLinux) { | ||
directory = await getApplicationSupportDirectory(); | ||
} else { | ||
directory = await getApplicationDocumentsDirectory(); | ||
} | ||
} catch (_) { | ||
try { | ||
directory = await getLibraryDirectory(); | ||
} catch (_) { | ||
directory = Directory.current; | ||
} | ||
} | ||
// do not destroy your stable FluffyChat in debug mode | ||
directory = Directory( | ||
directory.uri.resolve(kDebugMode ? 'hive_debug' : 'hive').toFilePath(), | ||
); | ||
directory.create(recursive: true); | ||
path = directory.path; | ||
} | ||
return path!; | ||
} | ||
|
||
Future<void> open() async { | ||
_collection = await BoxCollection.open( | ||
name, | ||
{_federationConfigurationsBoxName}, | ||
path: path, | ||
key: key, | ||
); | ||
federationConfigurationsBox = await _collection.openBox( | ||
_federationConfigurationsBoxName, | ||
preload: true, | ||
); | ||
} | ||
|
||
Future<void> clear() async { | ||
await federationConfigurationsBox.clear(); | ||
if (PlatformInfos.isMobile) { | ||
await _collection.deleteFromDisk(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.