
    O                         S r SSKJr  SSKrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
r
SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SS	KJr  \R,                  (       a-  \	R.                  R0                  r\	R2                  R4                  rOSSKr\R0                  r\	R4                  r\R:                  " S
5      rSr " S S\ 5      r! " S S\!5      r" " S S\#5      r$SS jr% " S S\#5      r& " S S\RN                  5      r( " S S\&5      r)S r*g)zLibrary with a variant of appengine_rpc using httplib2.

The httplib2 module offers some of the features in appengine_rpc, with
one important one being a simple integration point for OAuth2 integration.
    )absolute_importN)client)file)tools)encoding)
ValueMixin)
six_subsetz,googlecloudsdk.appengine.tools.appengine_rpc   c                       \ rS rSrSrg)Error>    N)__name__
__module____qualname____firstlineno____static_attributes__r       <lib/googlecloudsdk/appengine/tools/appengine_rpc_httplib2.pyr   r   >   s    r   r   c                       \ rS rSrSrSrg)AuthPermanentFailB   z7Authentication will not succeed in the current context.r   N)r   r   r   r   __doc__r   r   r   r   r   r   B   s    ?r   r   c                   0    \ rS rSrSrS rS rS rS rSr	g)	MemoryCacheF   z8httplib2 Cache implementation which only caches locally.c                     0 U l         g Ncacheselfs    r   __init__MemoryCache.__init__I   s	    DJr   c                 8    U R                   R                  U5      $ r   )r    getr"   keys     r   r&   MemoryCache.getL   s    ::>>#r   c                      X R                   U'   g r   r   )r"   r(   values      r   setMemoryCache.setO   s    JJsOr   c                 <    U R                   R                  US 5        g r   )r    popr'   s     r   deleteMemoryCache.deleteR   s    JJNN3r   r   N)
r   r   r   r   r   r#   r&   r,   r0   r   r   r   r   r   r   F   s    @r   r   c                     Ub8  [         R                  " 5       nUR                  U5        UR                  S5        OSnU(       d  UR                  nOUR                  S-   U-   n[        XR                  XQU5      e)z>Raise a urllib2.HTTPError based on an httplib2 response tuple.Nr    )ioBytesIOwriteseekreason	HTTPErrorstatus)urlresponse_inforesponse_body	extra_msgstreammsgs         r   RaiseHttpErrorrA   V   sg    ZZ\F
LL
KKNF	


C



$y
0C#++SHHr   c                   @    \ rS rSrSr    SS jrS r   S	S jrSrg)
HttpRpcServerHttpLib2e   zA variant of HttpRpcServer which uses httplib2.

This follows the same interface as appengine_rpc.AbstractRpcServer,
but is a totally separate implementation.
Nc                    Xl         X l        X0l        X@l        XPl        U=(       d    0 U l        Xpl        Xl        Xl        Xl	        Xl
        Xl        Xl        U=(       a    S=(       d    SU l        Xl        Xl        Ub  UO[         R"                  U l        UU l        SU l        SU l        U R                  (       d  [,        R.                  R1                  [,        R.                  R3                  [,        R.                  R5                  [6        5      SSSSSS5      5      U l        [,        R.                  R9                  U R(                  5      U l        [;        5       U l        g)	a  Creates a new HttpRpcServerHttpLib2.

Args:
  host: The host to send requests to.
  auth_function: Saved but ignored; may be used by subclasses.
  user_agent: The user-agent string to send to the server. Specify None to
    omit the user-agent header.
  source: Saved but ignored; may be used by subclasses.
  host_override: The host header to send to the server (defaults to host).
  extra_headers: A dict of extra headers to append to every request. Values
    supplied here will override other default headers that are supplied.
  save_cookies: Saved but ignored; may be used by subclasses.
  auth_tries: The number of times to attempt auth_function before failing.
  account_type: Saved but ignored; may be used by subclasses.
  debug_data: Whether debugging output should include data contents.
  secure: If the requests sent using Send should be sent over HTTPS.
  ignore_certs: If the certificate mismatches should be ignored.
  rpc_tries: The number of rpc retries upon http server error (i.e.
    Response code >= 500 and < 600) before failing.
  conflict_max_errors: The number of rpc retries upon http server error
    (i.e. Response code 409) before failing.
  timeout_max_errors: The number of rpc retries upon http server timeout
    (i.e. Response code 408) before failing.
  http_class: the httplib2.Http subclass to use. Defaults to httplib2.Http.
  http_object: an httlib2.Http object to use to make requests. If this is
    provided, http_class is ignored.
httpshttpNFz..libcacertszcacerts.txt)hostauth_function
user_agentsourcehost_overrideextra_headerssave_cookiesauth_max_errorsaccount_type
debug_datasecureignore_certsrpc_max_errorsschemeconflict_max_errorstimeout_max_errorshttplib2Http
http_classhttp_objectcertpathcert_file_availableospathnormpathjoindirname__file__existsr   memory_cache)r"   rJ   rK   rL   rM   rN   rO   rP   
auth_triesrR   rS   rT   rU   	rpc_triesrX   rY   r\   r]   s                     r   r#   HttpRpcServerHttpLib2.__init__l   s   @ I& OK&&,"D$%$ OK$#$W.DK20$.$:jDO"DDM$D gg&&rww||
''//(
#T4ui
( dm "$!>d#Dr   c                     [        5       e)a  Pre or Re-auth stuff...

Args:
  http: An 'Http' object from httplib2.
  saw_error: If the user has already tried to contact the server.
    If they have, it's OK to prompt them. If not, we should not be asking
    them for auth info--it's possible it'll suceed w/o auth.
)NotImplementedError)r"   rG   	saw_errors      r   _Authenticate#HttpRpcServerHttpLib2._Authenticate   s     
r   c                 n	  ^ ^^^^ T R                   =(       d4    T R                  T R                  T R                  T R                  (       + S9T l        ST R
                  l        UT R
                  l        T R                  < ST R                  < U< 3mU(       a(  TS[        [        UR                  5       5      5      -   -  m0 nT R                  (       a  UR                  T R                  5        SUS'   Ub  Sn[        [!        U5      5      US	'   X6S
'   OSnT R"                  (       a  T R"                  US'   SnS/mSn	Sn
UUUU U4S jnUT R$                  :  Ga  U	T R&                  :  Ga  U
T R(                  :  Ga  T R+                  T R
                  TS   S:  5        [,        R/                  STUT R0                  =(       a    U=(       d    U=(       a    S=(       d    S5         T R
                  R3                  TXrUS9u  mmTR@                  nUS:X  a  T$ [,        R/                  STR@                  5        US:X  a	  U" 5         M  US:X  aH  U
S-  n
[,        R/                  SU
T R(                  [B        5        [D        RF                  " [B        5        GMK  US:X  aW  U	S-  n	[H        RJ                  " SS5      n[,        R/                  SU	T R&                  U5        [D        RF                  " U5        GM  US:  a/  US :  a)  US-  n[,        R/                  S!UT R$                  5        GM  US":X  a  TRM                  S#5      n[,        R/                  S$U5        URO                  S%5      (       d  [P        RR                  " S&U5      (       a
  U" 5         GMF  URO                  S'T R                  < S(35      (       a  [U        TTTS)5        O9[U        TTTS*U-  5        O'[,        R/                  S+T5        [U        TTTS,U-  5        UT R$                  :  a#  U	T R&                  :  a  U
T R(                  :  a  GM  [V        R8                  " S-T5        [U        TTT5        g! [4        R6                   aI  n[,        R9                  SSS9  [:        R<                  " SS05      m[        U5      Tl        Sm SnAGNSnAff = f).aY  Sends an RPC and returns the response.

Args:
  request_path: The path to send the request to, eg /api/appversion/create.
  payload: The body of the request, or None to send an empty request.
  content_type: The Content-Type header to use.
  timeout: timeout in seconds; default None i.e. no timeout.
    (Note: for large requests on OS X, the timeout doesn't work right.)
  Any keyword arguments are converted into query string parameters.

Returns:
  The response body, as a string.

Raises:
  AuthPermanentFail: If authorization failed in a permanent way.
  urllib2.HTTPError: On most HTTP errors.
)r    ca_certs"disable_ssl_certificate_validationFz://?1zX-appcfg-api-versionNPOSTzcontent-lengthzContent-TypeGETHostr   c                     > T S==   S-  ss'   [         R                  ST S   TR                  5        T S   TR                  :  a  [        TTTS5        gg)zCMarker that we need auth; it'll actually be tried next time around.r      z)Attempting to auth. This is try %s of %s.zToo many auth attempts.N)loggerdebugrQ   rA   )auth_errorsresponser<   r"   r;   s   r   NeedAuth,HttpRpcServerHttpLib2.Send.<locals>.NeedAuth   sU    !nnll>q>4#7#79	Q$..	.sM85NO 
/r   z(Sending request to %s headers=%s body=%sELIDED )methodbodyheaderszGot access token errorry   )exc_infor:   i     zGot http error %s.i  z2Got timeout error %s of %s. Retrying in %s secondsi  
   z4Got conflict error %s of %s. Retrying in %s seconds.i  iX  z#Retrying. This is attempt %s of %s.i.  locationzGot 302 redirect. Location: %sz,https://www.google.com/accounts/ServiceLoginz3https://www\.google\.com/a/[a-z0-9.-]+/ServiceLoginzhttp://z
/_ah/loginz!dev_appserver login not supportedzUnexpected redirect to %szUnexpected results: %szUnexpected HTTP status %szToo many retries for url %s),r]   r\   rg   r^   r_   rG   follow_redirectstimeoutrW   rJ   urlencode_fnsorteditemsrO   updatestrlenrN   rV   rX   rY   rn   rz   r{   rS   requestr   AccessTokenRefreshErrorinforZ   Responser8   r:   _TIMEOUT_WAIT_TIMEtimesleeprandomrandintr&   
startswithrematchrA   logging)r"   request_pathpayloadcontent_typer   kwargsr   r   
rpc_errorsconflict_errorstimeout_errorsr~   er:   	wait_timelocr|   r}   r<   r;   s   `               @@@@r   SendHttpRpcServerHttpLib2.Send   s   4    KDOO$--040H0H,H %4 %KDI "'DIIDIIdii
>C	S<v||~ 6777cGnnT''( '*G"#f"%c'l"3g ,nf**gfoJ#KONP P +++T555D333
KNQ$67ll=??.wL'2FhL"N"&))"3"3g #4 #?x ##f	3ll')=)=>	3
S=!I#T%<%<'	) 	

%&S=1NN1b)	K$d&>&>		K

9S=Vc\a
:!4!4	6S= 
+5s;NNIJJHHK 
*
^^TYY@AA
mX<> mX4s:< 	-}=sM82V;	=A +++T555D333@ LL.43x0s ++ ,q9 ))8S/:"1vs   (Q R4+>R//R4)rR   rK   rQ   r_   r^   rX   rS   rO   rJ   rN   rG   r\   r]   rU   rg   rV   rP   rW   rT   rM   rY   rL   )NNFNNTTF   r      NN)r   zapplication/octet-streamN)	r   r   r   r   r   r#   rn   r   r   r   r   r   rC   rC   e   s3     EJKODFBF	=&~  (*2D1r   rC   c                   $    \ rS rSrSrS rS rSrg)	NoStoragei?  z"A no-op implementation of storage.c                     g r   r   r!   s    r   
locked_getNoStorage.locked_getB  s    r   c                     g r   r   )r"   credentialss     r   
locked_putNoStorage.locked_putE  s    r   r   N)r   r   r   r   r   r   r   r   r   r   r   r   r   ?  s    *	r   r   c                   j   ^  \ rS rSrSr " S S\5      r " S S\5      r    S
U 4S jjr	S r
S	rU =r$ )HttpRpcServerOAuth2iI  zA variant of HttpRpcServer which uses oauth2.

This variant is specifically meant for interactive command line usage,
as it will attempt to open a browser and ask the user to enter
information from the resulting web page.
c                   &    \ rS rSrSr  SS jrSrg)$HttpRpcServerOAuth2.OAuth2ParametersiQ  z@Class encapsulating parameters related to OAuth2 authentication.Nc	                 d    Xl         X l        X0l        X@l        XPl        X`l        Xpl        Xl        g r   )access_token	client_idclient_secretscoperefresh_tokencredential_file	token_urir   )	r"   r   r   r   r   r   r   r   r   s	            r   r#   -HttpRpcServerOAuth2.OAuth2Parameters.__init__T  s1     ' n(j(, n$r   )r   r   r   r   r   r   r   r   )NN)r   r   r   r   r   r#   r   r   r   r   OAuth2Parametersr   Q  s    J <@!
%r   r   c                       \ rS rSrS rSrg)HttpRpcServerOAuth2.FlowFlagsi`  c                     [         R                  " [         R                  " 5       R                  5      U l        U(       a  UR
                  (       + OSU l        SS/U l        SU l        g )NTi  i  	localhost)	r   getLevelName	getLoggerlevellogging_levelauth_local_webservernoauth_local_webserverauth_host_portauth_host_name)r"   optionss     r   r#   &HttpRpcServerOAuth2.FlowFlags.__init__b  sT    "//0A0A0C0I0IJd(/ *1)E)E%E59 !!4Ld'dr   )r   r   r   r   N)r   r   r   r   r#   r   r   r   r   	FlowFlagsr   `  s    (r   r   c                   > [         [        U ]  USX4UXhXUXUUUS9  [        X R                  5      (       d  [        SU-  5      eX l        U(       aN  UR                  =(       d    Sn[        R                  " [        R                  R                  U5      5      U l        O[        5       U l        UR                  (       a  UR                  U l        O[!        UR"                  UR$                  UR&                  45      (       a  UR&                  =(       d)    S[(        R*                  " [        R,                  SS5      -  n[.        R0                  " UR"                  UR2                  UR4                  UR$                  SUU R6                  5      U l        OU R                  R9                  5       U l        U R;                  U5      U l        g)a  Creates a new HttpRpcServerOAuth2.

Args:
  host: The host to send requests to.
  oauth2_parameters: An object of type OAuth2Parameters (defined above)
    that specifies all parameters related to OAuth2 authentication. (This
    replaces the auth_function parameter in the parent class.)
  user_agent: The user-agent string to send to the server. Specify None to
    omit the user-agent header.
  source: Saved but ignored.
  host_override: The host header to send to the server (defaults to host).
  extra_headers: A dict of extra headers to append to every request. Values
    supplied here will override other default headers that are supplied.
  save_cookies: If the refresh token should be saved.
  auth_tries: The number of times to attempt auth_function before failing.
  account_type: Ignored.
  debug_data: Whether debugging output should include data contents.
  secure: If the requests sent using Send should be sent over HTTPS.
  ignore_certs: If the certificate mismatches should be ignored.
  rpc_tries: The number of rpc retries upon http server error (i.e.
    Response code >= 500 and < 600) before failing.
  timeout_max_errors: The number of rpc retries upon http server timeout
    (i.e. Response code 408) before failing.
  options: the command line options.
  http_class: the httplib2.Http subclass to use. Defaults to httplib2.Http.
  http_object: an httlib2.Http object to use to make requests. If this is
    provided, http_class is ignored.
N)rN   rO   rh   rS   rT   rU   ri   rY   rP   r\   r]   z1oauth2_parameters must be an OAuth2Parameters: %rz~/.appcfg_oauth2_tokenszhttps://%s/o/oauth2/tokenAPPENGINE_AUTH_SERVERzaccounts.google.com)superr   r#   
isinstancer   	TypeErroroauth2_parametersr   oauth2client_fileStorager`   ra   
expanduserstorager   r   anyr   r   r   r   GetEncodedValueenvironr   OAuth2Credentialsr   r   rL   r&   r   flags)r"   rJ   r   rL   rM   rN   rO   rP   rh   rR   rS   rT   rU   ri   rY   r   r\   r]   oauth2_credential_filer   	__class__s                       r   r#   HttpRpcServerOAuth2.__init__i  s   B 

t-dJm#<!j . ! ')>)>??I'( ) ). 1 A A !=#< &..
''

3
46dl [dl$$*66d	,,.?.M.M))+ 
, 
,$.. 0/,,

$;-// 
  11

(
(

%
%

)
)

)
)


//d ))+d(DJr   c                    U(       Ga  U R                   (       a  U R                   R                  (       Gas  U R                  R                  (       a   [        R                  S5        [        S5      eU R                  R                  (       a   [        R                  S5        [        S5      eU R                  R                  (       a7  [        R                  S5        [        SU R                  R                  -   5      e[        R                  S5        [        R                  " U R                  R                  U R                  R                  [        U R                  R                  5      U R                   S9n["        R$                  " X0R&                  U R(                  5      U l         U R                   (       ao  U R                   R                  (       dT  U R                   R*                  (       a  U(       a2  [        R                  S	U5        U R                   R-                  U5        g
[        R                  SU5        g
)a#  Pre or Re-auth stuff...

This will attempt to avoid making any OAuth related HTTP connections or
user interactions unless it's needed.

Args:
  http: An 'Http' object from httplib2.
  needs_auth: If the user has already tried to contact the server.
    If they have, it's OK to prompt them. If not, we should not be asking
    them for auth info--it's possible it'll suceed w/o auth, but if we have
    some credentials we'll use them anyway.

Raises:
  AuthPermanentFail: The user has requested non-interactive auth but
    the token is invalid.
zM_Authenticate skipping auth because user explicitly supplied an access token.zAccess token is invalid.zM_Authenticate skipping auth because user explicitly supplied a refresh token.zRefresh token is invalid.z_Authenticate skipping auth because user explicitly supplied a Token URI, for example for service account authentication with Compute Enginez'Token URI did not yield a valid token: z_Authenticate requesting auth)r   r   r   rL   z-_Authenticate configuring auth; needs_auth=%sNz)_Authenticate skipped auth; needs_auth=%s)r   invalidr   r   rz   r{   r   r   r   oauth_parametersr   OAuth2WebServerFlowr   r   _ScopesToStringr   rL   r   run_flowr   r   access_token_expired	authorize)r"   rG   
needs_authflows       r   rn   !HttpRpcServerOAuth2._Authenticate  s   " 4++t/?/?/G/G/G
 
			,	, 1 	2 :;;				-	- 1 	2 ;<<				)	) : 	;   I $ 5 5 ? ?!@ A 	All23''**44..<< 6 6 < <=__	&d
 llDJJGd 0 0 8 8 22jD	!""4(
LL<jIr   )r   r   r   r   )NNFNNTTFr   r   NNN)r   r   r   r   r   r   r   objectr   r#   rn   r   __classcell__)r   s   @r   r   r   I  sC    % %(& ( EJKOCD:>	J)X3J 3Jr   r   c                 f    [        U [        R                  5      (       a  U $ SR                  U 5      $ )z!Converts scope value to a string.r3   )r   r	   string_typesrc   )scopess    r   r   r     s+     
//00M88Fr   )r   )+r   
__future__r   r4   r   r`   r   r   r   urllibrZ   oauth2clientr   r   r   r   googlecloudsdk.core.utilr   *googlecloudsdk.appengine.tools.value_mixinr   "googlecloudsdk.appengine._internalr	   PY3errorr9   parse	urlencoder   urllib2r   rz   r   	Exceptionr   r   r   r   rA   rC   r   r   r   r   r   r   r   <module>r      s    ' 
  	  	     2  - A 9 >>ll$$)'',)!!, 
		I	J  I @ @&  IW1F W1t	 	_J/ _JDr   