mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-08 00:51:20 +00:00
fix: Implement Backblaze bucket restoration on server recovery (#324)
Resolves issue [320](https://git.selfprivacy.org/SelfPrivacy/selfprivacy.org.app/issues/320). Co-authored-by: NaiJi <naijiworld@protonmail.com> Reviewed-on: https://git.selfprivacy.org/SelfPrivacy/selfprivacy.org.app/pulls/324 Reviewed-by: Inex Code <inex.code@selfprivacy.org>
This commit is contained in:
parent
1642cb907d
commit
82dfdf04f9
|
@ -2,6 +2,8 @@ import 'dart:io';
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:selfprivacy/config/get_it_config.dart';
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/backup.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/backups_credential.dart';
|
import 'package:selfprivacy/logic/models/hive/backups_credential.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/generic_result.dart';
|
import 'package:selfprivacy/logic/api_maps/generic_result.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/rest_api_map.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/rest_api_map.dart';
|
||||||
|
@ -179,6 +181,42 @@ class BackblazeApi extends RestApiMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<BackblazeBucket?> fetchBucket(
|
||||||
|
final BackupsCredential credentials,
|
||||||
|
final BackupConfiguration configuration,
|
||||||
|
) async {
|
||||||
|
BackblazeBucket? bucket;
|
||||||
|
final BackblazeApiAuth auth = await getAuthorizationToken();
|
||||||
|
final Dio client = await getClient();
|
||||||
|
client.options.baseUrl = auth.apiUrl;
|
||||||
|
final Response response = await client.get(
|
||||||
|
'$apiPrefix/b2_list_buckets',
|
||||||
|
queryParameters: {
|
||||||
|
'accountId': getIt<ApiConfigModel>().backblazeCredential!.keyId,
|
||||||
|
},
|
||||||
|
options: Options(
|
||||||
|
headers: {'Authorization': auth.authorizationToken},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
close(client);
|
||||||
|
if (response.statusCode == HttpStatus.ok) {
|
||||||
|
for (final rawBucket in response.data['buckets']) {
|
||||||
|
if (rawBucket['bucketId'] == configuration.locationId) {
|
||||||
|
bucket = BackblazeBucket(
|
||||||
|
bucketId: rawBucket['bucketId'],
|
||||||
|
bucketName: rawBucket['bucketName'],
|
||||||
|
encryptionKey: configuration.encryptionKey,
|
||||||
|
applicationKeyId: '',
|
||||||
|
applicationKey: '',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bucket;
|
||||||
|
} else {
|
||||||
|
throw Exception('code: ${response.statusCode}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool hasLogger;
|
bool hasLogger;
|
||||||
|
|
||||||
|
|
|
@ -109,17 +109,34 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
|
||||||
|
|
||||||
Future<void> reuploadKey() async {
|
Future<void> reuploadKey() async {
|
||||||
emit(state.copyWith(preventActions: true));
|
emit(state.copyWith(preventActions: true));
|
||||||
final BackblazeBucket? bucket = getIt<ApiConfigModel>().backblazeBucket;
|
BackblazeBucket? bucket = getIt<ApiConfigModel>().backblazeBucket;
|
||||||
if (bucket == null) {
|
if (bucket == null) {
|
||||||
emit(state.copyWith(isInitialized: false));
|
emit(state.copyWith(isInitialized: false));
|
||||||
} else {
|
} else {
|
||||||
|
String login = bucket.applicationKeyId;
|
||||||
|
String password = bucket.applicationKey;
|
||||||
|
if (login.isEmpty || password.isEmpty) {
|
||||||
|
final BackblazeApplicationKey key =
|
||||||
|
await backblaze.createKey(bucket.bucketId);
|
||||||
|
login = key.applicationKeyId;
|
||||||
|
password = key.applicationKey;
|
||||||
|
bucket = BackblazeBucket(
|
||||||
|
bucketId: bucket.bucketId,
|
||||||
|
bucketName: bucket.bucketName,
|
||||||
|
encryptionKey: bucket.encryptionKey,
|
||||||
|
applicationKey: password,
|
||||||
|
applicationKeyId: login,
|
||||||
|
);
|
||||||
|
await getIt<ApiConfigModel>().storeBackblazeBucket(bucket);
|
||||||
|
emit(state.copyWith(backblazeBucket: bucket));
|
||||||
|
}
|
||||||
final GenericResult result = await api.initializeRepository(
|
final GenericResult result = await api.initializeRepository(
|
||||||
InitializeRepositoryInput(
|
InitializeRepositoryInput(
|
||||||
provider: BackupsProviderType.backblaze,
|
provider: BackupsProviderType.backblaze,
|
||||||
locationId: bucket.bucketId,
|
locationId: bucket.bucketId,
|
||||||
locationName: bucket.bucketName,
|
locationName: bucket.bucketName,
|
||||||
login: bucket.applicationKeyId,
|
login: login,
|
||||||
password: bucket.applicationKey,
|
password: password,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (result.success == false) {
|
if (result.success == false) {
|
||||||
|
@ -129,7 +146,7 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
emit(state.copyWith(preventActions: false));
|
emit(state.copyWith(preventActions: false));
|
||||||
getIt<NavigationService>().showSnackBar('backup.reuploaded_key');
|
getIt<NavigationService>().showSnackBar('backup.reuploaded_key'.tr());
|
||||||
await updateBackups();
|
await updateBackups();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,9 @@ import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:selfprivacy/config/get_it_config.dart';
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server_api.dart';
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server_api.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/rest_maps/backblaze.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/tls_options.dart';
|
import 'package:selfprivacy/logic/api_maps/tls_options.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/backups_credential.dart';
|
import 'package:selfprivacy/logic/models/hive/backups_credential.dart';
|
||||||
import 'package:selfprivacy/logic/models/callback_dialogue_branching.dart';
|
import 'package:selfprivacy/logic/models/callback_dialogue_branching.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||||
|
@ -199,8 +201,23 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
||||||
applicationKey: applicationKey,
|
applicationKey: applicationKey,
|
||||||
provider: BackupsProviderType.backblaze,
|
provider: BackupsProviderType.backblaze,
|
||||||
);
|
);
|
||||||
|
final BackblazeBucket? bucket;
|
||||||
await repository.saveBackblazeKey(backblazeCredential);
|
await repository.saveBackblazeKey(backblazeCredential);
|
||||||
if (state is ServerInstallationRecovery) {
|
if (state is ServerInstallationRecovery) {
|
||||||
|
final configuration = await ServerApi(
|
||||||
|
customToken:
|
||||||
|
(state as ServerInstallationRecovery).serverDetails!.apiToken,
|
||||||
|
isWithToken: true,
|
||||||
|
).getBackupsConfiguration();
|
||||||
|
if (configuration != null) {
|
||||||
|
try {
|
||||||
|
bucket = await BackblazeApi()
|
||||||
|
.fetchBucket(backblazeCredential, configuration);
|
||||||
|
await getIt<ApiConfigModel>().storeBackblazeBucket(bucket!);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
finishRecoveryProcess(backblazeCredential);
|
finishRecoveryProcess(backblazeCredential);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue