
    k7i:                         S SK r S SKJr  S SKJr  SSKJr  SSKJr  SSKJr  SSKJr  SS	KJ	r	  SS
KJ
r
  SSKJr  \ R                  " \5      rSr " S S\\	5      rg)    N)	JoseError)jwt   )	BaseGrant)InvalidClientError)InvalidGrantError)InvalidRequestError)TokenEndpointMixin)UnauthorizedClientError   sign_jwt_bearer_assertionz+urn:ietf:params:oauth:grant-type:jwt-bearerc                       \ rS rSr\rSS0SS0SS0S.rSr\    SS j5       r	S r
S	 rS
 rS rS rS rS rS rSrg)JWTBearerGrant   	essentialT)issaudexp<   Nc           	           [        XX#XEU40 UD6$ )Nr   )keyissueraudiencesubject	issued_at
expires_atclaimskwargss           [/home/james-whalen/.local/lib/python3.13/site-packages/authlib/oauth2/rfc7523/jwt_bearer.pysignJWTBearerGrant.sign!   s"     )I6
MS
 	
    c                     [         R                  " XR                  U R                  S9nUR	                  U R
                  S9  U$ ! [         a/  n[        R                  SU5        [        UR                  S9UeSnAff = f)zExtract JWT payload claims from request "assertion", per
`Section 3.1`_.

:param assertion: assertion string value in the request
:return: JWTClaims
:raise: InvalidGrantError

.. _`Section 3.1`: https://tools.ietf.org/html/rfc7523#section-3.1
)claims_options)leewayzAssertion Error: %rdescriptionN)r   decoderesolve_public_keyCLAIMS_OPTIONSvalidateLEEWAYr   logdebugr   r(   )self	assertionr   es       r    process_assertion_claims'JWTBearerGrant.process_assertion_claims0   sv    	FZZ224CVCVF OO4;;O/   	FII+Q/#>AE	Fs   AA 
A?*A::A?c                 N    U R                  US   5      nU R                  X1U5      $ )Nr   )resolve_issuer_clientresolve_client_key)r0   headerspayloadclients       r    r*   !JWTBearerGrant.resolve_public_keyD   s)    ++GEN;&&v@@r#   c                    U R                   R                  R                  S5      nU(       d  [        S5      eU R	                  U5      nU R                  US   5      n[        R                  SU5        UR                  U R                  5      (       d  [        SU R                   S35      eX0R                   l        U R                  5         UR                  S5      nU(       ag  U R                  U5      nU(       d	  [        SS	9e[        R                  S
X55        U R                  X55      (       d	  [!        SS	9eXPR                   l        gg)aI  The client makes a request to the token endpoint by sending the
following parameters using the "application/x-www-form-urlencoded"
format per `Section 2.1`_:

grant_type
     REQUIRED.  Value MUST be set to
     "urn:ietf:params:oauth:grant-type:jwt-bearer".

assertion
     REQUIRED.  Value MUST contain a single JWT.

scope
    OPTIONAL.

The following example demonstrates an access token request with a JWT
as an authorization grant:

.. code-block:: http

    POST /token.oauth2 HTTP/1.1
    Host: as.example.com
    Content-Type: application/x-www-form-urlencoded

    grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer
    &assertion=eyJhbGciOiJFUzI1NiIsImtpZCI6IjE2In0.
    eyJpc3Mi[...omitted for brevity...].
    J9l-ZhwP[...omitted for brevity...]

.. _`Section 2.1`: https://tools.ietf.org/html/rfc7523#section-2.1
r1   zMissing 'assertion' in requestr   zValidate token request of %sz0The client is not authorized to use 'grant_type='subz Invalid 'sub' value in assertionr'   z'Check client(%s) permission to User(%s)z,Client has no permission to access user dataN)requestformgetr	   r3   r6   r.   r/   check_grant_type
GRANT_TYPEr   r:   validate_requested_scopeauthenticate_userr   has_granted_permissionr   user)r0   r1   r   r:   r   rG   s         r    validate_token_request%JWTBearerGrant.validate_token_requestH   s   > LL%%))+6	%&FGG..y9++F5M:		0&9&&t77)B4??BSSTU  %%%'**U#))'2D'4VWWII?N..v<<( N  !%LL r#   c                    U R                  U R                  R                  R                  U R                  R                  SS9n[
        R                  SXR                  R                  5        U R                  U5        SXR                  4$ )zJIf valid and authorized, the authorization server issues an access
token.
F)scoperG   include_refresh_tokenzIssue token %r to %r   )
generate_tokenr?   r9   rK   rG   r.   r/   r:   
save_tokenTOKEN_RESPONSE_HEADER)r0   tokens     r    create_token_response$JWTBearerGrant.create_token_response   st     ##,,&&,,"""' $ 

 			(%1D1DEE5555r#   c                     [        5       e)a  Fetch client via "iss" in assertion claims. Developers MUST
implement this method in subclass, e.g.::

    def resolve_issuer_client(self, issuer):
        return Client.query_by_iss(issuer)

:param issuer: "iss" value in assertion
:return: Client instance
NotImplementedError)r0   r   s     r    r6   $JWTBearerGrant.resolve_issuer_client        "##r#   c                     [        5       e)a  Resolve client key to decode assertion data. Developers MUST
implement this method in subclass. For instance, there is a
"jwks" column on client table, e.g.::

    def resolve_client_key(self, client, headers, payload):
        # from authlib.jose import JsonWebKey

        key_set = JsonWebKey.import_key_set(client.jwks)
        return key_set.find_by_kid(headers["kid"])

:param client: instance of OAuth client model
:param headers: headers part of the JWT
:param payload: payload part of the JWT
:return: ``authlib.jose.Key`` instance
rU   )r0   r:   r8   r9   s       r    r7   !JWTBearerGrant.resolve_client_key   s      "##r#   c                     [        5       e)zAuthenticate user with the given assertion claims. Developers MUST
implement it in subclass, e.g.::

    def authenticate_user(self, subject):
        return User.get_by_sub(subject)

:param subject: "sub" value in claims
:return: User instance
rU   )r0   r   s     r    rE    JWTBearerGrant.authenticate_user   rX   r#   c                     [        5       e)av  Check if the client has permission to access the given user's resource.
Developers MUST implement it in subclass, e.g.::

    def has_granted_permission(self, client, user):
        permission = ClientUserGrant.query(client=client, user=user)
        return permission.granted

:param client: instance of OAuth client model
:param user: instance of User model
:return: bool
rU   )r0   r:   rG   s      r    rF   %JWTBearerGrant.has_granted_permission   s     "##r#    )NNNN)__name__
__module____qualname____firstlineno__JWT_BEARER_GRANT_TYPErC   r+   r-   staticmethodr!   r3   r*   rH   rR   r6   r7   rE   rF   __static_attributes__r_   r#   r    r   r      sy    &J
 T"T"T"N F
 
 
(A:%x6
$$$
$$r#   r   )loggingauthlib.joser   r   rfc6749r   r   r   r	   r
   r   r1   r   	getLoggerr`   r.   rd   r   r_   r#   r    <module>rk      sJ     "   ( ' ) ( - 0!E u$Y 2 u$r#   