commit dc6946e930bc2cf459246d1dbaa5ec53ee7415fe
Author: Claude Paroz <claude@2xlibre.net>
Date: Sat Jul 9 22:53:42 2011 +0200
Validate email addresses with localhost as domain
diff --git a/django/core/validators.py b/django/core/validators.py
index de415d6..a7a1297 100644
a
|
b
|
def validate_integer(value):
|
140 | 140 | except (ValueError, TypeError): |
141 | 141 | raise ValidationError('') |
142 | 142 | |
143 | | class EmailValidator(RegexValidator): |
| 143 | class EmailValidator(object): |
| 144 | message = _(u'Enter a valid e-mail address.') |
| 145 | code = 'invalid' |
| 146 | user_regex = re.compile( |
| 147 | r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*$" # dot-atom |
| 148 | r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"$)', # quoted-string |
| 149 | re.IGNORECASE) |
| 150 | domain_regex = re.compile( |
| 151 | r'(^(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$)' # domain |
| 152 | # literal form, ipv4 address (SMTP 4.1.3) |
| 153 | r'|^\[(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\]$', |
| 154 | re.IGNORECASE) |
| 155 | domain_whitelist = ['localhost'] |
| 156 | |
| 157 | def __init__(self, message=None, code=None): |
| 158 | if message is not None: |
| 159 | self.message = message |
| 160 | if code is not None: |
| 161 | self.code = code |
144 | 162 | |
145 | 163 | def __call__(self, value): |
146 | | try: |
147 | | super(EmailValidator, self).__call__(value) |
148 | | except ValidationError, e: |
149 | | # Trivial case failed. Try for possible IDN domain-part |
150 | | if value and u'@' in value: |
151 | | parts = value.split(u'@') |
| 164 | if value and u'@' in value: |
| 165 | user_part, domain_part = value.split(u'@', 1) |
| 166 | res = self.user_regex.search(smart_unicode(user_part)) |
| 167 | if not self.user_regex.search(smart_unicode(user_part)): |
| 168 | raise ValidationError(self.message, code=self.code) |
| 169 | if (not smart_unicode(domain_part) in self.domain_whitelist and |
| 170 | not self.domain_regex.search(smart_unicode(domain_part))): |
| 171 | # Try for possible IDN domain-part |
152 | 172 | try: |
153 | | parts[-1] = parts[-1].encode('idna') |
| 173 | domain_part = domain_part.encode('idna') |
| 174 | if not self.domain_regex.search(smart_unicode(domain_part)): |
| 175 | raise ValidationError(self.message, code=self.code) |
| 176 | else: |
| 177 | return |
154 | 178 | except UnicodeError: |
155 | | raise e |
156 | | super(EmailValidator, self).__call__(u'@'.join(parts)) |
157 | | else: |
158 | | raise |
| 179 | pass |
| 180 | raise ValidationError(self.message, code=self.code) |
| 181 | else: |
| 182 | raise ValidationError(self.message, code=self.code) |
159 | 183 | |
160 | | email_re = re.compile( |
161 | | r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" # dot-atom |
162 | | r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string |
163 | | r')@((?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$)' # domain |
164 | | 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) |
165 | | validate_email = EmailValidator(email_re, _(u'Enter a valid e-mail address.'), 'invalid') |
| 184 | validate_email = EmailValidator() |
166 | 185 | |
167 | 186 | slug_re = re.compile(r'^[-\w]+$') |
168 | 187 | validate_slug = RegexValidator(slug_re, _(u"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."), 'invalid') |
diff --git a/tests/modeltests/validators/tests.py b/tests/modeltests/validators/tests.py
index 9e254b9..ed8bdfb 100644
a
|
b
|
TEST_DATA = (
|
23 | 23 | (validate_email, 'email@here.com', None), |
24 | 24 | (validate_email, 'weirder-email@here.and.there.com', None), |
25 | 25 | (validate_email, 'email@[127.0.0.1]', None), |
| 26 | (validate_email, 'email@localhost', None), |
26 | 27 | |
27 | 28 | (validate_email, None, ValidationError), |
28 | 29 | (validate_email, '', ValidationError), |