o
    Dfz.                     @   sf   d dl mZ ddl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 G dd dZd	d
 ZdS )    )ContinueIteration   )ClientAuthentication)OAuth2RequestJsonRequest)OAuth2ErrorInvalidScopeErrorUnsupportedResponseTypeErrorUnsupportedGrantTypeError)scope_to_listc                   @   s   e Zd ZdZd2ddZdd Zdd Z			d3d
dZdd Zd4ddZ	dd Z
dd Zdd ZdefddZdefddZdd Zd2ddZd2d d!Zd"d# Zd$d% Zd5d&d'Zd(d) Zd2d*d+Zd5d,d-Zd2d.d/Zd0d1 ZdS )6AuthorizationServerzAuthorization server that handles Authorization Endpoint and Token
    Endpoint.

    :param scopes_supported: A list of supported scopes by this authorization server.
    Nc                 C   s(   || _ i | _d | _g | _g | _i | _d S N)scopes_supported_token_generators_client_auth_authorization_grants_token_grants
_endpoints)selfr    r   d/home/ubuntu/webapp/venv/lib/python3.10/site-packages/authlib/oauth2/rfc6749/authorization_server.py__init__   s   
zAuthorizationServer.__init__c                 C      t  )zQuery OAuth client by client_id. The client model class MUST
        implement the methods described by
        :class:`~authlib.oauth2.rfc6749.ClientMixin`.
        NotImplementedError)r   	client_idr   r   r   query_client   s   z AuthorizationServer.query_clientc                 C   r   )z:Define function to save the generated token into database.r   )r   tokenrequestr   r   r   
save_token"      zAuthorizationServer.save_tokenTc                 C   s<   | j |}|s| j d}|std|||||||dS )a  Generate the token dict.

        :param grant_type: current requested grant_type.
        :param client: the client that making the request.
        :param user: current authorized user.
        :param expires_in: if provided, use this value as expires_in.
        :param scope: current requested scope.
        :param include_refresh_token: should refresh_token be included.
        :return: Token dict
        defaultzNo configured token generator)
grant_typeclientuserscope
expires_ininclude_refresh_token)r   getRuntimeError)r   r"   r#   r$   r%   r&   r'   funcr   r   r   generate_token&   s   z"AuthorizationServer.generate_tokenc                 C   s   || j |< dS )a  Register a function as token generator for the given ``grant_type``.
        Developers MUST register a default token generator with a special
        ``grant_type=default``::

            def generate_bearer_token(grant_type, client, user=None, scope=None,
                                      expires_in=None, include_refresh_token=True):
                token = {'token_type': 'Bearer', 'access_token': ...}
                if include_refresh_token:
                    token['refresh_token'] = ...
                ...
                return token

            authorization_server.register_token_generator('default', generate_bearer_token)

        If you register a generator for a certain grant type, that generator will only works
        for the given grant type::

            authorization_server.register_token_generator('client_credentials', generate_bearer_token)

        :param grant_type: string name of the grant type
        :param func: a function to generate token
        N)r   )r   r"   r*   r   r   r   register_token_generator>   s   z,AuthorizationServer.register_token_generatorr   c                 C   s*   | j du r| jrt| j| _ |  |||S )zAuthenticate client via HTTP request information with the given
        methods, such as ``client_secret_basic``, ``client_secret_post``.
        N)r   r   r   )r   r   methodsendpointr   r   r   authenticate_clientW   s   z'AuthorizationServer.authenticate_clientc                 C   s.   | j du r| jrt| j| _ | j || dS )af  Add more client auth method. The default methods are:

        * none: The client is a public client and does not have a client secret
        * client_secret_post: The client uses the HTTP POST parameters
        * client_secret_basic: The client uses HTTP Basic

        :param method: Name of the Auth method
        :param func: Function to authenticate the client

        The auth method accept two parameters: ``query_client`` and ``request``,
        an example for this method::

            def authenticate_client_via_custom(query_client, request):
                client_id = request.headers['X-Client-Id']
                client = query_client(client_id)
                do_some_validation(client)
                return client

            authorization_server.register_client_auth_method(
                'custom', authenticate_client_via_custom)
        N)r   r   r   register)r   methodr*   r   r   r   register_client_auth_method_   s   z/AuthorizationServer.register_client_auth_methodc                 C   s   dS )zFReturn a URI for the given error, framework may implement this method.Nr   r   r   errorr   r   r   get_error_uriz   s   z!AuthorizationServer.get_error_uric                 O   r   )z]Framework integration can re-implement this method to support
        signal system.
        r   )r   nameargskwargsr   r   r   send_signal~   s   zAuthorizationServer.send_signalreturnc                 C   r   )zThis method MUST be implemented in framework integrations. It is
        used to create an OAuth2Request instance.

        :param request: the "request" instance in framework
        :return: OAuth2Request instance
        r   r   r   r   r   r   create_oauth2_request      z)AuthorizationServer.create_oauth2_requestc                 C   r   )zThis method MUST be implemented in framework integrations. It is
        used to create an HttpRequest instance.

        :param request: the "request" instance in framework
        :return: HttpRequest instance
        r   r;   r   r   r   create_json_request   r=   z'AuthorizationServer.create_json_requestc                 C   r   )z=Return HTTP response. Framework MUST implement this function.r   )r   statusbodyheadersr   r   r   handle_response   r    z#AuthorizationServer.handle_responsec                 C   s<   |r| j rtt|}t| j |st|ddS dS dS )zValidate if requested scope is supported by Authorization Server.
        Developers CAN re-write this method to meet your needs.
        )stateN)r   setr   
issupersetr   )r   r%   rC   scopesr   r   r   validate_requested_scope   s   

z,AuthorizationServer.validate_requested_scopec                 C   s<   t |dr| j||f t |dr| j||f dS dS )a  Register a grant class into the endpoint registry. Developers
        can implement the grants in ``authlib.oauth2.rfc6749.grants`` and
        register with this method::

            class AuthorizationCodeGrant(grants.AuthorizationCodeGrant):
                def authenticate_user(self, credential):
                    # ...

            authorization_server.register_grant(AuthorizationCodeGrant)

        :param grant_cls: a grant class.
        :param extensions: extensions for the grant class.
        check_authorization_endpointcheck_token_endpointN)hasattrr   appendr   )r   	grant_cls
extensionsr   r   r   register_grant   s
   

z"AuthorizationServer.register_grantc                 C   s8   t |tr
|| }n| |_| j|jg }|| dS )zAdd extra endpoint to authorization server. e.g.
        RevocationEndpoint::

            authorization_server.register_endpoint(RevocationEndpoint)

        :param endpoint_cls: A endpoint class or instance.
        N)
isinstancetypeserverr   
setdefaultENDPOINT_NAMErK   )r   r.   	endpointsr   r   r   register_endpoint   s
   

z%AuthorizationServer.register_endpointc                 C   6   | j D ]\}}||rt||||   S qt|j)zFind the authorization grant for current request.

        :param request: OAuth2Request instance.
        :return: grant instance
        )r   rH   _create_grantr	   response_typer   r   rL   rM   r   r   r   get_authorization_grant   
   

z+AuthorizationServer.get_authorization_grantc                 C   s&   |  |}||_| |}|  |S )zValidate current HTTP request for authorization page. This page
        is designed for resource owner to grant or deny the authorization.
        )r<   r$   rZ   validate_consent_request)r   r   end_usergrantr   r   r   get_consent_grant   s
   

z%AuthorizationServer.get_consent_grantc                 C   rV   )zFind the token grant for current request.

        :param request: OAuth2Request instance.
        :return: grant instance
        )r   rI   rW   r
   r"   rY   r   r   r   get_token_grant   r[   z#AuthorizationServer.get_token_grantc                 C   s   || j vrtd| d| j | }|D ]3}||}z
| j|| W   S  ty.   Y q tyG } z| ||W  Y d}~  S d}~ww dS )zValidate endpoint request and create endpoint response.

        :param name: Endpoint name
        :param request: HTTP request instance.
        :return: Response
        zThere is no "z" endpoint.N)r   r)   create_endpoint_requestrB   r   r   handle_error_response)r   r6   r   rT   r.   r4   r   r   r   create_endpoint_response   s   


z,AuthorizationServer.create_endpoint_responsec              
   C   s   t |ts
| |}z| |}W n ty) } z| ||W  Y d}~S d}~ww z| }|||}| j| W S  t	yR } z| ||W  Y d}~S d}~ww )zValidate authorization request and create authorization response.

        :param request: HTTP request instance.
        :param grant_user: if granted, it is resource owner. If denied,
            it is None.
        :returns: Response
        N)
rO   r   r<   rZ   r	   rb   validate_authorization_requestcreate_authorization_responserB   r   )r   r   
grant_userr^   r4   redirect_urir7   r   r   r   re      s    

z1AuthorizationServer.create_authorization_responsec              
   C   s   |  |}z| |}W n ty$ } z| ||W  Y d}~S d}~ww z|  | }| j| W S  tyK } z| ||W  Y d}~S d}~ww )ziValidate token request and create token response.

        :param request: HTTP request instance
        N)r<   r`   r
   rb   validate_token_requestcreate_token_responserB   r   )r   r   r^   r4   r7   r   r   r   ri     s   
z)AuthorizationServer.create_token_responsec                 C   s   | j || || S r   )rB   r5   r3   r   r   r   rb   $  s   z)AuthorizationServer.handle_error_responser   )NNNT)r   )NN)__name__
__module____qualname____doc__r   r   r   r+   r,   r/   r2   r5   r9   r   r<   r   r>   rB   rG   rN   rU   rZ   r_   r`   rc   re   ri   rb   r   r   r   r   r      s4    


		

	



r   c                 C   s$   | ||}|r|D ]}|| q	|S r   r   )rL   rM   r   rQ   r^   extr   r   r   rW   (  s
   

rW   N)authlib.common.errorsr   r/   r   requestsr   r   errorsr   r   r	   r
   utilr   r   rW   r   r   r   r   <module>   s      