Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions tests/test_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,32 @@ def test_returns_true_on_valid_email(value, whitelist):
])
def test_returns_failed_validation_on_invalid_email(value):
assert isinstance(email(value), ValidationFailure)


@pytest.mark.parametrize(('value', 'whitelist'), [
('[email protected]', ['foo.here.com']),
('[email protected]', ['here.and.there.org']),
('email@[127.0.0.1]', ['[127.0.0.2]']),
('[email protected]', ['-----hyphens.com']),
('[email protected]', ['hyphens.com']),
('email@localhost', ['localdomain']),
('"test@test"@example.com', ['example.org', 'example.net', 'foo.org']),
('"\\\011"@here.com', ['there.com']),
])
def test_returns_failed_validation_on_bad_whitelist(value, whitelist):
assert isinstance(email(value, whitelist=whitelist, only_whitelist=True),
ValidationFailure)


@pytest.mark.parametrize(('value', 'whitelist'), [
('[email protected]', ['here.com']),
('[email protected]', ['here.and.there.com']),
('email@[127.0.0.1]', ['[127.0.0.1]']),
('[email protected]', ['valid-----hyphens.com']),
('[email protected]', ['valid-with-hyphens.com']),
('email@localhost', ['localdomain', 'localhost']),
('"test@test"@example.com', ['example.org', 'example.com', 'foo.org']),
('"\\\011"@here.com', ['here.com', 'test.org', 'zeta', 100]),
])
def test_returns_true_on_valid_email_and_only_whitelist(value, whitelist):
assert email(value, whitelist=whitelist, only_whitelist=True)
17 changes: 12 additions & 5 deletions validators/email.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@


@validator
def email(value, whitelist=None):
def email(value, whitelist=None, only_whitelist=False):
"""
Validate an email address.

Expand All @@ -46,27 +46,34 @@ def email(value, whitelist=None):

:param value: value to validate
:param whitelist: domain names to whitelist
:param only_whitelist: specify whether to fail non whitelisted domains

:copyright: (c) Django Software Foundation and individual contributors.
:license: BSD
"""
if not value or '@' not in value:
return False

if whitelist is None:
whitelist = domain_whitelist

if not value or '@' not in value:
return False

user_part, domain_part = value.rsplit('@', 1)

if not user_regex.match(user_part):
return False

if domain_part not in whitelist and not domain_regex.match(domain_part):
# skip domain regex check if user specified it explicitly in whitelist
if only_whitelist:
return domain_part in whitelist

# check if domain is good
if not (domain_regex.match(domain_part) or domain_part in whitelist):
# Try for possible IDN domain-part
try:
domain_part = domain_part.encode('idna').decode('ascii')
return domain_regex.match(domain_part)
except UnicodeError:
return False

# No whitelist and email passes user_regex and domain passes domain_regex.
return True