mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2024-11-17 22:29:15 +00:00
Merge pull request 'refactor(digital-ocean-dns): Implement basic DTO for Digital Ocean DNS to avoid dynamic objects' (#247) from dto into master
Reviewed-on: https://git.selfprivacy.org/SelfPrivacy/selfprivacy.org.app/pulls/247 Reviewed-by: Inex Code <inex.code@selfprivacy.org>
This commit is contained in:
commit
55740ac59d
|
@ -4,8 +4,7 @@ import 'package:dio/dio.dart';
|
||||||
import 'package:selfprivacy/config/get_it_config.dart';
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/generic_result.dart';
|
import 'package:selfprivacy/logic/api_maps/generic_result.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/rest_api_map.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/rest_api_map.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
import 'package:selfprivacy/logic/models/json/digital_ocean_dns_info.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/dns_records.dart';
|
|
||||||
|
|
||||||
class DigitalOceanDnsApi extends RestApiMap {
|
class DigitalOceanDnsApi extends RestApiMap {
|
||||||
DigitalOceanDnsApi({
|
DigitalOceanDnsApi({
|
||||||
|
@ -92,13 +91,17 @@ class DigitalOceanDnsApi extends RestApiMap {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<GenericResult<List>> getDomains() async {
|
Future<GenericResult<List<DigitalOceanDomain>>> getDomains() async {
|
||||||
List domains = [];
|
List<DigitalOceanDomain> domains = [];
|
||||||
|
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
try {
|
try {
|
||||||
final Response response = await client.get('/domains');
|
final Response response = await client.get('/domains');
|
||||||
domains = response.data['domains'];
|
domains = response.data['domains']!
|
||||||
|
.map<DigitalOceanDomain>(
|
||||||
|
(final e) => DigitalOceanDomain.fromJson(e),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
return GenericResult(
|
return GenericResult(
|
||||||
|
@ -114,25 +117,18 @@ class DigitalOceanDnsApi extends RestApiMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<GenericResult<void>> createMultipleDnsRecords({
|
Future<GenericResult<void>> createMultipleDnsRecords({
|
||||||
required final ServerDomain domain,
|
required final String domainName,
|
||||||
required final List<DnsRecord> records,
|
required final List<DigitalOceanDnsRecord> records,
|
||||||
}) async {
|
}) async {
|
||||||
final String domainName = domain.domainName;
|
|
||||||
final List<Future> allCreateFutures = <Future>[];
|
final List<Future> allCreateFutures = <Future>[];
|
||||||
|
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
try {
|
try {
|
||||||
for (final DnsRecord record in records) {
|
for (final DigitalOceanDnsRecord record in records) {
|
||||||
allCreateFutures.add(
|
allCreateFutures.add(
|
||||||
client.post(
|
client.post(
|
||||||
'/domains/$domainName/records',
|
'/domains/$domainName/records',
|
||||||
data: {
|
data: record.toJson(),
|
||||||
'type': record.type,
|
|
||||||
'name': record.name,
|
|
||||||
'data': record.content,
|
|
||||||
'ttl': record.ttl,
|
|
||||||
'priority': record.priority,
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -155,17 +151,15 @@ class DigitalOceanDnsApi extends RestApiMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<GenericResult<void>> removeSimilarRecords({
|
Future<GenericResult<void>> removeSimilarRecords({
|
||||||
required final ServerDomain domain,
|
required final String domainName,
|
||||||
required final List records,
|
required final List<DigitalOceanDnsRecord> records,
|
||||||
}) async {
|
}) async {
|
||||||
final String domainName = domain.domainName;
|
|
||||||
|
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
try {
|
try {
|
||||||
final List<Future> allDeleteFutures = [];
|
final List<Future> allDeleteFutures = [];
|
||||||
for (final record in records) {
|
for (final record in records) {
|
||||||
allDeleteFutures.add(
|
allDeleteFutures.add(
|
||||||
client.delete("/domains/$domainName/records/${record['id']}"),
|
client.delete('/domains/$domainName/records/${record.id}'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
await Future.wait(allDeleteFutures);
|
await Future.wait(allDeleteFutures);
|
||||||
|
@ -183,12 +177,11 @@ class DigitalOceanDnsApi extends RestApiMap {
|
||||||
return GenericResult(success: true, data: null);
|
return GenericResult(success: true, data: null);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<GenericResult<List>> getDnsRecords({
|
Future<GenericResult<List<DigitalOceanDnsRecord>>> getDnsRecords(
|
||||||
required final ServerDomain domain,
|
final String domainName,
|
||||||
}) async {
|
) async {
|
||||||
Response response;
|
Response response;
|
||||||
final String domainName = domain.domainName;
|
List<DigitalOceanDnsRecord> allRecords = [];
|
||||||
List allRecords = [];
|
|
||||||
|
|
||||||
/// Default amount is 20, but we will eventually overflow it,
|
/// Default amount is 20, but we will eventually overflow it,
|
||||||
/// so I hardcode it to the maximum available amount in advance just in case
|
/// so I hardcode it to the maximum available amount in advance just in case
|
||||||
|
@ -200,7 +193,12 @@ class DigitalOceanDnsApi extends RestApiMap {
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
try {
|
try {
|
||||||
response = await client.get(url);
|
response = await client.get(url);
|
||||||
allRecords = response.data['domain_records'] ?? [];
|
allRecords = response.data['domain_records']
|
||||||
|
.map<DigitalOceanDnsRecord>(
|
||||||
|
(final e) => DigitalOceanDnsRecord.fromJson(e),
|
||||||
|
)
|
||||||
|
.toList() ??
|
||||||
|
[];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
GenericResult(
|
GenericResult(
|
||||||
|
|
66
lib/logic/models/json/digital_ocean_dns_info.dart
Normal file
66
lib/logic/models/json/digital_ocean_dns_info.dart
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'digital_ocean_dns_info.g.dart';
|
||||||
|
|
||||||
|
/// https://docs.digitalocean.com/reference/api/api-reference/#tag/Domains
|
||||||
|
@JsonSerializable()
|
||||||
|
class DigitalOceanDomain {
|
||||||
|
DigitalOceanDomain({
|
||||||
|
required this.name,
|
||||||
|
this.ttl,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// The name of the domain itself.
|
||||||
|
/// This should follow the standard domain format of domain.TLD.
|
||||||
|
///
|
||||||
|
/// For instance, example.com is a valid domain name.
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
/// This value is the time to live for the records on this domain, in seconds.
|
||||||
|
///
|
||||||
|
/// This defines the time frame that clients can cache queried information before a refresh should be requested.
|
||||||
|
final int? ttl;
|
||||||
|
|
||||||
|
static DigitalOceanDomain fromJson(final Map<String, dynamic> json) =>
|
||||||
|
_$DigitalOceanDomainFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://docs.digitalocean.com/reference/api/api-reference/#tag/Domain-Records
|
||||||
|
@JsonSerializable()
|
||||||
|
class DigitalOceanDnsRecord {
|
||||||
|
DigitalOceanDnsRecord({
|
||||||
|
required this.id,
|
||||||
|
required this.name,
|
||||||
|
required this.type,
|
||||||
|
required this.ttl,
|
||||||
|
required this.data,
|
||||||
|
this.priority,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// A unique identifier for each domain record.
|
||||||
|
final int? id;
|
||||||
|
|
||||||
|
/// The host name, alias, or service being defined by the record.
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
/// The type of the DNS record. For example: A, CNAME, TXT, ...
|
||||||
|
final String type;
|
||||||
|
|
||||||
|
/// This value is the time to live for the record, in seconds.
|
||||||
|
///
|
||||||
|
/// This defines the time frame that clients can cache queried information before a refresh should be requested.
|
||||||
|
final int ttl;
|
||||||
|
|
||||||
|
/// Variable data depending on record type.
|
||||||
|
///
|
||||||
|
/// For example, the "data" value for an A record would be the IPv4 address to which the domain will be mapped.
|
||||||
|
/// For a CAA record, it would contain the domain name of the CA being granted permission to issue certificates.
|
||||||
|
final String data;
|
||||||
|
|
||||||
|
/// The priority for SRV and MX records.
|
||||||
|
final int? priority;
|
||||||
|
|
||||||
|
static DigitalOceanDnsRecord fromJson(final Map<String, dynamic> json) =>
|
||||||
|
_$DigitalOceanDnsRecordFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$DigitalOceanDnsRecordToJson(this);
|
||||||
|
}
|
41
lib/logic/models/json/digital_ocean_dns_info.g.dart
Normal file
41
lib/logic/models/json/digital_ocean_dns_info.g.dart
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'digital_ocean_dns_info.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
DigitalOceanDomain _$DigitalOceanDomainFromJson(Map<String, dynamic> json) =>
|
||||||
|
DigitalOceanDomain(
|
||||||
|
name: json['name'] as String,
|
||||||
|
ttl: json['ttl'] as int?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$DigitalOceanDomainToJson(DigitalOceanDomain instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'name': instance.name,
|
||||||
|
'ttl': instance.ttl,
|
||||||
|
};
|
||||||
|
|
||||||
|
DigitalOceanDnsRecord _$DigitalOceanDnsRecordFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
DigitalOceanDnsRecord(
|
||||||
|
id: json['id'] as int?,
|
||||||
|
name: json['name'] as String,
|
||||||
|
type: json['type'] as String,
|
||||||
|
ttl: json['ttl'] as int,
|
||||||
|
data: json['data'] as String,
|
||||||
|
priority: json['priority'] as int?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$DigitalOceanDnsRecordToJson(
|
||||||
|
DigitalOceanDnsRecord instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'id': instance.id,
|
||||||
|
'name': instance.name,
|
||||||
|
'type': instance.type,
|
||||||
|
'ttl': instance.ttl,
|
||||||
|
'data': instance.data,
|
||||||
|
'priority': instance.priority,
|
||||||
|
};
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/desired_dns_record.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/desired_dns_record.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/digital_ocean_dns/digital_ocean_dns_api.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/digital_ocean_dns/digital_ocean_dns_api.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/json/digital_ocean_dns_info.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/dns_records.dart';
|
import 'package:selfprivacy/logic/models/json/dns_records.dart';
|
||||||
import 'package:selfprivacy/logic/providers/dns_providers/dns_provider.dart';
|
import 'package:selfprivacy/logic/providers/dns_providers/dns_provider.dart';
|
||||||
|
|
||||||
|
@ -59,7 +60,7 @@ class DigitalOceanDnsProvider extends DnsProvider {
|
||||||
|
|
||||||
domains = result.data
|
domains = result.data
|
||||||
.map<String>(
|
.map<String>(
|
||||||
(final el) => el['name'] as String,
|
(final el) => el.name,
|
||||||
)
|
)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
@ -75,11 +76,22 @@ class DigitalOceanDnsProvider extends DnsProvider {
|
||||||
final String? ip4,
|
final String? ip4,
|
||||||
}) async =>
|
}) async =>
|
||||||
_adapter.api().createMultipleDnsRecords(
|
_adapter.api().createMultipleDnsRecords(
|
||||||
domain: domain,
|
domainName: domain.domainName,
|
||||||
records: getProjectDnsRecords(
|
records: getProjectDnsRecords(
|
||||||
domain.domainName,
|
domain.domainName,
|
||||||
ip4,
|
ip4,
|
||||||
),
|
)
|
||||||
|
.map<DigitalOceanDnsRecord>(
|
||||||
|
(final e) => DigitalOceanDnsRecord(
|
||||||
|
name: e.name ?? '',
|
||||||
|
id: null,
|
||||||
|
data: e.content ?? '',
|
||||||
|
ttl: e.ttl,
|
||||||
|
type: e.type,
|
||||||
|
priority: e.priority,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -87,7 +99,7 @@ class DigitalOceanDnsProvider extends DnsProvider {
|
||||||
required final ServerDomain domain,
|
required final ServerDomain domain,
|
||||||
final String? ip4,
|
final String? ip4,
|
||||||
}) async {
|
}) async {
|
||||||
final result = await _adapter.api().getDnsRecords(domain: domain);
|
final result = await _adapter.api().getDnsRecords(domain.domainName);
|
||||||
if (result.data.isEmpty || !result.success) {
|
if (result.data.isEmpty || !result.success) {
|
||||||
return GenericResult(
|
return GenericResult(
|
||||||
success: result.success,
|
success: result.success,
|
||||||
|
@ -98,15 +110,15 @@ class DigitalOceanDnsProvider extends DnsProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
const ignoreType = 'SOA';
|
const ignoreType = 'SOA';
|
||||||
final filteredRecords = [];
|
final List<DigitalOceanDnsRecord> filteredRecords = [];
|
||||||
for (final record in result.data) {
|
for (final record in result.data) {
|
||||||
if (record['type'] != ignoreType) {
|
if (record.type != ignoreType) {
|
||||||
filteredRecords.add(record);
|
filteredRecords.add(record);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _adapter.api().removeSimilarRecords(
|
return _adapter.api().removeSimilarRecords(
|
||||||
domain: domain,
|
domainName: domain.domainName,
|
||||||
records: filteredRecords,
|
records: filteredRecords,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -116,7 +128,7 @@ class DigitalOceanDnsProvider extends DnsProvider {
|
||||||
required final ServerDomain domain,
|
required final ServerDomain domain,
|
||||||
}) async {
|
}) async {
|
||||||
final List<DnsRecord> records = [];
|
final List<DnsRecord> records = [];
|
||||||
final result = await _adapter.api().getDnsRecords(domain: domain);
|
final result = await _adapter.api().getDnsRecords(domain.domainName);
|
||||||
if (result.data.isEmpty || !result.success) {
|
if (result.data.isEmpty || !result.success) {
|
||||||
return GenericResult(
|
return GenericResult(
|
||||||
success: result.success,
|
success: result.success,
|
||||||
|
@ -129,10 +141,10 @@ class DigitalOceanDnsProvider extends DnsProvider {
|
||||||
for (final rawRecord in result.data) {
|
for (final rawRecord in result.data) {
|
||||||
records.add(
|
records.add(
|
||||||
DnsRecord(
|
DnsRecord(
|
||||||
name: rawRecord['name'],
|
name: rawRecord.name,
|
||||||
type: rawRecord['type'],
|
type: rawRecord.type,
|
||||||
content: rawRecord['data'],
|
content: rawRecord.data,
|
||||||
ttl: rawRecord['ttl'],
|
ttl: rawRecord.ttl,
|
||||||
proxied: false,
|
proxied: false,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -147,8 +159,17 @@ class DigitalOceanDnsProvider extends DnsProvider {
|
||||||
final ServerDomain domain,
|
final ServerDomain domain,
|
||||||
) async =>
|
) async =>
|
||||||
_adapter.api().createMultipleDnsRecords(
|
_adapter.api().createMultipleDnsRecords(
|
||||||
domain: domain,
|
domainName: domain.domainName,
|
||||||
records: [record],
|
records: [
|
||||||
|
DigitalOceanDnsRecord(
|
||||||
|
data: record.content ?? '',
|
||||||
|
id: null,
|
||||||
|
name: record.name ?? '',
|
||||||
|
ttl: record.ttl,
|
||||||
|
type: record.type,
|
||||||
|
priority: record.priority,
|
||||||
|
),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
Loading…
Reference in a new issue