action / bt-source /panel /class /webauthn /helpers /parse_authentication_options_json.py
GGSheng's picture
feat: deploy Gemma 4 to hf space
020c337 verified
import json
from json import JSONDecodeError
from typing import List, Optional, Union
from .base64url_to_bytes import base64url_to_bytes
from .exceptions import InvalidJSONStructure, InvalidAuthenticationOptions
from .structs import (
AuthenticatorTransport,
PublicKeyCredentialDescriptor,
PublicKeyCredentialRequestOptions,
UserVerificationRequirement,
)
def parse_authentication_options_json(
json_val: Union[str, dict]
) -> PublicKeyCredentialRequestOptions:
"""
Parse a JSON form of authentication options, as either stringified JSON or a plain dict, into an
instance of `PublicKeyCredentialRequestOptions`. Typically useful in mapping output from
`generate_authentication_options()`, that's been persisted as JSON via Redis/etc... back into
structured data.
"""
if isinstance(json_val, str):
try:
json_val = json.loads(json_val)
except JSONDecodeError:
raise InvalidJSONStructure("Unable to decode options as JSON")
if not isinstance(json_val, dict):
raise InvalidJSONStructure("Options were not a JSON object")
"""
Check challenge
"""
options_challenge = json_val.get("challenge")
if not isinstance(options_challenge, str):
raise InvalidJSONStructure("Options missing required challenge")
"""
Check timeout
"""
options_timeout = json_val.get("timeout")
mapped_timeout = None
if isinstance(options_timeout, int):
mapped_timeout = options_timeout
"""
Check rpId
"""
options_rp_id = json_val.get("rpId")
mapped_rp_id = None
if isinstance(options_rp_id, str):
mapped_rp_id = options_rp_id
"""
Check userVerification
"""
options_user_verification = json_val.get("userVerification")
if not isinstance(options_user_verification, str):
raise InvalidJSONStructure("Options missing required userVerification")
try:
mapped_user_verification = UserVerificationRequirement(options_user_verification)
except ValueError as exc:
raise InvalidJSONStructure("Options userVerification was invalid value") from exc
"""
Check allowCredentials
"""
options_allow_credentials = json_val.get("allowCredentials")
mapped_allow_credentials: Optional[List[PublicKeyCredentialDescriptor]] = None
if isinstance(options_allow_credentials, list):
mapped_allow_credentials = []
for cred in options_allow_credentials:
_cred_id = cred.get("id")
if not isinstance(_cred_id, str):
raise InvalidJSONStructure("Options excludeCredentials entry missing required id")
_mapped = PublicKeyCredentialDescriptor(id=base64url_to_bytes(_cred_id))
_transports = cred.get("transports")
if _transports is not None:
if not isinstance(_transports, list):
raise InvalidJSONStructure(
"Options excludeCredentials entry transports was not list"
)
try:
_mapped.transports = [
AuthenticatorTransport(_transport) for _transport in _transports
]
except ValueError as exc:
raise InvalidJSONStructure(
"Options excludeCredentials entry transports had invalid value"
) from exc
mapped_allow_credentials.append(_mapped)
try:
authentication_options = PublicKeyCredentialRequestOptions(
challenge=base64url_to_bytes(options_challenge),
timeout=mapped_timeout,
rp_id=mapped_rp_id,
user_verification=mapped_user_verification,
allow_credentials=mapped_allow_credentials,
)
except Exception as exc:
raise InvalidAuthenticationOptions(
"Could not parse authentication options from JSON data"
) from exc
return authentication_options