Validate domain records (on update & creation)

This commit is contained in:
Santiago L 2023-11-29 15:03:12 +01:00
parent be3ca0aecd
commit d3b3547811
3 changed files with 51 additions and 4 deletions

View file

@ -5,6 +5,7 @@ from django.utils.translation import gettext_lazy as _
from orchestra.contrib.domains.models import Domain, Record
from orchestra.contrib.mailboxes.models import Address, Mailbox
from orchestra.contrib.musician.validators import ValidateZoneMixin
from . import api
@ -137,7 +138,7 @@ class MailboxUpdateForm(forms.ModelForm):
model = Mailbox
class RecordCreateForm(forms.ModelForm):
class RecordCreateForm(ValidateZoneMixin, forms.ModelForm):
class Meta:
model = Record
@ -155,8 +156,12 @@ class RecordCreateForm(forms.ModelForm):
return instance
class RecordUpdateForm(forms.ModelForm):
class RecordUpdateForm(ValidateZoneMixin, forms.ModelForm):
class Meta:
model = Record
fields = ("ttl", "type", "value")
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.domain = self.instance.domain

View file

@ -4,13 +4,16 @@
{% block content %}
<a class="btn-arrow-left" href="{% url 'musician:domain-detail' view.kwargs.pk %}">{% trans "Go back" %}</a>
<h1 class="service-name">{% trans "Add record for" %} <span class="font-weight-light">{{ form.domain.name }}</span></h1>
<h1 class="service-name">
{% if form.instance.pk %}{% trans "Update record of" %}{% else %}{% trans "Add record to" %}{% endif %}
<span class="font-weight-light">{{ form.domain.name }}</span>
</h1>
<form method="post">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<a class="btn btn-light mr-2" href="{% url 'musician:domain-detail' view.kwargs.pk %}"">{% trans "Cancel" %}</a>
<a class="btn btn-light mr-2" href="{% url 'musician:domain-detail' view.kwargs.pk %}">{% trans "Cancel" %}</a>
<button type="submit" class="btn btn-secondary">{% trans "Save" %}</button>
{% if form.instance.pk %}
<div class="float-right">

View file

@ -0,0 +1,39 @@
from orchestra.contrib.domains.helpers import domain_for_validation
from orchestra.contrib.domains.models import Record
from orchestra.contrib.domains.validators import validate_zone
class ValidateZoneMixin:
# NOTE: adapted code of orchestra.contrib.domains.forms.ValidateZoneMixin
# but only for one form (instead a admin inline formset)
def clean(self):
""" Checks if everything is consistent """
super(ValidateZoneMixin, self).clean()
if any(self.errors):
return
is_host = self.cleaned_data.get('type') in (Record.TXT, Record.SRV, Record.CNAME)
domain_names = []
if self.domain.name:
domain_names.append(self.domain.name)
domain_names.extend(getattr(self.domain, 'extra_names', []))
errors = []
for name in domain_names:
if '_' in name and is_host:
errors.append(ValidationError(
_("%s: Hosts can not have underscore character '_', consider providing a SRV, CNAME or TXT record.") % name
))
records = [self.cleaned_data]
domain = domain_for_validation(self.domain, records)
try:
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)