o
    ^[2h)                     @   s   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 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ZdS )    )jwt)	JoseError   )AuthorizationServer)ClientMixin)InvalidRequestError)_validate_client)BasicOAuth2Payload)OAuth2Request   )InvalidRequestObjectError)InvalidRequestUriError)RequestNotSupportedError)RequestUriNotSupportedErrorc                   @   s   e Zd ZdZd dedefddZdefdd	Zded
efddZ	ded
ede
defddZded
edefddZde
defddZdefddZde
fddZdefddZde
defddZdS )!JWTAuthenticationRequesta  Authorization server extension implementing the support
    for JWT secured authentication request, as defined in :rfc:`RFC9101 <9101>`.

    :param support_request: Whether to enable support for the ``request`` parameter.
    :param support_request_uri: Whether to enable support for the ``request_uri`` parameter.

    This extension is intended to be inherited and registered into the authorization server::

        class JWTAuthenticationRequest(rfc9101.JWTAuthenticationRequest):
            def resolve_client_public_key(self, client: ClientMixin):
                return get_jwks_for_client(client)

            def get_request_object(self, request_uri: str):
                try:
                    return requests.get(request_uri).text
                except requests.Exception:
                    return None

            def get_server_metadata(self):
                return {
                    "issuer": ...,
                    "authorization_endpoint": ...,
                    "require_signed_request_object": ...,
                }

            def get_client_require_signed_request_object(self, client: ClientMixin):
                return client.require_signed_request_object


        authorization_server.register_extension(JWTAuthenticationRequest())
    Tsupport_requestsupport_request_uric                 C   s   || _ || _d S N)r   r   )selfr   r    r   |/home/skpark/git/infrasmart_work/infrasmart/venv/lib/python3.10/site-packages/authlib/oauth2/rfc9101/authorization_server.py__init__1   s   
z!JWTAuthenticationRequest.__init__authorization_serverc                 C   s   | d| j d S )Nbefore_get_authorization_grant)register_hookparse_authorization_request)r   r   r   r   r   __call__5   s   z!JWTAuthenticationRequest.__call__requestc                 C   sN   t |j|jj}| |||sd S | ||}| |||}t|}||_d S r   )r   query_clientpayload	client_id"_shoud_proceed_with_request_object_get_raw_request_object_decode_request_objectr	   )r   r   r   clientraw_request_objectrequest_objectr   r   r   r   r   :   s   

z4JWTAuthenticationRequest.parse_authorization_requestr$   returnc                 C   s   d|j jv rd|j jv rtd|j jdd|j jv r&| js$t|j jddS d|j jv r8| js6t|j jddS | |rEtd|j jd| 	 }|rY|
ddrYtd	|j jddS )
Nr   request_urizBThe 'request' and 'request_uri' parameters are mutually exclusive.stateTGAuthorization requests for this client must use signed request objects.require_signed_request_objectFGAuthorization requests for this server must use signed request objects.)r   datar   r*   r   r   r   r   (get_client_require_signed_request_objectget_server_metadataget)r   r   r   r$   metadatar   r   r   r!   L   s2   
z;JWTAuthenticationRequest._shoud_proceed_with_request_objectc                 C   sD   d|j jv r| |j jd }|st|j jd|S |j jd }|S )Nr(   r)   r   )r   r.   get_request_objectr   r*   )r   r   r   r%   r   r   r   r"   w   s   
z0JWTAuthenticationRequest._get_raw_request_objectr%   c              
   C   s   |  |}zt||}|  W n ty* } zt|jptj|jjd|d }~ww | 	|r?|j
d dkr?td|jjd|  }|rZ|ddrZ|j
d dkrZtd|jjd|d	 |jjkrjtd
|jjdd|v srd|v rztd|jjd|S )N)descriptionr*   algnoner+   r)   r,   Fr-   r    z\The 'client_id' claim from the request parameters and the request object claims don't match.r   r(   zVThe 'request' and 'request_uri' parameters must not be included in the request object.)resolve_client_public_keyr   decodevalidater   r   r4   r   r*   r/   headerr   r0   r1   r    )r   r   r$   r%   jwksr&   errorr2   r   r   r   r#      sR   



	z/JWTAuthenticationRequest._decode_request_objectr(   c                 C      t  )a  Download the request object at ``request_uri``.

        This method must be implemented if the ``request_uri`` parameter is supported::

            class JWTAuthenticationRequest(rfc9101.JWTAuthenticationRequest):
                def get_request_object(self, request_uri: str):
                    try:
                        return requests.get(request_uri).text
                    except requests.Exception:
                        return None
        NotImplementedError)r   r(   r   r   r   r3         z+JWTAuthenticationRequest.get_request_objectc                 C   r=   )a   Resolve the client public key for verifying the JWT signature.
        A client may have many public keys, in this case, we can retrieve it
        via ``kid`` value in headers. Developers MUST implement this method::

            class JWTAuthenticationRequest(rfc9101.JWTAuthenticationRequest):
                def resolve_client_public_key(self, client):
                    if client.jwks_uri:
                        return requests.get(client.jwks_uri).json

                    return client.jwks
        r>   r   r$   r   r   r   resolve_client_public_keys   r@   z3JWTAuthenticationRequest.resolve_client_public_keysc                 C   s   i S )a  Return server metadata which includes supported grant types,
        response types and etc.

        When the ``require_signed_request_object`` claim is :data:`True`,
        all clients require that authorization requests
        use request objects, and an error will be returned when the authorization
        request payload is passed in the request body or query string::

            class JWTAuthenticationRequest(rfc9101.JWTAuthenticationRequest):
                def get_server_metadata(self):
                    return {
                        "issuer": ...,
                        "authorization_endpoint": ...,
                        "require_signed_request_object": ...,
                    }

        r   )r   r   r   r   r0      s   z,JWTAuthenticationRequest.get_server_metadatac                 C   s   dS )aI  Return the 'require_signed_request_object' client metadata.

        When :data:`True`, the client requires that authorization requests
        use request objects, and an error will be returned when the authorization
        request payload is passed in the request body or query string::

           class JWTAuthenticationRequest(rfc9101.JWTAuthenticationRequest):
               def get_client_require_signed_request_object(self, client):
                   return client.require_signed_request_object

        If not implemented, the value is considered as :data:`False`.
        Fr   rA   r   r   r   r/      s   zAJWTAuthenticationRequest.get_client_require_signed_request_objectN)TT)__name__
__module____qualname____doc__boolr   r   r   r
   r   r   r!   strr"   r#   r3   rB   dictr0   r/   r   r   r   r   r      sD     

+

<r   N)authlib.joser   authlib.jose.errorsr   rfc6749r   r   r   rfc6749.authenticate_clientr   rfc6749.requestsr	   r
   errorsr   r   r   r   r   r   r   r   r   <module>   s    