fix: Implement Backblaze bucket restoration on server recovery #324
|
@ -2,6 +2,8 @@ import 'dart:io';
|
|||
|
||||
import 'package:dio/dio.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/api_maps/generic_result.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: '',
|
||||
NaiJi marked this conversation as resolved
Outdated
|
||||
applicationKey: '',
|
||||
);
|
||||
}
|
||||
}
|
||||
return bucket;
|
||||
} else {
|
||||
throw Exception('code: ${response.statusCode}');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool hasLogger;
|
||||
|
||||
|
|
|
@ -109,17 +109,34 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
|
|||
|
||||
Future<void> reuploadKey() async {
|
||||
emit(state.copyWith(preventActions: true));
|
||||
final BackblazeBucket? bucket = getIt<ApiConfigModel>().backblazeBucket;
|
||||
BackblazeBucket? bucket = getIt<ApiConfigModel>().backblazeBucket;
|
||||
if (bucket == null) {
|
||||
emit(state.copyWith(isInitialized: false));
|
||||
} 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(
|
||||
InitializeRepositoryInput(
|
||||
provider: BackupsProviderType.backblaze,
|
||||
locationId: bucket.bucketId,
|
||||
locationName: bucket.bucketName,
|
||||
login: bucket.applicationKeyId,
|
||||
password: bucket.applicationKey,
|
||||
login: login,
|
||||
password: password,
|
||||
),
|
||||
);
|
||||
if (result.success == false) {
|
||||
|
@ -129,7 +146,7 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
|
|||
return;
|
||||
} else {
|
||||
emit(state.copyWith(preventActions: false));
|
||||
getIt<NavigationService>().showSnackBar('backup.reuploaded_key');
|
||||
getIt<NavigationService>().showSnackBar('backup.reuploaded_key'.tr());
|
||||
await updateBackups();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,9 @@ import 'package:easy_localization/easy_localization.dart';
|
|||
import 'package:equatable/equatable.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/rest_maps/backblaze.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/callback_dialogue_branching.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||
|
@ -199,8 +201,23 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
|||
applicationKey: applicationKey,
|
||||
provider: BackupsProviderType.backblaze,
|
||||
);
|
||||
final BackblazeBucket? bucket;
|
||||
await repository.saveBackblazeKey(backblazeCredential);
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Won't be correct, this is the key ID for the application key, which is the subkey generated using the primary key entered by user during restoration
And what does it mean? Should I force it to '' as well?
yes