tweak webauthn rest errors

simplify logic by changing the dao function to require a user id and a
webauthn cred id. Note that this changes the response from a 400 to a
404 if the cred is for a different user than the supplied id.

give a minimum length to the text fields in POSTS to create/update a
credential to avoid surprising unexpected edge cases involving empty
string names etc.
This commit is contained in:
Leo Hemsted
2021-05-12 15:34:37 +01:00
parent d6fead7c04
commit c190886bfe
4 changed files with 60 additions and 47 deletions

View File

@@ -3,9 +3,10 @@ from app.dao.dao_utils import autocommit
from app.models import WebauthnCredential
def dao_get_webauthn_credential_by_id(webauthn_credential_id):
return WebauthnCredential.query.filter_by(
id=webauthn_credential_id
def dao_get_webauthn_credential_by_user_and_id(user_id, webauthn_credential_id):
return WebauthnCredential.query.filter(
WebauthnCredential.user_id == user_id,
WebauthnCredential.id == webauthn_credential_id
).one()

View File

@@ -4,7 +4,7 @@ from app.dao.users_dao import get_user_by_id
from app.dao.webauthn_credential_dao import (
dao_create_webauthn_credential,
dao_delete_webauthn_credential,
dao_get_webauthn_credential_by_id,
dao_get_webauthn_credential_by_user_and_id,
dao_update_webauthn_credential_name,
)
from app.errors import InvalidRequest, register_errors
@@ -43,11 +43,7 @@ def update_webauthn_credential(user_id, webauthn_credential_id):
data = request.get_json()
validate(data, post_update_webauthn_credential_schema)
webauthn_credential = dao_get_webauthn_credential_by_id(webauthn_credential_id)
user = get_user_by_id(user_id)
check_credential_belongs_to_user(webauthn_credential.user_id, user.id)
webauthn_credential = dao_get_webauthn_credential_by_user_and_id(user_id, webauthn_credential_id)
dao_update_webauthn_credential_name(webauthn_credential, data['name'])
@@ -56,19 +52,13 @@ def update_webauthn_credential(user_id, webauthn_credential_id):
@webauthn_blueprint.route('/<uuid:webauthn_credential_id>', methods=['DELETE'])
def delete_webauthn_credential(user_id, webauthn_credential_id):
webauthn_credential = dao_get_webauthn_credential_by_id(webauthn_credential_id)
webauthn_credential = dao_get_webauthn_credential_by_user_and_id(user_id, webauthn_credential_id)
user = get_user_by_id(user_id)
check_credential_belongs_to_user(webauthn_credential.user_id, user.id)
if len(user.webauthn_credentials) == 1:
# TODO: Only raise an error if user has auth type webauthn_auth
raise InvalidRequest('Cannot delete last remaining webauthn credential for user', status_code=400)
dao_delete_webauthn_credential(webauthn_credential)
return '', 204
def check_credential_belongs_to_user(credential_user_id, user_id):
if credential_user_id != user_id:
raise InvalidRequest('Webauthn credential does not belong to this user', status_code=400)

View File

@@ -3,9 +3,9 @@ post_create_webauthn_credential_schema = {
"description": "POST webauthn_credential schema",
"type": "object",
"properties": {
"name": {"type": "string"},
"credential_data": {"type": "string"},
"registration_response": {"type": "string"},
"name": {"type": "string", "minLength": 1},
"credential_data": {"type": "string", "minLength": 1},
"registration_response": {"type": "string", "minLength": 1},
},
"required": ["name", "credential_data", "registration_response"],
"additionalProperties": False
@@ -16,7 +16,7 @@ post_update_webauthn_credential_schema = {
"description": "POST update webauthn_credential schema",
"type": "object",
"properties": {
"name": {"type": "string"},
"name": {"type": "string", "minLength": 1},
},
"required": ["name"],
"additionalProperties": False