From 309396c906193cffa4cd5577f2a31bc73badd9ab Mon Sep 17 00:00:00 2001
From: Katie Smith
Date: Thu, 21 Dec 2017 16:42:16 +0000
Subject: [PATCH 1/5] Make email addresses case insensitive when inviting users
to services
Email addresses in invites should be case insensitive. This is to stop
the bug where a user creates their account using a lower case email
address (e.g. user1@gov.uk), but is then invited to a service using
their email address in a different case (e.g. USER1.gov.uk) and sees
an error message telling them that they can't accept an invite for a
different email address.
---
app/main/views/invites.py | 2 +-
app/main/views/sign_in.py | 2 +-
tests/app/main/views/test_accept_invite.py | 23 ++++++++++++++++++
tests/app/main/views/test_sign_in.py | 27 ++++++++++++++++++++++
4 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/app/main/views/invites.py b/app/main/views/invites.py
index 43e994e06..2da96a154 100644
--- a/app/main/views/invites.py
+++ b/app/main/views/invites.py
@@ -38,7 +38,7 @@ def accept_invite(token):
invited_user = invite_api_client.check_token(token)
- if not current_user.is_anonymous and current_user.email_address != invited_user.email_address:
+ if not current_user.is_anonymous and current_user.email_address.lower() != invited_user.email_address.lower():
message = Markup("""
You’re signed in as {}.
This invite is for another email address.
diff --git a/app/main/views/sign_in.py b/app/main/views/sign_in.py
index eb77ad7a7..20033afa0 100644
--- a/app/main/views/sign_in.py
+++ b/app/main/views/sign_in.py
@@ -40,7 +40,7 @@ def sign_in():
if user and session.get('invited_user'):
invited_user = session.get('invited_user')
- if user.email_address != invited_user['email_address']:
+ if user.email_address.lower() != invited_user['email_address'].lower():
flash("You can't accept an invite for another person.")
session.pop('invited_user', None)
abort(403)
diff --git a/tests/app/main/views/test_accept_invite.py b/tests/app/main/views/test_accept_invite.py
index ae94139c8..0ff67f30b 100644
--- a/tests/app/main/views/test_accept_invite.py
+++ b/tests/app/main/views/test_accept_invite.py
@@ -315,6 +315,29 @@ def test_signed_in_existing_user_cannot_use_anothers_invite(
assert mock_accept_invite.call_count == 0
+def test_accept_invite_does_not_treat_email_addresses_as_case_sensitive(
+ logged_in_client,
+ mocker,
+ api_user_active,
+ sample_invite,
+ service_one,
+ mock_accept_invite,
+ mock_get_user_by_email
+):
+ mocker.patch('app.main.views.invites.check_token')
+
+ # the email address of api_user_active is 'test@user.gov.uk'
+ sample_invite['email_address'] = 'TEST@user.gov.uk'
+ invite = InvitedUser(**sample_invite)
+ mocker.patch('app.invite_api_client.check_token', return_value=invite)
+ mocker.patch('app.user_api_client.get_users_for_service', return_value=[api_user_active])
+
+ response = logged_in_client.get(url_for('main.accept_invite', token='thisisnotarealtoken'))
+
+ assert response.status_code == 302
+ assert response.location == url_for('main.service_dashboard', service_id=service_one['id'], _external=True)
+
+
def test_new_invited_user_verifies_and_added_to_service(
client,
service_one,
diff --git a/tests/app/main/views/test_sign_in.py b/tests/app/main/views/test_sign_in.py
index 6f44c8d4a..563d29751 100644
--- a/tests/app/main/views/test_sign_in.py
+++ b/tests/app/main/views/test_sign_in.py
@@ -170,3 +170,30 @@ def test_should_attempt_redirect_when_user_is_pending(
'password': 'val1dPassw0rd!'})
assert response.location == url_for('main.resend_email_verification', _external=True)
assert response.status_code == 302
+
+
+def test_email_address_is_treated_case_insensitively_when_signing_in_as_invited_user(
+ client,
+ mocker,
+ mock_verify_password,
+ api_user_active,
+ sample_invite,
+ mock_accept_invite,
+ mock_send_verify_code
+):
+ sample_invite['email_address'] = 'TEST@user.gov.uk'
+
+ mocker.patch('app.user_api_client.get_user_by_email_or_none', return_value=api_user_active)
+ mocker.patch('app.main.views.sign_in._get_and_verify_user', return_value=api_user_active)
+
+ with client.session_transaction() as session:
+ session['invited_user'] = sample_invite
+
+ response = client.post(
+ url_for('main.sign_in'), data={
+ 'email_address': 'test@user.gov.uk',
+ 'password': 'val1dPassw0rd!'})
+
+ assert mock_accept_invite.called
+ assert response.status_code == 302
+ assert mock_send_verify_code.called
From bb460bd300d516367b49515f3e518d011737d77a Mon Sep 17 00:00:00 2001
From: Chris Hill-Scott
Date: Tue, 2 Jan 2018 11:23:32 +0000
Subject: [PATCH 2/5] Enable Markdown links in emails
Depends on:
- [ ] https://github.com/alphagov/notifications-utils/pull/293
- [ ] https://github.com/alphagov/notifications-api/pull/1535
---
requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/requirements.txt b/requirements.txt
index bbc4342a4..80dff8cdd 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -20,4 +20,4 @@ notifications-python-client==4.7.1
awscli==1.14.16
awscli-cwlogs>=1.4,<1.5
-git+https://github.com/alphagov/notifications-utils.git@23.3.5#egg=notifications-utils==23.3.5
+git+https://github.com/alphagov/notifications-utils.git@23.4.0#egg=notifications-utils==23.4.0
From 85b3978061fce718f260f8231392fd4bee14ea64 Mon Sep 17 00:00:00 2001
From: Chris Hill-Scott
Date: Tue, 2 Jan 2018 14:06:39 +0000
Subject: [PATCH 3/5] Force example CSV to download, not open in browser
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We wouldn’t wan’t anyone just seeing the raw CSV data in their browser – it isn’t clear what a user would do with it at that point. And we wouldn’t want it navigating them away from the send page, because this might cause them to lose their place.
This commit forces the file to download using the HTML5 `download` attribute:
> This attribute instructs browsers to download a URL instead of navigating to it, so the user will be prompted to save it as a local file.
– https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-download
---
app/templates/views/send.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/templates/views/send.html b/app/templates/views/send.html
index 0049292f6..3215b4601 100644
--- a/app/templates/views/send.html
+++ b/app/templates/views/send.html
@@ -40,7 +40,7 @@
{% endcall %}
diff --git a/app/templates/views/check/ok.html b/app/templates/views/check/ok.html
index 792f016d1..85f79b97b 100644
--- a/app/templates/views/check/ok.html
+++ b/app/templates/views/check/ok.html
@@ -39,7 +39,7 @@
{% if template.template_type != 'letter' or not request.args.from_test %}
{% else %}
- Download as a printable PDF
+ Download as a printable PDF
{% endif %}
Back
diff --git a/app/templates/views/dashboard/_inbox_messages.html b/app/templates/views/dashboard/_inbox_messages.html
index b46b16a8c..bba1e741d 100644
--- a/app/templates/views/dashboard/_inbox_messages.html
+++ b/app/templates/views/dashboard/_inbox_messages.html
@@ -4,7 +4,7 @@