mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-07 00:24:18 +00:00
Merge pull request 'Implement Dns Provider Api Abstractions' (#101) from dns-provider-api into develop
Reviewed-on: https://git.selfprivacy.org/kherel/selfprivacy.org.app/pulls/101
This commit is contained in:
commit
2c9dcbe5e6
|
@ -1,23 +1,37 @@
|
|||
import 'package:selfprivacy/logic/api_maps/rest_maps/providers/hetzner/hetzner_factory.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/providers/provider_factory.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/cloudflare/cloudflare_factory.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/hetzner/hetzner_factory.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider_factory.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||
|
||||
class UnknownApiProviderException implements Exception {
|
||||
UnknownApiProviderException(this.message);
|
||||
final String message;
|
||||
}
|
||||
|
||||
class ApiFactoryCreator {
|
||||
static ProviderApiFactory createProviderApiFactory(
|
||||
static ServerProviderApiFactory createServerProviderApiFactory(
|
||||
final ServerProvider provider,
|
||||
) {
|
||||
switch (provider) {
|
||||
case ServerProvider.hetzner:
|
||||
case ServerProvider.unknown: // ?? :)
|
||||
return HetznerApiFactory();
|
||||
case ServerProvider.unknown:
|
||||
throw UnknownApiProviderException('Unknown server provider');
|
||||
}
|
||||
}
|
||||
|
||||
// createDnsApiFactory
|
||||
|
||||
// createStorageApiFactory
|
||||
|
||||
// etc . . .
|
||||
static DnsProviderApiFactory createDnsProviderApiFactory(
|
||||
final DnsProvider provider,
|
||||
) {
|
||||
switch (provider) {
|
||||
case DnsProvider.cloudflare:
|
||||
return CloudflareApiFactory();
|
||||
case DnsProvider.unknown:
|
||||
throw UnknownApiProviderException('Unknown DNS provider');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VolumeApiFactoryCreator {
|
||||
|
@ -26,14 +40,9 @@ class VolumeApiFactoryCreator {
|
|||
) {
|
||||
switch (provider) {
|
||||
case ServerProvider.hetzner:
|
||||
case ServerProvider.unknown: // ?? :)
|
||||
return HetznerApiFactory();
|
||||
case ServerProvider.unknown:
|
||||
throw UnknownApiProviderException('Unknown volume provider');
|
||||
}
|
||||
}
|
||||
|
||||
// createDnsApiFactory
|
||||
|
||||
// createStorageApiFactory
|
||||
|
||||
// etc . . .
|
||||
}
|
||||
|
|
|
@ -2,16 +2,11 @@ import 'dart:io';
|
|||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/api_map.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/json/dns_records.dart';
|
||||
|
||||
class DomainNotFoundException implements Exception {
|
||||
DomainNotFoundException(this.message);
|
||||
final String message;
|
||||
}
|
||||
|
||||
class CloudflareApi extends ApiMap {
|
||||
class CloudflareApi extends DnsProviderApi {
|
||||
CloudflareApi({
|
||||
this.hasLogger = false,
|
||||
this.isWithToken = true,
|
||||
|
@ -24,6 +19,10 @@ class CloudflareApi extends ApiMap {
|
|||
|
||||
final String? customToken;
|
||||
|
||||
@override
|
||||
RegExp getApiTokenValidation() =>
|
||||
RegExp(r'\s+|[!$%^&*()@+|~=`{}\[\]:<>?,.\/]');
|
||||
|
||||
@override
|
||||
BaseOptions get options {
|
||||
final BaseOptions options = BaseOptions(baseUrl: rootAddress);
|
||||
|
@ -46,27 +45,37 @@ class CloudflareApi extends ApiMap {
|
|||
@override
|
||||
String rootAddress = 'https://api.cloudflare.com/client/v4';
|
||||
|
||||
Future<bool> isValid(final String token) async {
|
||||
validateStatus = (final status) =>
|
||||
status == HttpStatus.ok || status == HttpStatus.unauthorized;
|
||||
|
||||
@override
|
||||
Future<bool> isApiTokenValid(final String token) async {
|
||||
bool isValid = false;
|
||||
Response? response;
|
||||
final Dio client = await getClient();
|
||||
final Response response = await client.get(
|
||||
'/user/tokens/verify',
|
||||
options: Options(headers: {'Authorization': 'Bearer $token'}),
|
||||
);
|
||||
|
||||
close(client);
|
||||
|
||||
if (response.statusCode == HttpStatus.ok) {
|
||||
return true;
|
||||
} else if (response.statusCode == HttpStatus.unauthorized) {
|
||||
return false;
|
||||
} else {
|
||||
throw Exception('code: ${response.statusCode}');
|
||||
try {
|
||||
response = await client.get(
|
||||
'/user/tokens/verify',
|
||||
options: Options(headers: {'Authorization': 'Bearer $token'}),
|
||||
);
|
||||
} catch (e) {
|
||||
print(e);
|
||||
isValid = false;
|
||||
} finally {
|
||||
close(client);
|
||||
}
|
||||
|
||||
if (response != null) {
|
||||
if (response.statusCode == HttpStatus.ok) {
|
||||
isValid = true;
|
||||
} else if (response.statusCode == HttpStatus.unauthorized) {
|
||||
isValid = false;
|
||||
} else {
|
||||
throw Exception('code: ${response.statusCode}');
|
||||
}
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> getZoneId(final String domain) async {
|
||||
validateStatus = (final status) =>
|
||||
status == HttpStatus.ok || status == HttpStatus.forbidden;
|
||||
|
@ -85,12 +94,13 @@ class CloudflareApi extends ApiMap {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> removeSimilarRecords({
|
||||
required final ServerDomain cloudFlareDomain,
|
||||
required final ServerDomain domain,
|
||||
final String? ip4,
|
||||
}) async {
|
||||
final String domainName = cloudFlareDomain.domainName;
|
||||
final String domainZoneId = cloudFlareDomain.zoneId;
|
||||
final String domainName = domain.domainName;
|
||||
final String domainZoneId = domain.zoneId;
|
||||
|
||||
final String url = '/zones/$domainZoneId/dns_records';
|
||||
|
||||
|
@ -112,11 +122,12 @@ class CloudflareApi extends ApiMap {
|
|||
close(client);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<DnsRecord>> getDnsRecords({
|
||||
required final ServerDomain cloudFlareDomain,
|
||||
required final ServerDomain domain,
|
||||
}) async {
|
||||
final String domainName = cloudFlareDomain.domainName;
|
||||
final String domainZoneId = cloudFlareDomain.zoneId;
|
||||
final String domainName = domain.domainName;
|
||||
final String domainZoneId = domain.zoneId;
|
||||
|
||||
final String url = '/zones/$domainZoneId/dns_records';
|
||||
|
||||
|
@ -144,12 +155,13 @@ class CloudflareApi extends ApiMap {
|
|||
return allRecords;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> createMultipleDnsRecords({
|
||||
required final ServerDomain cloudFlareDomain,
|
||||
required final ServerDomain domain,
|
||||
final String? ip4,
|
||||
}) async {
|
||||
final String domainName = cloudFlareDomain.domainName;
|
||||
final String domainZoneId = cloudFlareDomain.zoneId;
|
||||
final String domainName = domain.domainName;
|
||||
final String domainZoneId = domain.zoneId;
|
||||
final List<DnsRecord> listDnsRecords = projectDnsRecords(domainName, ip4);
|
||||
final List<Future> allCreateFutures = <Future>[];
|
||||
|
||||
|
@ -219,11 +231,12 @@ class CloudflareApi extends ApiMap {
|
|||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setDkim(
|
||||
final String dkimRecordString,
|
||||
final ServerDomain cloudFlareDomain,
|
||||
final ServerDomain domain,
|
||||
) async {
|
||||
final String domainZoneId = cloudFlareDomain.zoneId;
|
||||
final String domainZoneId = domain.zoneId;
|
||||
final String url = '$rootAddress/zones/$domainZoneId/dns_records';
|
||||
|
||||
final DnsRecord dkimRecord = DnsRecord(
|
||||
|
@ -242,6 +255,7 @@ class CloudflareApi extends ApiMap {
|
|||
client.close();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<String>> domainList() async {
|
||||
final String url = '$rootAddress/zones';
|
||||
final Dio client = await getClient();
|
|
@ -0,0 +1,15 @@
|
|||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/cloudflare/cloudflare.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.dart';
|
||||
|
||||
class CloudflareApiFactory extends DnsProviderApiFactory {
|
||||
@override
|
||||
DnsProviderApi getDnsProvider({
|
||||
final DnsProviderApiSettings settings = const DnsProviderApiSettings(),
|
||||
}) =>
|
||||
CloudflareApi(
|
||||
hasLogger: settings.hasLogger,
|
||||
isWithToken: settings.isWithToken,
|
||||
customToken: settings.customToken,
|
||||
);
|
||||
}
|
31
lib/logic/api_maps/rest_maps/dns_providers/dns_provider.dart
Normal file
31
lib/logic/api_maps/rest_maps/dns_providers/dns_provider.dart
Normal file
|
@ -0,0 +1,31 @@
|
|||
import 'package:selfprivacy/logic/api_maps/rest_maps/api_map.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/json/dns_records.dart';
|
||||
|
||||
class DomainNotFoundException implements Exception {
|
||||
DomainNotFoundException(this.message);
|
||||
final String message;
|
||||
}
|
||||
|
||||
abstract class DnsProviderApi extends ApiMap {
|
||||
Future<List<DnsRecord>> getDnsRecords({
|
||||
required final ServerDomain domain,
|
||||
});
|
||||
Future<void> removeSimilarRecords({
|
||||
required final ServerDomain domain,
|
||||
final String? ip4,
|
||||
});
|
||||
Future<void> createMultipleDnsRecords({
|
||||
required final ServerDomain domain,
|
||||
final String? ip4,
|
||||
});
|
||||
Future<void> setDkim(
|
||||
final String dkimRecordString,
|
||||
final ServerDomain domain,
|
||||
);
|
||||
Future<String> getZoneId(final String domain);
|
||||
Future<List<String>> domainList();
|
||||
|
||||
Future<bool> isApiTokenValid(final String token);
|
||||
RegExp getApiTokenValidation();
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/provider_api_settings.dart';
|
||||
|
||||
class DnsProviderApiSettings extends ProviderApiSettings {
|
||||
const DnsProviderApiSettings({
|
||||
final super.hasLogger = false,
|
||||
final super.isWithToken = true,
|
||||
final this.customToken,
|
||||
});
|
||||
final String? customToken;
|
||||
}
|
||||
|
||||
abstract class DnsProviderApiFactory {
|
||||
DnsProviderApi getDnsProvider({
|
||||
final DnsProviderApiSettings settings = const DnsProviderApiSettings(),
|
||||
});
|
||||
}
|
5
lib/logic/api_maps/rest_maps/provider_api_settings.dart
Normal file
5
lib/logic/api_maps/rest_maps/provider_api_settings.dart
Normal file
|
@ -0,0 +1,5 @@
|
|||
class ProviderApiSettings {
|
||||
const ProviderApiSettings({this.hasLogger = false, this.isWithToken = true});
|
||||
final bool hasLogger;
|
||||
final bool isWithToken;
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
import 'package:selfprivacy/logic/api_maps/rest_maps/providers/hetzner/hetzner.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/providers/provider.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/providers/provider_factory.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/providers/volume_provider.dart';
|
||||
|
||||
class HetznerApiFactory extends ProviderApiFactory
|
||||
with VolumeProviderApiFactory {
|
||||
@override
|
||||
ServerProviderApi getProvider({
|
||||
final ProviderApiSettings settings = const ProviderApiSettings(),
|
||||
}) =>
|
||||
HetznerApi(
|
||||
hasLogger: settings.hasLogger,
|
||||
isWithToken: settings.isWithToken,
|
||||
);
|
||||
|
||||
@override
|
||||
VolumeProviderApi getVolumeProvider({
|
||||
final ProviderApiSettings settings = const ProviderApiSettings(),
|
||||
}) =>
|
||||
HetznerApi(
|
||||
hasLogger: settings.hasLogger,
|
||||
isWithToken: settings.isWithToken,
|
||||
);
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
import 'package:selfprivacy/logic/api_maps/rest_maps/providers/provider.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/providers/volume_provider.dart';
|
||||
|
||||
class ProviderApiSettings {
|
||||
const ProviderApiSettings({this.hasLogger = false, this.isWithToken = true});
|
||||
final bool hasLogger;
|
||||
final bool isWithToken;
|
||||
}
|
||||
|
||||
abstract class ProviderApiFactory {
|
||||
ServerProviderApi getProvider({
|
||||
final ProviderApiSettings settings = const ProviderApiSettings(),
|
||||
});
|
||||
}
|
||||
|
||||
mixin VolumeProviderApiFactory {
|
||||
VolumeProviderApi getVolumeProvider({
|
||||
final ProviderApiSettings settings = const ProviderApiSettings(),
|
||||
});
|
||||
}
|
|
@ -3,8 +3,8 @@ import 'dart:io';
|
|||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/providers/volume_provider.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/providers/provider.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/volume_provider.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/json/hetzner_server_info.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
|
@ -0,0 +1,26 @@
|
|||
import 'package:selfprivacy/logic/api_maps/rest_maps/provider_api_settings.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/hetzner/hetzner.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider_factory.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/volume_provider.dart';
|
||||
|
||||
class HetznerApiFactory extends ServerProviderApiFactory
|
||||
with VolumeProviderApiFactory {
|
||||
@override
|
||||
ServerProviderApi getServerProvider({
|
||||
final ProviderApiSettings settings = const ProviderApiSettings(),
|
||||
}) =>
|
||||
HetznerApi(
|
||||
hasLogger: settings.hasLogger,
|
||||
isWithToken: settings.isWithToken,
|
||||
);
|
||||
|
||||
@override
|
||||
VolumeProviderApi getVolumeProvider({
|
||||
final ProviderApiSettings settings = const ProviderApiSettings(),
|
||||
}) =>
|
||||
HetznerApi(
|
||||
hasLogger: settings.hasLogger,
|
||||
isWithToken: settings.isWithToken,
|
||||
);
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import 'package:selfprivacy/logic/api_maps/rest_maps/provider_api_settings.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/volume_provider.dart';
|
||||
|
||||
abstract class ServerProviderApiFactory {
|
||||
ServerProviderApi getServerProvider({
|
||||
final ProviderApiSettings settings = const ProviderApiSettings(),
|
||||
});
|
||||
}
|
||||
|
||||
mixin VolumeProviderApiFactory {
|
||||
VolumeProviderApi getVolumeProvider({
|
||||
final ProviderApiSettings settings = const ProviderApiSettings(),
|
||||
});
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
import 'package:cubit_form/cubit_form.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/api_factory_creator.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.dart';
|
||||
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||
import 'package:selfprivacy/logic/models/json/dns_records.dart';
|
||||
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/cloudflare.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server.dart';
|
||||
|
||||
part 'dns_records_state.dart';
|
||||
|
@ -16,8 +18,12 @@ class DnsRecordsCubit
|
|||
const DnsRecordsState(dnsState: DnsRecordsStatus.refreshing),
|
||||
);
|
||||
|
||||
DnsProviderApiFactory? dnsProviderApiFactory =
|
||||
ApiFactoryCreator.createDnsProviderApiFactory(
|
||||
DnsProvider.cloudflare, // TODO: HARDCODE FOR NOW!!!
|
||||
); // TODO: Remove when provider selection is implemented.
|
||||
|
||||
final ServerApi api = ServerApi();
|
||||
final CloudflareApi cloudflare = CloudflareApi();
|
||||
|
||||
@override
|
||||
Future<void> load() async {
|
||||
|
@ -31,14 +37,15 @@ class DnsRecordsCubit
|
|||
),
|
||||
),
|
||||
);
|
||||
print('Loading DNS status');
|
||||
|
||||
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
||||
final ServerDomain? domain = serverInstallationCubit.state.serverDomain;
|
||||
final String? ipAddress =
|
||||
serverInstallationCubit.state.serverDetails?.ip4;
|
||||
if (domain != null && ipAddress != null) {
|
||||
final List<DnsRecord> records =
|
||||
await cloudflare.getDnsRecords(cloudFlareDomain: domain);
|
||||
final List<DnsRecord> records = await dnsProviderApiFactory!
|
||||
.getDnsProvider()
|
||||
.getDnsRecords(domain: domain);
|
||||
final String? dkimPublicKey = await api.getDkim();
|
||||
final List<DesiredDnsRecord> desiredRecords =
|
||||
_getDesiredDnsRecords(domain.domainName, ipAddress, dkimPublicKey);
|
||||
|
@ -116,12 +123,14 @@ class DnsRecordsCubit
|
|||
final ServerDomain? domain = serverInstallationCubit.state.serverDomain;
|
||||
final String? ipAddress = serverInstallationCubit.state.serverDetails?.ip4;
|
||||
final String? dkimPublicKey = await api.getDkim();
|
||||
await cloudflare.removeSimilarRecords(cloudFlareDomain: domain!);
|
||||
await cloudflare.createMultipleDnsRecords(
|
||||
cloudFlareDomain: domain,
|
||||
final DnsProviderApi dnsProviderApi =
|
||||
dnsProviderApiFactory!.getDnsProvider();
|
||||
await dnsProviderApi.removeSimilarRecords(domain: domain!);
|
||||
await dnsProviderApi.createMultipleDnsRecords(
|
||||
domain: domain,
|
||||
ip4: ipAddress,
|
||||
);
|
||||
await cloudflare.setDkim(dkimPublicKey ?? '', domain);
|
||||
await dnsProviderApi.setDkim(dkimPublicKey ?? '', domain);
|
||||
await load();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,13 +2,12 @@ import 'dart:async';
|
|||
|
||||
import 'package:cubit_form/cubit_form.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/cloudflare.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/forms/validations/validations.dart';
|
||||
|
||||
class CloudFlareFormCubit extends FormCubit {
|
||||
CloudFlareFormCubit(this.initializingCubit) {
|
||||
final RegExp regExp = RegExp(r'\s+|[!$%^&*()@+|~=`{}\[\]:<>?,.\/]');
|
||||
class DnsProviderFormCubit extends FormCubit {
|
||||
DnsProviderFormCubit(this.initializingCubit) {
|
||||
final RegExp regExp = initializingCubit.getDnsProviderApiTokenValidation();
|
||||
apiKey = FieldCubit(
|
||||
initalValue: '',
|
||||
validations: [
|
||||
|
@ -30,16 +29,15 @@ class CloudFlareFormCubit extends FormCubit {
|
|||
}
|
||||
|
||||
final ServerInstallationCubit initializingCubit;
|
||||
|
||||
late final FieldCubit<String> apiKey;
|
||||
|
||||
@override
|
||||
FutureOr<bool> asyncValidation() async {
|
||||
late bool isKeyValid;
|
||||
final CloudflareApi apiClient = CloudflareApi(isWithToken: false);
|
||||
|
||||
try {
|
||||
isKeyValid = await apiClient.isValid(apiKey.state.value);
|
||||
isKeyValid = await initializingCubit
|
||||
.isDnsProviderApiTokenValid(apiKey.state.value);
|
||||
} catch (e) {
|
||||
addError(e);
|
||||
isKeyValid = false;
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:cubit_form/cubit_form.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/cloudflare.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||
|
||||
|
@ -10,9 +9,10 @@ class DomainSetupCubit extends Cubit<DomainSetupState> {
|
|||
|
||||
Future<void> load() async {
|
||||
emit(Loading(LoadingTypes.loadingDomain));
|
||||
final CloudflareApi api = CloudflareApi();
|
||||
|
||||
final List<String> list = await api.domainList();
|
||||
final List<String> list = await serverInstallationCubit
|
||||
.repository.dnsProviderApiFactory!
|
||||
.getDnsProvider()
|
||||
.domainList();
|
||||
if (list.isEmpty) {
|
||||
emit(Empty());
|
||||
} else if (list.length == 1) {
|
||||
|
@ -28,11 +28,13 @@ class DomainSetupCubit extends Cubit<DomainSetupState> {
|
|||
Future<void> saveDomain() async {
|
||||
assert(state is Loaded, 'wrong state');
|
||||
final String domainName = (state as Loaded).domain;
|
||||
final CloudflareApi api = CloudflareApi();
|
||||
|
||||
emit(Loading(LoadingTypes.saving));
|
||||
|
||||
final String zoneId = await api.getZoneId(domainName);
|
||||
final String zoneId = await serverInstallationCubit
|
||||
.repository.dnsProviderApiFactory!
|
||||
.getDnsProvider()
|
||||
.getZoneId(domainName);
|
||||
|
||||
final ServerDomain domain = ServerDomain(
|
||||
domainName: domainName,
|
|
@ -8,7 +8,7 @@ import 'package:selfprivacy/logic/cubit/forms/validations/validations.dart';
|
|||
class ProviderFormCubit extends FormCubit {
|
||||
ProviderFormCubit(this.serverInstallationCubit) {
|
||||
final RegExp regExp =
|
||||
serverInstallationCubit.getProviderApiTokenValidation();
|
||||
serverInstallationCubit.getServerProviderApiTokenValidation();
|
||||
apiKey = FieldCubit(
|
||||
initalValue: '',
|
||||
validations: [
|
||||
|
@ -38,7 +38,7 @@ class ProviderFormCubit extends FormCubit {
|
|||
|
||||
try {
|
||||
isKeyValid = await serverInstallationCubit
|
||||
.isProviderApiTokenValid(apiKey.state.value);
|
||||
.isServerProviderApiTokenValid(apiKey.state.value);
|
||||
} catch (e) {
|
||||
addError(e);
|
||||
isKeyValid = false;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import 'package:selfprivacy/logic/api_maps/rest_maps/providers/hetzner/hetzner.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/hetzner/hetzner.dart';
|
||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||
import 'package:selfprivacy/logic/models/hetzner_metrics.dart';
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import 'package:selfprivacy/logic/api_maps/rest_maps/providers/hetzner/hetzner.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/hetzner/hetzner.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server.dart';
|
||||
import 'package:selfprivacy/logic/models/json/auto_upgrade_settings.dart';
|
||||
import 'package:selfprivacy/logic/models/json/hetzner_server_info.dart';
|
||||
|
|
|
@ -4,7 +4,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||
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/rest_maps/providers/provider_factory.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/provider_api_settings.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||
|
@ -50,13 +51,31 @@ class ServerInstallationCubit extends Cubit<ServerInstallationState> {
|
|||
}
|
||||
}
|
||||
|
||||
RegExp getProviderApiTokenValidation() => repository.serverProviderApiFactory!
|
||||
.getProvider()
|
||||
RegExp getServerProviderApiTokenValidation() =>
|
||||
repository.serverProviderApiFactory!
|
||||
.getServerProvider()
|
||||
.getApiTokenValidation();
|
||||
|
||||
RegExp getDnsProviderApiTokenValidation() => repository.dnsProviderApiFactory!
|
||||
.getDnsProvider()
|
||||
.getApiTokenValidation();
|
||||
|
||||
Future<bool> isProviderApiTokenValid(final String providerToken) async =>
|
||||
Future<bool> isServerProviderApiTokenValid(
|
||||
final String providerToken,
|
||||
) async =>
|
||||
repository.serverProviderApiFactory!
|
||||
.getProvider(settings: const ProviderApiSettings(isWithToken: false))
|
||||
.getServerProvider(
|
||||
settings: const ProviderApiSettings(isWithToken: false),
|
||||
)
|
||||
.isApiTokenValid(providerToken);
|
||||
|
||||
Future<bool> isDnsProviderApiTokenValid(
|
||||
final String providerToken,
|
||||
) async =>
|
||||
repository.dnsProviderApiFactory!
|
||||
.getDnsProvider(
|
||||
settings: const DnsProviderApiSettings(isWithToken: false),
|
||||
)
|
||||
.isApiTokenValid(providerToken);
|
||||
|
||||
void setHetznerKey(final String hetznerKey) async {
|
||||
|
|
|
@ -10,9 +10,10 @@ import 'package:pub_semver/pub_semver.dart';
|
|||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/config/hive_config.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/api_factory_creator.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/cloudflare.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/providers/provider.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/providers/provider_factory.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider_factory.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server.dart';
|
||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/backblaze_credential.dart';
|
||||
|
@ -40,10 +41,14 @@ class ServerAuthorizationException implements Exception {
|
|||
class ServerInstallationRepository {
|
||||
Box box = Hive.box(BNames.serverInstallationBox);
|
||||
Box<User> usersBox = Hive.box(BNames.usersBox);
|
||||
ProviderApiFactory? serverProviderApiFactory =
|
||||
ApiFactoryCreator.createProviderApiFactory(
|
||||
ServerProvider.hetzner, // HARDCODE FOR NOW!!!
|
||||
); // Remove when provider selection is implemented.
|
||||
ServerProviderApiFactory? serverProviderApiFactory =
|
||||
ApiFactoryCreator.createServerProviderApiFactory(
|
||||
ServerProvider.hetzner, // TODO: HARDCODE FOR NOW!!!
|
||||
); // TODO: Remove when provider selection is implemented.
|
||||
DnsProviderApiFactory? dnsProviderApiFactory =
|
||||
ApiFactoryCreator.createDnsProviderApiFactory(
|
||||
DnsProvider.cloudflare, // TODO: HARDCODE FOR NOW!!!
|
||||
);
|
||||
|
||||
Future<ServerInstallationState> load() async {
|
||||
final String? providerApiToken = getIt<ApiConfigModel>().hetznerKey;
|
||||
|
@ -54,9 +59,18 @@ class ServerInstallationRepository {
|
|||
final ServerHostingDetails? serverDetails =
|
||||
getIt<ApiConfigModel>().serverDetails;
|
||||
|
||||
if (serverDetails != null) {
|
||||
if (serverDetails != null &&
|
||||
serverDetails.provider != ServerProvider.unknown) {
|
||||
serverProviderApiFactory =
|
||||
ApiFactoryCreator.createProviderApiFactory(serverDetails.provider);
|
||||
ApiFactoryCreator.createServerProviderApiFactory(
|
||||
serverDetails.provider,
|
||||
);
|
||||
}
|
||||
|
||||
if (serverDomain != null && serverDomain.provider != DnsProvider.unknown) {
|
||||
dnsProviderApiFactory = ApiFactoryCreator.createDnsProviderApiFactory(
|
||||
serverDomain.provider,
|
||||
);
|
||||
}
|
||||
|
||||
if (box.get(BNames.hasFinalChecked, defaultValue: false)) {
|
||||
|
@ -142,20 +156,22 @@ class ServerInstallationRepository {
|
|||
) async {
|
||||
ServerHostingDetails? serverDetails;
|
||||
|
||||
final ServerProviderApi api = serverProviderApiFactory!.getProvider();
|
||||
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider();
|
||||
serverDetails = await api.powerOn();
|
||||
|
||||
return serverDetails;
|
||||
}
|
||||
|
||||
Future<String?> getDomainId(final String token, final String domain) async {
|
||||
final CloudflareApi cloudflareApi = CloudflareApi(
|
||||
isWithToken: false,
|
||||
customToken: token,
|
||||
final DnsProviderApi dnsProviderApi = dnsProviderApiFactory!.getDnsProvider(
|
||||
settings: DnsProviderApiSettings(
|
||||
isWithToken: false,
|
||||
customToken: token,
|
||||
),
|
||||
);
|
||||
|
||||
try {
|
||||
final String domainId = await cloudflareApi.getZoneId(domain);
|
||||
final String domainId = await dnsProviderApi.getZoneId(domain);
|
||||
return domainId;
|
||||
} on DomainNotFoundException {
|
||||
return null;
|
||||
|
@ -220,7 +236,7 @@ class ServerInstallationRepository {
|
|||
required final Future<void> Function(ServerHostingDetails serverDetails)
|
||||
onSuccess,
|
||||
}) async {
|
||||
final ServerProviderApi api = serverProviderApiFactory!.getProvider();
|
||||
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider();
|
||||
try {
|
||||
final ServerHostingDetails? serverDetails = await api.createServer(
|
||||
dnsApiToken: cloudFlareKey,
|
||||
|
@ -285,18 +301,20 @@ class ServerInstallationRepository {
|
|||
final ServerDomain domain, {
|
||||
required final void Function() onCancel,
|
||||
}) async {
|
||||
final CloudflareApi cloudflareApi = CloudflareApi();
|
||||
final ServerProviderApi serverApi = serverProviderApiFactory!.getProvider();
|
||||
final DnsProviderApi dnsProviderApi =
|
||||
dnsProviderApiFactory!.getDnsProvider();
|
||||
final ServerProviderApi serverApi =
|
||||
serverProviderApiFactory!.getServerProvider();
|
||||
|
||||
await cloudflareApi.removeSimilarRecords(
|
||||
await dnsProviderApi.removeSimilarRecords(
|
||||
ip4: serverDetails.ip4,
|
||||
cloudFlareDomain: domain,
|
||||
domain: domain,
|
||||
);
|
||||
|
||||
try {
|
||||
await cloudflareApi.createMultipleDnsRecords(
|
||||
await dnsProviderApi.createMultipleDnsRecords(
|
||||
ip4: serverDetails.ip4,
|
||||
cloudFlareDomain: domain,
|
||||
domain: domain,
|
||||
);
|
||||
} on DioError catch (e) {
|
||||
final NavigationService nav = getIt.get<NavigationService>();
|
||||
|
@ -337,12 +355,13 @@ class ServerInstallationRepository {
|
|||
}
|
||||
|
||||
Future<void> createDkimRecord(final ServerDomain cloudFlareDomain) async {
|
||||
final CloudflareApi cloudflareApi = CloudflareApi();
|
||||
final DnsProviderApi dnsProviderApi =
|
||||
dnsProviderApiFactory!.getDnsProvider();
|
||||
final ServerApi api = ServerApi();
|
||||
|
||||
final String? dkimRecordString = await api.getDkim();
|
||||
|
||||
await cloudflareApi.setDkim(dkimRecordString ?? '', cloudFlareDomain);
|
||||
await dnsProviderApi.setDkim(dkimRecordString ?? '', cloudFlareDomain);
|
||||
}
|
||||
|
||||
Future<bool> isHttpServerWorking() async {
|
||||
|
@ -357,12 +376,12 @@ class ServerInstallationRepository {
|
|||
}
|
||||
|
||||
Future<ServerHostingDetails> restart() async {
|
||||
final ServerProviderApi api = serverProviderApiFactory!.getProvider();
|
||||
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider();
|
||||
return api.restart();
|
||||
}
|
||||
|
||||
Future<ServerHostingDetails> powerOn() async {
|
||||
final ServerProviderApi api = serverProviderApiFactory!.getProvider();
|
||||
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider();
|
||||
return api.powerOn();
|
||||
}
|
||||
|
||||
|
@ -599,7 +618,7 @@ class ServerInstallationRepository {
|
|||
}
|
||||
|
||||
Future<List<ServerBasicInfo>> getServersOnProviderAccount() async {
|
||||
final ServerProviderApi api = serverProviderApiFactory!.getProvider();
|
||||
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider();
|
||||
return api.getServers();
|
||||
}
|
||||
|
||||
|
@ -678,8 +697,9 @@ class ServerInstallationRepository {
|
|||
}
|
||||
|
||||
Future<void> deleteServer(final ServerDomain serverDomain) async {
|
||||
final ServerProviderApi api = serverProviderApiFactory!.getProvider();
|
||||
final CloudflareApi cloudFlare = CloudflareApi();
|
||||
final ServerProviderApi api = serverProviderApiFactory!.getServerProvider();
|
||||
final DnsProviderApi dnsProviderApi =
|
||||
dnsProviderApiFactory!.getDnsProvider();
|
||||
|
||||
await api.deleteServer(
|
||||
domainName: serverDomain.domainName,
|
||||
|
@ -692,7 +712,7 @@ class ServerInstallationRepository {
|
|||
await box.put(BNames.isLoading, false);
|
||||
await box.put(BNames.serverDetails, null);
|
||||
|
||||
await cloudFlare.removeSimilarRecords(cloudFlareDomain: serverDomain);
|
||||
await dnsProviderApi.removeSimilarRecords(domain: serverDomain);
|
||||
}
|
||||
|
||||
Future<void> deleteServerRelatedRecords() async {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/api_factory_creator.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/providers/provider_factory.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider_factory.dart';
|
||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
|
||||
import 'package:selfprivacy/logic/models/hive/server_details.dart';
|
||||
|
|
|
@ -5,8 +5,8 @@ import 'package:selfprivacy/config/brand_theme.dart';
|
|||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart';
|
||||
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/backblaze_form_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/cloudflare_form_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/domain_cloudflare.dart';
|
||||
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/dns_provider_form_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/domain_setup_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/provider_form_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/root_user_form_cubit.dart';
|
||||
import 'package:selfprivacy/ui/components/brand_bottom_sheet/brand_bottom_sheet.dart';
|
||||
|
@ -195,10 +195,10 @@ class InitializingPage extends StatelessWidget {
|
|||
|
||||
Widget _stepCloudflare(final ServerInstallationCubit initializingCubit) =>
|
||||
BlocProvider(
|
||||
create: (final context) => CloudFlareFormCubit(initializingCubit),
|
||||
create: (final context) => DnsProviderFormCubit(initializingCubit),
|
||||
child: Builder(
|
||||
builder: (final context) {
|
||||
final formCubitState = context.watch<CloudFlareFormCubit>().state;
|
||||
final formCubitState = context.watch<DnsProviderFormCubit>().state;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
|
@ -213,7 +213,7 @@ class InitializingPage extends StatelessWidget {
|
|||
BrandText.body2('initializing.4'.tr()),
|
||||
const Spacer(),
|
||||
CubitFormTextField(
|
||||
formFieldCubit: context.read<CloudFlareFormCubit>().apiKey,
|
||||
formFieldCubit: context.read<DnsProviderFormCubit>().apiKey,
|
||||
textAlign: TextAlign.center,
|
||||
scrollPadding: const EdgeInsets.only(bottom: 70),
|
||||
decoration: InputDecoration(
|
||||
|
@ -224,7 +224,7 @@ class InitializingPage extends StatelessWidget {
|
|||
BrandButton.rised(
|
||||
onPressed: formCubitState.isSubmitting
|
||||
? null
|
||||
: () => context.read<CloudFlareFormCubit>().trySubmit(),
|
||||
: () => context.read<DnsProviderFormCubit>().trySubmit(),
|
||||
text: 'basis.connect'.tr(),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'package:cubit_form/cubit_form.dart';
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:selfprivacy/config/brand_theme.dart';
|
||||
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/cloudflare_form_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/forms/setup/initializing/dns_provider_form_cubit.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||
import 'package:selfprivacy/ui/components/brand_bottom_sheet/brand_bottom_sheet.dart';
|
||||
import 'package:selfprivacy/ui/components/brand_button/brand_button.dart';
|
||||
|
@ -18,11 +18,11 @@ class RecoveryConfirmCloudflare extends StatelessWidget {
|
|||
context.watch<ServerInstallationCubit>();
|
||||
|
||||
return BlocProvider(
|
||||
create: (final BuildContext context) => CloudFlareFormCubit(appConfig),
|
||||
create: (final BuildContext context) => DnsProviderFormCubit(appConfig),
|
||||
child: Builder(
|
||||
builder: (final BuildContext context) {
|
||||
final FormCubitState formCubitState =
|
||||
context.watch<CloudFlareFormCubit>().state;
|
||||
context.watch<DnsProviderFormCubit>().state;
|
||||
|
||||
return BrandHeroScreen(
|
||||
heroTitle: 'recovering.confirm_cloudflare'.tr(),
|
||||
|
@ -35,7 +35,7 @@ class RecoveryConfirmCloudflare extends StatelessWidget {
|
|||
context.read<ServerInstallationCubit>().revertRecoveryStep,
|
||||
children: [
|
||||
CubitFormTextField(
|
||||
formFieldCubit: context.read<CloudFlareFormCubit>().apiKey,
|
||||
formFieldCubit: context.read<DnsProviderFormCubit>().apiKey,
|
||||
decoration: InputDecoration(
|
||||
border: const OutlineInputBorder(),
|
||||
labelText: 'initializing.5'.tr(),
|
||||
|
@ -45,7 +45,7 @@ class RecoveryConfirmCloudflare extends StatelessWidget {
|
|||
BrandButton.rised(
|
||||
onPressed: formCubitState.isSubmitting
|
||||
? null
|
||||
: () => context.read<CloudFlareFormCubit>().trySubmit(),
|
||||
: () => context.read<DnsProviderFormCubit>().trySubmit(),
|
||||
text: 'basis.connect'.tr(),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
|
Loading…
Reference in a new issue