Improved domain validation

This commit is contained in:
Marc Aymerich 2016-09-02 14:50:43 +00:00
parent 53541b16a1
commit dd9621cc63
2 changed files with 41 additions and 9 deletions

View File

@ -25,7 +25,7 @@ Overview
* You can [develop new services](docs/create-services.md) without worring about those parts * You can [develop new services](docs/create-services.md) without worring about those parts
* You can replace any of these parts by your own implementation without carring about the others * You can replace any of these parts by your own implementation without carring about the others
* You can reuse any of those modules on your Django projects * You can reuse any of those modules on your Django projects
* Be advised, because its flexibility Orchestra may be more difficult to deploy than traditional web hosting control panels. * Be advised, because its flexibility Orchestra may be more tedious to deploy than traditional web hosting control panels.
![](docs/images/index-screenshot.png) ![](docs/images/index-screenshot.png)

View File

@ -18,14 +18,15 @@ class BatchDomainCreationAdminForm(forms.ModelForm):
def clean_name(self): def clean_name(self):
self.extra_names = [] self.extra_names = []
target = None target = None
existing = set(Domain.objects.values_list('name', flat=True)) existing = set()
errors = [] errors = []
for name in self.cleaned_data['name'].strip().splitlines(): domain_names = self.cleaned_data['name'].strip().splitlines()
for name in domain_names:
name = name.strip() name = name.strip()
if not name: if not name:
continue continue
if name in existing: if name in existing:
errors.append(ValidationError(_("%s domain name already exists.") % name)) errors.append(ValidationError(_("%s domain name provided multiple times.") % name))
existing.add(name) existing.add(name)
if target is None: if target is None:
target = name target = name
@ -34,7 +35,11 @@ class BatchDomainCreationAdminForm(forms.ModelForm):
try: try:
domain.full_clean(exclude=['top']) domain.full_clean(exclude=['top'])
except ValidationError as e: except ValidationError as e:
raise ValidationError(e.error_dict['name']) for error in e.error_dict['name']:
for msg in error.messages:
errors.append(
ValidationError("%s: %s" % (name, msg))
)
self.extra_names.append(name) self.extra_names.append(name)
if errors: if errors:
raise ValidationError(errors) raise ValidationError(errors)
@ -42,10 +47,15 @@ class BatchDomainCreationAdminForm(forms.ModelForm):
def clean(self): def clean(self):
""" inherit related parent domain account, when exists """ """ inherit related parent domain account, when exists """
cleaned_data = super(BatchDomainCreationAdminForm, self).clean() cleaned_data = super().clean()
if not cleaned_data['account']: if not cleaned_data['account']:
account = None account = None
for name in [cleaned_data['name']] + self.extra_names: domain_names = []
if 'name' in cleaned_data:
first = cleaned_data['name']
domain_names.append(first)
domain_names.extend(self.extra_names)
for name in domain_names:
parent = Domain.objects.get_parent(name) parent = Domain.objects.get_parent(name)
if not parent: if not parent:
# Fake an account to make django validation happy # Fake an account to make django validation happy
@ -62,8 +72,13 @@ class BatchDomainCreationAdminForm(forms.ModelForm):
'account': _("Provided domain names belong to different accounts."), 'account': _("Provided domain names belong to different accounts."),
}) })
account = parent.account account = parent.account
cleaned_data['account'] = account cleaned_data['account'] = account
return cleaned_data return cleaned_data
def full_clean(self):
# set extra_names on instance to use it on inline formsets validation
super().full_clean()
self.instance.extra_names = extra_names
class RecordForm(forms.ModelForm): class RecordForm(forms.ModelForm):
@ -82,14 +97,31 @@ class ValidateZoneMixin(object):
super(ValidateZoneMixin, self).clean() super(ValidateZoneMixin, self).clean()
if any(self.errors): if any(self.errors):
return return
domain_names = []
if self.instance.name: if self.instance.name:
domain_names.append(self.instance.name)
domain_names.extend(getattr(self.instance, 'extra_names', []))
errors = []
for name in domain_names:
records = [] records = []
for form in self.forms: for form in self.forms:
data = form.cleaned_data data = form.cleaned_data
if data and not data['DELETE']: if data and not data['DELETE']:
records.append(data) records.append(data)
if '_' in name:
errors.append(ValidationError(
_("%s: Domains containing underscore character '_' must provide an SRV record.") % name
))
domain = domain_for_validation(self.instance, records) domain = domain_for_validation(self.instance, records)
validators.validate_zone(domain.render_zone()) try:
validators.validate_zone(domain.render_zone())
except ValidationError as error:
for msg in error:
errors.append(
ValidationError("%s: %s" % (name, msg))
)
if errors:
raise ValidationError(errors)
class RecordEditFormSet(ValidateZoneMixin, AdminFormSet): class RecordEditFormSet(ValidateZoneMixin, AdminFormSet):