mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-08 00:51:20 +00:00
Merge pull request 'refactor(desec): Implement basic DTO for DESEC to avoid dynamic objects' (#246) from dto into master
Reviewed-on: https://git.selfprivacy.org/SelfPrivacy/selfprivacy.org.app/pulls/246 Reviewed-by: Inex Code <inex.code@selfprivacy.org>
This commit is contained in:
commit
fd1be6358c
|
@ -4,7 +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/desec_dns_info.dart';
|
||||||
|
|
||||||
class DesecApi extends RestApiMap {
|
class DesecApi extends RestApiMap {
|
||||||
DesecApi({
|
DesecApi({
|
||||||
|
@ -92,8 +92,8 @@ class DesecApi extends RestApiMap {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<GenericResult<List>> getDomains() async {
|
Future<GenericResult<List<DesecDomain>>> getDomains() async {
|
||||||
List domains = [];
|
List<DesecDomain> domains = [];
|
||||||
|
|
||||||
late final Response? response;
|
late final Response? response;
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
|
@ -102,7 +102,11 @@ class DesecApi extends RestApiMap {
|
||||||
'',
|
'',
|
||||||
);
|
);
|
||||||
await Future.delayed(const Duration(seconds: 1));
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
domains = response.data;
|
domains = response.data!
|
||||||
|
.map<DesecDomain>(
|
||||||
|
(final e) => DesecDomain.fromJson(e),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
return GenericResult(
|
return GenericResult(
|
||||||
|
@ -124,15 +128,17 @@ class DesecApi extends RestApiMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<GenericResult<void>> createMultipleDnsRecords({
|
Future<GenericResult<void>> createMultipleDnsRecords({
|
||||||
required final ServerDomain domain,
|
required final String domainName,
|
||||||
required final List<dynamic> records,
|
required final List<DesecDnsRecord> records,
|
||||||
}) async {
|
}) async {
|
||||||
final String domainName = domain.domainName;
|
|
||||||
final String url = '/$domainName/rrsets/';
|
final String url = '/$domainName/rrsets/';
|
||||||
|
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
try {
|
try {
|
||||||
await client.post(url, data: records);
|
await client.post(
|
||||||
|
url,
|
||||||
|
data: records.map((final rec) => rec.toJson()).toList(),
|
||||||
|
);
|
||||||
await Future.delayed(const Duration(seconds: 1));
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
|
@ -149,15 +155,17 @@ class DesecApi extends RestApiMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<GenericResult<void>> removeSimilarRecords({
|
Future<GenericResult<void>> removeSimilarRecords({
|
||||||
required final ServerDomain domain,
|
required final String domainName,
|
||||||
required final List<dynamic> records,
|
required final List<DesecDnsRecord> records,
|
||||||
}) async {
|
}) async {
|
||||||
final String domainName = domain.domainName;
|
|
||||||
final String url = '/$domainName/rrsets/';
|
final String url = '/$domainName/rrsets/';
|
||||||
|
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
try {
|
try {
|
||||||
await client.put(url, data: records);
|
await client.put(
|
||||||
|
url,
|
||||||
|
data: records.map((final rec) => rec.toJson()).toList(),
|
||||||
|
);
|
||||||
await Future.delayed(const Duration(seconds: 1));
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
|
@ -173,12 +181,11 @@ class DesecApi extends RestApiMap {
|
||||||
return GenericResult(success: true, data: null);
|
return GenericResult(success: true, data: null);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<GenericResult<List<dynamic>>> getDnsRecords({
|
Future<GenericResult<List<DesecDnsRecord>>> getDnsRecords(
|
||||||
required final ServerDomain domain,
|
final String domainName,
|
||||||
}) async {
|
) async {
|
||||||
Response? response;
|
Response? response;
|
||||||
final String domainName = domain.domainName;
|
List<DesecDnsRecord> allRecords = [];
|
||||||
List allRecords = [];
|
|
||||||
|
|
||||||
final String url = '/$domainName/rrsets/';
|
final String url = '/$domainName/rrsets/';
|
||||||
|
|
||||||
|
@ -186,7 +193,11 @@ class DesecApi extends RestApiMap {
|
||||||
try {
|
try {
|
||||||
response = await client.get(url);
|
response = await client.get(url);
|
||||||
await Future.delayed(const Duration(seconds: 1));
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
allRecords = response.data;
|
allRecords = response.data!
|
||||||
|
.map<DesecDnsRecord>(
|
||||||
|
(final e) => DesecDnsRecord.fromJson(e),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
return GenericResult(
|
return GenericResult(
|
||||||
|
|
63
lib/logic/models/json/desec_dns_info.dart
Normal file
63
lib/logic/models/json/desec_dns_info.dart
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'desec_dns_info.g.dart';
|
||||||
|
|
||||||
|
/// https://desec.readthedocs.io/en/latest/dns/domains.html#domain-management
|
||||||
|
@JsonSerializable()
|
||||||
|
class DesecDomain {
|
||||||
|
DesecDomain(
|
||||||
|
this.name,
|
||||||
|
this.minimumTtl,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Restrictions on what is a valid domain name apply on
|
||||||
|
/// a per-user basis.
|
||||||
|
///
|
||||||
|
/// The maximum length is 191.
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
/// Smallest TTL that can be used in an RRset.
|
||||||
|
/// The value is set automatically by DESEC
|
||||||
|
@JsonKey(name: 'minimum_ttl')
|
||||||
|
final int minimumTtl;
|
||||||
|
|
||||||
|
static DesecDomain fromJson(final Map<String, dynamic> json) =>
|
||||||
|
_$DesecDomainFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://desec.readthedocs.io/en/latest/dns/rrsets.html#retrieving-and-creating-dns-records
|
||||||
|
@JsonSerializable()
|
||||||
|
class DesecDnsRecord {
|
||||||
|
DesecDnsRecord({
|
||||||
|
required this.subname,
|
||||||
|
required this.type,
|
||||||
|
required this.ttl,
|
||||||
|
required this.records,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Subdomain string which, together with domain, defines the RRset name.
|
||||||
|
/// Typical examples are www or _443._tcp.
|
||||||
|
final String subname;
|
||||||
|
|
||||||
|
/// RRset type (uppercase). A broad range of record types is supported,
|
||||||
|
/// with most DNSSEC-related types (and the SOA type) managed automagically
|
||||||
|
/// by the backend.
|
||||||
|
final String type;
|
||||||
|
|
||||||
|
/// Time-to-live value, which dictates for how long resolvers may
|
||||||
|
/// cache this RRset, measured in seconds.
|
||||||
|
///
|
||||||
|
/// The smallest acceptable value is given by the domain’s minimum TTL setting.
|
||||||
|
/// The maximum value is 86400 (one day).
|
||||||
|
final int ttl;
|
||||||
|
|
||||||
|
/// Array of record content strings.
|
||||||
|
///
|
||||||
|
/// The maximum number of array elements is 4091,
|
||||||
|
/// and the maximum length of the array is 64,000 (after JSON encoding).
|
||||||
|
final List<String> records;
|
||||||
|
|
||||||
|
static DesecDnsRecord fromJson(final Map<String, dynamic> json) =>
|
||||||
|
_$DesecDnsRecordFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$DesecDnsRecordToJson(this);
|
||||||
|
}
|
35
lib/logic/models/json/desec_dns_info.g.dart
Normal file
35
lib/logic/models/json/desec_dns_info.g.dart
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'desec_dns_info.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
DesecDomain _$DesecDomainFromJson(Map<String, dynamic> json) => DesecDomain(
|
||||||
|
json['name'] as String,
|
||||||
|
json['minimum_ttl'] as int,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$DesecDomainToJson(DesecDomain instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'name': instance.name,
|
||||||
|
'minimum_ttl': instance.minimumTtl,
|
||||||
|
};
|
||||||
|
|
||||||
|
DesecDnsRecord _$DesecDnsRecordFromJson(Map<String, dynamic> json) =>
|
||||||
|
DesecDnsRecord(
|
||||||
|
subname: json['subname'] as String,
|
||||||
|
type: json['type'] as String,
|
||||||
|
ttl: json['ttl'] as int,
|
||||||
|
records:
|
||||||
|
(json['records'] as List<dynamic>).map((e) => e as String).toList(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$DesecDnsRecordToJson(DesecDnsRecord instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'subname': instance.subname,
|
||||||
|
'type': instance.type,
|
||||||
|
'ttl': instance.ttl,
|
||||||
|
'records': instance.records,
|
||||||
|
};
|
|
@ -9,7 +9,6 @@ class DnsRecord {
|
||||||
required this.type,
|
required this.type,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.content,
|
required this.content,
|
||||||
this.id,
|
|
||||||
this.ttl = 3600,
|
this.ttl = 3600,
|
||||||
this.priority = 10,
|
this.priority = 10,
|
||||||
this.proxied = false,
|
this.proxied = false,
|
||||||
|
@ -32,8 +31,5 @@ class DnsRecord {
|
||||||
final int priority;
|
final int priority;
|
||||||
final bool proxied;
|
final bool proxied;
|
||||||
|
|
||||||
/// TODO: Refactoring refactoring refactoring refactoring >:c
|
|
||||||
final int? id;
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => _$DnsRecordToJson(this);
|
Map<String, dynamic> toJson() => _$DnsRecordToJson(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,5 +13,4 @@ Map<String, dynamic> _$DnsRecordToJson(DnsRecord instance) => <String, dynamic>{
|
||||||
'ttl': instance.ttl,
|
'ttl': instance.ttl,
|
||||||
'priority': instance.priority,
|
'priority': instance.priority,
|
||||||
'proxied': instance.proxied,
|
'proxied': instance.proxied,
|
||||||
'id': instance.id,
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/desec/desec_api.dart';
|
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/desec/desec_api.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/desired_dns_record.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/desec_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 DesecDnsProvider extends DnsProvider {
|
||||||
|
|
||||||
domains = result.data
|
domains = result.data
|
||||||
.map<String>(
|
.map<String>(
|
||||||
(final el) => el['name'] as String,
|
(final el) => el.name,
|
||||||
)
|
)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
@ -79,20 +80,20 @@ class DesecDnsProvider extends DnsProvider {
|
||||||
ip4,
|
ip4,
|
||||||
);
|
);
|
||||||
|
|
||||||
final List<dynamic> bulkRecords = [];
|
final List<DesecDnsRecord> bulkRecords = [];
|
||||||
for (final DnsRecord record in listDnsRecords) {
|
for (final DnsRecord record in listDnsRecords) {
|
||||||
bulkRecords.add(
|
bulkRecords.add(
|
||||||
{
|
DesecDnsRecord(
|
||||||
'subname': record.name,
|
subname: record.name ?? '',
|
||||||
'type': record.type,
|
type: record.type,
|
||||||
'ttl': record.ttl,
|
ttl: record.ttl,
|
||||||
'records': [extractContent(record)],
|
records: [extractContent(record) ?? ''],
|
||||||
},
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _adapter.api().createMultipleDnsRecords(
|
return _adapter.api().createMultipleDnsRecords(
|
||||||
domain: domain,
|
domainName: domain.domainName,
|
||||||
records: bulkRecords,
|
records: bulkRecords,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -107,28 +108,28 @@ class DesecDnsProvider extends DnsProvider {
|
||||||
ip4,
|
ip4,
|
||||||
);
|
);
|
||||||
|
|
||||||
final List<dynamic> bulkRecords = [];
|
final List<DesecDnsRecord> bulkRecords = [];
|
||||||
for (final DnsRecord record in listDnsRecords) {
|
for (final DnsRecord record in listDnsRecords) {
|
||||||
bulkRecords.add(
|
bulkRecords.add(
|
||||||
{
|
DesecDnsRecord(
|
||||||
'subname': record.name,
|
subname: record.name ?? '',
|
||||||
'type': record.type,
|
type: record.type,
|
||||||
'ttl': record.ttl,
|
ttl: record.ttl,
|
||||||
'records': [],
|
records: [],
|
||||||
},
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
bulkRecords.add(
|
bulkRecords.add(
|
||||||
{
|
DesecDnsRecord(
|
||||||
'subname': 'selector._domainkey',
|
subname: 'selector._domainkey',
|
||||||
'type': 'TXT',
|
type: 'TXT',
|
||||||
'ttl': 18000,
|
ttl: 18000,
|
||||||
'records': [],
|
records: [],
|
||||||
},
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
return _adapter.api().removeSimilarRecords(
|
return _adapter.api().removeSimilarRecords(
|
||||||
domain: domain,
|
domainName: domain.domainName,
|
||||||
records: bulkRecords,
|
records: bulkRecords,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -138,7 +139,7 @@ class DesecDnsProvider 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,
|
||||||
|
@ -150,15 +151,14 @@ class DesecDnsProvider extends DnsProvider {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (final record in result.data) {
|
for (final record in result.data) {
|
||||||
final String? content = (record['records'] is List<dynamic>)
|
final String? content =
|
||||||
? record['records'][0]
|
record.records.isEmpty ? null : record.records[0];
|
||||||
: record['records'];
|
|
||||||
records.add(
|
records.add(
|
||||||
DnsRecord(
|
DnsRecord(
|
||||||
name: record['subname'],
|
name: record.subname,
|
||||||
type: record['type'],
|
type: record.type,
|
||||||
content: content,
|
content: content,
|
||||||
ttl: record['ttl'],
|
ttl: record.ttl,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -180,14 +180,14 @@ class DesecDnsProvider extends DnsProvider {
|
||||||
final ServerDomain domain,
|
final ServerDomain domain,
|
||||||
) async {
|
) async {
|
||||||
final result = await _adapter.api().createMultipleDnsRecords(
|
final result = await _adapter.api().createMultipleDnsRecords(
|
||||||
domain: domain,
|
domainName: domain.domainName,
|
||||||
records: [
|
records: [
|
||||||
{
|
DesecDnsRecord(
|
||||||
'subname': record.name,
|
subname: record.name ?? '',
|
||||||
'type': record.type,
|
type: record.type,
|
||||||
'ttl': record.ttl,
|
ttl: record.ttl,
|
||||||
'records': [extractContent(record)],
|
records: [extractContent(record) ?? ''],
|
||||||
},
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,6 @@ class DigitalOceanDnsProvider extends DnsProvider {
|
||||||
for (final rawRecord in result.data) {
|
for (final rawRecord in result.data) {
|
||||||
records.add(
|
records.add(
|
||||||
DnsRecord(
|
DnsRecord(
|
||||||
id: rawRecord['id'],
|
|
||||||
name: rawRecord['name'],
|
name: rawRecord['name'],
|
||||||
type: rawRecord['type'],
|
type: rawRecord['type'],
|
||||||
content: rawRecord['data'],
|
content: rawRecord['data'],
|
||||||
|
|
Loading…
Reference in a new issue