U
    {Zg|]                     @   s|   d dl 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m	Z	 d dl
Z
e eZG dd deZG dd	 d	e
jZdS )
    N)generate_token	urldecode)WebApplicationClientInsecureTransportError)LegacyApplicationClient)TokenExpiredErroris_secure_transportc                       s   e Zd Z fddZ  ZS )TokenUpdatedc                    s   t t|   || _d S N)superr	   __init__token)selfr   	__class__ D/tmp/pip-unpacked-wheel-dr3g6iil/requests_oauthlib/oauth2_session.pyr      s    zTokenUpdated.__init__)__name__
__module____qualname__r   __classcell__r   r   r   r   r	      s   r	   c                       s   e Zd ZdZd& fdd	Zedd Zejdd Zdd	 Zed
d Z	e	jdd Z	e	j
dd Z	edd Zejdd Zedd Zejdd Zej
dd Zedd Zd'ddZd(ddZdd Zd)d d!Zd* fd"d#	Zd$d% Z  ZS )+OAuth2Sessiona*  Versatile OAuth 2 extension to :class:`requests.Session`.

    Supports any grant type adhering to :class:`oauthlib.oauth2.Client` spec
    including the four core OAuth 2 grants.

    Can be used to create authorization urls, fetch tokens and access protected
    resources using the :class:`requests.Session` interface you are used to.

    - :class:`oauthlib.oauth2.WebApplicationClient` (default): Authorization Code Grant
    - :class:`oauthlib.oauth2.MobileApplicationClient`: Implicit Grant
    - :class:`oauthlib.oauth2.LegacyApplicationClient`: Password Credentials Grant
    - :class:`oauthlib.oauth2.BackendApplicationClient`: Client Credentials Grant

    Note that the only time you will be using Implicit Grant from python is if
    you are driving a user agent able to obtain URL fragments.
    Nc                    s   t t| jf | |p t||d| _|p*i | _|| _|| _|p@t| _	|| _
|| _|pVi | _|	| _|
| _| jdkrtd| j| jdd | _t t t t t d| _dS )a  Construct a new OAuth 2 client session.

        :param client_id: Client id obtained during registration
        :param client: :class:`oauthlib.oauth2.Client` to be used. Default is
                       WebApplicationClient which is useful for any
                       hosted application but not mobile or desktop.
        :param scope: List of scopes you wish to request access to
        :param redirect_uri: Redirect URI you registered as callback
        :param token: Token dictionary, must include access_token
                      and token_type.
        :param state: State string used to prevent CSRF. This will be given
                      when creating the authorization url and must be supplied
                      when parsing the authorization response.
                      Can be either a string or a no argument callable.
        :auto_refresh_url: Refresh token endpoint URL, must be HTTPS. Supply
                           this if you wish the client to automatically refresh
                           your access tokens.
        :auto_refresh_kwargs: Extra arguments to pass to the refresh token
                              endpoint.
        :token_updater: Method with one argument, token, to be used to update
                        your token database on automatic token refresh. If not
                        set a TokenUpdated warning will be raised when a token
                        has been refreshed. This warning will carry the token
                        in its token argument.
        :param pkce: Set "S256" or "plain" to enable PKCE. Default is disabled.
        :param kwargs: Arguments to pass to the Session constructor.
        )r   )ZS256plainNzWrong value for {}(.., pkce={})c                 S   s   | S r
   r   )rr   r   r   <lambda>^       z(OAuth2Session.__init__.<locals>.<lambda>)access_token_responserefresh_token_responseprotected_requestrefresh_token_requestaccess_token_requestN)r   r   r   r   _clientr   _scoperedirect_urir   state_stateauto_refresh_urlauto_refresh_kwargstoken_updater_pkceAttributeErrorformatr   authsetcompliance_hook)r   	client_idclientr&   r'   scoper#   r   r$   r(   Zpkcekwargsr   r   r   r   $   s(    )




zOAuth2Session.__init__c                 C   s*   | j dk	r| j S | jdk	r"| jjS dS dS )zBBy default the scope from the client is used, except if overriddenN)r"   r!   r1   r   r   r   r   r1   j   s
    

zOAuth2Session.scopec                 C   s
   || _ d S r
   )r"   )r   r1   r   r   r   r1   t   s    c                 C   sN   z|   | _td| j W n* tk
rF   | j | _td| j Y nX | jS )z6Generates a state string to be used in authorizations.zGenerated new state %s.z&Re-using previously supplied state %s.)r$   r%   logdebug	TypeErrorr3   r   r   r   	new_statex   s    
zOAuth2Session.new_statec                 C   s   t | jdd S )Nr/   getattrr!   r3   r   r   r   r/      s    zOAuth2Session.client_idc                 C   s   || j _d S r
   r!   r/   r   valuer   r   r   r/      s    c                 C   s
   | j `d S r
   r:   r3   r   r   r   r/      s    c                 C   s   t | jdd S )Nr   r8   r3   r   r   r   r      s    zOAuth2Session.tokenc                 C   s   || j _| j | d S r
   )r!   r   Zpopulate_token_attributesr;   r   r   r   r      s    c                 C   s   t | jdd S )Naccess_tokenr8   r3   r   r   r   r=      s    zOAuth2Session.access_tokenc                 C   s   || j _d S r
   r!   r=   r;   r   r   r   r=      s    c                 C   s
   | j `d S r
   r>   r3   r   r   r   r=      s    c                 C   s
   t | jS )a  Boolean that indicates whether this session has an OAuth token
        or not. If `self.authorized` is True, you can reasonably expect
        OAuth-protected requests to the resource to succeed. If
        `self.authorized` is False, you need the user to go through the OAuth
        authentication dance before OAuth-protected requests to the resource
        will succeed.
        )boolr=   r3   r   r   r   
authorized   s    	zOAuth2Session.authorizedc                 K   sf   |p
|   }| jrB| jd| _| j|d< | jj| j| jd|d< | jj|f| j| j|d||fS )aF  Form an authorization URL.

        :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 kwargs: Extra parameters to include.
        :return: authorization_url, state
        +   code_challenge_method)code_verifierrB   Zcode_challenge)r#   r1   r$   )	r7   r)   r!   Zcreate_code_verifier_code_verifierZcreate_code_challengeZprepare_request_urir#   r1   )r   urlr$   r2   r   r   r   authorization_url   s&    	

zOAuth2Session.authorization_url POSTFc                 K   s  t |st |s2|r2| jj|| jd | jj}n$|sVt| jtrV| jj}|sVtd| j	rx| j
dkrntd| j
|d< t| jtr|dkrtd|dkrtd|dk	r||d< |dk	r||d	< |dk	r|dkrd
}nB|dk	r| j}|rtd| |dk	r
|nd}tj||}|r4|dk	r4||d< | jjf ||| j|d|}|p`ddd}i | _i }| dkrtt|||	rdnd< n(| dkrtt||d< ntd| jd D ]$}td| ||||\}}}q| jf |||
|||||d|}td|j td|jj td|jj td|jj td|j|j td t| jd!  | jd! D ]}td"| ||}q| jj |j| j!d# | jj| _td$| j | jS )%a  Generic method for fetching an access token from the token endpoint.

        If you are using the MobileApplicationClient you will want to use
        `token_from_fragment` instead of `fetch_token`.

        The current implementation enforces the RFC guidelines.

        :param token_url: Token endpoint URL, must use HTTPS.
        :param code: Authorization code (used by WebApplicationClients).
        :param authorization_response: Authorization response URL, the callback
                                       URL of the request back to you. Used by
                                       WebApplicationClients instead of code.
        :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 username: Username required by LegacyApplicationClients to appear
                         in the request body.
        :param password: Password required by LegacyApplicationClients to appear
                         in the request 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 force_querystring: If True, force the request body to be sent
            in the querystring instead.
        :param timeout: Timeout of the request in seconds.
        :param headers: Dict to default request headers with.
        :param verify: Verify SSL certificate.
        :param proxies: The `proxies` argument is passed onto `requests`.
        :param include_client_id: Should the request body include the
                                  `client_id` parameter. Default is `None`,
                                  which will attempt to autodetect. This can be
                                  forced to always include (True) or never
                                  include (False).
        :param client_secret: The `client_secret` paired to the `client_id`.
                              This is generally required unless provided in the
                              `auth` tuple. If the value is `None`, it will be
                              omitted from the request, however if the value is
                              an empty string, an empty string will be sent.
        :param cert: Client certificate to send for OAuth 2.0 Mutual-TLS Client
                     Authentication (draft-ietf-oauth-mtls). Can either be the
                     path of a file containing the private key and certificate or
                     a tuple of two filenames for certificate and key.
        :param kwargs: Extra parameters to include in the token request.
        :return: A token dict
        r$   z?Please supply either code or authorization_response parameters.NzFCode verifier is not found, authorization URL must be generated beforerC   zQ`LegacyApplicationClient` requires both the `username` and `password` parameters.zGThe required parameter `username` was supplied, but `password` was not.usernamepasswordFTzIEncoding `client_id` "%s" with `client_secret` as Basic auth credentials.rG   client_secret)codebodyr#   include_client_idapplication/json!application/x-www-form-urlencodedAcceptzContent-TyperH   paramsdataGETz%The method kwarg must be POST or GET.r    z&Invoking access_token_request hook %s.)methodrE   timeoutheadersr,   verifyproxiescertz0Request to fetch token completed with status %s.zRequest url was %szRequest headers were %szRequest body was %s(Response headers were %s and content %s.!Invoking %d token response hooks.r   Invoking hook %s.r1   zObtained token %s.)"r   r   r!   parse_request_uri_responser%   rM   
isinstancer   
ValueErrorr)   rD   r   r/   r4   r5   requestsr,   HTTPBasicAuthZprepare_request_bodyr#   r   upperdictr   r.   requeststatus_coderE   rY   rN   textlenparse_request_body_responser1   )r   	token_urlrM   authorization_responserN   r,   rJ   rK   rW   Zforce_querystringrX   rY   rZ   r[   rO   rL   r\   r2   r/   Zrequest_kwargshookr   r   r   r   fetch_token   s    A 




  	
zOAuth2Session.fetch_tokenc                 C   s"   | j j|| jd | j j| _| jS )zParse token from the URI fragment, used by MobileApplicationClients.

        :param authorization_response: The full URL of the redirect back to you
        :return: A token dict
        rI   )r!   ra   r%   r   )r   rn   r   r   r   token_from_fragment  s     
z!OAuth2Session.token_from_fragmentc	              
   K   sf  |st dt|st |p(| jd}td| j |	| j | j	j
f ||| jd|	}td| |dkr~ddd	}| jd
 D ]"}
td|
 |
|||\}}}q| j|tt|||||d|d}td|j td|j|j tdt| jd  | jd D ]}
td|
 |
|}q| j	j|j| jd| _d| jkr`td || jd< | jS )a  Fetch a new access token using a refresh token.

        :param token_url: The 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 timeout: Timeout of the request in seconds.
        :param headers: A dict of headers to be used by `requests`.
        :param verify: Verify SSL certificate.
        :param proxies: The `proxies` argument will be passed to `requests`.
        :param kwargs: Extra parameters to include in the token request.
        :return: A token dict
        z'No token endpoint set for auto_refresh.refresh_tokenz*Adding auto refresh key word arguments %s.)rN   rr   r1   z&Prepared refresh token request body %sNrP   rQ   rR   r   z'Invoking refresh_token_request hook %s.T)rU   r,   rX   rY   rZ   withhold_tokenr[   z2Request to refresh token completed with status %s.r]   r^   r   r_   r`   z)No new refresh token given. Re-using old.)rc   r   r   r   getr4   r5   r'   updater!   Zprepare_refresh_bodyr1   r.   postrg   r   ri   rY   rj   rk   rl   )r   rm   rr   rN   r,   rX   rY   rZ   r[   r2   ro   r   r   r   r   rr     sb       



zOAuth2Session.refresh_tokenc	              	      s  t |st | jrR|sRtdt| jd  | jd D ]"}
td|
 |
|||\}}}q<td| j z| jj||||d\}}}W n t	k
rP   | j
rJtd| j
 |	dd}|r|r|dkrtd	| tj||}| j| j
fd|i|	}| jr@td
|| j | | | jj||||d\}}}nt|n Y nX td|| td|| td|	 tt| j||f|||d|	S )z<Intercept all requests and add the OAuth 2 token if present.z-Invoking %d protected resource request hooks.r   r_   zAdding token %s to request.)Zhttp_methodrN   rY   z1Auto refresh is set, attempting to refresh at %s.r,   NzEEncoding client_id "%s" with client_secret as Basic auth credentials.zUpdating token to %s using %s.z"Requesting url %s using method %s.z Supplying headers %s and data %sz&Passing through key word arguments %s.)rY   rU   files)r   r   r   r4   r5   rk   r.   r!   Z	add_tokenr   r&   poprd   r,   re   rr   r(   r	   r   r   rh   )r   rW   rE   rU   rY   rs   r/   rL   rw   r2   ro   r,   r   r   r   r   rh     s         
   

   zOAuth2Session.requestc                 C   s,   || j k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_response invoked before refresh token parsing.
            protected_request invoked before making a request.
            access_token_request invoked before making a token fetch request.
            refresh_token_request invoked before making a refresh request.

        If you find a new hook is needed please send a GitHub PR request
        or open an issue.
        zHook type %s is not in %s.N)r.   rc   add)r   Z	hook_typero   r   r   r   register_compliance_hook:  s    
  z&OAuth2Session.register_compliance_hook)
NNNNNNNNNN)N)NNrG   NNNrH   FNNNNNNN)NrG   NNNNN)NNFNNN)r   r   r   __doc__r   propertyr1   setterr7   r/   deleterr   r=   r@   rF   rp   rq   rr   rh   rz   r   r   r   r   r   r      s             F
	












               
 R       
S      Dr   )loggingZoauthlib.commonr   r   Zoauthlib.oauth2r   r   r   r   r   rd   	getLoggerr   r4   Warningr	   Sessionr   r   r   r   r   <module>   s   
