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