From 8a203c0155278053c34139d2feb3f8508ce45f4d Mon Sep 17 00:00:00 2001 From: Nicholas Staples Date: Fri, 18 Mar 2016 12:05:50 +0000 Subject: [PATCH] Valid email domains added and tests passing. --- app/main/forms.py | 8 ++--- app/main/validators.py | 16 +++++++++ app/templates/components/textbox.html | 5 +-- app/templates/views/email-not-received.html | 2 +- app/templates/views/forgot-password.html | 2 +- app/templates/views/invite-user.html | 2 +- app/templates/views/register.html | 2 +- app/templates/views/user-profile/change.html | 2 +- config.py | 12 +++++++ tests/app/main/test_validators.py | 37 +++++++++++++++++++- tests/app/main/views/test_register.py | 3 +- 11 files changed, 77 insertions(+), 14 deletions(-) diff --git a/app/main/forms.py b/app/main/forms.py index 640e993de..80d651822 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -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): diff --git a/app/main/validators.py b/app/main/validators.py index 3149a7729..b33e9f162 100644 --- a/app/main/validators.py +++ b/app/main/validators.py @@ -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' + ' contact us').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) diff --git a/app/templates/components/textbox.html b/app/templates/components/textbox.html index 78241a630..f4c0f368f 100644 --- a/app/templates/components/textbox.html +++ b/app/templates/components/textbox.html @@ -7,7 +7,8 @@ help_link_text=None, width='2-3', suffix=None, - disabled=False + disabled=False, + safe_error_message=False ) %}
diff --git a/app/templates/views/email-not-received.html b/app/templates/views/email-not-received.html index 5b98d330a..cefacf3ab 100644 --- a/app/templates/views/email-not-received.html +++ b/app/templates/views/email-not-received.html @@ -15,7 +15,7 @@

Check your email address is correct and then resend the confirmation code.

- {{ textbox(form.email_address, hint='Your email address must end in .gov.uk') }} + {{ textbox(form.email_address, hint='You must use an email address from a central government organisation', safe_error_message=True) }} {{ page_footer('Resend confirmation code') }}
diff --git a/app/templates/views/forgot-password.html b/app/templates/views/forgot-password.html index 0a42f905f..b8e97ebb9 100644 --- a/app/templates/views/forgot-password.html +++ b/app/templates/views/forgot-password.html @@ -15,7 +15,7 @@ Create a new password – GOV.UK Notify

If you have forgotten your password, we can send you an email to create a new password.

- {{ textbox(form.email_address) }} + {{ textbox(form.email_address, safe_error_message=True) }} {{ page_footer("Send email") }}
diff --git a/app/templates/views/invite-user.html b/app/templates/views/invite-user.html index b50b9d663..37961b8fa 100644 --- a/app/templates/views/invite-user.html +++ b/app/templates/views/invite-user.html @@ -16,7 +16,7 @@ Manage users – GOV.UK Notify
- {{ 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) }}
diff --git a/app/templates/views/register.html b/app/templates/views/register.html index bceb246ac..e8bdf7786 100644 --- a/app/templates/views/register.html +++ b/app/templates/views/register.html @@ -16,7 +16,7 @@ Create an account – GOV.UK Notify {{ 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") }} diff --git a/app/templates/views/user-profile/change.html b/app/templates/views/user-profile/change.html index 65b44ef8b..f0e55c288 100644 --- a/app/templates/views/user-profile/change.html +++ b/app/templates/views/user-profile/change.html @@ -18,7 +18,7 @@ GOV.UK Notify | Service settings {% endif %}
- {{ textbox(form_field) }} + {{ textbox(form_field, safe_error_message=True) }} {{ page_footer( 'Save', back_link=url_for('.user_profile'), diff --git a/config.py b/config.py index 8c93a5b9e..6e4c4950b 100644 --- a/config.py +++ b/config.py @@ -49,6 +49,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 diff --git a/tests/app/main/test_validators.py b/tests/app/main/test_validators.py index 219a04844..1e637a932 100644 --- a/tests/app/main/test_validators.py +++ b/tests/app/main/test_validators.py @@ -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() diff --git a/tests/app/main/views/test_register.py b/tests/app/main/views/test_register.py index 9849da99f..58479198f 100644 --- a/tests/app/main/views/test_register.py +++ b/tests/app/main/views/test_register.py @@ -71,7 +71,8 @@ def test_should_return_400_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_verify_codes_on_session(app_,