From 0b22d5e63a842ad66e10509321104088a3d920c2 Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Mon, 30 Oct 2023 17:57:45 -0400 Subject: [PATCH] added isValidDomain to host validation; added INVALID_HOST to error messages --- src/registrar/forms/domain.py | 19 ++++++++++++++++--- src/registrar/models/domain.py | 27 ++++++++++++++++++++++++++- src/registrar/utility/errors.py | 3 +++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/registrar/forms/domain.py b/src/registrar/forms/domain.py index 3aca7af6d..992d283a4 100644 --- a/src/registrar/forms/domain.py +++ b/src/registrar/forms/domain.py @@ -51,9 +51,8 @@ class DomainNameserverForm(forms.Form): ip_list = self.extract_ip_list(ip) - if ip and not server and ip_list: - self.add_error("server", NameserverError(code=nsErrorCodes.MISSING_HOST)) - elif server: + # validate if the form has a server or an ip + if ip and ip_list or server: self.validate_nameserver_ip_combo(domain, server, ip_list) return cleaned_data @@ -86,6 +85,20 @@ class DomainNameserverForm(forms.Form): code=nsErrorCodes.MISSING_IP, nameserver=domain, ip=ip_list ), ) + elif e.code == nsErrorCodes.MISSING_HOST: + self.add_error( + "server", + NameserverError( + code=nsErrorCodes.MISSING_HOST, nameserver=domain, ip=ip_list + ), + ) + elif e.code == nsErrorCodes.INVALID_HOST: + self.add_error( + "server", + NameserverError( + code=nsErrorCodes.INVALID_HOST, nameserver=server, ip=ip_list + ), + ) else: self.add_error("ip", str(e)) diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index 07e49dfdd..5f201865c 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -304,6 +304,25 @@ class Domain(TimeStampedModel, DomainHelper): regex = re.compile(full_pattern) return bool(regex.match(nameserver)) + @classmethod + def isValidDomain(cls, nameserver: str): + """Checks for validity of nameserver string based on these rules: + - first character is alpha + - last character is not - or . + - all characters alpha, 0-9, -, or . + - 2 character min, 24 character max + """ + # pattern to test for valid domain + # pattern = r'^[a-zA-Z][a-zA-Z0-9-.]{0,22}[a-zA-Z0-9]$' + pattern = r"^[a-zA-Z][a-zA-Z0-9-.]*(\.[a-zA-Z0-9-]+){2}[a-zA-Z0-9]$" + + # attempt to match the pattern + match = re.match(pattern, nameserver) + + # return true if nameserver matches, and length less than 25; + # otherwise false + return bool(match) and len(nameserver) < 25 + @classmethod def checkHostIPCombo(cls, name: str, nameserver: str, ip: list[str]): """Checks the parameters past for a valid combination @@ -311,6 +330,8 @@ class Domain(TimeStampedModel, DomainHelper): - nameserver is a subdomain but is missing ip - nameserver is not a subdomain but has ip - nameserver is a subdomain but an ip passed is invalid + - nameserver is not a valid domain + - ip is provided but is missing domain Args: hostname (str)- nameserver or subdomain @@ -319,7 +340,11 @@ class Domain(TimeStampedModel, DomainHelper): NameserverError (if exception hit) Returns: None""" - if cls.isSubdomain(name, nameserver) and (ip is None or ip == []): + if ip and not nameserver: + raise NameserverError(code=nsErrorCodes.MISSING_HOST) + elif nameserver and not cls.isValidDomain(nameserver): + raise NameserverError(code=nsErrorCodes.INVALID_HOST, nameserver=nameserver) + elif cls.isSubdomain(name, nameserver) and (ip is None or ip == []): raise NameserverError(code=nsErrorCodes.MISSING_IP, nameserver=nameserver) elif not cls.isSubdomain(name, nameserver) and (ip is not None and ip != []): diff --git a/src/registrar/utility/errors.py b/src/registrar/utility/errors.py index c1d3c5849..9b9cfea0e 100644 --- a/src/registrar/utility/errors.py +++ b/src/registrar/utility/errors.py @@ -66,6 +66,7 @@ class NameserverErrorCodes(IntEnum): - 4 TOO_MANY_HOSTS more than the max allowed host values - 5 UNABLE_TO_UPDATE_DOMAIN unable to update the domain - 6 MISSING_HOST host is missing for a nameserver + - 7 INVALID_HOST host is invalid for a nameserver """ MISSING_IP = 1 @@ -74,6 +75,7 @@ class NameserverErrorCodes(IntEnum): TOO_MANY_HOSTS = 4 UNABLE_TO_UPDATE_DOMAIN = 5 MISSING_HOST = 6 + INVALID_HOST = 7 class NameserverError(Exception): @@ -102,6 +104,7 @@ class NameserverError(Exception): NameserverErrorCodes.MISSING_HOST: ( "Name server must be provided to enter IP address." ), + NameserverErrorCodes.INVALID_HOST: ("Name server, {}, is not valid."), } def __init__(self, *args, code=None, nameserver=None, ip=None, **kwargs):