From a3870af87d73ad5a05c6112e7c97436321509d4a Mon Sep 17 00:00:00 2001 From: Leo Hemsted Date: Thu, 27 May 2021 12:58:42 +0100 Subject: [PATCH] allow password reset with webauthn login flow --- app/main/views/new_password.py | 2 +- tests/app/main/views/test_new_password.py | 26 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/app/main/views/new_password.py b/app/main/views/new_password.py index e060736a1..5167d7ae2 100644 --- a/app/main/views/new_password.py +++ b/app/main/views/new_password.py @@ -45,7 +45,7 @@ def new_password(token): # they've just clicked an email link, so have done an email auth journey anyway. Just log them in. return log_in_user(user.id) elif user.webauthn_auth: - raise NotImplementedError('webauthn not supported yet') + return redirect(url_for('main.two_factor_webauthn', next=request.args.get('next'))) else: # send user a 2fa sms code user.send_verify_code() diff --git a/tests/app/main/views/test_new_password.py b/tests/app/main/views/test_new_password.py index c7102771e..b0c690d1f 100644 --- a/tests/app/main/views/test_new_password.py +++ b/tests/app/main/views/test_new_password.py @@ -60,6 +60,32 @@ def test_should_redirect_to_two_factor_when_password_reset_is_successful( mock_get_user_by_email_request_password_reset.assert_called_once_with(user['email_address']) +@pytest.mark.parametrize('redirect_url', [ + None, + f'/services/{SERVICE_ONE_ID}/templates', +]) +def test_should_redirect_to_two_factor_webauthn_when_password_reset_is_successful( + notify_admin, + client, + mock_get_user_by_email_request_password_reset, + mock_send_verify_code, + mock_reset_failed_login_count, + redirect_url +): + user = mock_get_user_by_email_request_password_reset.return_value + user['auth_type'] = 'webauthn_auth' + data = json.dumps({'email': user['email_address'], 'created_at': str(datetime.utcnow())}) + token = generate_token(data, notify_admin.config['SECRET_KEY'], notify_admin.config['DANGEROUS_SALT']) + response = client.post(url_for_endpoint_with_token('.new_password', token=token, next=redirect_url), + data={'new_password': 'a-new_password'}) + assert response.status_code == 302 + assert response.location == url_for('.two_factor_webauthn', _external=True, next=redirect_url) + mock_get_user_by_email_request_password_reset.assert_called_once_with(user['email_address']) + + assert not mock_send_verify_code.called + assert mock_reset_failed_login_count.called + + def test_should_redirect_index_if_user_has_already_changed_password( notify_admin, client,