diff --git a/lib/logic/api_maps/rest_maps/api_factory_creator.dart b/lib/logic/api_maps/rest_maps/api_factory_creator.dart index 0343f402..18b4ea33 100644 --- a/lib/logic/api_maps/rest_maps/api_factory_creator.dart +++ b/lib/logic/api_maps/rest_maps/api_factory_creator.dart @@ -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 . . . } diff --git a/lib/logic/api_maps/rest_maps/cloudflare.dart b/lib/logic/api_maps/rest_maps/dns_providers/cloudflare/cloudflare.dart similarity index 79% rename from lib/logic/api_maps/rest_maps/cloudflare.dart rename to lib/logic/api_maps/rest_maps/dns_providers/cloudflare/cloudflare.dart index 2b78c6fe..46dc72ac 100644 --- a/lib/logic/api_maps/rest_maps/cloudflare.dart +++ b/lib/logic/api_maps/rest_maps/dns_providers/cloudflare/cloudflare.dart @@ -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 isValid(final String token) async { - validateStatus = (final status) => - status == HttpStatus.ok || status == HttpStatus.unauthorized; - + @override + Future 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 getZoneId(final String domain) async { validateStatus = (final status) => status == HttpStatus.ok || status == HttpStatus.forbidden; @@ -85,12 +94,13 @@ class CloudflareApi extends ApiMap { } } + @override Future 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> 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 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 listDnsRecords = projectDnsRecords(domainName, ip4); final List allCreateFutures = []; @@ -219,11 +231,12 @@ class CloudflareApi extends ApiMap { ]; } + @override Future 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> domainList() async { final String url = '$rootAddress/zones'; final Dio client = await getClient(); diff --git a/lib/logic/api_maps/rest_maps/dns_providers/cloudflare/cloudflare_factory.dart b/lib/logic/api_maps/rest_maps/dns_providers/cloudflare/cloudflare_factory.dart new file mode 100644 index 00000000..9266471b --- /dev/null +++ b/lib/logic/api_maps/rest_maps/dns_providers/cloudflare/cloudflare_factory.dart @@ -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, + ); +} diff --git a/lib/logic/api_maps/rest_maps/dns_providers/dns_provider.dart b/lib/logic/api_maps/rest_maps/dns_providers/dns_provider.dart new file mode 100644 index 00000000..5c2a9369 --- /dev/null +++ b/lib/logic/api_maps/rest_maps/dns_providers/dns_provider.dart @@ -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> getDnsRecords({ + required final ServerDomain domain, + }); + Future removeSimilarRecords({ + required final ServerDomain domain, + final String? ip4, + }); + Future createMultipleDnsRecords({ + required final ServerDomain domain, + final String? ip4, + }); + Future setDkim( + final String dkimRecordString, + final ServerDomain domain, + ); + Future getZoneId(final String domain); + Future> domainList(); + + Future isApiTokenValid(final String token); + RegExp getApiTokenValidation(); +} diff --git a/lib/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.dart b/lib/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.dart new file mode 100644 index 00000000..01f59e98 --- /dev/null +++ b/lib/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.dart @@ -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(), + }); +} diff --git a/lib/logic/api_maps/rest_maps/provider_api_settings.dart b/lib/logic/api_maps/rest_maps/provider_api_settings.dart new file mode 100644 index 00000000..4350fbe7 --- /dev/null +++ b/lib/logic/api_maps/rest_maps/provider_api_settings.dart @@ -0,0 +1,5 @@ +class ProviderApiSettings { + const ProviderApiSettings({this.hasLogger = false, this.isWithToken = true}); + final bool hasLogger; + final bool isWithToken; +} diff --git a/lib/logic/api_maps/rest_maps/providers/hetzner/hetzner_factory.dart b/lib/logic/api_maps/rest_maps/providers/hetzner/hetzner_factory.dart deleted file mode 100644 index 301d4b61..00000000 --- a/lib/logic/api_maps/rest_maps/providers/hetzner/hetzner_factory.dart +++ /dev/null @@ -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, - ); -} diff --git a/lib/logic/api_maps/rest_maps/providers/provider_factory.dart b/lib/logic/api_maps/rest_maps/providers/provider_factory.dart deleted file mode 100644 index b238d299..00000000 --- a/lib/logic/api_maps/rest_maps/providers/provider_factory.dart +++ /dev/null @@ -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(), - }); -} diff --git a/lib/logic/api_maps/rest_maps/providers/hetzner/hetzner.dart b/lib/logic/api_maps/rest_maps/server_providers/hetzner/hetzner.dart similarity index 98% rename from lib/logic/api_maps/rest_maps/providers/hetzner/hetzner.dart rename to lib/logic/api_maps/rest_maps/server_providers/hetzner/hetzner.dart index 3b0dfd42..fa75db17 100644 --- a/lib/logic/api_maps/rest_maps/providers/hetzner/hetzner.dart +++ b/lib/logic/api_maps/rest_maps/server_providers/hetzner/hetzner.dart @@ -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'; diff --git a/lib/logic/api_maps/rest_maps/server_providers/hetzner/hetzner_factory.dart b/lib/logic/api_maps/rest_maps/server_providers/hetzner/hetzner_factory.dart new file mode 100644 index 00000000..60f61d1b --- /dev/null +++ b/lib/logic/api_maps/rest_maps/server_providers/hetzner/hetzner_factory.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, + ); +} diff --git a/lib/logic/api_maps/rest_maps/providers/provider.dart b/lib/logic/api_maps/rest_maps/server_providers/server_provider.dart similarity index 100% rename from lib/logic/api_maps/rest_maps/providers/provider.dart rename to lib/logic/api_maps/rest_maps/server_providers/server_provider.dart diff --git a/lib/logic/api_maps/rest_maps/server_providers/server_provider_factory.dart b/lib/logic/api_maps/rest_maps/server_providers/server_provider_factory.dart new file mode 100644 index 00000000..10f4c40f --- /dev/null +++ b/lib/logic/api_maps/rest_maps/server_providers/server_provider_factory.dart @@ -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(), + }); +} diff --git a/lib/logic/api_maps/rest_maps/providers/volume_provider.dart b/lib/logic/api_maps/rest_maps/server_providers/volume_provider.dart similarity index 100% rename from lib/logic/api_maps/rest_maps/providers/volume_provider.dart rename to lib/logic/api_maps/rest_maps/server_providers/volume_provider.dart diff --git a/lib/logic/cubit/dns_records/dns_records_cubit.dart b/lib/logic/cubit/dns_records/dns_records_cubit.dart index 8d8ae496..e0ab4d42 100644 --- a/lib/logic/cubit/dns_records/dns_records_cubit.dart +++ b/lib/logic/cubit/dns_records/dns_records_cubit.dart @@ -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 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 records = - await cloudflare.getDnsRecords(cloudFlareDomain: domain); + final List records = await dnsProviderApiFactory! + .getDnsProvider() + .getDnsRecords(domain: domain); final String? dkimPublicKey = await api.getDkim(); final List 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(); } diff --git a/lib/logic/cubit/forms/setup/initializing/cloudflare_form_cubit.dart b/lib/logic/cubit/forms/setup/initializing/dns_provider_form_cubit.dart similarity index 75% rename from lib/logic/cubit/forms/setup/initializing/cloudflare_form_cubit.dart rename to lib/logic/cubit/forms/setup/initializing/dns_provider_form_cubit.dart index 20c99f38..d27d7053 100644 --- a/lib/logic/cubit/forms/setup/initializing/cloudflare_form_cubit.dart +++ b/lib/logic/cubit/forms/setup/initializing/dns_provider_form_cubit.dart @@ -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 apiKey; @override FutureOr 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; diff --git a/lib/logic/cubit/forms/setup/initializing/domain_cloudflare.dart b/lib/logic/cubit/forms/setup/initializing/domain_setup_cubit.dart similarity index 83% rename from lib/logic/cubit/forms/setup/initializing/domain_cloudflare.dart rename to lib/logic/cubit/forms/setup/initializing/domain_setup_cubit.dart index b38e8313..4a14b862 100644 --- a/lib/logic/cubit/forms/setup/initializing/domain_cloudflare.dart +++ b/lib/logic/cubit/forms/setup/initializing/domain_setup_cubit.dart @@ -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 { Future load() async { emit(Loading(LoadingTypes.loadingDomain)); - final CloudflareApi api = CloudflareApi(); - - final List list = await api.domainList(); + final List 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 { Future 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, diff --git a/lib/logic/cubit/forms/setup/initializing/provider_form_cubit.dart b/lib/logic/cubit/forms/setup/initializing/provider_form_cubit.dart index 24910ad1..9f3b5d58 100644 --- a/lib/logic/cubit/forms/setup/initializing/provider_form_cubit.dart +++ b/lib/logic/cubit/forms/setup/initializing/provider_form_cubit.dart @@ -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; diff --git a/lib/logic/cubit/hetzner_metrics/hetzner_metrics_repository.dart b/lib/logic/cubit/hetzner_metrics/hetzner_metrics_repository.dart index 9b09d7f6..0fb780ae 100644 --- a/lib/logic/cubit/hetzner_metrics/hetzner_metrics_repository.dart +++ b/lib/logic/cubit/hetzner_metrics/hetzner_metrics_repository.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/common_enum/common_enum.dart'; import 'package:selfprivacy/logic/models/hetzner_metrics.dart'; diff --git a/lib/logic/cubit/server_detailed_info/server_detailed_info_repository.dart b/lib/logic/cubit/server_detailed_info/server_detailed_info_repository.dart index 8fd3e711..e5858d2d 100644 --- a/lib/logic/cubit/server_detailed_info/server_detailed_info_repository.dart +++ b/lib/logic/cubit/server_detailed_info/server_detailed_info_repository.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'; diff --git a/lib/logic/cubit/server_installation/server_installation_cubit.dart b/lib/logic/cubit/server_installation/server_installation_cubit.dart index e6402836..6899240f 100644 --- a/lib/logic/cubit/server_installation/server_installation_cubit.dart +++ b/lib/logic/cubit/server_installation/server_installation_cubit.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 { } } - RegExp getProviderApiTokenValidation() => repository.serverProviderApiFactory! - .getProvider() + RegExp getServerProviderApiTokenValidation() => + repository.serverProviderApiFactory! + .getServerProvider() + .getApiTokenValidation(); + + RegExp getDnsProviderApiTokenValidation() => repository.dnsProviderApiFactory! + .getDnsProvider() .getApiTokenValidation(); - Future isProviderApiTokenValid(final String providerToken) async => + Future isServerProviderApiTokenValid( + final String providerToken, + ) async => repository.serverProviderApiFactory! - .getProvider(settings: const ProviderApiSettings(isWithToken: false)) + .getServerProvider( + settings: const ProviderApiSettings(isWithToken: false), + ) + .isApiTokenValid(providerToken); + + Future isDnsProviderApiTokenValid( + final String providerToken, + ) async => + repository.dnsProviderApiFactory! + .getDnsProvider( + settings: const DnsProviderApiSettings(isWithToken: false), + ) .isApiTokenValid(providerToken); void setHetznerKey(final String hetznerKey) async { diff --git a/lib/logic/cubit/server_installation/server_installation_repository.dart b/lib/logic/cubit/server_installation/server_installation_repository.dart index a91432dc..1c94a2d0 100644 --- a/lib/logic/cubit/server_installation/server_installation_repository.dart +++ b/lib/logic/cubit/server_installation/server_installation_repository.dart @@ -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 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 load() async { final String? providerApiToken = getIt().hetznerKey; @@ -54,9 +59,18 @@ class ServerInstallationRepository { final ServerHostingDetails? serverDetails = getIt().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 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 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(); @@ -337,12 +355,13 @@ class ServerInstallationRepository { } Future 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 isHttpServerWorking() async { @@ -357,12 +376,12 @@ class ServerInstallationRepository { } Future restart() async { - final ServerProviderApi api = serverProviderApiFactory!.getProvider(); + final ServerProviderApi api = serverProviderApiFactory!.getServerProvider(); return api.restart(); } Future powerOn() async { - final ServerProviderApi api = serverProviderApiFactory!.getProvider(); + final ServerProviderApi api = serverProviderApiFactory!.getServerProvider(); return api.powerOn(); } @@ -599,7 +618,7 @@ class ServerInstallationRepository { } Future> getServersOnProviderAccount() async { - final ServerProviderApi api = serverProviderApiFactory!.getProvider(); + final ServerProviderApi api = serverProviderApiFactory!.getServerProvider(); return api.getServers(); } @@ -678,8 +697,9 @@ class ServerInstallationRepository { } Future 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 deleteServerRelatedRecords() async { diff --git a/lib/logic/cubit/volumes/volumes_cubit.dart b/lib/logic/cubit/volumes/volumes_cubit.dart index d724e121..2645e502 100644 --- a/lib/logic/cubit/volumes/volumes_cubit.dart +++ b/lib/logic/cubit/volumes/volumes_cubit.dart @@ -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'; diff --git a/lib/ui/pages/setup/initializing.dart b/lib/ui/pages/setup/initializing.dart index 01b3cb35..b4a504b8 100644 --- a/lib/ui/pages/setup/initializing.dart +++ b/lib/ui/pages/setup/initializing.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().state; + final formCubitState = context.watch().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().apiKey, + formFieldCubit: context.read().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().trySubmit(), + : () => context.read().trySubmit(), text: 'basis.connect'.tr(), ), const SizedBox(height: 10), diff --git a/lib/ui/pages/setup/recovering/recovery_confirm_cloudflare.dart b/lib/ui/pages/setup/recovering/recovery_confirm_cloudflare.dart index 0e12b51e..b7891bc1 100644 --- a/lib/ui/pages/setup/recovering/recovery_confirm_cloudflare.dart +++ b/lib/ui/pages/setup/recovering/recovery_confirm_cloudflare.dart @@ -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(); 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().state; + context.watch().state; return BrandHeroScreen( heroTitle: 'recovering.confirm_cloudflare'.tr(), @@ -35,7 +35,7 @@ class RecoveryConfirmCloudflare extends StatelessWidget { context.read().revertRecoveryStep, children: [ CubitFormTextField( - formFieldCubit: context.read().apiKey, + formFieldCubit: context.read().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().trySubmit(), + : () => context.read().trySubmit(), text: 'basis.connect'.tr(), ), const SizedBox(height: 16),