o
    DfD                     @   s   d dl mZ d dlmZ ddlmZmZmZmZ ddl	m
Z
 ddlmZ ddlmZmZ ddlmZ d	d
dZG dd dZdd ZdS )    )generate_token)
url_decode   )prepare_grant_uriprepare_token_request!parse_authorization_code_responseparse_implicit_response)prepare_revoke_token_request)create_s256_code_challenge)	TokenAuth
ClientAuth)OAuth2Errorzapplication/jsonz/application/x-www-form-urlencoded;charset=UTF-8)AcceptzContent-Typec                   @   s
  e Zd ZdZeZeZeZ	dZ
g Z					d.ddZdd Zd	d
 Zedd Zejdd Zd/ddZ		d0ddZd1ddZ		d2ddZdd Z		d3ddZ		d3ddZdd Zd d! Z		d4d"d#Z		d2d$d%Z		d3d&d'Zd(d) Zd*d+ Zd5d,d-Z dS )6OAuth2ClientaZ  Construct a new OAuth 2 protocol client.

    :param session: Requests session object to communicate with
                    authorization server.
    :param client_id: Client ID, which you get from client registration.
    :param client_secret: Client Secret, which you get from registration.
    :param token_endpoint_auth_method: client authentication method for
        token endpoint.
    :param revocation_endpoint_auth_method: client authentication method for
        revocation endpoint.
    :param scope: Scope that you needed to access user resources.
    :param state: Shared secret to prevent CSRF attack.
    :param redirect_uri: Redirect URI you registered as callback.
    :param code_challenge_method: PKCE method name, only S256 is supported.
    :param token: A dict of token attributes such as ``access_token``,
        ``token_type`` and ``expires_at``.
    :param token_placement: The place to put token in HTTP request. Available
        values: "header", "body", "uri".
    :param update_token: A function for you to update token. It accept a
        :class:`OAuth2Token` as parameter.
    )response_modenonceprompt
login_hintNheaderc                 K   s   || _ || _|| _|| _|d u r|rd}nd}|| _|d u r%|r#d}nd}|| _|| _|| _|	| _| 	|
|| | _
|| _|dd }|rHtd|| _t t t t t d| _i | _d S )Nclient_secret_basicnonetoken_updaterz<update token has been redesigned, checkout the documentation)access_token_responserefresh_token_requestrefresh_token_responserevoke_token_requestintrospect_token_request)session	client_idclient_secretstatetoken_endpoint_auth_methodrevocation_endpoint_auth_methodscoperedirect_uricode_challenge_methodtoken_auth_class
token_authupdate_tokenpop
ValueErrormetadatasetcompliance_hook_auth_methods)selfr   r   r   r!   r"   r#   r    r$   r%   tokentoken_placementr(   r+   r    r2   N/home/ubuntu/webapp/venv/lib/python3.10/site-packages/authlib/oauth2/client.py__init__3   s<   
zOAuth2Client.__init__c                 C   s0   t |tr|d | j|d < dS || j|j< dS )zmExtend client authenticate for token endpoint.

        :param auth: an instance to sign the request
        r   r   N)
isinstancetupler.   name)r/   authr2   r2   r3   register_client_auth_methodd   s   
z(OAuth2Client.register_client_auth_methodc                 C   s2   t |tr|| jv r| j| }| j| j| j|dS )N)r   r   auth_method)r5   strr.   client_auth_classr   r   )r/   r:   r2   r2   r3   client_authn   s   
zOAuth2Client.client_authc                 C   s   | j jS N)r'   r0   )r/   r2   r2   r3   r0   w   s   zOAuth2Client.tokenc                 C   s   | j | d S r>   )r'   	set_token)r/   r0   r2   r2   r3   r0   {   s   c                 K   s   |du rt  }| jdd}|d|}d|vr| j|d< d|vr&| j|d< |r<|dkr<| jdkr<t||d< | j|d< | jD ]}||vrQ|| jv rQ| j| ||< q?t	|f| j
||d	|}||fS )
a  Generate an authorization URL and state.

        :param url: Authorization endpoint url, must be HTTPS.
        :param state: An optional state string for CSRF protection. If not
                      given it will be generated for you.
        :param code_verifier: An optional code_verifier for code challenge.
        :param kwargs: Extra parameters to include.
        :return: authorization_url, state
        Nresponse_typecoder$   r#   S256code_challenger%   )r   r@   r    )r   r+   getr)   r$   r#   r%   r
   EXTRA_AUTHORIZE_PARAMSr   r   )r/   urlr    code_verifierkwargsr@   kurir2   r2   r3   create_authorization_url   s0   




z%OAuth2Client.create_authorization_url POSTc                 K   s   |p| j }|dd}	|	rd|	v r| |	|S | |}
|	r0d|	v r0d}t|	|d}|d |d< |du r:| jd}|du rGt|}|| jd< | j||fi |}|du r[| 	| j
}|du rat}|du rk| jd	}| j|f||||d
|
S )am  Generic method for fetching an access token from the token endpoint.

        :param url: Access Token endpoint URL, if not configured,
                    ``authorization_response`` is used to extract token from
                    its fragment (implicit way).
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param method: The HTTP method used to make the request. Defaults
                       to POST, but may also be GET. Other methods should
                       be added as needed.
        :param headers: Dict to default request headers with.
        :param auth: An auth tuple or method as accepted by requests.
        :param grant_type: Use specified grant_type to fetch token
        :return: A :class:`OAuth2Token` object (a dict too).
        authorization_responseN#zcode=authorization_code)r    rA   
grant_typetoken_endpoint)bodyr8   methodheaders)r    r)   token_from_fragment_extract_session_request_paramsr   r+   rD   _guess_grant_type_prepare_token_endpoint_bodyr=   r!   DEFAULT_HEADERS_fetch_token)r/   rF   rS   rT   rU   r8   rQ   r    rH   rN   session_kwargsparamsr2   r2   r3   fetch_token   s@   


zOAuth2Client.fetch_tokenc                 C   s4   t ||}d|v r| j|d |dd|| _|S )Nerrorerror_descriptionr_   description)r   oauth_error_classrD   r0   )r/   rN   r    r0   r2   r2   r3   rV      s   
z OAuth2Client.token_from_fragmentc           	      K   s   |  |}|p| jd}d|vr| jr| j|d< td|fd|i|}|du r,t }| jd D ]}||||\}}}q1|du rG| | j	}| j
|f||||d|S )a	  Fetch a new access token using a refresh token.

        :param url: Refresh Token endpoint, must be HTTPS.
        :param refresh_token: The refresh_token to use.
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param auth: An auth tuple or method as accepted by requests.
        :param headers: Dict to default request headers with.
        :return: A :class:`OAuth2Token` object (a dict too).
        refresh_tokenr#   Nr   )rd   rS   rU   r8   )rW   r0   rD   r#   r   rZ   copyr-   r=   r!   _refresh_token)	r/   rF   rd   rS   r8   rU   rH   r\   hookr2   r2   r3   rd      s2   

zOAuth2Client.refresh_tokenc                 C   s~   |  sdS |d}| jd}|r|r| j||d dS | jddkr=|d }| j|dd}| jr;| j||d	 dS d S )
NTrd   rR   rd   rQ   client_credentialsaccess_token)rQ   )rj   )
is_expiredrD   r+   rd   r^   r(   )r/   r0   rd   rF   rj   	new_tokenr2   r2   r3   ensure_active_token  s   
z OAuth2Client.ensure_active_tokenc                 K       | j d|f|||||d|S )a  Revoke token method defined via `RFC7009`_.

        :param url: Revoke Token endpoint, must be HTTPS.
        :param token: The token to be revoked.
        :param token_type_hint: The type of the token that to be revoked.
                                It can be "access_token" or "refresh_token".
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param auth: An auth tuple or method as accepted by requests.
        :param headers: Dict to default request headers with.
        :return: Revocation Response

        .. _`RFC7009`: https://tools.ietf.org/html/rfc7009
        r   r0   token_type_hintrS   r8   rU   _handle_token_hintr/   rF   r0   rp   rS   r8   rU   rH   r2   r2   r3   revoke_token     zOAuth2Client.revoke_tokenc                 K   rn   )a  Implementation of OAuth 2.0 Token Introspection defined via `RFC7662`_.

        :param url: Introspection Endpoint, must be HTTPS.
        :param token: The token to be introspected.
        :param token_type_hint: The type of the token that to be revoked.
                                It can be "access_token" or "refresh_token".
        :param body: Optional application/x-www-form-urlencoded body to add the
                     include in the token request. Prefer kwargs over body.
        :param auth: An auth tuple or method as accepted by requests.
        :param headers: Dict to default request headers with.
        :return: Introspection Response

        .. _`RFC7662`: https://tools.ietf.org/html/rfc7662
        r   ro   rq   rs   r2   r2   r3   introspect_token(  ru   zOAuth2Client.introspect_tokenc                 C   sF   |dkr| j j| dS || jvrtd|| j| j| | dS )a  Register a hook for request/response tweaking.

        Available hooks are:

        * access_token_response: invoked before token parsing.
        * refresh_token_request: invoked before refreshing token.
        * refresh_token_response: invoked before refresh token parsing.
        * protected_request: invoked before making a request.
        * revoke_token_request: invoked before revoking a token.
        * introspect_token_request: invoked before introspecting a token.
        protected_requestNzHook type %s is not in %s.)r'   hooksaddr-   r*   )r/   	hook_typerg   r2   r2   r3   register_compliance_hook=  s   
z%OAuth2Client.register_compliance_hookc                 C   sF   |j dkr	|  | }d|v r| j|d |dd|| _| jS )Ni  r_   r`   ra   )status_coderaise_for_statusjsonrc   rD   r0   )r/   respr0   r2   r2   r3   parse_response_tokenR  s   
z!OAuth2Client.parse_response_tokenc           	      K   s   |  dkr| jj|ftt|||d|}n!d|v r%d||g}nd||g}| jj||f||d|}| jd D ]}||}q?| |S )NrM   datarU   r8   ?&)rU   r8   r   )	upperr   postdictr   joinrequestr-   r   )	r/   rF   rS   rU   r8   rT   rH   r   rg   r2   r2   r3   r[   _  s    


zOAuth2Client._fetch_tokenc           
      K   sn   | j |f|||d|}| jd D ]}||}q| |}	d|	vr'|| jd< t| jr4| j| j|d | jS )N)rS   r8   rU   r   rd   rh   )
_http_postr-   r   r0   callabler(   )
r/   rF   rd   rS   rU   r8   rH   r   rg   r0   r2   r2   r3   rf   r  s   



zOAuth2Client._refresh_tokenc           
      K   s   |d u r| j r| j dp| j d}|d u rd}t||||\}}| j| D ]}||||\}}}q'|d u r=| | j}| |}	| j||f||d|	S )Nrd   rj   rL   )r8   rU   )r0   rD   r	   r-   r=   r"   rW   r   )
r/   rg   rF   r0   rp   rS   r8   rU   rH   r\   r2   r2   r3   rr     s&   
zOAuth2Client._handle_token_hintc                 K   sV   |dkrd|vr| j |d< t||fi |S d|vr"| jr"| j|d< t||fi |S )NrP   r$   r#   )r$   r   r#   )r/   rS   rQ   rH   r2   r2   r3   rY     s   

z)OAuth2Client._prepare_token_endpoint_bodyc                 C   s*   i }| j D ]}||v r||||< q|S )zDExtract parameters for session object from the passing ``**kwargs``.)SESSION_REQUEST_PARAMSr)   )r/   rH   rvrI   r2   r2   r3   rW     s   
z,OAuth2Client._extract_session_request_paramsc                 K   s$   | j j|ftt|||d|S )Nr   )r   r   r   r   )r/   rF   rS   r8   rU   rH   r2   r2   r3   r     s   
zOAuth2Client._http_post)NNNNNNNNNr   N)NN)NrL   rM   NNNNr>   )NrL   NN)NNNNN)rL   NNrM   )NNN)!__name__
__module____qualname____doc__r   r<   r   r&   r   rc   rE   r   r4   r9   r=   propertyr0   setterrK   r^   rV   rd   rm   rt   rv   r{   r   r[   rf   rr   rY   rW   r   r2   r2   r2   r3   r      s`    
1
	


!

8

"





r   c                 C   s0   d| v rd}|S d| v rd| v rd}|S d}|S )NrA   rP   usernamepasswordri   r2   )rH   rQ   r2   r2   r3   rX     s   rX   N)authlib.common.securityr   authlib.common.urlsr   rfc6749.parametersr   r   r   r   rfc7009r	   rfc7636r
   r8   r   r   baser   rZ   r   rX   r2   r2   r2   r3   <module>   s       