From 56eac279dfb0b5b4a7d40921ced8f533d976b81d Mon Sep 17 00:00:00 2001 From: Pea Tyczynska Date: Fri, 14 May 2021 17:52:13 +0100 Subject: [PATCH] Show manage security key page with name change form --- app/main/forms.py | 10 ++++ app/main/views/user_profile.py | 13 ++++- .../user-profile/manage-security-key.html | 13 ++++- tests/app/main/views/test_user_profile.py | 51 +++++++++++++++++++ tests/conftest.py | 13 ++++- 5 files changed, 97 insertions(+), 3 deletions(-) diff --git a/app/main/forms.py b/app/main/forms.py index 065b62a6d..6775cef50 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -2504,3 +2504,13 @@ class BroadcastAreaFormWithSelectAll(BroadcastAreaForm): if self.select_all.data: return [self.select_all.area_slug] return self.areas.data + + +class ChangeNameOfSecurityKey(StripWhitespaceForm): + name_of_key = GovukTextInputField( + 'Name of key', + validators=[ + DataRequired(message='Cannot be empty'), + MustContainAlphanumericCharacters(), + Length(max=255, message='Name of key must be 255 characters or fewer') + ]) diff --git a/app/main/views/user_profile.py b/app/main/views/user_profile.py index 9f57f573f..8aa8db858 100644 --- a/app/main/views/user_profile.py +++ b/app/main/views/user_profile.py @@ -17,6 +17,7 @@ from app.main.forms import ( ChangeEmailForm, ChangeMobileNumberForm, ChangeNameForm, + ChangeNameOfSecurityKey, ChangePasswordForm, ConfirmPasswordForm, ServiceOnOffSettingForm, @@ -241,7 +242,17 @@ def user_profile_security_keys(): @main.route("/user-profile/security-keys//manage", methods=['GET']) @user_is_platform_admin -def user_profile_manage_security_key(): +def user_profile_manage_security_key(key_id): + security_keys = user_api_client.get_webauthn_credentials_for_user(current_user.id) + security_key = next((key for key in security_keys if key["id"] == key_id), None) + + if not security_key: + abort(404) + + form = ChangeNameOfSecurityKey(name_of_key=security_key["name"]) + return render_template( 'views/user-profile/manage-security-key.html', + security_key=security_key, + form=form ) diff --git a/app/templates/views/user-profile/manage-security-key.html b/app/templates/views/user-profile/manage-security-key.html index bb229de86..7c5030c9c 100644 --- a/app/templates/views/user-profile/manage-security-key.html +++ b/app/templates/views/user-profile/manage-security-key.html @@ -1,8 +1,10 @@ {% extends "withoutnav_template.html" %} {% from "components/page-header.html" import page_header %} +{% from "components/page-footer.html" import page_footer %} +{% from "components/form.html" import form_wrapper %} -{% set page_title = 'Manage security key' %} +{% set page_title = 'Manage ' + '‘' + security_key.name + '’' %} {% block per_page_title %} {{ page_title }} @@ -14,4 +16,13 @@ back_link=url_for('.user_profile_security_keys') ) }} +
+
+ {% call form_wrapper(autocomplete=True) %} + {{ form.name_of_key }} + {{ page_footer('Save') }} + {% endcall %} +
+
+ {% endblock %} diff --git a/tests/app/main/views/test_user_profile.py b/tests/app/main/views/test_user_profile.py index 32f743b1f..f33d27898 100644 --- a/tests/app/main/views/test_user_profile.py +++ b/tests/app/main/views/test_user_profile.py @@ -374,3 +374,54 @@ def test_should_show_security_keys_page( register_button = page.select_one("[data-module='register-security-key']") assert register_button.text.strip() == 'Register a key' + + +def test_should_show_manage_security_key_page( + mocker, + client_request, + platform_admin_user, + webauthn_credential, + webauthn_credential_2 +): + client_request.login(platform_admin_user) + + mocker.patch( + 'app.user_api_client.get_webauthn_credentials_for_user', + return_value=[webauthn_credential, webauthn_credential_2], + ) + + 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') + + assert page.select_one('#name_of_key')["value"] == webauthn_credential["name"] + + +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( + 'app.user_api_client.get_webauthn_credentials_for_user', + return_value=[webauthn_credential_2], + ) + client_request.get( + '.user_profile_manage_security_key', + key_id=webauthn_credential['id'], + _expected_status=404, + ) + + +def test_non_platform_admin_user_doesnt_see_manage_security_key_page(client_request, webauthn_credential,): + client_request.get( + '.user_profile_manage_security_key', + key_id=webauthn_credential['id'], + _expected_status=403, + ) diff --git a/tests/conftest.py b/tests/conftest.py index 6ec70da96..6898d9802 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4484,9 +4484,20 @@ def mock_get_invited_org_user_by_id(mocker, sample_org_invite): @pytest.fixture def webauthn_credential(): return { - 'id': uuid4(), + 'id': str(uuid4()), 'name': 'Test credential', 'credential_data': 'WJ0AAAAAAAAAAAAAAAAAAAAAAECKU1ppjl9gmhHWyDkgHsUvZmhr6oF3/lD3llzLE2SaOSgOGIsIuAQqgp8JQSUu3r/oOaP8RS44dlQjrH+ALfYtpAECAyYhWCAxnqAfESXOYjKUc2WACuXZ3ch0JHxV0VFrrTyjyjIHXCJYIFnx8H87L4bApR4M+hPcV+fHehEOeW+KCyd0H+WGY8s6', # noqa 'registration_response': 'anything', 'created_at': '2017-10-18T16:57:14.154185Z', } + + +@pytest.fixture +def webauthn_credential_2(): + return { + 'id': str(uuid4()), + 'name': 'Another test credential', + 'credential_data': 'WJ0AAAAAAAAAAAAAAAAAAAAAAECKU1jppl9mhgHWyDkgHsUvZmhr6oF3/lD3llzLE2SaOSgOGIsIuAQqgp8JQSUu3r/oOaP8RS44dlQjrH+ALfYtpAECAyYhWCAxnqAfESXOYjKUc2WACuXZ3ch0JHxV0VFrrTyjyjIHXCJYIFnx8L4H87bApR4M+hPcV+fHehEOeW+KCyd0H+WGY8s6', # noqa + 'registration_response': 'stuff', + 'created_at': '2021-05-14T16:57:14.154185Z', + }