Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
webauthn_util.py159 linesDownload Raw Back to flask_security
1"""2    flask_security.webauthn_util3    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~4 5    Utility class providing methods controlling various aspects of webauthn.6 7    :copyright: (c) 2020-2024 by J. Christopher Wagner (jwag).8    :license: MIT, see LICENSE for more details.9 10"""11 12from __future__ import annotations13 14import secrets15import typing as t16 17from flask import current_app, request18 19try:20    # noinspection PyUnresolvedReferences21    from webauthn.helpers.structs import (22        AuthenticatorAttachment,23        AuthenticatorSelectionCriteria,24        ResidentKeyRequirement,25        UserVerificationRequirement,26    )27except ImportError:  # pragma: no cover28    pass29 30 31if t.TYPE_CHECKING:  # pragma: no cover32    import flask33    from .datastore import User34 35 36class WebauthnUtil:37    """38    Utility class allowing an application to fine-tune various Relying Party39    attributes.40 41    To provide your own implementation, pass in the class as ``webauthn_util_cls``42    at init time.  Your class will be instantiated once as part of app initialization.43 44    .. versionadded:: 5.0.045    """46 47    def __init__(self, app: flask.Flask):48        """Instantiate class.49 50        :param app: The Flask application being initialized.51        """52        pass53 54    def generate_challenge(self, nbytes: int | None = None) -> str:55        # Mostly override this for testing, so we can have a 'constant' challenge.56        return secrets.token_urlsafe(nbytes)57 58    def origin(self) -> str:59        # Return the RP origin - normally this is just the URL of the application.60        return request.host_url.rstrip("/")61 62    def registration_options(63        self, user: User, usage: str, existing_options: dict[str, t.Any]64    ) -> dict[str, t.Any]:65        """66        :param user: User object - could be used to configure on a per-user basis.67        :param usage: Either "first" or "secondary" (webauthn is being used as a second68            factor for authentication)69        :param existing_options: Currently filled in registration options.70 71        Return a dict that will be sent in to py-webauthn generate_registration_options72        """73        existing_options["authenticator_selection"] = self.authenticator_selection(74            user, usage75        )76        return existing_options77 78    def authenticator_selection(79        self, user: User, usage: str80    ) -> AuthenticatorSelectionCriteria:81        """82        :param user: User object - could be used to configure on a per-user basis.83        :param usage: Either "first" or "secondary" (webauthn is being used as a second84            factor for authentication85 86        Part of the registration ceremony is providing information about what kind87        of authenticators the app is interested in.88        See: https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dictionary-authenticatorSelection89 90        The main options are:91            - whether you want a ResidentKey (discoverable)92            - Attachment - platform or cross-platform93            - Does the key have to provide user-verification94 95        :note::96            If the key isn't resident then it isn't discoverable which means that97            the user won't be able to use that key unless they identify themselves98            (use the key as a second factor OR type in their identity). If they are forced99            to type in their identity PRIOR to being authenticated, then there is the100            possibility that the app will leak username information.101        """  # noqa: E501102 103        select_criteria = AuthenticatorSelectionCriteria()104        # TODO: look at #sctn-usecase-new-device-registration to see a reason105        # to allow multiple keys as "first" - only one would need to be cross-platform106        if usage == "first":107            select_criteria.authenticator_attachment = (108                AuthenticatorAttachment.CROSS_PLATFORM109            )110            select_criteria.user_verification = UserVerificationRequirement.PREFERRED111        else:112            # For second factor minimize user-interaction by not asking for UV113            select_criteria.user_verification = UserVerificationRequirement.DISCOURAGED114 115        if not current_app.config.get("SECURITY_WAN_ALLOW_USER_HINTS"):116            select_criteria.resident_key = ResidentKeyRequirement.REQUIRED117        else:118            select_criteria.resident_key = ResidentKeyRequirement.PREFERRED119        return select_criteria120 121    def authentication_options(122        self,123        user: User | None,124        usage: list[str],125        existing_options: dict[str, t.Any],126    ) -> dict[str, t.Any]:127        """128        :param user: User object - could be used to configure on a per-user basis.129            However, this can be null.130        :param usage: Either "first" or "secondary" (webauthn is being used as a second131            factor for authentication)132        :param existing_options: Currently filled in authentication options.133 134        Return a dict that will be sent in to135         py-webauthn generate_authentication_options136        """137        existing_options["user_verification"] = self.user_verification(user, usage)138        return existing_options139 140    def user_verification(141        self, user: User | None, usage: list[str]142    ) -> UserVerificationRequirement:143        """144        As part of signin - do we want/need user verification.145        This is called from /wan-signin and /wan-verify146 147        :param user: User object - could be used to configure on a per-user basis.148            Note that this may not be set on initial wan-signin.149        :param usage: List of  "first", "secondary" (webauthn is being used as a second150            factor for authentication). Note that in the ``verify``/``reauthentication``151            case this list is derived from :py:data:`SECURITY_WAN_ALLOW_AS_VERIFY`152 153        """154        if "secondary" in usage:155            return UserVerificationRequirement.DISCOURAGED156        if current_app.config.get("SECURITY_WAN_ALLOW_AS_MULTI_FACTOR"):157            return UserVerificationRequirement.PREFERRED158        return UserVerificationRequirement.PREFERRED159 
codekingpro/portable-devtools · Team Ai