U
    6dU                     @   s   d dl mZ 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 )    )unicode_literalsN)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-h5x5xq8v/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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 | _|	| _dd | _t t t d| _dS )aH  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 kwargs: Arguments to pass to the Session constructor.
        )r   c                 S   s   | S r   r   )rr   r   r   <lambda>Z       z(OAuth2Session.__init__.<locals>.<lambda>)access_token_responserefresh_token_responseprotected_requestN)r   r   r   r   _clientr   scoperedirect_urir   state_stateauto_refresh_urlauto_refresh_kwargstoken_updaterauthsetcompliance_hook)r   	client_idclientr$   r%   r    r!   r   r"   r&   kwargsr   r   r   r   &   s    '



zOAuth2Session.__init__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	TypeErrorr   r   r   r   	new_stated   s    
zOAuth2Session.new_statec                 C   s   t | jdd S )Nr*   getattrr   r0   r   r   r   r*   n   s    zOAuth2Session.client_idc                 C   s   || j _d S r   r   r*   r   valuer   r   r   r*   r   s    c                 C   s
   | j `d S r   r4   r0   r   r   r   r*   v   s    c                 C   s   t | jdd S )Nr   r2   r0   r   r   r   r   z   s    zOAuth2Session.tokenc                 C   s   || j _| j | d S r   )r   r   Zpopulate_token_attributesr5   r   r   r   r   ~   s    c                 C   s   t | jdd S )Naccess_tokenr2   r0   r   r   r   r7      s    zOAuth2Session.access_tokenc                 C   s   || j _d S r   r   r7   r5   r   r   r   r7      s    c                 C   s
   | j `d S r   r8   r0   r   r   r   r7      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.
        )boolr7   r0   r   r   r   
authorized   s    	zOAuth2Session.authorizedc                 K   s0   |p
|   }| 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
        )r!   r    r"   )r1   r   Zprepare_request_urir!   r    )r   urlr"   r,   r   r   r   authorization_url   s    	zOAuth2Session.authorization_url POSTFTc                 K   sv  t |st |s2|r2| jj|| jd | jj}n$|sVt| jtrV| jj}|sVtdt| jt	r|dkrrtd|dkrtd|dk	r||d< |dk	r||d< |dk	r|dkrd}n<|d	k	r| j
}|rtd
| |dk	r|nd}tj||}|r|dk	r||d< | jjf ||| j|d|}|p8ddd}i | _i }| dkrntt|||	rhdnd< n(| dkrtt||d< ntd| 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.NzQ`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.r=   client_secret)codebodyr!   include_client_idapplication/json/application/x-www-form-urlencoded;charset=UTF-8AcceptzContent-Typer>   paramsdataGETz%The method kwarg must be POST or GET.)methodr;   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.r    zObtained token %s.) r	   r   r   parse_request_uri_responser#   rC   
isinstancer   
ValueErrorr   r*   r-   r.   requestsr'   HTTPBasicAuthZprepare_request_bodyr!   r   upperdictr   requeststatus_coder;   rO   rD   textlenr)   parse_request_body_responser    )r   	token_urlrC   authorization_responserD   r'   r@   rA   rM   Zforce_querystringrN   rO   rP   rQ   rE   rB   rR   r,   r*   Zrequest_kwargsr   hookr   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
        r?   )r   rW   r#   r   )r   rd   r   r   r   token_from_fragments  s     
z!OAuth2Session.token_from_fragmentc	              
   K   s6  |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|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r0t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.)rD   rh   r    z&Prepared refresh token request body %sNrF   rG   rH   T)rK   r'   rN   rO   rP   withhold_tokenrQ   z2Request to refresh token completed with status %s.rS   rT   r   rU   rV   z)No new refresh token given. Re-using old.)rY   r	   r   r   getr-   r.   r%   updater   Zprepare_refresh_bodyr    postr]   r   r_   rO   r`   ra   r)   rb   )r   rc   rh   rD   r'   rN   rO   rP   rQ   r,   r   re   r   r   r   rh     s\       




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   rU   zAdding token %s to request.)Zhttp_methodrD   rO   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.)rO   rK   )r	   r   r   r-   r.   ra   r)   r   Z	add_tokenr   r$   poprZ   r'   r[   rh   r&   r
   r   r   r^   )r   rM   r;   rK   rO   ri   r*   rB   r,   re   r'   r   r   r   r   r^     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.

        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)   rY   add)r   Z	hook_typere   r   r   r   register_compliance_hook  s    
  z&OAuth2Session.register_compliance_hook)	NNNNNNNNN)N)NNr=   NNNr>   FNNTNNNN)Nr=   NNNTN)NNFNN)r   r   r   __doc__r   r1   propertyr*   setterdeleterr   r7   r:   r<   rf   rg   rh   r^   ro   r   r   r   r   r   r      s            >











               
 E       
O     Cr   )
__future__r   loggingZoauthlib.commonr   r   Zoauthlib.oauth2r   r   r   r   r	   rZ   	getLoggerr   r-   Warningr
   Sessionr   r   r   r   r   <module>   s   
