
    N                         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j                  e      Z G d de      Z G d	 d
ej$                        Zy)    )unicode_literalsN)generate_token	urldecode)WebApplicationClientInsecureTransportError)LegacyApplicationClient)TokenExpiredErroris_secure_transportc                        e Zd Z fdZ xZS )TokenUpdatedc                 8    t         t        |           || _        y N)superr   __init__token)selfr   	__class__s     3lib/third_party/requests_oauthlib/oauth2_session.pyr   zTokenUpdated.__init__   s    	,&(DJ    )__name__
__module____qualname__r   __classcell__r   s   @r   r   r      s     r   r   c                       e Zd ZdZ	 	 	 	 	 	 	 	 	 d fd	Zd Zed        Zej                  d        Zej                  d        Zed        Z
e
j                  d        Z
ed	        Zej                  d
        Zej                  d        Zed        ZddZ	 	 	 	 	 	 	 	 	 	 	 	 	 ddZd Z	 	 	 	 	 	 	 ddZ	 	 	 	 	 d fd	Zd Z xZS )OAuth2Sessiona6  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.
    c
                 >   t        t        | 
  di |
 |xs t        ||      | _        |xs i | _        || _        || _        |xs t        | _	        || _
        || _        |xs i | _        |	| _        d | _        t               t               t               d| _        y)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 r    )rs    r   <lambda>z(OAuth2Session.__init__.<locals>.<lambda>\   s    !r   )access_token_responserefresh_token_responseprotected_requestNr   )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   s              r   r   zOAuth2Session.__init__*   s    J 
-'1&1I1)5IDL"DJDJ$D(.DJDK,D28bD&D DI
 "%"%% UDr   c                    	 | j                         | _        t        j                  d| j                         | j                  S # t        $ r? | j                   | _        t        j                  d| j                         Y | j                  S w xY w)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   s    r   	new_statezOAuth2Session.new_statef   so    GJJLdk	ii)4;;7 ;;  GJJdk	ii8$++F;;Gs   5A :B
Bc                 0    t        | j                  dd       S )Nr0   getattrr%   r7   s    r   r0   zOAuth2Session.client_idp   s    4<<d33r   c                 &    || j                   _        y r   r%   r0   r   values     r   r0   zOAuth2Session.client_idt   s    "DLLr   c                     | j                   `y r   r=   r7   s    r   r0   zOAuth2Session.client_idx   s    r   c                 0    t        | j                  dd       S )Nr   r:   r7   s    r   r   zOAuth2Session.token|   s    4<<$//r   c                 \    || j                   _        | j                   j                  |       y r   )r%   r   populate_token_attributesr>   s     r   r   zOAuth2Session.token   s     DLLLL**51r   c                 0    t        | j                  dd       S )Naccess_tokenr:   r7   s    r   rE   zOAuth2Session.access_token   s    4<<66r   c                 &    || j                   _        y r   r%   rE   r>   s     r   rE   zOAuth2Session.access_token   s     %DLLr   c                     | j                   `y r   rG   r7   s    r   rE   zOAuth2Session.access_token   s    !r   c                 ,    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.
        )boolrE   r7   s    r   
authorizedzOAuth2Session.authorized   s     !!""r   c                     |xs | j                         } | 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(   )r8   r%   prepare_request_urir'   r&   )r   urlr(   r2   s       r   authorization_urlzOAuth2Session.authorization_url   s]     %T^^%E+4<<++&&jj	
 
  r   c           	      4   t        |      s
t               |s@|r>| j                  j                  || j                         | j                  j
                  }n?|s=t        | j                  t              r#| j                  j
                  }|st        d      t        | j                  t              r|t        d      |t        d      |||d<   |||d<   ||Qd}nN|durJ| j                  }|r<t        j                  d	|       ||nd
}t        j                  j                  ||      }|r|||d<    | j                  j                   d ||| j"                  |d|}|
xs ddd}
i | _        |j'                         dk(  rA| j)                  |t+        t-        |            |	|
|||      }t        j                  d|       n_|j'                         dk(  rA| j/                  |t+        t-        |            |	|
|||      }t        j                  d|       nt        d      t        j                  d|j0                         t        j                  d|j2                  j4                         t        j                  d|j2                  j6                         t        j                  d|j4                  |j8                         t        j                  dt;        | j<                  d                | j<                  d   D ]   }t        j                  d|        ||      }" | j                  j?                  |j8                  | j@                         | j                  j$                  | _        t        j                  d| j$                         | j$                  S )!ai	  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 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 kwargs: Extra parameters to include in the token request.
        :return: A token dict
        r(   z?Please supply either code or authorization_response parameters.zQ`LegacyApplicationClient` requires both the `username` and `password` parameters.zFThe required paramter `username` was supplied, but `password` was not.usernamepasswordFTzIEncoding `client_id` "%s" with `client_secret` as Basic auth credentials. client_secret)codebodyr'   include_client_idapplication/json/application/x-www-form-urlencoded;charset=UTF-8AcceptzContent-TypePOST)datatimeoutheadersr-   verifyproxiesz$Prepared fetch token request body %sGET)paramsr_   r`   r-   ra   rb   z+Prepared fetch token request querystring %sz%The method kwarg must be POST or GET.z0Request to fetch token completed with status %s.z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   r%   parse_request_uri_responser)   rV   
isinstancer   
ValueErrorr   r0   r4   r5   requestsr-   HTTPBasicAuthprepare_request_bodyr'   r   upperpostdictr   getstatus_coderequestr`   rW   textlenr/   parse_request_body_responser&   )r   	token_urlrV   authorization_responserW   r-   rR   rS   methodr_   r`   ra   rb   rX   rU   r2   r0   r    hooks                      r   fetch_tokenzOAuth2Session.fetch_token   s_   n y)"$$*
ll--
  . 5\\dj/CD\\d > ? 	? $,, 78		 A B 	B		 3 4 	4 #fZ#fZ  
	"! 
$	&NN	
))+,57 ,9+D-"-,,YF$ 
	""/,4<<,, &&+	
 D  $IG DJ||~
))
IdO$  a 
ii6=	5	 
((
io&  a 
ii=tD>??II@!--PII'):):;II#QYY^^4II8!))QVVLII1$&&'>?@B$$%<=	ii#T*
q'a > 	LL,,QVV4::,F##DJII"DJJ/::r   c                     | j                   j                  || j                         | 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
        rQ   )r%   ri   r)   r   )r   ry   s     r   token_from_fragmentz!OAuth2Session.token_from_fragment^  s?     	LL++dkk , 3##DJ::r   c	           
         |st        d      t        |      s
t               |xs | j                  j	                  d      }t
        j                  d| j                         |	j                  | j                          | j                  j                  d||| j                  d|	}t
        j                  d|       |ddd}| j                  |t        t        |            ||||d	|
      }
t
        j                  d|
j                         t
        j                  d|
j                   |
j"                         t
        j                  dt%        | j&                  d                | j&                  d   D ]   }t
        j                  d|        ||
      }
" | j                  j)                  |
j"                  | j                        | _        d| j                  vr$t
        j                  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.)rW   r   r&   z&Prepared refresh token request body %srY   rZ   r[   T)r^   r-   r_   r`   ra   withhold_tokenrb   z2Request to refresh token completed with status %s.re   rf   r#   rg   rh   z)No new refresh token given. Re-using old.r   )rk   r
   r   r   rr   r4   r5   r+   updater%   prepare_refresh_bodyr&   rp   rq   r   rs   r`   ru   rv   r/   rw   )r   rx   r   rW   r-   r_   r`   ra   rb   r2   r    r{   s               r   r   zOAuth2Session.refresh_tokeni  s   0 @AAy)"$$!DTZZ^^O%DMII:&&(
MM$**+,4<<,, LdjjLDJLDII6=&Lg
 			)D/" 	 	A IIBmmII8!))QVVLII1$&&'?@AC$$%=>	ii#T*
q'a ? 99	djj : "DJdjj(	ii;<$1djj!::r   c                    t        |      s
t               | j                  r|st        j	                  dt        | j                  d                | j                  d   D ]&  }	t        j	                  d|	        |	|||      \  }}}( t        j	                  d| j                         	 | j                  j                  ||||      \  }}}t        j	                  d||       t        j	                  d||       t        j	                  d|       t%        t&        | R  ||f||d|S # t        $ r | j                  rt        j	                  d| j                         |j                  dd      }
|r:|r8|
6t        j	                  d	|       t        j                  j                  ||      }
 | j                  | j                  fd|
i|}| j                   rVt        j	                  d
|| j                          | j!                  |       | j                  j                  ||||      \  }}}nt#        |       Y pw xY w)z<Intercept all requests and add the OAuth 2 token if present.z-Invoking %d protected resource request hooks.r$   rg   zAdding token %s to request.)http_methodrW   r`   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.)r`   r^   )r
   r   r   r4   r5   rv   r/   r%   	add_tokenr	   r*   poprl   r-   rm   r   r,   r   r   r   rt   )r   rz   rN   r^   r`   r   r0   rU   r2   r{   r-   r   r   s               r   rt   zOAuth2Session.request  s(    s#"$$zz.	ii?D(()<=>@&&':;$		%t,!#w5Wd < 
ii-tzz:!\\33V$ 4 AWd6 II2C@II0'4@II6?-;$4;39; ;7    
))G))+ FD)$=dlIIW ==..y-HD$$$$T%:%:PPP%II6((*u%!%!7!7dG "8 "EC$ u%%
 #s   *#D) )DH>=H>c                     || j                   vrt        d|| j                         | j                   |   j                  |       y)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/   rk   add)r   	hook_typer{   s      r   register_compliance_hookz&OAuth2Session.register_compliance_hook  sF     ,,,3Y++- -#''-r   )	NNNNNNNNNr   )NNrT   NNNr]   NNTNNN)NrT   NNNTN)NNFNN)r   r   r   __doc__r   r8   propertyr0   setterdeleterr   rE   rK   rO   r|   r~   r   rt   r   r   r   s   @r   r   r      st   *  $#' !:x 4 4 # #   0 0 	<<2 2 7 7 & & " " 	# 	#& )-$( $n`	 #'   DR " 4;l.r   r   )
__future__r   loggingoauthlib.commonr   r   oauthlib.oauth2r   r   r   r	   r
   rl   	getLoggerr   r4   Warningr   Sessionr   r   r   r   <module>r      sL    '  5 H 3 B g!7 ^.H$$ ^.r   