From 834b0fc3d55322b156d1631fe1c14881e19b39ba Mon Sep 17 00:00:00 2001
From: Chris Hill-Scott
Date: Mon, 10 Aug 2020 15:56:48 +0100
Subject: [PATCH 1/3] Put hidden email field on register from invite page
Password managers will try to guess what they should save as a username
by looking at the fields on the page where you set up your password.
When registering from an invite the email address (what we use as a
username) is predefined, and only shown on the page as text, not an
input.
This commit also adds a hidden input field for password managers to pick
up.
Adapted from: https://github.com/UKGovernmentBEIS/beis-opss-psd/blob/master/app/views/users/complete_registration.html.erb#L29-L36
---
app/templates/views/register-from-invite.html | 3 +
tests/app/main/views/test_register.py | 62 ++++++++++++++++---
2 files changed, 56 insertions(+), 9 deletions(-)
diff --git a/app/templates/views/register-from-invite.html b/app/templates/views/register-from-invite.html
index 65afb6edd..b02e3bf9e 100644
--- a/app/templates/views/register-from-invite.html
+++ b/app/templates/views/register-from-invite.html
@@ -17,6 +17,9 @@ Create an account
{{invited_user.email_address}}
{% call form_wrapper() %}
+
+
+
{{ textbox(form.name, width='3-4') }}
{% if invited_user.auth_type == 'sms_auth' %}
diff --git a/tests/app/main/views/test_register.py b/tests/app/main/views/test_register.py
index 7131d956b..c16ce346a 100644
--- a/tests/app/main/views/test_register.py
+++ b/tests/app/main/views/test_register.py
@@ -203,7 +203,7 @@ def test_register_with_existing_email_sends_emails(
("f.last@example.com", ""),
("f.m.last@example.com", ""),
])
-def test_shows_registration_page_from_invite(
+def test_shows_name_on_registration_page_from_invite(
client_request,
fake_uuid,
email_address,
@@ -226,6 +226,48 @@ def test_shows_registration_page_from_invite(
assert page.select_one('input[name=name]')['value'] == expected_value
+def test_shows_email_address_on_registration_page_from_invite(
+ client_request,
+ fake_uuid,
+):
+ with client_request.session_transaction() as session:
+ session['invited_user'] = {
+ 'id': fake_uuid,
+ 'service': fake_uuid,
+ 'from_user': "",
+ 'email_address': "test@example.com",
+ 'permissions': ["manage_users"],
+ 'status': "pending",
+ 'created_at': datetime.utcnow(),
+ 'auth_type': 'sms_auth',
+ 'folder_permissions': [],
+ }
+
+ page = client_request.get('main.register_from_invite')
+ assert normalize_spaces(page.select_one('main p').text) == (
+ 'Your account will be created with this email address: test@example.com'
+ )
+ hidden_input = page.select_one('form .visually-hidden input')
+ for attr, value in (
+ ('type', 'email'),
+ ('name', 'username'),
+ ('id', 'username'),
+ ('value', 'test@example.com'),
+ ('disabled', "disabled"),
+ ('tabindex', '-1'),
+ ('aria-hidden', 'true'),
+ ('autocomplete', 'username'),
+ ):
+ assert hidden_input[attr] == value
+
+
+@pytest.mark.parametrize('extra_data', (
+ {},
+ # The username field is present in the page but the POST request
+ # should ignore it
+ {'username': 'invited@user.com'},
+ {'username': 'anythingelse@example.com'},
+))
def test_register_from_invite(
client,
fake_uuid,
@@ -233,6 +275,7 @@ def test_register_from_invite(
mock_register_user,
mock_send_verify_code,
mock_accept_invite,
+ extra_data,
):
invited_user = InvitedUser(
{
@@ -251,14 +294,15 @@ def test_register_from_invite(
session['invited_user'] = invited_user.serialize()
response = client.post(
url_for('main.register_from_invite'),
- data={
- 'name': 'Registered in another Browser',
- 'email_address': invited_user.email_address,
- 'mobile_number': '+4407700900460',
- 'service': str(invited_user.id),
- 'password': 'somreallyhardthingtoguess',
- 'auth_type': 'sms_auth'
- }
+ data=dict(
+ name='Registered in another Browser',
+ email_address=invited_user.email_address,
+ mobile_number='+4407700900460',
+ service=str(invited_user.id),
+ password='somreallyhardthingtoguess',
+ auth_type='sms_auth',
+ **extra_data
+ ),
)
assert response.status_code == 302
assert response.location == url_for('main.verify', _external=True)
From b0fc1cd27175b15f2ba6f9efcf8c73ad8cd27e2c Mon Sep 17 00:00:00 2001
From: Chris Hill-Scott
Date: Tue, 11 Aug 2020 11:22:59 +0100
Subject: [PATCH 2/3] Make test name more explicit
---
tests/app/main/views/test_register.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/app/main/views/test_register.py b/tests/app/main/views/test_register.py
index c16ce346a..55eaad18b 100644
--- a/tests/app/main/views/test_register.py
+++ b/tests/app/main/views/test_register.py
@@ -226,7 +226,7 @@ def test_shows_name_on_registration_page_from_invite(
assert page.select_one('input[name=name]')['value'] == expected_value
-def test_shows_email_address_on_registration_page_from_invite(
+def test_shows_hidden_email_address_on_registration_page_from_invite(
client_request,
fake_uuid,
):
From cf999b5d8e843ee1ba205934803ca8e736660e12 Mon Sep 17 00:00:00 2001
From: Chris Hill-Scott
Date: Tue, 11 Aug 2020 11:26:31 +0100
Subject: [PATCH 3/3] Add inline comment explaining presence of field
---
app/templates/views/register-from-invite.html | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/app/templates/views/register-from-invite.html b/app/templates/views/register-from-invite.html
index b02e3bf9e..ae88fdd6d 100644
--- a/app/templates/views/register-from-invite.html
+++ b/app/templates/views/register-from-invite.html
@@ -17,6 +17,11 @@ Create an account
{{invited_user.email_address}}
{% call form_wrapper() %}
+ {#
+ This field is to enable password managers to capture the username as
+ well as the password, but should not be visible to users, nor should
+ the view process the input.
+ #}