validators.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. import re
  2. from django.core.exceptions import ValidationError
  3. from django.core.validators import _lazy_re_compile, BaseValidator, URLValidator
  4. from netbox.config import Config
  5. class EnhancedURLValidator(URLValidator):
  6. """
  7. Extends Django's built-in URLValidator to permit the use of hostnames with no domain extension and enforce allowed
  8. schemes specified in the configuration.
  9. """
  10. fqdn_re = URLValidator.hostname_re + URLValidator.domain_re + URLValidator.tld_re
  11. host_res = [URLValidator.ipv4_re, URLValidator.ipv6_re, fqdn_re, URLValidator.hostname_re]
  12. regex = _lazy_re_compile(
  13. r'^(?:[a-z0-9\.\-\+]*)://' # Scheme (enforced separately)
  14. r'(?:\S+(?::\S*)?@)?' # HTTP basic authentication
  15. r'(?:' + '|'.join(host_res) + ')' # IPv4, IPv6, FQDN, or hostname
  16. r'(?::\d{2,5})?' # Port number
  17. r'(?:[/?#][^\s]*)?' # Path
  18. r'\Z', re.IGNORECASE)
  19. def __init__(self, schemes=None, **kwargs):
  20. super().__init__(**kwargs)
  21. if schemes is not None:
  22. self.schemes = Config().ALLOWED_URL_SCHEMES
  23. class ExclusionValidator(BaseValidator):
  24. """
  25. Ensure that a field's value is not equal to any of the specified values.
  26. """
  27. message = 'This value may not be %(show_value)s.'
  28. def compare(self, a, b):
  29. return a in b
  30. def validate_regex(value):
  31. """
  32. Checks that the value is a valid regular expression. (Don't confuse this with RegexValidator, which *uses* a regex
  33. to validate a value.)
  34. """
  35. try:
  36. re.compile(value)
  37. except re.error:
  38. raise ValidationError(f"{value} is not a valid regular expression.")