
    ([f                         d dl Z d dlmZmZ ddlmZmZ ddlmZmZm	Z	m
Z
 ddlmZ  e j        e          ZdZ G d	 d
ee          ZdS )    N)jwt	JoseError   )	BaseGrantTokenEndpointMixin)UnauthorizedClientErrorInvalidRequestErrorInvalidGrantErrorInvalidClientError   sign_jwt_bearer_assertionz+urn:ietf:params:oauth:grant-type:jwt-bearerc                   v    e Zd ZeZddiddiddidZe	 	 dd            Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd ZdS )JWTBearerGrant	essentialT)issaudexpNc           	      (    t          | ||||||fi |S )Nr   )keyissueraudiencesubject	issued_at
expires_atclaimskwargss           U/var/www/piapp/venv/lib/python3.11/site-packages/authlib/oauth2/rfc7523/jwt_bearer.pysignzJWTBearerGrant.sign   s3     )7I* *"(* * 	*    c                     	 t          j        || j        | j                  }|                                 nB# t
          $ r5}t                              d|           t          |j	                  d}~ww xY w|S )a#  Extract 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_optionszAssertion Error: %rdescriptionN)
r   decoderesolve_public_keyCLAIMS_OPTIONSvalidater   logdebugr
   r$   )self	assertionr   es       r   process_assertion_claimsz'JWTBearerGrant.process_assertion_claims"   s    	?Z42#24 4 4F OO 	? 	? 	?II+Q///#>>>>	? s   58 
A70A22A7c                 f    |                      |d                   }|                     |||          S )Nr   )resolve_issuer_clientresolve_client_key)r+   headerspayloadclients       r   r&   z!JWTBearerGrant.resolve_public_key6   s1    ++GEN;;&&vw@@@r    c                    | j         j                            d          }|st          d          |                     |          }|                     |d                   }t                              d|           |                    | j	                  st                      || j         _        |                                  |                    d          }|rw|                     |          }|st          d          t                              d||           |                     ||          st!          d	          || j         _        d
S d
S )a  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
        r,   zMissing "assertion" in requestr   zValidate token request of %s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	   r.   r0   r)   r*   check_grant_type
GRANT_TYPEr   r4   validate_requested_scopeauthenticate_userr
   has_granted_permissionr   user)r+   r,   r   r4   r   r?   s         r   validate_token_requestz%JWTBearerGrant.validate_token_request:   sb   > L%))+66	 	H%&FGGG..y99++F5M::		0&999&&t77 	,)+++$%%'''**U## 		%))'22D X'4VWWWWII?NNN..vt<< P( NP P P P $DL		% 		%r    c                     |                      | j        j        | j        j        d          }t                              d|| j        j                   |                     |           d|| j        fS )zZIf valid and authorized, the authorization server issues an access
        token.
        F)scoper?   include_refresh_tokenzIssue token %r to %r   )	generate_tokenr7   rB   r?   r)   r*   r4   
save_tokenTOKEN_RESPONSE_HEADER)r+   tokens     r   create_token_responsez$JWTBearerGrant.create_token_responses   sq     ##,$""' $ 
 

 			(%1DEEEE4555r    c                     t                      )a1  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)r+   r   s     r   r0   z$JWTBearerGrant.resolve_issuer_client        "###r    c                     t                      )au  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
        rK   )r+   r4   r2   r3   s       r   r1   z!JWTBearerGrant.resolve_client_key   s      "###r    c                     t                      )a%  Authenticate 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
        rK   )r+   r   s     r   r=   z JWTBearerGrant.authenticate_user   rM   r    c                     t                      )a  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
        rK   )r+   r4   r?   s      r   r>   z%JWTBearerGrant.has_granted_permission   s     "###r    )NNNN)__name__
__module____qualname__JWT_BEARER_GRANT_TYPEr;   r'   staticmethodr   r.   r&   r@   rI   r0   r1   r=   r>    r    r   r   r      s        &J
 T"T"T" N ,059* * * \*  (A A A7% 7% 7%r6 6 6
$ 
$ 
$$ $ $$
$ 
$ 
$$ $ $ $ $r    r   )loggingauthlib.joser   r   rfc6749r   r   r   r	   r
   r   r,   r   	getLoggerrQ   r)   rT   r   rV   r    r   <module>r[      s     ' ' ' ' ' ' ' ' 3 3 3 3 3 3 3 3            1 0 0 0 0 0g!!E f$ f$ f$ f$ f$Y 2 f$ f$ f$ f$ f$r    