o
    bU                     @   s   d dl Z d dlZd dlZd dlmZ d dlmZ d dlmZm	Z	 ddl
mZmZ ddlmZ dd	lmZ dd
lmZmZmZ G dd deZdS )    N)default_json_headersgenerate_token)JsonWebToken	JoseError   )AccessDeniedErrorInvalidRequestError)scope_to_list   )ClientMetadataClaims)InvalidClientMetadataError UnapprovedSoftwareStatementErrorInvalidSoftwareStatementErrorc                   @   s   e Zd ZdZdZeZdZdd Zdd Z	dd	 Z
d
d Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZdS ) ClientRegistrationEndpointzThe client registration endpoint is an OAuth 2.0 endpoint designed to
    allow a client to be registered with the authorization server.
    Zclient_registrationNc                 C   s
   || _ d S N)server)selfr    r   ^/var/www/secure340b-portal/env/lib/python3.10/site-packages/authlib/oauth2/rfc7591/endpoint.py__init__      
z#ClientRegistrationEndpoint.__init__c                 C   s
   |  |S r   )create_registration_responser   requestr   r   r   __call__!   r   z#ClientRegistrationEndpoint.__call__c                 C   sv   |  |}|s
t ||_| |}|  }i }|| || | |||}| ||}|r6|| d|tfS )N   )	authenticate_tokenr   Z
credentialextract_client_metadatagenerate_client_infoupdatesave_client!generate_client_registration_infor   )r   r   tokenclient_metadataclient_infobodyclientZregistration_infor   r   r   r   $   s   





z7ClientRegistrationEndpoint.create_registration_responsec              
   C   s   |j st |j  }|dd }|r!| jr!| ||}|| |  }| |i || j	j
}z	|  W | S  tyI } zt|jd }~ww )Nsoftware_statement)datar	   copypop'software_statement_alg_values_supportedextract_software_statementr    get_claims_optionsclaims_classr   metadatavalidater   r   descriptionZget_registered_claims)r   r   Z	json_datar(   r)   optionsclaimserrorr   r   r   r   6   s    




z2ClientRegistrationEndpoint.extract_client_metadatac                 C   sF   |  |}|s
t zt| j}|||}|W S  ty"   t w r   )resolve_public_keyr   r   r,   decoder   r   )r   r(   r   keyZjwtr4   r   r   r   r-   H   s   

z5ClientRegistrationEndpoint.extract_software_statementc                    s   | j j}|si S |d|d|d |d}i }dur2tfdd}d|i|d	< durFtfd
d}d|i|d<  durZt   fdd}d|i|d< |durdd|i|d< |S )zFGenerate claims options validation from Authorization Server metadata.scopes_supportedresponse_types_supportedgrant_types_supportedZ%token_endpoint_auth_methods_supportedNc                    s   |sdS t t|} |S )NT)setr
   
issuperset)r4   valueZscopes)r9   r   r   _validate_scopec   s   
zFClientRegistrationEndpoint.get_claims_options.<locals>._validate_scoper1   scopec                         t|S r   r=   r<   r4   r>   )r:   r   r   _validate_response_typesn      zOClientRegistrationEndpoint.get_claims_options.<locals>._validate_response_typesZresponse_typesc                    rA   r   rB   rC   )r;   r   r   _validate_grant_typesv   rE   zLClientRegistrationEndpoint.get_claims_options.<locals>._validate_grant_typesZgrant_typesvaluesZtoken_endpoint_auth_method)r   r0   getr<   )r   r0   Zauth_methods_supportedr3   r?   rD   rF   r   )r;   r:   r9   r   r.   U   s.   



z-ClientRegistrationEndpoint.get_claims_optionsc                 C   s0   |   }|  }tt }d}t||||dS )Nr   )	client_idclient_secretclient_id_issued_atclient_secret_expires_at)generate_client_idgenerate_client_secretinttimedict)r   rI   rJ   rK   rL   r   r   r   r      s   z/ClientRegistrationEndpoint.generate_client_infoc                 C   s   dS )zGenerate ```registration_client_uri`` and ``registration_access_token``
        for RFC7592. This method returns ``None`` by default. Developers MAY rewrite
        this method to return registration information.Nr   )r   r'   r   r   r   r   r"      s   z<ClientRegistrationEndpoint.generate_client_registration_infoc                 C   s   | j |S r   )r   Zcreate_json_requestr   r   r   r   create_endpoint_request   s   z2ClientRegistrationEndpoint.create_endpoint_requestc                 C   s   t dS )zGenerate ``client_id`` value. Developers MAY rewrite this method
        to use their own way to generate ``client_id``.
        *   r   r   r   r   r   rM      s   z-ClientRegistrationEndpoint.generate_client_idc                 C   s   t tddS )zGenerate ``client_secret`` value. Developers MAY rewrite this method
        to use their own way to generate ``client_secret``.
           ascii)binasciihexlifyosurandomr7   rT   r   r   r   rN      s   z1ClientRegistrationEndpoint.generate_client_secretc                 C      t  )aL  Authenticate current credential who is requesting to register a client.
        Developers MUST implement this method in subclass::

            def authenticate_token(self, request):
                auth = request.headers.get('Authorization')
                return get_token_by_auth(auth)

        :return: token instance
        NotImplementedErrorr   r   r   r   r         
z-ClientRegistrationEndpoint.authenticate_tokenc                 C   r[   )aI  Resolve a public key for decoding ``software_statement``. If
        ``enable_software_statement=True``, developers MUST implement this
        method in subclass::

            def resolve_public_key(self, request):
                return get_public_key_from_user(request.credential)

        :return: JWK or Key string
        r\   r   r   r   r   r6      r^   z-ClientRegistrationEndpoint.resolve_public_keyc                 C   r[   )a  Save client into database. Developers MUST implement this method
        in subclass::

            def save_client(self, client_info, client_metadata, request):
                client = OAuthClient(
                    client_id=client_info['client_id'],
                    client_secret=client_info['client_secret'],
                    ...
                )
                client.save()
                return client
        r\   )r   r%   r$   r   r   r   r   r!      s   z&ClientRegistrationEndpoint.save_client)__name__
__module____qualname____doc__ZENDPOINT_NAMEr   r/   r,   r   r   r   r   r-   r.   r   r"   rR   rM   rN   r   r6   r!   r   r   r   r   r      s&    +r   )rY   rP   rW   Zauthlib.constsr   Zauthlib.common.securityr   Zauthlib.joser   r   Zrfc6749r   r	   Zrfc6749.utilr
   r4   r   errorsr   r   r   objectr   r   r   r   r   <module>   s    