added form validation

This commit is contained in:
David Kennedy 2023-10-19 16:42:36 -04:00
parent d48312f74b
commit 150e89d2ee
No known key found for this signature in database
GPG key ID: 6528A5386E66B96B
4 changed files with 40 additions and 37 deletions

View file

@ -47,6 +47,8 @@ class IPAddressField(forms.CharField):
class DomainNameserverForm(forms.Form): class DomainNameserverForm(forms.Form):
"""Form for changing nameservers.""" """Form for changing nameservers."""
domain = forms.CharField(widget=forms.HiddenInput, required=False)
server = forms.CharField(label="Name server", strip=True) server = forms.CharField(label="Name server", strip=True)
ip = IPAddressField( ip = IPAddressField(
@ -58,21 +60,12 @@ class DomainNameserverForm(forms.Form):
# ], # ],
) )
def __init__(self, *args, **kwargs):
# Access the context object passed to the form
print(f"kwargs in __init__ {kwargs}")
self.domain = kwargs.pop('domain', None)
super().__init__(*args, **kwargs)
# def __init__(self, request, *args, **kwargs):
# # Pass the request object to the form during initialization
# self.request = request
# super().__init__(*args, **kwargs)
def clean(self): def clean(self):
cleaned_data = super().clean() cleaned_data = super().clean()
server = cleaned_data.get('server', '') server = cleaned_data.get('server', '')
ip = cleaned_data.get('ip', '') ip = cleaned_data.get('ip', '')
domain = cleaned_data.get('domain', '')
print(f"clean is called on {domain} {server}")
# make sure there's a nameserver if an ip is passed # make sure there's a nameserver if an ip is passed
if ip: if ip:
@ -82,15 +75,12 @@ class DomainNameserverForm(forms.Form):
raise forms.ValidationError("Name server must be provided to enter IP address.") raise forms.ValidationError("Name server must be provided to enter IP address.")
# if there's a nameserver and an ip, validate nameserver/ip combo # if there's a nameserver and an ip, validate nameserver/ip combo
domain, _ = Domain.objects.get_or_create(name="realize-shake-too.gov")
# Access session data from the request object if server:
# session_data = self.request.session.get('nameservers_form_domain', None) if ip:
ip_list = [ip.strip() for ip in ip.split(",")]
print(f"domain in clean: {self.domain}") else:
ip_list = ['']
if server and ip:
ip_list = [ip.strip() for ip in ip.split(",")]
try: try:
Domain.checkHostIPCombo(domain, server, ip_list) Domain.checkHostIPCombo(domain, server, ip_list)
except NameserverError as e: except NameserverError as e:

View file

@ -291,14 +291,16 @@ class Domain(TimeStampedModel, DomainHelper):
newDict[tup[0]] = tup[1] newDict[tup[0]] = tup[1]
return newDict return newDict
def isSubdomain(self, nameserver: str): @classmethod
def isSubdomain(cls, name: str, nameserver: str):
"""Returns boolean if the domain name is found in the argument passed""" """Returns boolean if the domain name is found in the argument passed"""
subdomain_pattern = r"([\w-]+\.)*" subdomain_pattern = r"([\w-]+\.)*"
full_pattern = subdomain_pattern + self.name full_pattern = subdomain_pattern + name
regex = re.compile(full_pattern) regex = re.compile(full_pattern)
return bool(regex.match(nameserver)) return bool(regex.match(nameserver))
def checkHostIPCombo(self, nameserver: str, ip: list[str]): @classmethod
def checkHostIPCombo(cls, name: str, nameserver: str, ip: list[str]):
"""Checks the parameters past for a valid combination """Checks the parameters past for a valid combination
raises error if: raises error if:
- nameserver is a subdomain but is missing ip - nameserver is a subdomain but is missing ip
@ -312,23 +314,27 @@ class Domain(TimeStampedModel, DomainHelper):
NameserverError (if exception hit) NameserverError (if exception hit)
Returns: Returns:
None""" None"""
if self.isSubdomain(nameserver) and (ip is None or ip == [] or ip == ['']): logger.info("checkHostIPCombo is called on %s, %s", name, nameserver)
if cls.isSubdomain(name, nameserver) and (ip is None or ip == [] or ip == ['']):
raise NameserverError(code=nsErrorCodes.MISSING_IP, nameserver=nameserver) raise NameserverError(code=nsErrorCodes.MISSING_IP, nameserver=nameserver)
elif not self.isSubdomain(nameserver) and (ip is not None and ip != [] and ip != ['']): elif not cls.isSubdomain(name, nameserver) and (ip is not None and ip != [] and ip != ['']):
raise NameserverError( raise NameserverError(
code=nsErrorCodes.GLUE_RECORD_NOT_ALLOWED, nameserver=nameserver, ip=ip code=nsErrorCodes.GLUE_RECORD_NOT_ALLOWED, nameserver=nameserver, ip=ip
) )
elif ip is not None and ip != [] and ip != ['']: elif ip is not None and ip != [] and ip != ['']:
for addr in ip: for addr in ip:
logger.info(f"ip address {addr}") logger.info(f"ip address {addr}")
if not self._valid_ip_addr(addr): if not cls._valid_ip_addr(addr):
raise NameserverError( raise NameserverError(
code=nsErrorCodes.INVALID_IP, nameserver=nameserver, ip=ip code=nsErrorCodes.INVALID_IP, nameserver=nameserver, ip=ip
) )
logger.info("got no errors")
return None return None
def _valid_ip_addr(self, ipToTest: str): @classmethod
def _valid_ip_addr(cls, ipToTest: str):
"""returns boolean if valid ip address string """returns boolean if valid ip address string
We currently only accept v4 or v6 ips We currently only accept v4 or v6 ips
returns: returns:
@ -383,7 +389,7 @@ class Domain(TimeStampedModel, DomainHelper):
if newHostDict[prevHost] is not None and set( if newHostDict[prevHost] is not None and set(
newHostDict[prevHost] newHostDict[prevHost]
) != set(addrs): ) != set(addrs):
self.checkHostIPCombo(nameserver=prevHost, ip=newHostDict[prevHost]) self.__class__.checkHostIPCombo(name=self.name, nameserver=prevHost, ip=newHostDict[prevHost])
updated_values.append((prevHost, newHostDict[prevHost])) updated_values.append((prevHost, newHostDict[prevHost]))
new_values = { new_values = {
@ -393,7 +399,7 @@ class Domain(TimeStampedModel, DomainHelper):
} }
for nameserver, ip in new_values.items(): for nameserver, ip in new_values.items():
self.checkHostIPCombo(nameserver=nameserver, ip=ip) self.__class__.checkHostIPCombo(name=self.name, nameserver=nameserver, ip=ip)
return (deleted_values, updated_values, new_values, previousHostDict) return (deleted_values, updated_values, new_values, previousHostDict)

View file

@ -24,6 +24,7 @@
<div class="server-form"> <div class="server-form">
<div class="grid-row grid-gap-2 flex-end"> <div class="grid-row grid-gap-2 flex-end">
<div class="tablet:grid-col-6"> <div class="tablet:grid-col-6">
{{ form.domain }}
{% with sublabel_text="Example: ns"|concat:forloop.counter|concat:".example.com" %} {% with sublabel_text="Example: ns"|concat:forloop.counter|concat:".example.com" %}
{% if forloop.counter <= 2 %} {% if forloop.counter <= 2 %}
{% with attr_required=True add_group_class="usa-form-group--unstyled-error" %} {% with attr_required=True add_group_class="usa-form-group--unstyled-error" %}

View file

@ -221,13 +221,6 @@ class DomainNameserversView(DomainFormBaseView, BaseFormSet):
form_class = NameserverFormset form_class = NameserverFormset
model = Domain model = Domain
def get_formset_kwargs(self, index):
kwargs = super().get_formset_kwargs(index)
# kwargs['domain'] = self.object # Pass the context data
kwargs.update({"domain", self.object})
print(f"kwargs in get_formset_kwargs {kwargs}")
return kwargs
def get_initial(self): def get_initial(self):
"""The initial value for the form (which is a formset here).""" """The initial value for the form (which is a formset here)."""
nameservers = self.object.nameservers nameservers = self.object.nameservers
@ -257,7 +250,6 @@ class DomainNameserversView(DomainFormBaseView, BaseFormSet):
def get_form(self, **kwargs): def get_form(self, **kwargs):
"""Override the labels and required fields every time we get a formset.""" """Override the labels and required fields every time we get a formset."""
# kwargs.update({"domain", self.object}) # kwargs.update({"domain", self.object})
formset = super().get_form(**kwargs) formset = super().get_form(**kwargs)
for i, form in enumerate(formset): for i, form in enumerate(formset):
@ -268,8 +260,22 @@ class DomainNameserversView(DomainFormBaseView, BaseFormSet):
form.fields["server"].required = True form.fields["server"].required = True
else: else:
form.fields["server"].required = False form.fields["server"].required = False
form.fields["domain"].initial = self.object.name
print(f"domain in get_form {self.object.name}")
return formset return formset
def post(self, request, *args, **kwargs):
"""Form submission posts to this view.
This post method harmonizes using DomainBaseView and FormMixin
"""
self._get_domain(request)
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
def form_valid(self, formset): def form_valid(self, formset):
"""The formset is valid, perform something with it.""" """The formset is valid, perform something with it."""
@ -286,7 +292,7 @@ class DomainNameserversView(DomainFormBaseView, BaseFormSet):
# this will return [''] if no ips have been entered, which is taken # this will return [''] if no ips have been entered, which is taken
# into account in the model in checkHostIPCombo # into account in the model in checkHostIPCombo
ip_list = [ip.strip() for ip in ip_list] ip_list = [ip.strip() for ip in ip_list]
as_tuple = ( as_tuple = (
form.cleaned_data["server"], form.cleaned_data["server"],
ip_list, ip_list,