Implement Dns Provider Api Abstractions

pull/101/head
NaiJi ✨ 2022-07-14 16:34:08 +03:00
parent 8deb240426
commit dac310f913
24 changed files with 305 additions and 170 deletions

View File

@ -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 . . .
}

View File

@ -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();

View File

@ -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,
);
}

View 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();
}

View File

@ -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(),
});
}

View File

@ -0,0 +1,5 @@
class ProviderApiSettings {
const ProviderApiSettings({this.hasLogger = false, this.isWithToken = true});
final bool hasLogger;
final bool isWithToken;
}

View File

@ -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,
);
}

View File

@ -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(),
});
}

View File

@ -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';

View File

@ -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,
);
}

View File

@ -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(),
});
}

View File

@ -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();
}

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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';

View File

@ -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';

View File

@ -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 {

View File

@ -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 {

View File

@ -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';

View File

@ -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),

View File

@ -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),