
    Ld,                     h    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e          Zd ZdS )	   )ClientAuthentication)OAuth2RequestJsonRequest)OAuth2ErrorInvalidScopeErrorUnsupportedResponseTypeErrorUnsupportedGrantTypeError)scope_to_listc                       e Zd ZdZddZd Zd Z	 	 ddZd Zdd
Z	d Z
d Zd ZdefdZdefdZd ZddZddZd Zd ZddZd ZddZddZddZd ZdS ) AuthorizationServerzAuthorization server that handles Authorization Endpoint and Token
    Endpoint.

    :param scopes_supported: A list of supported scopes by this authorization server.
    Nc                 Z    || _         i | _        d | _        g | _        g | _        i | _        d S N)scopes_supported_token_generators_client_auth_authorization_grants_token_grants
_endpoints)selfr   s     QF:\djangOuth\env\Lib\site-packages\authlib/oauth2/rfc6749/authorization_server.py__init__zAuthorizationServer.__init__   s5     0!# %'"    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_ids     r   query_clientz AuthorizationServer.query_client   s    
 "###r   c                     t                      )z:Define function to save the generated token into database.r   )r   tokenrequests      r   
save_tokenzAuthorizationServer.save_token!       !###r   Tc                     | j                             |          }|s| j                             d          }|st          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*   funcs           r   generate_tokenz"AuthorizationServer.generate_token%   s|     %))*55 	9)--i88D 	@>???t!&t5!9NP P P 	Pr   c                     || 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-   s      r   register_token_generatorz,AuthorizationServer.register_token_generator=   s    . .2z***r   r   c                 ~    | j          | j        rt          | j                  | _         |                      |||          S )zAuthenticate client via HTTP request information with the given
        methods, such as ``client_secret_basic``, ``client_secret_post``.
        )r   r   r   )r   r    methodsendpoints       r   authenticate_clientz'AuthorizationServer.authenticate_clientV   s@     $):$ 4T5F G GD  '8<<<r   c                     | j          | 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-   s      r   register_client_auth_methodz/AuthorizationServer.register_client_auth_method^   sG    , $):$ 4T5F G GD""6400000r   c                     dS )zFReturn a URI for the given error, framework may implement this method.N r   r    errors      r   get_error_uriz!AuthorizationServer.get_error_uriy   s    tr   c                     t                      )z]Framework integration can re-implement this method to support
        signal system.
        r   )r   nameargskwargss       r   send_signalzAuthorizationServer.send_signal}   s     "###r   returnc                     t                      )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    s     r   create_oauth2_requestz)AuthorizationServer.create_oauth2_request        "###r   c                     t                      )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   rE   s     r   create_json_requestz'AuthorizationServer.create_json_request   rG   r   c                     t                      )z=Return HTTP response. Framework MUST implement this function.r   )r   statusbodyheaderss       r   handle_responsez#AuthorizationServer.handle_response   r"   r   c                     |rZ| j         rUt          t          |                    }t          | j                                       |          st	          |          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(   rP   scopess       r   validate_requested_scopez,AuthorizationServer.validate_requested_scope   s{      	5T* 	5u--..Ft,--88@@ 5'e4444	5 	5 	5 	55 5r   c                     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
extensionss      r   register_grantz"AuthorizationServer.register_grant   ss     9<== 	G&--y*.EFFF9455 	?%%y*&=>>>>>	? 	?r   c                 6     ||           | j         |j        <   dS )zAdd extra endpoint to authorization server. e.g.
        RevocationEndpoint::

            authorization_server.register_endpoint(RevocationEndpoint)

        :param endpoint_cls: A endpoint class
        N)r   ENDPOINT_NAME)r   endpoint_clss     r   register_endpointz%AuthorizationServer.register_endpoint   s$     7Cl46H6H2333r   c                     | j         D ].\  }}|                    |          rt          ||||           c S /t          |j                  )zFind the authorization grant for current request.

        :param request: OAuth2Request instance.
        :return: grant instance
        )r   rV   _create_grantr   response_typer   r    rZ   r[   s       r   get_authorization_grantz+AuthorizationServer.get_authorization_grant   se     (,'A 	K 	K#Y
55g>> K$Y
GTJJJJJK*7+@AAAr   c                     |                      |          }||_        |                     |          }|                                 |S )zValidate current HTTP request for authorization page. This page
        is designed for resource owner to grant or deny the authorization.
        )rF   r'   re   validate_consent_request)r   r    end_usergrants       r   get_consent_grantz%AuthorizationServer.get_consent_grant   sH     ,,W55,,W55&&(((r   c                     | j         D ].\  }}|                    |          rt          ||||           c S /t          |j                  )zFind the token grant for current request.

        :param request: OAuth2Request instance.
        :return: grant instance
        )r   rW   rb   r	   r%   rd   s       r   get_token_grantz#AuthorizationServer.get_token_grant   se     (,'9 	K 	K#Y
--g66 K$Y
GTJJJJJK'(:;;;r   c                     || j         vrt          d| d          | j         |         }|                    |          }	  | j         ||           S # t          $ r }|                     ||          cY d}~S d}~ww xY w)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_requestrN   r   handle_error_response)r   r?   r    r3   r<   s        r   create_endpoint_responsez,AuthorizationServer.create_endpoint_response   s     t&&@t@@@AAA?4(227;;	>'4''):):;; 	> 	> 	>--gu========	>s    A 
A=A82A=8A=c                 x   |                      |          }	 |                     |          }n-# t          $ r }|                     ||          cY d}~S d}~ww xY w	 |                                }|                    ||          } | j        | S # t          $ r }|                     ||          cY d}~S d}~ww xY 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)rF   re   r   ro   validate_authorization_requestcreate_authorization_responserN   r   )r   r    
grant_userri   r<   redirect_urir@   s          r   rs   z1AuthorizationServer.create_authorization_response   s     ,,W55	>0099EE+ 	> 	> 	>--gu========	>	> ??AAL66|ZPPD'4'.. 	> 	> 	>--gu========	>s8   - 
AAAA3B 
B9B4.B94B9c                 t   |                      |          }	 |                     |          }n-# t          $ r }|                     ||          cY d}~S d}~ww xY w	 |                                 |                                } | j        | S # t          $ r }|                     ||          cY d}~S d}~ww xY w)ziValidate token request and create token response.

        :param request: HTTP request instance
        N)rF   rl   r	   ro   validate_token_requestcreate_token_responserN   r   )r   r    ri   r<   r@   s        r   rx   z)AuthorizationServer.create_token_response  s    
 ,,W55	>((11EE( 	> 	> 	>--gu========	>	>((***..00D'4'.. 	> 	> 	>--gu========	>s8   - 
AAAA1B 
B7B2,B72B7c                 P     | j          ||                     ||                     S r   )rN   r=   r;   s      r   ro   z)AuthorizationServer.handle_error_response  s,    #t#UU4+=+=gu+M+M%N%NOOr   r   )NNNT)r   )NN)__name__
__module____qualname____doc__r   r   r!   r.   r0   r4   r8   r=   rB   r   rF   r   rI   rN   rT   r\   r`   re   rj   rl   rp   rs   rx   ro   r:   r   r   r   r      s        
   $ $ $$ $ $ CG>BP P P P02 2 22= = = =1 1 16  $ $ $$ $ $ $ $$k $ $ $ $$ $ $5 5 5 5? ? ? ?&I I I	B 	B 	B	 	 	 		< 	< 	<> > > >"> > > >*> > > >$P P P P Pr   r   c                 B     | ||          }|r|D ]} ||           |S r   r:   )rZ   r[   r    serverri   exts         r   rb   rb     s>    Igv&&E  	 	CCJJJJLr   N)r4   r   requestsr   r   errorsr   r   r   r	   utilr
   objectr   rb   r:   r   r   <module>r      s    5 5 5 5 5 5 0 0 0 0 0 0 0 0                  MP MP MP MP MP& MP MP MP`    r   