Common: Improve network range validation (less regex)

This commit is contained in:
vakarisz 2022-07-28 11:29:43 +03:00
parent a1d9118433
commit ce33a7b2f4
1 changed files with 53 additions and 13 deletions

View File

@ -1,24 +1,64 @@
import re
from ipaddress import AddressValueError, IPv4Address, IPv4Network, NetmaskValueError
from marshmallow import ValidationError
ip_regex = r"((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
cird_notation_regex = r"([0-9]|1[0-9]|2[0-9]|3[0-2])"
hostname_regex = r"([A-Za-z0-9]*[A-Za-z]+[A-Za-z0-9]*.?)*([A-Za-z0-9]*[A-Za-z]+[A-Za-z0-9]*)"
hostname_pattern = r"([A-Za-z0-9]*[A-Za-z]+[A-Za-z0-9]*.?)*([A-Za-z0-9]*[A-Za-z]+[A-Za-z0-9]*)"
hostname_regex = re.compile(hostname_pattern)
def validate_subnet_range(subnet_range: str):
range_regexes = [
"^" + ip_regex + "$|",
"^" + ip_regex + r"\s*-\s*" + ip_regex + "$|",
"^" + ip_regex + "/" + cird_notation_regex + "$|",
"^" + hostname_regex + "$",
]
range_regexes = re.compile("".join(range_regexes))
if not re.match(range_regexes, subnet_range):
try:
return validate_ip(subnet_range)
except ValidationError:
pass
try:
return validate_ip_range(subnet_range)
except ValidationError:
pass
try:
return validate_ip_network(subnet_range)
except ValidationError:
pass
try:
return validate_hostname(subnet_range)
except ValidationError:
raise ValidationError(f"Invalid subnet range {subnet_range}")
def validate_hostname(hostname: str):
match = re.match(hostname_regex, hostname)
if match and match.group() == hostname:
return
else:
raise ValidationError(f"Invalid hostname {hostname}")
def validate_ip_network(ip_network: str):
try:
IPv4Network(ip_network, strict=False)
return
except (NetmaskValueError, AddressValueError):
raise ValidationError(f"Invalid IPv4 network {ip_network}")
def validate_ip_range(ip_range: str):
try:
ip_range = ip_range.replace(" ", "")
ips = ip_range.split("-")
validate_ip(ips[0])
validate_ip(ips[1])
if len(ips) != 2:
raise ValidationError(f"Invalid IP range {ip_range}")
except (AddressValueError, IndexError):
raise ValidationError(f"Invalid IP range {ip_range}")
def validate_ip(ip: str):
if not re.match(re.compile("".join(["^", ip_regex, "$"])), ip):
raise ValidationError(f"Invalid ip address {ip}")
try:
IPv4Address(ip)
except AddressValueError:
raise ValidationError(f"Invalid IP address {ip}")