mirror of
https://github.com/GSA/notifications-api.git
synced 2025-12-23 08:51:30 -05:00
added some simple validation to the delete endpoint for sanity, but generally my assumption is that more validation will happen on the admin side. noteably im not checking whether the credentials are duplicated, nor is there a uniqueness constraint in the database - I'm not sure if the credential blob will always reliably be equivalent, and I believe the browser should hopefully take care of dupes.
174 lines
5.5 KiB
Python
174 lines
5.5 KiB
Python
import uuid
|
|
from unittest.mock import ANY
|
|
|
|
from tests.app.db import create_user, create_webauthn_credential
|
|
|
|
|
|
def test_get_webauthn_credentials_returns_all_credentials_for_user(admin_request, notify_db_session):
|
|
me = create_user(email='a')
|
|
other = create_user(email='b')
|
|
first = create_webauthn_credential(me, '1')
|
|
create_webauthn_credential(me, '2')
|
|
create_webauthn_credential(other, '3')
|
|
|
|
response = admin_request.get(
|
|
'webauthn.get_webauthn_credentials',
|
|
user_id=me.id,
|
|
)
|
|
|
|
creds = sorted(response['data'], key=lambda x: x['name'])
|
|
assert len(creds) == 2
|
|
|
|
assert creds[0] == {
|
|
'id': str(first.id),
|
|
'user_id': str(me.id),
|
|
'name': '1',
|
|
'credential_data': 'ABC123',
|
|
'registration_response': 'DEF456',
|
|
'created_at': ANY,
|
|
'updated_at': None
|
|
}
|
|
|
|
assert creds[1]['name'] == '2'
|
|
|
|
|
|
def test_get_webauthn_credentials_returns_empty_list_if_no_creds(admin_request, sample_user):
|
|
response = admin_request.get('webauthn.get_webauthn_credentials', user_id=sample_user.id)
|
|
assert response == {'data': []}
|
|
|
|
|
|
def test_get_webauthn_credentials_errors_if_user_doesnt_exist(admin_request, sample_user):
|
|
create_webauthn_credential(sample_user, '1')
|
|
|
|
admin_request.get(
|
|
'webauthn.get_webauthn_credentials',
|
|
user_id=uuid.uuid4(),
|
|
_expected_status=404
|
|
)
|
|
|
|
|
|
def test_create_webauthn_credential_returns_201(admin_request, sample_user):
|
|
response = admin_request.post(
|
|
'webauthn.create_webauthn_credential',
|
|
user_id=sample_user.id,
|
|
_data={
|
|
'name': 'my key',
|
|
'credential_data': 'ABC123',
|
|
'registration_response': 'DEF456',
|
|
},
|
|
_expected_status=201
|
|
)
|
|
assert len(sample_user.webauthn_credentials) == 1
|
|
|
|
new_cred = sample_user.webauthn_credentials[0]
|
|
|
|
assert new_cred.name == 'my key'
|
|
assert new_cred.credential_data == 'ABC123'
|
|
assert new_cred.registration_response == 'DEF456'
|
|
assert response['data']['id'] == str(new_cred.id)
|
|
|
|
|
|
def test_create_webauthn_credential_errors_if_schema_violation(admin_request, sample_user):
|
|
response = admin_request.post(
|
|
'webauthn.create_webauthn_credential',
|
|
user_id=sample_user.id,
|
|
_data={
|
|
'name': 'my key',
|
|
'credential_data': 'ABC123',
|
|
# missing registration_response
|
|
},
|
|
_expected_status=400
|
|
)
|
|
assert response['errors'][0] == {
|
|
'error': 'ValidationError',
|
|
'message': 'registration_response is a required property'
|
|
}
|
|
|
|
|
|
def test_update_webauthn_credential_returns_200(admin_request, sample_user):
|
|
cred = create_webauthn_credential(sample_user)
|
|
assert cred.name != 'new name'
|
|
|
|
response = admin_request.post(
|
|
'webauthn.update_webauthn_credential',
|
|
user_id=sample_user.id,
|
|
webauthn_credential_id=cred.id,
|
|
_data={
|
|
'name': 'new name',
|
|
},
|
|
)
|
|
assert response['data']['id'] == str(cred.id)
|
|
assert response['data']['name'] == 'new name'
|
|
|
|
|
|
def test_update_webauthn_credential_errors_if_schema_violation(admin_request, sample_user):
|
|
cred = create_webauthn_credential(sample_user)
|
|
response = admin_request.post(
|
|
'webauthn.update_webauthn_credential',
|
|
user_id=sample_user.id,
|
|
webauthn_credential_id=cred.id,
|
|
_data={
|
|
'name': 'my key',
|
|
# you can't update credential_data
|
|
'credential_data': 'NAUGHTY123'
|
|
},
|
|
_expected_status=400
|
|
)
|
|
assert response['errors'][0] == {
|
|
'error': 'ValidationError',
|
|
'message': 'Additional properties are not allowed (credential_data was unexpected)'
|
|
}
|
|
|
|
|
|
def test_update_webauthn_credential_errors_if_webauthn_credential_doesnt_exist(admin_request, sample_user):
|
|
admin_request.post(
|
|
'webauthn.update_webauthn_credential',
|
|
user_id=sample_user.id,
|
|
webauthn_credential_id=uuid.uuid4(),
|
|
_data={
|
|
'name': 'my key',
|
|
},
|
|
_expected_status=404
|
|
)
|
|
|
|
|
|
def test_delete_webauthn_credential_returns_204(admin_request, sample_user):
|
|
cred1 = create_webauthn_credential(sample_user)
|
|
cred2 = create_webauthn_credential(sample_user)
|
|
admin_request.delete(
|
|
'webauthn.update_webauthn_credential',
|
|
user_id=sample_user.id,
|
|
webauthn_credential_id=cred1.id,
|
|
_expected_status=204
|
|
)
|
|
assert sample_user.webauthn_credentials == [cred2]
|
|
|
|
|
|
def test_delete_webauthn_credential_errors_if_last_key(admin_request, sample_user):
|
|
cred = create_webauthn_credential(sample_user)
|
|
response = admin_request.delete(
|
|
'webauthn.delete_webauthn_credential',
|
|
user_id=sample_user.id,
|
|
webauthn_credential_id=cred.id,
|
|
_expected_status=400
|
|
)
|
|
assert response['message'] == 'Cannot delete last remaining webauthn credential for user'
|
|
|
|
|
|
def test_delete_webauthn_credential_errors_if_user_id_doesnt_match(admin_request, notify_db_session):
|
|
user_1 = create_user(email='1')
|
|
user_2 = create_user(email='2')
|
|
cred_1a = create_webauthn_credential(user_1) # noqa
|
|
cred_1b = create_webauthn_credential(user_1) # noqa
|
|
cred_2a = create_webauthn_credential(user_2)
|
|
cred_2b = create_webauthn_credential(user_2) # noqa
|
|
|
|
response = admin_request.delete(
|
|
'webauthn.delete_webauthn_credential',
|
|
user_id=user_1.id,
|
|
webauthn_credential_id=cred_2a.id,
|
|
_expected_status=400
|
|
)
|
|
|
|
assert response['message'] == 'Webauthn credential does not belong to this user'
|