Prevent switching auth type for Platform Admins

This closes a security loophole, where the auth type of a Platform
Admin could be unwittingly changed when they accept an invite, or
by an admin of a service they are a member of.
This commit is contained in:
Ben Thorner
2021-05-25 15:58:33 +01:00
parent a10304d9c6
commit 6d0d9d46f7
5 changed files with 92 additions and 11 deletions

View File

@@ -1,4 +1,5 @@
from unittest.mock import ANY, Mock
from uuid import uuid4
import pytest
from bs4 import BeautifulSoup
@@ -690,6 +691,43 @@ def test_existing_user_accepts_and_sets_email_auth(
mock_add_user_to_service.assert_called_once_with(ANY, USER_ONE_ID, ANY, ANY)
def test_platform_admin_user_accepts_and_preserves_auth(
client_request,
platform_admin_user,
service_one,
sample_invite,
mock_get_users_by_service,
mock_accept_invite,
mock_update_user_attribute,
mock_add_user_to_service,
mocker
):
sample_invite['email_address'] = platform_admin_user['email_address']
sample_invite['auth_type'] = 'email_auth'
service_one['permissions'].append('email_auth')
# mock_get_users_by_service uses the same global UUID as the platform admin user,
# so we need to reset it to pretend this user isn't a member of the service
platform_admin_user['id'] = uuid4()
platform_admin_user['auth_type'] = 'webauthn_auth'
# mock_get_unknown_user_by_email returns the active_api_user, which we don't want
mocker.patch('app.user_api_client.get_user_by_email', return_value=platform_admin_user)
mocker.patch('app.invite_api_client.check_token', return_value=sample_invite)
client_request.login(platform_admin_user)
client_request.get(
'main.accept_invite',
token='thisisnotarealtoken',
_expected_status=302,
_expected_redirect=url_for('main.service_dashboard', service_id=service_one['id'], _external=True),
)
assert not mock_update_user_attribute.called
assert mock_add_user_to_service.called
def test_existing_user_doesnt_get_auth_changed_by_service_without_permission(
client_request,
api_user_active,

View File

@@ -795,6 +795,42 @@ def test_edit_user_permissions_including_authentication_with_email_auth_service(
)
@pytest.mark.parametrize('auth_type', ['email_auth', 'sms_auth'])
def test_edit_user_permissions_preserves_auth_type_for_platform_admin(
client_request,
service_one,
platform_admin_user,
mock_get_users_by_service,
mock_get_invites_for_service,
mock_set_user_permissions,
mock_update_user_attribute,
auth_type,
mock_get_template_folders
):
service_one['permissions'].append('email_auth')
client_request.login(platform_admin_user)
client_request.post(
'main.edit_user_permissions',
service_id=SERVICE_ONE_ID,
user_id=platform_admin_user['id'],
_data={
'email_address': platform_admin_user['email_address'],
'permissions_field': [],
'login_authentication': auth_type,
},
_expected_status=302,
)
mock_set_user_permissions.assert_called_with(
str(platform_admin_user['id']),
SERVICE_ONE_ID,
permissions=set(),
folder_permissions=[],
)
mock_update_user_attribute.assert_not_called()
def test_should_show_page_for_inviting_user(
client_request,
mock_get_template_folders,