mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-07 00:24:18 +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/logic/api_maps/generic_result.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/dns_records.dart';
|
||||
import 'package:selfprivacy/logic/models/json/digital_ocean_dns_info.dart';
|
||||
|
||||
class DigitalOceanDnsApi extends RestApiMap {
|
||||
DigitalOceanDnsApi({
|
||||
|
@ -92,13 +91,17 @@ class DigitalOceanDnsApi extends RestApiMap {
|
|||
);
|
||||
}
|
||||
|
||||
Future<GenericResult<List>> getDomains() async {
|
||||
List domains = [];
|
||||
Future<GenericResult<List<DigitalOceanDomain>>> getDomains() async {
|
||||
List<DigitalOceanDomain> domains = [];
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
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) {
|
||||
print(e);
|
||||
return GenericResult(
|
||||
|
@ -114,25 +117,18 @@ class DigitalOceanDnsApi extends RestApiMap {
|
|||
}
|
||||
|
||||
Future<GenericResult<void>> createMultipleDnsRecords({
|
||||
required final ServerDomain domain,
|
||||
required final List<DnsRecord> records,
|
||||
required final String domainName,
|
||||
required final List<DigitalOceanDnsRecord> records,
|
||||
}) async {
|
||||
final String domainName = domain.domainName;
|
||||
final List<Future> allCreateFutures = <Future>[];
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
for (final DnsRecord record in records) {
|
||||
for (final DigitalOceanDnsRecord record in records) {
|
||||
allCreateFutures.add(
|
||||
client.post(
|
||||
'/domains/$domainName/records',
|
||||
data: {
|
||||
'type': record.type,
|
||||
'name': record.name,
|
||||
'data': record.content,
|
||||
'ttl': record.ttl,
|
||||
'priority': record.priority,
|
||||
},
|
||||
data: record.toJson(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -155,17 +151,15 @@ class DigitalOceanDnsApi extends RestApiMap {
|
|||
}
|
||||
|
||||
Future<GenericResult<void>> removeSimilarRecords({
|
||||
required final ServerDomain domain,
|
||||
required final List records,
|
||||
required final String domainName,
|
||||
required final List<DigitalOceanDnsRecord> records,
|
||||
}) async {
|
||||
final String domainName = domain.domainName;
|
||||
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
final List<Future> allDeleteFutures = [];
|
||||
for (final record in records) {
|
||||
allDeleteFutures.add(
|
||||
client.delete("/domains/$domainName/records/${record['id']}"),
|
||||
client.delete('/domains/$domainName/records/${record.id}'),
|
||||
);
|
||||
}
|
||||
await Future.wait(allDeleteFutures);
|
||||
|
@ -183,12 +177,11 @@ class DigitalOceanDnsApi extends RestApiMap {
|
|||
return GenericResult(success: true, data: null);
|
||||
}
|
||||
|
||||
Future<GenericResult<List>> getDnsRecords({
|
||||
required final ServerDomain domain,
|
||||
}) async {
|
||||
Future<GenericResult<List<DigitalOceanDnsRecord>>> getDnsRecords(
|
||||
final String domainName,
|
||||
) async {
|
||||
Response response;
|
||||
final String domainName = domain.domainName;
|
||||
List allRecords = [];
|
||||
List<DigitalOceanDnsRecord> allRecords = [];
|
||||
|
||||
/// Default amount is 20, but we will eventually overflow it,
|
||||
/// 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();
|
||||
try {
|
||||
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) {
|
||||
print(e);
|
||||
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/digital_ocean_dns/digital_ocean_dns_api.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/providers/dns_providers/dns_provider.dart';
|
||||
|
||||
|
@ -59,7 +60,7 @@ class DigitalOceanDnsProvider extends DnsProvider {
|
|||
|
||||
domains = result.data
|
||||
.map<String>(
|
||||
(final el) => el['name'] as String,
|
||||
(final el) => el.name,
|
||||
)
|
||||
.toList();
|
||||
|
||||
|
@ -75,11 +76,22 @@ class DigitalOceanDnsProvider extends DnsProvider {
|
|||
final String? ip4,
|
||||
}) async =>
|
||||
_adapter.api().createMultipleDnsRecords(
|
||||
domain: domain,
|
||||
domainName: domain.domainName,
|
||||
records: getProjectDnsRecords(
|
||||
domain.domainName,
|
||||
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
|
||||
|
@ -87,7 +99,7 @@ class DigitalOceanDnsProvider extends DnsProvider {
|
|||
required final ServerDomain domain,
|
||||
final String? ip4,
|
||||
}) async {
|
||||
final result = await _adapter.api().getDnsRecords(domain: domain);
|
||||
final result = await _adapter.api().getDnsRecords(domain.domainName);
|
||||
if (result.data.isEmpty || !result.success) {
|
||||
return GenericResult(
|
||||
success: result.success,
|
||||
|
@ -98,15 +110,15 @@ class DigitalOceanDnsProvider extends DnsProvider {
|
|||
}
|
||||
|
||||
const ignoreType = 'SOA';
|
||||
final filteredRecords = [];
|
||||
final List<DigitalOceanDnsRecord> filteredRecords = [];
|
||||
for (final record in result.data) {
|
||||
if (record['type'] != ignoreType) {
|
||||
if (record.type != ignoreType) {
|
||||
filteredRecords.add(record);
|
||||
}
|
||||
}
|
||||
|
||||
return _adapter.api().removeSimilarRecords(
|
||||
domain: domain,
|
||||
domainName: domain.domainName,
|
||||
records: filteredRecords,
|
||||
);
|
||||
}
|
||||
|
@ -116,7 +128,7 @@ class DigitalOceanDnsProvider extends DnsProvider {
|
|||
required final ServerDomain domain,
|
||||
}) async {
|
||||
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) {
|
||||
return GenericResult(
|
||||
success: result.success,
|
||||
|
@ -129,10 +141,10 @@ class DigitalOceanDnsProvider extends DnsProvider {
|
|||
for (final rawRecord in result.data) {
|
||||
records.add(
|
||||
DnsRecord(
|
||||
name: rawRecord['name'],
|
||||
type: rawRecord['type'],
|
||||
content: rawRecord['data'],
|
||||
ttl: rawRecord['ttl'],
|
||||
name: rawRecord.name,
|
||||
type: rawRecord.type,
|
||||
content: rawRecord.data,
|
||||
ttl: rawRecord.ttl,
|
||||
proxied: false,
|
||||
),
|
||||
);
|
||||
|
@ -147,8 +159,17 @@ class DigitalOceanDnsProvider extends DnsProvider {
|
|||
final ServerDomain domain,
|
||||
) async =>
|
||||
_adapter.api().createMultipleDnsRecords(
|
||||
domain: domain,
|
||||
records: [record],
|
||||
domainName: domain.domainName,
|
||||
records: [
|
||||
DigitalOceanDnsRecord(
|
||||
data: record.content ?? '',
|
||||
id: null,
|
||||
name: record.name ?? '',
|
||||
ttl: record.ttl,
|
||||
type: record.type,
|
||||
priority: record.priority,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@override
|
||||
|
|
Loading…
Reference in a new issue