|
@@ -15,10 +15,41 @@ import re
|
15
|
15
|
import ipaddress
|
16
|
16
|
|
17
|
17
|
|
18
|
|
-class DomainForm(MntFormMixin, WhoisObjectFormMixin, forms.ModelForm):
|
|
18
|
+class DSRecordMixin(object):
|
|
19
|
+ ds_re = re.compile(r"^(?P<id>\d+)\s+(?P<crypto>\d+)\s+(?P<hashtype>\d+)\s+(?P<hash>[0-9a-fA-F]+)$")
|
|
20
|
+ HASH_SUPPORTED = (1, 2)
|
|
21
|
+ CRYPTO_SUPPORTED = (3, 5, 6, 8, 10, 13, 15)
|
|
22
|
+
|
|
23
|
+ def clean_ds_records(self):
|
|
24
|
+ ds_records = self.cleaned_data['ds_records'].strip()
|
|
25
|
+ result = []
|
|
26
|
+
|
|
27
|
+ if not ds_records:
|
|
28
|
+ return ''
|
|
29
|
+
|
|
30
|
+ for n, rec in enumerate(ds_records.split("\n"), 1):
|
|
31
|
+ rec = rec.strip()
|
|
32
|
+ m = self.ds_re.match(rec)
|
|
33
|
+ if not m:
|
|
34
|
+ raise forms.ValidationError("Could not parse records {} - needs to be in format "
|
|
35
|
+ "'<id> <crypto> <hashtype> <hash>'".format(n))
|
|
36
|
+
|
|
37
|
+ if int(m.group('hashtype')) not in self.HASH_SUPPORTED:
|
|
38
|
+ raise forms.ValidationError("Record {} has an invalid hashtype of {}, supported are {}"
|
|
39
|
+ "".format(n, m.group('hashtype'), " ".join(map(str, self.HASH_SUPPORTED))))
|
|
40
|
+ if int(m.group('crypto')) not in self.CRYPTO_SUPPORTED:
|
|
41
|
+ raise forms.ValidationError("Record {} has unsupported crypto {}, supported are {}"
|
|
42
|
+ "".format(n, m.group('crypto'), " ".join(map(str, self.CRYPTO_SUPPORTED))))
|
|
43
|
+
|
|
44
|
+ result.append("{id} {crypto} {hashtype} {hash}".format(**m.groupdict()))
|
|
45
|
+
|
|
46
|
+ return "\n".join(result)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+class DomainForm(MntFormMixin, WhoisObjectFormMixin, DSRecordMixin, forms.ModelForm):
|
19
|
50
|
class Meta:
|
20
|
51
|
model = Domain
|
21
|
|
- fields = ['name', 'nameservers', 'mnt_by', 'admin_c']
|
|
52
|
+ fields = ['name', 'nameservers', 'mnt_by', 'admin_c', 'ds_records']
|
22
|
53
|
|
23
|
54
|
def __init__(self, *args, **kwargs):
|
24
|
55
|
super(DomainForm, self).__init__(*args, **kwargs)
|