mirror of https://github.com/django/django.git
Fixed #4833 -- Validate email addresses with localhost as domain
This commit is contained in:
parent
1bbd36a36a
commit
4e2e8f39d1
|
@ -78,30 +78,53 @@ def validate_integer(value):
|
||||||
raise ValidationError('')
|
raise ValidationError('')
|
||||||
|
|
||||||
|
|
||||||
class EmailValidator(RegexValidator):
|
class EmailValidator(object):
|
||||||
|
message = _('Enter a valid e-mail address.')
|
||||||
|
code = 'invalid'
|
||||||
|
user_regex = re.compile(
|
||||||
|
r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*$" # dot-atom
|
||||||
|
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"$)', # quoted-string
|
||||||
|
re.IGNORECASE)
|
||||||
|
domain_regex = re.compile(
|
||||||
|
r'(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?$)' # domain
|
||||||
|
# literal form, ipv4 address (SMTP 4.1.3)
|
||||||
|
r'|^\[(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\]$',
|
||||||
|
re.IGNORECASE)
|
||||||
|
domain_whitelist = ['localhost']
|
||||||
|
|
||||||
|
def __init__(self, message=None, code=None, whitelist=None):
|
||||||
|
if message is not None:
|
||||||
|
self.message = message
|
||||||
|
if code is not None:
|
||||||
|
self.code = code
|
||||||
|
if whitelist is not None:
|
||||||
|
self.domain_whitelist = whitelist
|
||||||
|
|
||||||
def __call__(self, value):
|
def __call__(self, value):
|
||||||
try:
|
value = force_text(value)
|
||||||
super(EmailValidator, self).__call__(value)
|
|
||||||
except ValidationError as e:
|
|
||||||
# Trivial case failed. Try for possible IDN domain-part
|
|
||||||
if value and '@' in value:
|
|
||||||
parts = value.split('@')
|
|
||||||
try:
|
|
||||||
parts[-1] = parts[-1].encode('idna').decode('ascii')
|
|
||||||
except UnicodeError:
|
|
||||||
raise e
|
|
||||||
super(EmailValidator, self).__call__('@'.join(parts))
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
|
|
||||||
email_re = re.compile(
|
if not value or '@' not in value:
|
||||||
r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" # dot-atom
|
raise ValidationError(self.message, code=self.code)
|
||||||
# quoted-string, see also http://tools.ietf.org/html/rfc2822#section-3.2.5
|
|
||||||
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"'
|
user_part, domain_part = value.split('@', 1)
|
||||||
r')@((?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)$)' # domain
|
|
||||||
r'|\[(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\]$', re.IGNORECASE) # literal form, ipv4 address (SMTP 4.1.3)
|
if not self.user_regex.match(user_part):
|
||||||
validate_email = EmailValidator(email_re, _('Enter a valid email address.'), 'invalid')
|
raise ValidationError(self.message, code=self.code)
|
||||||
|
|
||||||
|
if (not domain_part in self.domain_whitelist and
|
||||||
|
not self.domain_regex.match(domain_part)):
|
||||||
|
# Try for possible IDN domain-part
|
||||||
|
try:
|
||||||
|
domain_part = domain_part.encode('idna').decode('ascii')
|
||||||
|
if not self.domain_regex.match(domain_part):
|
||||||
|
raise ValidationError(self.message, code=self.code)
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
except UnicodeError:
|
||||||
|
pass
|
||||||
|
raise ValidationError(self.message, code=self.code)
|
||||||
|
|
||||||
|
validate_email = EmailValidator()
|
||||||
|
|
||||||
slug_re = re.compile(r'^[-a-zA-Z0-9_]+$')
|
slug_re = re.compile(r'^[-a-zA-Z0-9_]+$')
|
||||||
validate_slug = RegexValidator(slug_re, _("Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."), 'invalid')
|
validate_slug = RegexValidator(slug_re, _("Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."), 'invalid')
|
||||||
|
|
|
@ -96,7 +96,7 @@ to, or in lieu of custom ``field.clean()`` methods.
|
||||||
------------------
|
------------------
|
||||||
.. data:: validate_email
|
.. data:: validate_email
|
||||||
|
|
||||||
A :class:`RegexValidator` instance that ensures a value looks like an
|
An ``EmailValidator`` instance that ensures a value looks like an
|
||||||
email address.
|
email address.
|
||||||
|
|
||||||
``validate_slug``
|
``validate_slug``
|
||||||
|
|
|
@ -29,6 +29,8 @@ TEST_DATA = (
|
||||||
(validate_email, 'example@valid-----hyphens.com', None),
|
(validate_email, 'example@valid-----hyphens.com', None),
|
||||||
(validate_email, 'example@valid-with-hyphens.com', None),
|
(validate_email, 'example@valid-with-hyphens.com', None),
|
||||||
(validate_email, 'test@domain.with.idn.tld.उदाहरण.परीक्षा', None),
|
(validate_email, 'test@domain.with.idn.tld.उदाहरण.परीक्षा', None),
|
||||||
|
(validate_email, 'email@localhost', None),
|
||||||
|
(EmailValidator(whitelist=['localdomain']), 'email@localdomain', None),
|
||||||
|
|
||||||
(validate_email, None, ValidationError),
|
(validate_email, None, ValidationError),
|
||||||
(validate_email, '', ValidationError),
|
(validate_email, '', ValidationError),
|
||||||
|
|
Loading…
Reference in New Issue