Merge pull request #304 from alphagov/add_valid_email_regexes

Add valid email regexes
This commit is contained in:
NIcholas Staples
2016-03-21 09:54:33 +00:00
10 changed files with 76 additions and 13 deletions

View File

@@ -12,9 +12,9 @@ from wtforms import (
HiddenField
)
from wtforms.fields.html5 import EmailField, TelField
from wtforms.validators import DataRequired, Email, Length, Regexp
from wtforms.validators import (DataRequired, Email, Length, Regexp)
from app.main.validators import Blacklist, CsvFileValidator
from app.main.validators import (Blacklist, CsvFileValidator, ValidEmailDomainRegex)
from utils.recipients import (
validate_phone_number,
@@ -24,13 +24,11 @@ from utils.recipients import (
def email_address(label='Email address'):
gov_uk_email \
= "(^[^@^\\s]+@[^@^\\.^\\s]+(\\.[^@^\\.^\\s]*)*.gov.uk)"
return EmailField(label, validators=[
Length(min=5, max=255),
DataRequired(message='Email cannot be empty'),
Email(message='Enter a valid email address'),
Regexp(regex=gov_uk_email, message='Enter a gov.uk email address')])
ValidEmailDomainRegex()])
class UKMobileNumber(TelField):

View File

@@ -1,3 +1,4 @@
import re
from wtforms import ValidationError
from datetime import datetime
from app.main.encryption import check_hash
@@ -22,3 +23,18 @@ class CsvFileValidator(object):
def __call__(self, form, field):
if not form.file.data.mimetype == 'text/csv':
raise ValidationError(self.message)
class ValidEmailDomainRegex(object):
def __call__(self, form, field):
from flask import (current_app, url_for)
message = (
'Enter a central government email address.'
' If you think you should have access'
' <a href="{}">contact us</a>').format(
"https://docs.google.com/forms/d/1AL8U-xJX_HAFEiQiJszGQw0PcEaEUnYATSntEghNDGo/viewform")
valid_domains = current_app.config.get('EMAIL_DOMAIN_REGEXES', [])
email_regex = "(^[^@^\\s]+@[^@^\\.^\\s]+(\\.[^@^\\.^\\s]*)*.({}))".format("|".join(valid_domains))
if not re.match(email_regex, field.data):
raise ValidationError(message)

View File

@@ -7,7 +7,8 @@
help_link_text=None,
width='2-3',
suffix=None,
disabled=False
disabled=False,
safe_error_message=False
) %}
<div class="form-group{% if field.errors %} error{% endif %}" {% if autofocus %}data-module="autofocus"{% endif %}>
<label class="form-label" for="{{ field.name }}">
@@ -19,7 +20,7 @@
{% endif %}
{% if field.errors %}
<span class="error-message">
{{ field.errors[0] }}
{% if not safe_error_message %}{{ field.errors[0] }}{% else %}{{ field.errors[0]|safe }}{% endif %}
</span>
{% endif %}
</label>

View File

@@ -15,7 +15,7 @@ Create a new password GOV.UK Notify
<p>If you have forgotten your password, we can send you an email to create a new password.</p>
<form autocomplete="off" method="post">
{{ textbox(form.email_address) }}
{{ textbox(form.email_address, safe_error_message=True) }}
{{ page_footer("Send email") }}
</form>

View File

@@ -16,7 +16,7 @@ Manage users GOV.UK Notify
<div class="grid-row">
<form method="post" class="column-three-quarters">
{{ textbox(form.email_address, hint='Email address must end in .gov.uk', width='1-1') }}
{{ textbox(form.email_address, hint='You must use an email address from a central government organisation', width='1-1', safe_error_message=True) }}
<fieldset class='yes-no-wrapper'>
<legend class='heading-small'>

View File

@@ -16,7 +16,7 @@ Create an account GOV.UK Notify
<form method="post" autocomplete="nope">
{{ textbox(form.name, width='3-4') }}
{{ textbox(form.email_address, hint="Your email address must end in .gov.uk", width='3-4') }}
{{ textbox(form.email_address, hint="You must use an email address from a central government organisation", width='3-4', safe_error_message=True) }}
{{ textbox(form.mobile_number, width='3-4') }}
{{ textbox(form.password, hint="Your password must have at least 10 characters", width='3-4') }}
{{ page_footer("Continue") }}

View File

@@ -18,7 +18,7 @@ GOV.UK Notify | Service settings
{% endif %}
<div class="column-three-quarters">
<form method="post">
{{ textbox(form_field) }}
{{ textbox(form_field, safe_error_message=True) }}
{{ page_footer(
'Save',
back_link=url_for('.user_profile'),

View File

@@ -50,6 +50,18 @@ class Config(object):
SHOW_STYLEGUIDE = True
EMAIL_DOMAIN_REGEXES = [
"gov.uk",
"mod.uk",
"mil.uk",
"ddc-mod.org",
"slc.co.uk"
"gov.scot",
"parliament.uk",
"nhs.uk",
"nhs.net",
"police.uk"]
class Development(Config):
DEBUG = True

View File

@@ -6,8 +6,43 @@ def test_should_raise_validation_error_for_password(app_, mock_get_user_by_email
form = RegisterUserForm()
form.name.data = 'test'
form.email_address.data = 'teset@example.gov.uk'
form.mobile_number.data = '+441231231231'
form.mobile_number.data = '441231231231'
form.password.data = 'password1234'
form.validate()
assert 'That password is blacklisted, too common' in form.errors['password']
def test_valid_email_not_in_valid_domains(app_):
with app_.test_request_context():
form = RegisterUserForm(email_address="test@test.com", mobile_number='441231231231')
assert not form.validate()
assert "Enter a central government email address" in form.errors['email_address'][0]
def test_valid_email_in_valid_domains(app_):
with app_.test_request_context():
form = RegisterUserForm(
name="test",
email_address="test@my.gov.uk",
mobile_number='4407888999111',
password='1234567890')
form.validate()
assert form.errors == {}
def test_invalid_email_address_error_message(app_):
with app_.test_request_context():
form = RegisterUserForm(
name="test",
email_address="test.com",
mobile_number='4407888999111',
password='1234567890')
assert not form.validate()
form = RegisterUserForm(
name="test",
email_address="test.com",
mobile_number='4407888999111',
password='1234567890')
assert not form.validate()

View File

@@ -82,7 +82,8 @@ def test_should_return_200_when_email_is_not_gov_uk(app_,
'password': 'validPassword!'})
assert response.status_code == 200
assert 'Enter a gov.uk email address' in response.get_data(as_text=True)
print(response.get_data(as_text=True))
assert 'Enter a central government email address' in response.get_data(as_text=True)
def test_should_add_user_details_to_session(app_,