o
    Df                     @   sl   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 dd	lmZ G d
d de
ZdS )a   
    authlib.oauth2.rfc9068.token_validator
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Implementation of Validating JWT Access Tokens per `Section 4`_.

    .. _`Section 7`: https://www.rfc-editor.org/rfc/rfc9068.html#name-validating-jwt-access-token
    )jwt)DecodeError)	JoseError)InsufficientScopeError)InvalidTokenError)BearerTokenValidator   )JWTAccessTokenClaimsc                       sN   e Zd ZdZ fddZdd Zdddefd	d
Zdd Z	dddZ	  Z
S )JWTBearerTokenValidatora"  JWTBearerTokenValidator can protect your resource server endpoints.

    :param issuer: The issuer from which tokens will be accepted.
    :param resource_server: An identifier for the current resource server,
        which must appear in the JWT ``aud`` claim.

    Developers needs to implement the missing methods::

        class MyJWTBearerTokenValidator(JWTBearerTokenValidator):
            def get_jwks(self):
                ...

        require_oauth = ResourceProtector()
        require_oauth.register_token_validator(
            MyJWTBearerTokenValidator(
                issuer='https://authorization-server.example.org',
                resource_server='https://resource-server.example.org',
            )
        )

    You can then protect resources depending on the JWT `scope`, `groups`,
    `roles` or `entitlements` claims::

        @require_oauth(
            scope='profile',
            groups='admins',
            roles='student',
            entitlements='captain',
        )
        def resource_endpoint():
            ...
    c                    s"   || _ || _t j|i | d S N)issuerresource_serversuper__init__)selfr   r   argskwargs	__class__ _/home/ubuntu/webapp/venv/lib/python3.10/site-packages/authlib/oauth2/rfc9068/token_validator.pyr   4   s   z JWTBearerTokenValidator.__init__c                 C   s   t  )az  Return the JWKs that will be used to check the JWT access token signature.
        Developers MUST re-implement this method. Typically the JWKs are statically
        stored in the resource server configuration, or dynamically downloaded and
        cached using :ref:`specs/rfc8414`::

            def get_jwks(self):
                if 'jwks' in cache:
                    return cache.get('jwks')

                server_metadata = get_server_metadata(self.issuer)
                jwks_uri = server_metadata.get('jwks_uri')
                cache['jwks'] = requests.get(jwks_uri).json()
                return cache['jwks']
        )NotImplementedError)r   r   r   r   get_jwks9   s   z JWTBearerTokenValidator.get_jwksissstrreturnc                 C   s
   || j kS r   )r   )r   claimsr   r   r   r   validate_issJ   s   
z$JWTBearerTokenValidator.validate_issc                 C   s   d| j dddid| jdddiddiddiddiddiddiddiddiddiddiddid}|  }z
tj||t|dW S  tyN   t| j| j	dw )	 T)	essentialvalidater   )r   valueF)r   expaudsub	client_idiatjti	auth_timeacramrscopegroupsrolesentitlements)key
claims_clsclaims_optionsrealmextra_attributes)
r   r   r   r   decoder	   r   r   r3   r4   )r   token_stringr1   jwksr   r   r   authenticate_tokenP   s8   

z*JWTBearerTokenValidator.authenticate_tokenNc              
   C   s   z|   W n ty } z	t| j| jd|d}~ww | |dg |r)t | |d|r5t | |d|rAt | |d|rMt dS )r   r2   Nr+   r,   r-   r.   )r    r   r   r3   r4   scope_insufficientgetr   )r   tokenscopesrequestr,   r-   r.   excr   r   r   validate_token|   s&   z&JWTBearerTokenValidator.validate_token)NNN)__name__
__module____qualname____doc__r   r   boolr   r8   r?   __classcell__r   r   r   r   r
      s    !-r
   N)rC   authlib.joser   authlib.jose.errorsr   r   authlib.oauth2.rfc6750.errorsr   r    authlib.oauth2.rfc6750.validatorr   r   r	   r
   r   r   r   r   <module>   s    