2016-01-27 12:22:32 +00:00
|
|
|
|
import json
|
2018-02-20 11:22:17 +00:00
|
|
|
|
import uuid
|
2017-02-24 16:21:41 +00:00
|
|
|
|
|
2018-02-20 11:22:17 +00:00
|
|
|
|
import pytest
|
2016-01-27 12:22:32 +00:00
|
|
|
|
from flask import url_for
|
2021-05-18 14:50:25 +01:00
|
|
|
|
from notifications_python_client.errors import HTTPError
|
2016-10-13 17:05:37 +01:00
|
|
|
|
from notifications_utils.url_safe_token import generate_token
|
2018-04-25 14:12:58 +01:00
|
|
|
|
|
2021-06-08 09:41:39 +01:00
|
|
|
|
from app.models.webauthn_credential import (
|
|
|
|
|
|
WebAuthnCredential,
|
|
|
|
|
|
WebAuthnCredentials,
|
|
|
|
|
|
)
|
2021-05-14 18:42:57 +01:00
|
|
|
|
from tests.conftest import (
|
|
|
|
|
|
create_api_user_active,
|
2022-03-23 12:40:43 +00:00
|
|
|
|
create_user,
|
2021-05-14 18:42:57 +01:00
|
|
|
|
normalize_spaces,
|
|
|
|
|
|
url_for_endpoint_with_token,
|
|
|
|
|
|
)
|
2017-02-24 16:21:41 +00:00
|
|
|
|
|
2016-01-12 10:28:14 +00:00
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_should_show_overview_page(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2021-05-07 15:00:01 +01:00
|
|
|
|
page = client_request.get('main.user_profile')
|
2019-03-26 12:35:32 +00:00
|
|
|
|
assert page.select_one('h1').text.strip() == 'Your profile'
|
2019-06-14 12:32:47 +01:00
|
|
|
|
assert 'Use platform admin view' not in page
|
2021-05-07 15:00:01 +01:00
|
|
|
|
assert 'Security keys' not in page
|
2019-06-13 19:00:17 +01:00
|
|
|
|
|
|
|
|
|
|
|
2019-06-14 12:32:47 +01:00
|
|
|
|
def test_overview_page_shows_disable_for_platform_admin(
|
2019-06-13 19:00:17 +01:00
|
|
|
|
client_request,
|
2021-05-13 15:54:05 +01:00
|
|
|
|
platform_admin_user,
|
|
|
|
|
|
mocker
|
2019-06-13 19:00:17 +01:00
|
|
|
|
):
|
2021-06-08 09:41:39 +01:00
|
|
|
|
mocker.patch('app.models.webauthn_credential.WebAuthnCredentials.client_method')
|
2019-06-13 19:00:17 +01:00
|
|
|
|
client_request.login(platform_admin_user)
|
2021-05-07 15:00:01 +01:00
|
|
|
|
page = client_request.get('main.user_profile')
|
2019-06-13 19:00:17 +01:00
|
|
|
|
assert page.select_one('h1').text.strip() == 'Your profile'
|
2021-05-11 17:53:36 +01:00
|
|
|
|
disable_platform_admin_row = page.select_one('#disable-platform-admin')
|
2021-08-05 15:32:56 +01:00
|
|
|
|
assert ' '.join(disable_platform_admin_row.text.split()) == \
|
|
|
|
|
|
'Use platform admin view Yes Change whether to use platform admin view'
|
2016-01-12 10:28:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
2021-05-27 17:38:24 +01:00
|
|
|
|
@pytest.mark.parametrize('key_count, expected_row_text', [
|
2021-08-05 15:32:56 +01:00
|
|
|
|
(0, 'Security keys None registered Change security keys'),
|
|
|
|
|
|
(1, 'Security keys 1 registered Change security keys'),
|
|
|
|
|
|
(2, 'Security keys 2 registered Change security keys'),
|
2021-05-27 17:38:24 +01:00
|
|
|
|
])
|
2021-06-30 15:30:29 +01:00
|
|
|
|
def test_overview_page_shows_security_keys_if_user_they_can_use_webauthn(
|
2021-05-07 15:00:01 +01:00
|
|
|
|
mocker,
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
platform_admin_user,
|
|
|
|
|
|
webauthn_credential,
|
2021-05-27 17:38:24 +01:00
|
|
|
|
key_count,
|
|
|
|
|
|
expected_row_text,
|
2021-05-07 15:00:01 +01:00
|
|
|
|
):
|
|
|
|
|
|
client_request.login(platform_admin_user)
|
2021-05-27 17:38:24 +01:00
|
|
|
|
credentials = [webauthn_credential for _ in range(key_count)]
|
2021-06-08 09:41:39 +01:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
'app.models.webauthn_credential.WebAuthnCredentials.client_method',
|
|
|
|
|
|
return_value=credentials,
|
|
|
|
|
|
)
|
2021-05-07 15:00:01 +01:00
|
|
|
|
page = client_request.get('main.user_profile')
|
|
|
|
|
|
security_keys_row = page.select_one('#security-keys')
|
2021-05-27 17:38:24 +01:00
|
|
|
|
assert ' '.join(security_keys_row.text.split()) == expected_row_text
|
2021-05-07 15:00:01 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_should_show_name_page(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get(('main.user_profile_name'))
|
|
|
|
|
|
assert page.select_one('h1').text.strip() == 'Change your name'
|
2016-01-12 10:28:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_should_redirect_after_name_change(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mock_update_user_attribute,
|
|
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request.post(
|
|
|
|
|
|
'main.user_profile_name',
|
|
|
|
|
|
_data={'new_name': 'New Name'},
|
|
|
|
|
|
_expected_status=302,
|
2022-05-27 14:46:35 +01:00
|
|
|
|
_expected_redirect=url_for('main.user_profile'),
|
2019-03-26 12:35:32 +00:00
|
|
|
|
)
|
|
|
|
|
|
assert mock_update_user_attribute.called is True
|
2016-01-12 10:28:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_should_show_email_page(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get(
|
|
|
|
|
|
'main.user_profile_email'
|
|
|
|
|
|
)
|
|
|
|
|
|
assert page.select_one('h1').text.strip() == 'Change your email address'
|
2022-03-23 12:40:43 +00:00
|
|
|
|
# template is shared with "Change your mobile number" but we don't want to show Delete mobile number link
|
|
|
|
|
|
assert 'Delete your number' not in page.text
|
2016-01-12 11:25:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_should_redirect_after_email_change(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mock_login,
|
2018-02-19 16:53:29 +00:00
|
|
|
|
mock_email_is_not_already_in_use,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request.post(
|
|
|
|
|
|
'main.user_profile_email',
|
2022-08-05 00:25:03 -07:00
|
|
|
|
_data={'email_address': 'new_notify@notify.gsa.gov'},
|
2019-03-26 12:35:32 +00:00
|
|
|
|
_expected_status=302,
|
|
|
|
|
|
_expected_redirect=url_for(
|
|
|
|
|
|
'main.user_profile_email_authenticate',
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
2016-01-12 11:25:46 +00:00
|
|
|
|
|
2021-12-10 16:56:08 +00:00
|
|
|
|
assert mock_email_is_not_already_in_use.called
|
|
|
|
|
|
|
2016-01-12 11:25:46 +00:00
|
|
|
|
|
2021-12-10 14:59:18 +00:00
|
|
|
|
@pytest.mark.parametrize('email_address,error_message', [
|
|
|
|
|
|
('me@example.com', 'Enter a public sector email address or find out who can use Notify'),
|
|
|
|
|
|
('not_valid', 'Enter a valid email address') # 2 errors with email address, only first error shown
|
|
|
|
|
|
])
|
|
|
|
|
|
def test_should_show_errors_if_new_email_address_does_not_validate(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
mock_email_is_not_already_in_use,
|
|
|
|
|
|
mock_get_organisations,
|
|
|
|
|
|
email_address,
|
|
|
|
|
|
error_message,
|
|
|
|
|
|
):
|
|
|
|
|
|
page = client_request.post(
|
|
|
|
|
|
'main.user_profile_email',
|
|
|
|
|
|
_data={'email_address': email_address},
|
|
|
|
|
|
_expected_status=200,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
assert normalize_spaces(page.find('span', class_='govuk-error-message').text) == f'Error: {error_message}'
|
2021-12-10 16:56:08 +00:00
|
|
|
|
# We only call API to check if the email address is already in use if there are no other errors
|
|
|
|
|
|
assert not mock_email_is_not_already_in_use.called
|
2021-12-10 14:59:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_should_show_authenticate_after_email_change(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
with client_request.session_transaction() as session:
|
2022-08-05 00:25:03 -07:00
|
|
|
|
session['new-email'] = 'new_notify@notify.gsa.gov'
|
2016-01-12 11:25:46 +00:00
|
|
|
|
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get('main.user_profile_email_authenticate')
|
|
|
|
|
|
|
|
|
|
|
|
assert 'Change your email address' in page.text
|
|
|
|
|
|
assert 'Confirm' in page.text
|
2016-01-12 10:28:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_should_render_change_email_continue_after_authenticate_email(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mock_verify_password,
|
|
|
|
|
|
mock_send_change_email_verification,
|
|
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
with client_request.session_transaction() as session:
|
2022-08-05 00:25:03 -07:00
|
|
|
|
session['new-email'] = 'new_notify@notify.gsa.gov'
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.post(
|
|
|
|
|
|
'main.user_profile_email_authenticate',
|
2020-11-30 16:36:38 +00:00
|
|
|
|
_data={'password': '12345'},
|
2019-03-26 12:35:32 +00:00
|
|
|
|
_expected_status=200,
|
|
|
|
|
|
)
|
|
|
|
|
|
assert 'Click the link in the email to confirm the change to your email address.' in page.text
|
2016-10-13 17:05:37 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_should_redirect_to_user_profile_when_user_confirms_email_link(
|
2021-05-12 14:57:21 +01:00
|
|
|
|
notify_admin,
|
2021-12-31 12:08:14 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
api_user_active,
|
|
|
|
|
|
mock_update_user_attribute,
|
|
|
|
|
|
):
|
2016-10-13 17:05:37 +01:00
|
|
|
|
|
2022-08-05 00:25:03 -07:00
|
|
|
|
token = generate_token(payload=json.dumps({'user_id': api_user_active['id'], 'email': 'new_email@gsa.gov'}),
|
2021-05-12 14:57:21 +01:00
|
|
|
|
secret=notify_admin.config['SECRET_KEY'], salt=notify_admin.config['DANGEROUS_SALT'])
|
2021-12-31 12:08:14 +00:00
|
|
|
|
client_request.get_url(
|
|
|
|
|
|
url_for_endpoint_with_token(
|
|
|
|
|
|
'main.user_profile_email_confirm',
|
|
|
|
|
|
token=token,
|
|
|
|
|
|
),
|
2022-05-27 14:46:35 +01:00
|
|
|
|
_expected_redirect=url_for('main.user_profile'),
|
2021-12-31 12:08:14 +00:00
|
|
|
|
)
|
2016-01-12 10:28:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_should_show_mobile_number_page(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get(('main.user_profile_mobile_number'))
|
|
|
|
|
|
assert 'Change your mobile number' in page.text
|
2022-02-23 18:31:00 +00:00
|
|
|
|
assert 'Delete your number' not in page.text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_change_your_mobile_number_page_shows_delete_link_if_user_on_email_auth(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
api_user_active_email_auth,
|
|
|
|
|
|
mocker
|
|
|
|
|
|
):
|
2023-01-19 17:29:21 -05:00
|
|
|
|
client_request.login(api_user_active_email_auth)
|
2022-02-23 18:31:00 +00:00
|
|
|
|
page = client_request.get(('main.user_profile_mobile_number'))
|
|
|
|
|
|
assert 'Change your mobile number' in page.text
|
|
|
|
|
|
assert 'Delete your number' in page.text
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-03-23 12:40:43 +00:00
|
|
|
|
def test_change_your_mobile_number_page_doesnt_show_delete_link_if_user_has_no_mobile_number(
|
|
|
|
|
|
client_request,
|
2023-01-19 17:29:21 -05:00
|
|
|
|
fake_uuid,
|
2022-03-23 12:40:43 +00:00
|
|
|
|
mocker
|
|
|
|
|
|
):
|
|
|
|
|
|
user = create_user(
|
|
|
|
|
|
id=fake_uuid,
|
|
|
|
|
|
auth_type='email_auth',
|
|
|
|
|
|
mobile_number=None
|
|
|
|
|
|
)
|
2023-01-19 17:29:21 -05:00
|
|
|
|
client_request.login(user)
|
2022-03-23 12:40:43 +00:00
|
|
|
|
page = client_request.get(('main.user_profile_mobile_number'))
|
|
|
|
|
|
assert 'Change your mobile number' in page.text
|
|
|
|
|
|
assert 'Delete your number' not in page.text
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-02-23 18:31:00 +00:00
|
|
|
|
def test_confirm_delete_mobile_number(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
api_user_active_email_auth,
|
|
|
|
|
|
mocker
|
|
|
|
|
|
):
|
2023-01-19 17:29:21 -05:00
|
|
|
|
client_request.login(api_user_active_email_auth)
|
2022-02-23 18:31:00 +00:00
|
|
|
|
|
|
|
|
|
|
page = client_request.get(
|
|
|
|
|
|
'.user_profile_confirm_delete_mobile_number',
|
|
|
|
|
|
_test_page_title=False,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
assert normalize_spaces(page.select_one('.banner-dangerous').text) == (
|
|
|
|
|
|
'Are you sure you want to delete your mobile number from Notify? '
|
|
|
|
|
|
'Yes, delete'
|
|
|
|
|
|
)
|
|
|
|
|
|
assert 'action' not in page.select_one('.banner-dangerous form')
|
|
|
|
|
|
assert page.select_one('.banner-dangerous form')['method'] == 'post'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_delete_mobile_number(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
api_user_active_email_auth,
|
|
|
|
|
|
mocker
|
|
|
|
|
|
):
|
2023-01-19 17:29:21 -05:00
|
|
|
|
client_request.login(api_user_active_email_auth)
|
2022-02-23 18:31:00 +00:00
|
|
|
|
mock_delete = mocker.patch('app.user_api_client.update_user_attribute')
|
|
|
|
|
|
|
|
|
|
|
|
client_request.post(
|
|
|
|
|
|
'.user_profile_mobile_number_delete',
|
|
|
|
|
|
_expected_redirect=url_for(
|
|
|
|
|
|
'.user_profile',
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
|
|
|
|
|
mock_delete.assert_called_once_with(
|
|
|
|
|
|
api_user_active_email_auth["id"],
|
|
|
|
|
|
mobile_number=None
|
|
|
|
|
|
)
|
2016-01-12 11:25:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-08-29 14:52:24 +01:00
|
|
|
|
@pytest.mark.parametrize('phone_number_to_register_with', [
|
2022-12-22 22:11:07 -05:00
|
|
|
|
'+12024900460',
|
|
|
|
|
|
'+1800-555-5555',
|
2017-08-29 14:52:24 +01:00
|
|
|
|
])
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_should_redirect_after_mobile_number_change(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-08-29 14:52:24 +01:00
|
|
|
|
phone_number_to_register_with,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request.post(
|
|
|
|
|
|
'main.user_profile_mobile_number',
|
|
|
|
|
|
_data={'mobile_number': phone_number_to_register_with},
|
|
|
|
|
|
_expected_status=302,
|
|
|
|
|
|
_expected_redirect=url_for(
|
|
|
|
|
|
'main.user_profile_mobile_number_authenticate',
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
|
|
|
|
|
with client_request.session_transaction() as session:
|
2017-08-29 14:52:24 +01:00
|
|
|
|
assert session['new-mob'] == phone_number_to_register_with
|
2016-01-12 11:25:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_should_show_authenticate_after_mobile_number_change(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
with client_request.session_transaction() as session:
|
2022-12-22 22:11:07 -05:00
|
|
|
|
session['new-mob'] = '+12021234123'
|
2016-01-12 11:25:46 +00:00
|
|
|
|
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get(
|
|
|
|
|
|
'main.user_profile_mobile_number_authenticate',
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
assert 'Change your mobile number' in page.text
|
|
|
|
|
|
assert 'Confirm' in page.text
|
2016-01-12 10:28:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_should_redirect_after_mobile_number_authenticate(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mock_verify_password,
|
|
|
|
|
|
mock_send_verify_code,
|
|
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
with client_request.session_transaction() as session:
|
2022-12-22 22:11:07 -05:00
|
|
|
|
session['new-mob'] = '+12021234123'
|
2016-01-12 10:28:14 +00:00
|
|
|
|
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request.post(
|
|
|
|
|
|
'main.user_profile_mobile_number_authenticate',
|
|
|
|
|
|
_data={'password': '12345667'},
|
|
|
|
|
|
_expected_status=302,
|
|
|
|
|
|
_expected_redirect=url_for(
|
|
|
|
|
|
'main.user_profile_mobile_number_confirm',
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
2016-01-12 10:28:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_should_show_confirm_after_mobile_number_change(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
with client_request.session_transaction() as session:
|
2017-02-03 12:07:21 +00:00
|
|
|
|
session['new-mob-password-confirmed'] = True
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get(
|
|
|
|
|
|
'main.user_profile_mobile_number_confirm'
|
|
|
|
|
|
)
|
2016-01-12 10:28:14 +00:00
|
|
|
|
|
2019-03-26 12:35:32 +00:00
|
|
|
|
assert 'Change your mobile number' in page.text
|
|
|
|
|
|
assert 'Confirm' in page.text
|
2016-01-12 10:28:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-08-29 14:52:24 +01:00
|
|
|
|
@pytest.mark.parametrize('phone_number_to_register_with', [
|
2022-12-22 22:11:07 -05:00
|
|
|
|
'+12020900460',
|
2017-08-29 14:52:24 +01:00
|
|
|
|
'+1800-555-555',
|
|
|
|
|
|
])
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_should_redirect_after_mobile_number_confirm(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-02-24 16:21:41 +00:00
|
|
|
|
mocker,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mock_update_user_attribute,
|
|
|
|
|
|
mock_check_verify_code,
|
2017-08-29 14:52:24 +01:00
|
|
|
|
phone_number_to_register_with,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2019-12-19 16:59:07 +00:00
|
|
|
|
user_before = create_api_user_active(with_unique_id=True)
|
|
|
|
|
|
user_after = create_api_user_active(with_unique_id=True)
|
2019-05-23 15:27:35 +01:00
|
|
|
|
user_before['current_session_id'] = str(uuid.UUID(int=1))
|
|
|
|
|
|
user_after['current_session_id'] = str(uuid.UUID(int=2))
|
2017-02-24 16:21:41 +00:00
|
|
|
|
|
2023-01-19 17:29:21 -05:00
|
|
|
|
client_request.login(user_before)
|
|
|
|
|
|
mocker.patch('app.user_api_client.get_user', side_effect=[user_after])
|
2017-02-24 16:21:41 +00:00
|
|
|
|
|
2019-03-26 12:35:32 +00:00
|
|
|
|
with client_request.session_transaction() as session:
|
2017-02-03 12:07:21 +00:00
|
|
|
|
session['new-mob-password-confirmed'] = True
|
2017-08-29 14:52:24 +01:00
|
|
|
|
session['new-mob'] = phone_number_to_register_with
|
2019-05-23 15:27:35 +01:00
|
|
|
|
session['current_session_id'] = user_before['current_session_id']
|
2017-02-24 16:21:41 +00:00
|
|
|
|
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request.post(
|
|
|
|
|
|
'main.user_profile_mobile_number_confirm',
|
2023-02-17 11:53:44 -05:00
|
|
|
|
_data={'sms_code': '123456'},
|
2019-03-26 12:35:32 +00:00
|
|
|
|
_expected_status=302,
|
|
|
|
|
|
_expected_redirect=url_for(
|
|
|
|
|
|
'main.user_profile',
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
2016-01-12 10:28:14 +00:00
|
|
|
|
|
2017-02-24 16:21:41 +00:00
|
|
|
|
# make sure the current_session_id has changed to what the API returned
|
2019-03-26 12:35:32 +00:00
|
|
|
|
with client_request.session_transaction() as session:
|
2019-05-23 15:27:35 +01:00
|
|
|
|
assert session['current_session_id'] == user_after['current_session_id']
|
2017-02-24 16:21:41 +00:00
|
|
|
|
|
2016-01-12 10:28:14 +00:00
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_should_show_password_page(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get(('main.user_profile_password'))
|
2016-01-12 10:28:14 +00:00
|
|
|
|
|
2019-03-26 12:35:32 +00:00
|
|
|
|
assert page.select_one('h1').text.strip() == 'Change your password'
|
2016-01-27 12:22:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_should_redirect_after_password_change(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-02-07 13:32:20 +00:00
|
|
|
|
mock_update_user_password,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mock_verify_password,
|
|
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request.post(
|
|
|
|
|
|
'main.user_profile_password',
|
|
|
|
|
|
_data={
|
|
|
|
|
|
'new_password': 'the new password',
|
|
|
|
|
|
'old_password': 'the old password',
|
|
|
|
|
|
},
|
|
|
|
|
|
_expected_status=302,
|
|
|
|
|
|
_expected_redirect=url_for(
|
|
|
|
|
|
'main.user_profile',
|
|
|
|
|
|
),
|
|
|
|
|
|
)
|
2016-10-28 11:45:05 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_non_gov_user_cannot_see_change_email_link(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
|
|
|
|
|
api_nongov_user_active,
|
2019-05-28 16:11:54 +01:00
|
|
|
|
mock_get_organisations,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request.login(api_nongov_user_active)
|
|
|
|
|
|
page = client_request.get('main.user_profile')
|
2020-02-21 14:05:34 +00:00
|
|
|
|
assert not page.find('a', {'href': url_for('main.user_profile_email')})
|
2019-03-26 12:35:32 +00:00
|
|
|
|
assert page.select_one('h1').text.strip() == 'Your profile'
|
2016-10-28 11:45:05 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_non_gov_user_cannot_access_change_email_page(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
|
|
|
|
|
api_nongov_user_active,
|
2019-05-28 16:11:54 +01:00
|
|
|
|
mock_get_organisations,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request.login(api_nongov_user_active)
|
|
|
|
|
|
client_request.get('main.user_profile_email', _expected_status=403)
|
2019-06-13 19:00:17 +01:00
|
|
|
|
|
|
|
|
|
|
|
2019-06-14 12:32:47 +01:00
|
|
|
|
def test_normal_user_doesnt_see_disable_platform_admin(client_request):
|
|
|
|
|
|
client_request.get('main.user_profile_disable_platform_admin_view', _expected_status=403)
|
2019-06-13 19:00:17 +01:00
|
|
|
|
|
|
|
|
|
|
|
2019-06-14 12:32:47 +01:00
|
|
|
|
def test_platform_admin_can_see_disable_platform_admin_page(client_request, platform_admin_user):
|
2019-06-13 19:00:17 +01:00
|
|
|
|
client_request.login(platform_admin_user)
|
2019-06-14 12:32:47 +01:00
|
|
|
|
page = client_request.get('main.user_profile_disable_platform_admin_view')
|
2019-06-13 19:00:17 +01:00
|
|
|
|
|
2019-06-14 12:32:47 +01:00
|
|
|
|
assert page.select_one('h1').text.strip() == 'Use platform admin view'
|
|
|
|
|
|
assert page.select_one('input[checked]')['value'] == 'True'
|
2019-06-13 19:00:17 +01:00
|
|
|
|
|
|
|
|
|
|
|
2019-06-14 12:32:47 +01:00
|
|
|
|
def test_can_disable_platform_admin(client_request, platform_admin_user):
|
2019-06-13 19:00:17 +01:00
|
|
|
|
client_request.login(platform_admin_user)
|
|
|
|
|
|
|
|
|
|
|
|
with client_request.session_transaction() as session:
|
2019-06-14 12:32:47 +01:00
|
|
|
|
assert 'disable_platform_admin_view' not in session
|
2019-06-13 19:00:17 +01:00
|
|
|
|
|
|
|
|
|
|
client_request.post(
|
2019-06-14 12:32:47 +01:00
|
|
|
|
'main.user_profile_disable_platform_admin_view',
|
2019-06-13 19:00:17 +01:00
|
|
|
|
_data={'enabled': False},
|
|
|
|
|
|
_expected_status=302,
|
2022-05-27 14:46:35 +01:00
|
|
|
|
_expected_redirect=url_for('main.user_profile'),
|
2019-06-13 19:00:17 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
with client_request.session_transaction() as session:
|
2019-06-14 12:32:47 +01:00
|
|
|
|
assert session['disable_platform_admin_view'] is True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_can_reenable_platform_admin(client_request, platform_admin_user):
|
|
|
|
|
|
client_request.login(platform_admin_user)
|
|
|
|
|
|
|
|
|
|
|
|
with client_request.session_transaction() as session:
|
|
|
|
|
|
session['disable_platform_admin_view'] = True
|
|
|
|
|
|
|
|
|
|
|
|
client_request.post(
|
|
|
|
|
|
'main.user_profile_disable_platform_admin_view',
|
|
|
|
|
|
_data={'enabled': True},
|
|
|
|
|
|
_expected_status=302,
|
2022-05-27 14:46:35 +01:00
|
|
|
|
_expected_redirect=url_for('main.user_profile'),
|
2019-06-14 12:32:47 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
with client_request.session_transaction() as session:
|
|
|
|
|
|
assert session['disable_platform_admin_view'] is False
|
2021-05-07 15:00:01 +01:00
|
|
|
|
|
|
|
|
|
|
|
2021-06-30 15:30:29 +01:00
|
|
|
|
def test_user_doesnt_see_security_keys_unless_they_can_use_webauthn(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
platform_admin_user
|
|
|
|
|
|
):
|
|
|
|
|
|
platform_admin_user['can_use_webauthn'] = False
|
|
|
|
|
|
client_request.login(platform_admin_user)
|
|
|
|
|
|
|
2021-05-07 15:00:01 +01:00
|
|
|
|
client_request.get(
|
|
|
|
|
|
'.user_profile_security_keys',
|
|
|
|
|
|
_expected_status=403,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_should_show_security_keys_page(
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
platform_admin_user,
|
|
|
|
|
|
webauthn_credential,
|
|
|
|
|
|
):
|
|
|
|
|
|
client_request.login(platform_admin_user)
|
|
|
|
|
|
|
|
|
|
|
|
mocker.patch(
|
2021-06-08 09:41:39 +01:00
|
|
|
|
'app.models.webauthn_credential.WebAuthnCredentials.client_method',
|
2021-05-07 15:00:01 +01:00
|
|
|
|
return_value=[webauthn_credential],
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
page = client_request.get('.user_profile_security_keys')
|
|
|
|
|
|
assert page.select_one('h1').text.strip() == 'Security keys'
|
|
|
|
|
|
|
|
|
|
|
|
credential_row = page.select('tr')[-1]
|
|
|
|
|
|
assert 'Test credential' in credential_row.text
|
2021-05-14 12:40:24 +01:00
|
|
|
|
assert "Manage" in credential_row.find('a').text
|
|
|
|
|
|
assert credential_row.find('a')["href"] == url_for(
|
|
|
|
|
|
'.user_profile_manage_security_key',
|
|
|
|
|
|
key_id=webauthn_credential['id']
|
|
|
|
|
|
)
|
2021-05-07 15:00:01 +01:00
|
|
|
|
|
|
|
|
|
|
register_button = page.select_one("[data-module='register-security-key']")
|
|
|
|
|
|
assert register_button.text.strip() == 'Register a key'
|
2021-05-14 17:52:13 +01:00
|
|
|
|
|
|
|
|
|
|
|
2021-06-08 09:41:39 +01:00
|
|
|
|
def test_get_key_from_list_of_keys(
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
webauthn_credential,
|
|
|
|
|
|
webauthn_credential_2,
|
|
|
|
|
|
fake_uuid,
|
|
|
|
|
|
):
|
|
|
|
|
|
mocker.patch(
|
|
|
|
|
|
'app.models.webauthn_credential.WebAuthnCredentials.client_method',
|
|
|
|
|
|
return_value=[webauthn_credential, webauthn_credential_2],
|
|
|
|
|
|
)
|
|
|
|
|
|
assert WebAuthnCredentials(fake_uuid).by_id(webauthn_credential["id"]) == WebAuthnCredential(webauthn_credential)
|
2021-05-25 11:15:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
2021-05-14 17:52:13 +01:00
|
|
|
|
def test_should_show_manage_security_key_page(
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
platform_admin_user,
|
|
|
|
|
|
webauthn_credential,
|
|
|
|
|
|
):
|
|
|
|
|
|
client_request.login(platform_admin_user)
|
|
|
|
|
|
|
|
|
|
|
|
mocker.patch(
|
2021-06-08 09:41:39 +01:00
|
|
|
|
'app.models.webauthn_credential.WebAuthnCredentials.client_method',
|
2021-05-25 11:15:57 +01:00
|
|
|
|
return_value=[webauthn_credential],
|
2021-05-14 17:52:13 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
page = client_request.get('.user_profile_manage_security_key', key_id=webauthn_credential['id'])
|
|
|
|
|
|
assert page.select_one('h1').text.strip() == f'Manage ‘{webauthn_credential["name"]}’'
|
|
|
|
|
|
|
|
|
|
|
|
assert page.select_one('.govuk-back-link').text.strip() == 'Back'
|
|
|
|
|
|
assert page.select_one('.govuk-back-link')['href'] == url_for('.user_profile_security_keys')
|
|
|
|
|
|
|
2021-05-21 17:10:34 +01:00
|
|
|
|
assert page.select_one('#security_key_name')["value"] == webauthn_credential["name"]
|
2021-05-14 17:52:13 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_manage_security_key_page_404s_when_key_not_found(
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
platform_admin_user,
|
|
|
|
|
|
webauthn_credential,
|
|
|
|
|
|
webauthn_credential_2
|
|
|
|
|
|
):
|
|
|
|
|
|
client_request.login(platform_admin_user)
|
|
|
|
|
|
|
|
|
|
|
|
mocker.patch(
|
2021-06-08 09:41:39 +01:00
|
|
|
|
'app.models.webauthn_credential.WebAuthnCredentials.client_method',
|
2021-05-14 17:52:13 +01:00
|
|
|
|
return_value=[webauthn_credential_2],
|
|
|
|
|
|
)
|
|
|
|
|
|
client_request.get(
|
|
|
|
|
|
'.user_profile_manage_security_key',
|
|
|
|
|
|
key_id=webauthn_credential['id'],
|
|
|
|
|
|
_expected_status=404,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-05-21 18:02:04 +01:00
|
|
|
|
@pytest.mark.parametrize('endpoint,method', [
|
|
|
|
|
|
(".user_profile_manage_security_key", "get"),
|
|
|
|
|
|
(".user_profile_manage_security_key", "post"),
|
|
|
|
|
|
(".user_profile_confirm_delete_security_key", "get"),
|
|
|
|
|
|
(".user_profile_confirm_delete_security_key", "post"),
|
|
|
|
|
|
(".user_profile_delete_security_key", "post"),
|
|
|
|
|
|
])
|
2021-06-30 15:30:29 +01:00
|
|
|
|
def test_cant_manage_security_keys_unless_can_use_webauthn(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
platform_admin_user,
|
|
|
|
|
|
webauthn_credential,
|
|
|
|
|
|
endpoint,
|
|
|
|
|
|
method
|
2021-05-21 18:02:04 +01:00
|
|
|
|
):
|
2021-06-30 15:30:29 +01:00
|
|
|
|
platform_admin_user['can_use_webauthn'] = False
|
|
|
|
|
|
client_request.login(platform_admin_user)
|
|
|
|
|
|
|
2021-05-21 18:02:04 +01:00
|
|
|
|
if method == "get":
|
|
|
|
|
|
client_request.get(
|
|
|
|
|
|
endpoint,
|
|
|
|
|
|
key_id=webauthn_credential['id'],
|
|
|
|
|
|
_expected_status=403,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
client_request.post(
|
|
|
|
|
|
endpoint,
|
|
|
|
|
|
key_id=webauthn_credential['id'],
|
|
|
|
|
|
_expected_status=403,
|
|
|
|
|
|
)
|
2021-05-14 18:19:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_should_redirect_after_change_of_security_key_name(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
platform_admin_user,
|
|
|
|
|
|
webauthn_credential,
|
|
|
|
|
|
mocker
|
|
|
|
|
|
):
|
|
|
|
|
|
client_request.login(platform_admin_user)
|
|
|
|
|
|
|
|
|
|
|
|
mocker.patch(
|
2021-06-08 09:41:39 +01:00
|
|
|
|
'app.models.webauthn_credential.WebAuthnCredentials.client_method',
|
2021-05-14 18:19:02 +01:00
|
|
|
|
return_value=[webauthn_credential],
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2021-05-25 11:15:57 +01:00
|
|
|
|
mock_update = mocker.patch('app.user_api_client.update_webauthn_credential_name_for_user')
|
|
|
|
|
|
|
2021-05-14 18:19:02 +01:00
|
|
|
|
client_request.post(
|
|
|
|
|
|
'main.user_profile_manage_security_key',
|
|
|
|
|
|
key_id=webauthn_credential['id'],
|
2021-05-21 17:10:34 +01:00
|
|
|
|
_data={'security_key_name': "new name"},
|
2021-05-14 18:19:02 +01:00
|
|
|
|
_expected_status=302,
|
|
|
|
|
|
_expected_redirect=url_for(
|
|
|
|
|
|
'main.user_profile_security_keys',
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
mock_update.assert_called_once_with(
|
|
|
|
|
|
credential_id=webauthn_credential['id'],
|
|
|
|
|
|
new_name_for_credential="new name",
|
|
|
|
|
|
user_id=platform_admin_user["id"]
|
|
|
|
|
|
)
|
2021-05-14 18:42:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
2021-05-18 15:00:35 +01:00
|
|
|
|
def test_user_profile_manage_security_key_should_not_call_api_if_key_name_stays_the_same(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
platform_admin_user,
|
|
|
|
|
|
webauthn_credential,
|
|
|
|
|
|
mocker
|
|
|
|
|
|
):
|
|
|
|
|
|
client_request.login(platform_admin_user)
|
|
|
|
|
|
|
|
|
|
|
|
mocker.patch(
|
2021-06-08 09:41:39 +01:00
|
|
|
|
'app.models.webauthn_credential.WebAuthnCredentials.client_method',
|
2021-05-18 15:00:35 +01:00
|
|
|
|
return_value=[webauthn_credential],
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2021-05-25 11:15:57 +01:00
|
|
|
|
mock_update = mocker.patch('app.user_api_client.update_webauthn_credential_name_for_user')
|
|
|
|
|
|
|
2021-05-18 15:00:35 +01:00
|
|
|
|
client_request.post(
|
|
|
|
|
|
'main.user_profile_manage_security_key',
|
|
|
|
|
|
key_id=webauthn_credential['id'],
|
2021-05-21 17:10:34 +01:00
|
|
|
|
_data={'security_key_name': webauthn_credential['name']},
|
2021-05-18 15:00:35 +01:00
|
|
|
|
_expected_status=302,
|
|
|
|
|
|
_expected_redirect=url_for(
|
|
|
|
|
|
'main.user_profile_security_keys',
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
assert not mock_update.called
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-05-14 18:42:57 +01:00
|
|
|
|
def test_shows_delete_link_for_security_key(
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
platform_admin_user,
|
|
|
|
|
|
webauthn_credential,
|
|
|
|
|
|
):
|
|
|
|
|
|
client_request.login(platform_admin_user)
|
|
|
|
|
|
|
|
|
|
|
|
mocker.patch(
|
2021-06-08 09:41:39 +01:00
|
|
|
|
'app.models.webauthn_credential.WebAuthnCredentials.client_method',
|
2021-05-25 11:15:57 +01:00
|
|
|
|
return_value=[webauthn_credential],
|
2021-05-14 18:42:57 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
page = client_request.get('.user_profile_manage_security_key', key_id=webauthn_credential['id'])
|
|
|
|
|
|
assert page.select_one('h1').text.strip() == f'Manage ‘{webauthn_credential["name"]}’'
|
|
|
|
|
|
|
|
|
|
|
|
link = page.select_one('.page-footer a')
|
|
|
|
|
|
assert normalize_spaces(link.text) == 'Delete'
|
|
|
|
|
|
assert link['href'] == url_for('.user_profile_confirm_delete_security_key', key_id=webauthn_credential['id'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_confirm_delete_security_key(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
platform_admin_user,
|
|
|
|
|
|
webauthn_credential,
|
|
|
|
|
|
mocker
|
|
|
|
|
|
):
|
|
|
|
|
|
client_request.login(platform_admin_user)
|
|
|
|
|
|
|
|
|
|
|
|
mocker.patch(
|
2021-06-08 09:41:39 +01:00
|
|
|
|
'app.models.webauthn_credential.WebAuthnCredentials.client_method',
|
2021-05-25 11:15:57 +01:00
|
|
|
|
return_value=[webauthn_credential],
|
2021-05-14 18:42:57 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
page = client_request.get(
|
|
|
|
|
|
'.user_profile_confirm_delete_security_key',
|
|
|
|
|
|
key_id=webauthn_credential['id'],
|
|
|
|
|
|
_test_page_title=False,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
assert normalize_spaces(page.select_one('.banner-dangerous').text) == (
|
|
|
|
|
|
'Are you sure you want to delete this security key? '
|
|
|
|
|
|
'Yes, delete'
|
|
|
|
|
|
)
|
|
|
|
|
|
assert 'action' not in page.select_one('.banner-dangerous form')
|
|
|
|
|
|
assert page.select_one('.banner-dangerous form')['method'] == 'post'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_delete_security_key(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
platform_admin_user,
|
|
|
|
|
|
webauthn_credential,
|
|
|
|
|
|
mocker
|
|
|
|
|
|
):
|
|
|
|
|
|
client_request.login(platform_admin_user)
|
|
|
|
|
|
mock_delete = mocker.patch('app.user_api_client.delete_webauthn_credential_for_user')
|
|
|
|
|
|
|
|
|
|
|
|
client_request.post(
|
|
|
|
|
|
'.user_profile_delete_security_key',
|
|
|
|
|
|
key_id=webauthn_credential['id'],
|
|
|
|
|
|
_expected_redirect=url_for(
|
|
|
|
|
|
'.user_profile_security_keys',
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
|
|
|
|
|
mock_delete.assert_called_once_with(
|
|
|
|
|
|
credential_id=webauthn_credential['id'],
|
|
|
|
|
|
user_id=platform_admin_user["id"]
|
|
|
|
|
|
)
|
2021-05-18 14:50:25 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_delete_security_key_handles_last_credential_error(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
platform_admin_user,
|
|
|
|
|
|
webauthn_credential,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
):
|
|
|
|
|
|
client_request.login(platform_admin_user)
|
|
|
|
|
|
mocker.patch(
|
2021-06-08 09:41:39 +01:00
|
|
|
|
'app.models.webauthn_credential.WebAuthnCredentials.client_method',
|
2021-05-18 14:50:25 +01:00
|
|
|
|
return_value=[webauthn_credential],
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
mocker.patch(
|
|
|
|
|
|
'app.user_api_client.delete_webauthn_credential_for_user',
|
|
|
|
|
|
side_effect=HTTPError(
|
|
|
|
|
|
response={},
|
|
|
|
|
|
message='Cannot delete last remaining webauthn credential for user'
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
page = client_request.post(
|
|
|
|
|
|
'.user_profile_delete_security_key',
|
|
|
|
|
|
key_id=webauthn_credential['id'],
|
|
|
|
|
|
_follow_redirects=True
|
|
|
|
|
|
)
|
|
|
|
|
|
assert 'Manage ‘Test credential’' in page.find('h1').text
|
|
|
|
|
|
expected_message = "You cannot delete your last security key."
|
|
|
|
|
|
assert expected_message in page.find('div', class_="banner-dangerous").text
|