
                         D   S 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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r\R6                  " \5      rSrSr\c  Sr Sr!Sr"Sr#Sr$Sr%OH\R@                  r \RB                  r!\RD                  r"\RL                  r#\RN                  r$\RJ                  r%S r( " S S\RR                  5      r*S r+S r, " S S\RZ                  5      r. " S S\R^                  5      r0 " S S\R^                  5      r1 " S S\Rd                  5      r3 " S S\RR                  5      r4S r5S  r6 " S! S"\75      r8 " S# S$\85      r9\Rt                  " S%5       S'S& j5       r;g! \ a    Sr GN:f = f)(zgUtilities for Google App Engine

Utilities for making it easier to use OAuth 2.0 on Google App Engine.
    N)app_identity)memcache)users)db)login_required)client)clientsecrets)util)xsrfutil)_appengine_ndbz$jcgregorio@google.com (Joe Gregorio)zoauth2client#nsxsrf_secret_keyc                 L    [         R                  " U SS9R                  SS5      $ )z~Escape text to make it safe to display.

Args:
    s: string, The text to escape.

Returns:
    The escaped text as a string.
   )quote'z&#39;)cgiescapereplace)ss    1lib/third_party/oauth2client/contrib/appengine.py
_safe_htmlr   H   s"     ::aq!))#w77    c                   :    \ rS rSrSr\R                  " 5       rSrg)SiteXsrfSecretKeyT   zyStorage for the sites XSRF secret key.

There will only be one instance stored of this model, the one used for the
site.
 N)	__name__
__module____qualname____firstlineno____doc__r   StringPropertysecret__static_attributes__r   r   r   r   r   T   s    
  Fr   r   c                  L    [         R                  " S5      R                  S5      $ )z!Returns a random XSRF secret key.   hex)osurandomencoder   r   r   _generate_new_xsrf_secret_keyr+   ]   s    ::b>  ''r   c                  :   [         R                  " [        [        S9n U (       dm  [        R                  SS9nUR                  (       d  [        5       Ul        UR                  5         UR                  n [         R                  " [        U [        S9  [        U 5      $ )zReturn the secret key for use for XSRF protection.

If the Site entity does not have a secret key, this method will also create
one and persist it.

Returns:
    The secret key.
)	namespacesite)key_name)r   getXSRF_MEMCACHE_IDOAUTH2CLIENT_NAMESPACEr   get_or_insertr#   r+   putaddstr)r#   models     r   r   r   b   so     \\*6LMF!///@||8:ELIIK%v5	7 v;r   c                      ^  \ rS rSrSr\R                  " S5      U 4S j5       r\S 5       r	S r
\S 5       rS rS	 rS
 r\S 5       rSrU =r$ )AppAssertionCredentialsy   a  Credentials object for App Engine Assertion Grants

This object will allow an App Engine application to identify itself to
Google and other OAuth 2.0 servers that can verify assertions. It can be
used for the purpose of accessing data stored under an account assigned to
the App Engine application itself.

This credential does not require a flow to instantiate because it
represents a two legged flow, and therefore has all of the required
information to generate and refresh its own access tokens.
   c                    > [         R                  " U5      U l        X l        UR	                  SS5      U l        SU l        [        [        U ]'  S5        g)ay  Constructor for AppAssertionCredentials

Args:
    scope: string or iterable of strings, scope(s) of the credentials
           being requested.
    **kwargs: optional keyword args, including:
    service_account_id: service account id of the application. If None
                        or unspecified, the default service account for
                        the app is used.
service_account_idN)
r
   scopes_to_stringscope_kwargsr0   r=   _service_account_emailsuperr9   __init__)selfr?   kwargs	__class__s      r   rC    AppAssertionCredentials.__init__   sJ     **51
"(**-A4"H&*# 	%t5d;r   c                 J    [         R                  " U5      n[        US   5      $ )Nr?   )jsonloadsr9   )cls	json_datadatas      r   	from_json!AppAssertionCredentials.from_json   s    zz)$&tG}55r   c                      U R                   R                  5       n[        R                  " X R                  S9u  p4X0l	        g! [        R
                   a$  n[        R                  " [        U5      5      eSnAff = f)a  Refreshes the access_token.

Since the underlying App Engine app_identity implementation does its
own caching we can skip all the storage hoops and just to a refresh
using the API.

Args:
    http_request: callable, a callable that matches the method
                  signature of httplib2.Http.request, used to make the
                  refresh request.

Raises:
    AccessTokenRefreshError: When the refresh fails.
)r=   N)
r?   splitr   get_access_tokenr=   Errorr   AccessTokenRefreshErrorr6   access_token)rD   http_requestscopestoken_es         r   _refresh AppAssertionCredentials._refresh   sj    	9ZZ%%'F%66+B+BDJU " !! 	900Q88	9s   :A A;A66A;c                     [        S5      e)Nz3Cannot serialize credentials for Google App Engine.)NotImplementedErrorrD   s    r   serialization_data*AppAssertionCredentials.serialization_data   s    ! #; < 	<r   c                 $    U R                   (       + $ N)r?   r_   s    r   create_scoped_required.AppAssertionCredentials.create_scoped_required   s    ::~r   c                 .    [        U40 U R                  D6$ rc   )r9   r@   )rD   rW   s     r   create_scoped%AppAssertionCredentials.create_scoped   s    &v>>>r   c                 .    [         R                  " U5      $ )a  Cryptographically sign a blob (of bytes).

Implements abstract method
:meth:`oauth2client.client.AssertionCredentials.sign_blob`.

Args:
    blob: bytes, Message to be signed.

Returns:
    tuple, A pair of the private key ID used to sign the blob and
    the signed contents.
)r   	sign_blob)rD   blobs     r   rj   !AppAssertionCredentials.sign_blob   s     %%d++r   c                 h    U R                   c  [        R                  " 5       U l         U R                   $ )zGet the email for the current service account.

Returns:
    string, The email associated with the Google App Engine
    service account.
)rA   r   get_service_account_namer_   s    r   service_account_email-AppAssertionCredentials.service_account_email   s0     &&.557 '***r   )r@   rA   rU   r?   r=   )r   r   r   r    r!   r
   
positionalrC   classmethodrN   r[   propertyr`   rd   rg   rj   ro   r$   __classcell__rF   s   @r   r9   r9   y   su    
 
__Q< <( 6 6". < <?, 
+ 
+r   r9   c                   \   ^  \ rS rSrSr\R                  rU 4S jrS r	U 4S jr
S rSrU =r$ )FlowProperty   zyApp Engine datastore Property for Flow.

Utility property that allows easy storage and retrieval of an
oauth2client.Flow
c                 ~   > [         [        U ]  U5      n[        R                  " [
        R                  " U5      5      $ rc   )rB   rw   get_value_for_datastorer   Blobpickledumps)rD   model_instanceflowrF   s      r   rz   $FlowProperty.get_value_for_datastore   s/    \4@wwv||D)**r   c                 6    Uc  g [         R                  " U5      $ rc   )r|   rJ   rD   values     r   make_value_from_datastore&FlowProperty.make_value_from_datastore   s    =||E""r   c                    > UbO  [        U[        R                  5      (       d0  [        R                  " SR                  U R                  U5      5      e[        [        U ]'  U5      $ )NzDProperty {0} must be convertible to a FlowThreeLegged instance ({1}))

isinstancer   Flowr   BadValueErrorformatnamerB   rw   validaterD   r   rF   s     r   r   FlowProperty.validate   sW    Zv{{%C%C""66<fTYY6NP P \41%88r   c                     U(       + $ rc   r   r   s     r   emptyFlowProperty.empty   s
    yr   r   )r   r   r   r    r!   r   r   	data_typerz   r   r   r   r$   rt   ru   s   @r   rw   rw      s,     I+#
9 r   rw   c                   V   ^  \ rS rSrSr\R                  rU 4S jrS r	U 4S jr
SrU =r$ )CredentialsProperty   zApp Engine datastore Property for Credentials.

Utility property that allows easy storage and retrieval of
oauth2client.Credentials
c                    > [         R                  S[        [        U5      5      -   5        [        [
        U ]  U5      nUc  SnOUR                  5       n[        R                  " U5      $ )Nzget: Got type  )
loggerinfor6   typerB   r   rz   to_jsonr   r{   )rD   r~   credrF   s      r   rz   +CredentialsProperty.get_value_for_datastore  sW    $s4+?'@@A($G<D<<>Dwwt}r   c                     [         R                  S[        [        U5      5      -   5        Uc  g [	        U5      S:X  a  g  [
        R                  R                  U5      nU$ ! [         a    S n U$ f = f)Nzmake: Got type r   )	r   r   r6   r   lenr   Credentialsnew_from_json
ValueError)rD   r   credentialss      r   r   -CredentialsProperty.make_value_from_datastore  sr    %DK(889=u:?	 ,,::5AK   	K	s    A! !A10A1c                 &  > [         [        U ]  U5      n[        R	                  S[        [        U5      5      -   5        UbO  [        U[        R                  5      (       d0  [        R                  " SR                  U R                  U5      5      eU$ )Nzvalidate: Got type z@Property {0} must be convertible to a Credentials instance ({1}))rB   r   r   r   r   r6   r   r   r   r   r   r   r   r   r   s     r   r   CredentialsProperty.validate"  sy    )49%@)CU,<<=Zv7I7I%J%J""228&E2JL L r   r   )r   r   r   r    r!   r   r   r   rz   r   r   r$   rt   ru   s   @r   r   r      s)     ""I
 r   r   c                      ^  \ rS rSrSr\R                  " S5      SU 4S jj5       rS rS r	S r
\R                  " SS	9S
 5       r\R                  " SS	9S 5       r\R                  " SS	9S 5       rSrU =r$ )StorageByKeyNamei,  zStore and retrieve a credential to and from the App Engine datastore.

This Storage helper presumes the Credentials have been stored as a
CredentialsProperty or CredentialsNDBProperty on a datastore model class,
and that entities are stored by key_name.
   c                    > [         [        U ]  5         Uc  Uc  [        S5      eUR	                  5       nXl        X l        X0l        X@l        g)a  Constructor for Storage.

Args:
    model: db.Model or ndb.Model, model class
    key_name: string, key name for the entity that has the credentials
    property_name: string, name of the property that is a
                   CredentialsProperty or CredentialsNDBProperty.
    cache: memcache, a write-through cache to put in front of the
           datastore. If the model you are using is an NDB model, using
           a cache will be redundant since the model uses an instance
           cache and memcache for you.
    user: users.User object, optional. Can be used to grab user ID as a
          key_name if no key name is specified.
Nz1StorageByKeyName called with no key name or user.)	rB   r   rC   r   user_id_model	_key_name_property_name_cache)rD   r7   r/   property_namecacheuserrF   s         r   rC   StorageByKeyName.__init__4  sP      	.0|  "5 6 6||~H!+r   c                 *   [        U R                  [        5      (       aQ  [        b   [	        U R                  [        5      (       a  g[	        U R                  [
        R                  5      (       a  g[        SR                  U R                  5      5      e)zDetermine whether the model of the instance is an NDB model.

Returns:
    Boolean indicating whether or not the model is an NDB or DB model.
TFz(Model class not an NDB or DB model: {0}.)	r   r   r   
_NDB_MODEL
issubclassr   Model	TypeErrorr   r_   s    r   _is_ndbStorageByKeyName._is_ndbQ  sg     dkk4((%*T[[**M*MDKK226==dkkJL 	Lr   c                     U R                  5       (       a%  U R                  R                  U R                  5      $ U R                  R	                  U R                  5      $ )zRetrieve entity from datastore.

Uses a different model method for db or ndb models.

Returns:
    Instance of the model corresponding to the current storage object
    and stored using the key name of the storage object.
)r   r   	get_by_idr   get_by_key_namer_   s    r   _get_entityStorageByKeyName._get_entityc  sA     <<>>;;((88;;..t~~>>r   c                 <   U R                  5       (       a/  [        U R                  U R                  5      R	                  5         g[
        R                  R                  U R                  R                  5       U R                  5      n[
        R                  " U5        g)zDelete entity from datastore.

Attempts to delete using the key_name stored on the object, whether or
not the given key is in the datastore.
N)	r   _NDB_KEYr   r   deleter   Key	from_pathkind)rD   
entity_keys     r   _delete_entityStorageByKeyName._delete_entityq  s]     <<>>T[[$..188:))$++*:*:*<dnnMJIIj!r   T)allow_existingc                    SnU R                   (       aK  U R                   R                  U R                  5      nU(       a  [        R                  R                  U5      nUcm  U R                  5       nUbZ  [        X0R                  5      nU R                   (       a4  U R                   R                  U R                  UR                  5       5        U(       a"  [        US5      (       a  UR                  U 5        U$ )zKRetrieve Credential from datastore.

Returns:
    oauth2client.Credentials
N	set_store)r   r0   r   r   r   r   r   getattrr   setr   hasattrr   )rD   r   rI   entitys       r   
locked_getStorageByKeyName.locked_get}  s     ;;;;??4>>2D$00>>tD%%'F!%f.A.AB;;KKOODNNK4G4G4IJ7;<<!!$'r   c                 &   U R                   R                  U R                  5      n[        X R                  U5        UR                  5         U R                  (       a5  U R                  R                  U R                  UR                  5       5        gg)zeWrite a Credentials to the datastore.

Args:
    credentials: Credentials, the credentials to store.
N)	r   r3   r   setattrr   r4   r   r   r   )rD   r   r   s      r   
locked_putStorageByKeyName.locked_put  s`     **4>>:++[9

;;KKOODNNK,?,?,AB r   c                     U R                   (       a%  U R                   R                  U R                  5        U R                  5         g)z!Delete Credential from datastore.N)r   r   r   r   r_   s    r   locked_deleteStorageByKeyName.locked_delete  s-     ;;KKt~~.r   )r   r   r   r   NN)r   r   r   r    r!   r
   rq   rC   r   r   r   r   non_transactionalr   r   r   r$   rt   ru   s   @r   r   r   ,  s     
__Q 8L$?
" . /, .
C /
C . /r   r   c                   &    \ rS rSrSr\" 5       rSrg)CredentialsModeli  zXStorage for OAuth 2.0 Credentials

Storage of the model is keyed by the user.user_id().
r   N)r   r   r   r    r!   r   r   r$   r   r   r   r   r     s     &'Kr   r   c                     U R                   R                  n[        R                  " [	        5       UR                  5       [        U5      S9nUS-   U-   $ )ah  Composes the value for the 'state' parameter.

Packs the current request URI and an XSRF token into an opaque string that
can be passed to the authentication server via the 'state' parameter.

Args:
    request_handler: webapp.RequestHandler, The request.
    user: google.appengine.api.users.User, The current user.

Returns:
    The state value as a string.
	action_id:)requesturlr   generate_tokenr   r   r6   )request_handlerr   urirX   s       r   _build_state_valuer     sH     
!
!
%
%C##O$5t||~.1#h8E9ur   c                     U R                  SS5      u  p#[        R                  " [        5       X1R	                  5       US9(       a  U$ g)a.  Parse the value of the 'state' parameter.

Parses the value and validates the XSRF token in the state parameter.

Args:
    state: string, The value of the state parameter.
    user: google.appengine.api.users.User, The current user.

Returns:
    The redirect URI, or None if XSRF token is not valid.
r   r   r   N)rsplitr   validate_tokenr   r   )stater   r   rX   s       r   _parse_state_valuer     s<     c1%JC0%),.
r   c                      \ rS rSrSrS rS r\" \\5      rS r	S r
\" \
\	5      r\R                  " S5      \R                  \R                   \R"                  SSS	S\\S
4
S j5       rS rS rS rS rS rS rS r\S 5       rS rS rSrg)OAuth2Decoratori  a(  Utility for making OAuth 2.0 easier.

Instantiate and then use with oauth_required or oauth_aware
as decorators on webapp.RequestHandler methods.

::

    decorator = OAuth2Decorator(
        client_id='837...ent.com',
        client_secret='Qh...wwI',
        scope='https://www.googleapis.com/auth/plus')

    class MainHandler(webapp.RequestHandler):
        @decorator.oauth_required
        def get(self):
            http = decorator.http()
            # http is authorized with the user's Credentials and can be
            # used in API calls

c                 $    XR                   l        g rc   )_tlsr   )rD   r   s     r   set_credentialsOAuth2Decorator.set_credentials  s     +		r   c                 0    [        U R                  SS5      $ )zA thread local Credentials object.

Returns:
    A client.Credentials object, or None if credentials hasn't been set
    in this thread yet, which may happen when calling has_credentials
    inside oauth_aware.
r   Nr   r   r_   s    r   get_credentialsOAuth2Decorator.get_credentials  s     tyy-66r   c                 $    XR                   l        g rc   )r   r   )rD   r   s     r   set_flowOAuth2Decorator.set_flow  s    		r   c                 0    [        U R                  SS5      $ )zA thread local Flow object.

Returns:
    A credentials.Flow object, or None if the flow hasn't been set in
    this thread yet, which happens in _create_flow() since Flows are
    created lazily.
r   Nr   r_   s    r   get_flowOAuth2Decorator.get_flow  s     tyy&$//r   r   Nz/oauth2callbackr   c                 4   [         R                  " 5       U l        SU l        SU l        Xl        X l        [        R                  " U5      U l	        X@l
        XPl        X`l        Xpl        Xl        Xl        SU l        Xl        Xl        Xl        Xl        Xl        g)a
  Constructor for OAuth2Decorator

Args:
    client_id: string, client identifier.
    client_secret: string client secret.
    scope: string or iterable of strings, scope(s) of the credentials
           being requested.
    auth_uri: string, URI for authorization endpoint. For convenience
              defaults to Google's endpoints but any OAuth 2.0 provider
              can be used.
    token_uri: string, URI for token endpoint. For convenience defaults
               to Google's endpoints but any OAuth 2.0 provider can be
               used.
    revoke_uri: string, URI for revoke endpoint. For convenience
                defaults to Google's endpoints but any OAuth 2.0
                provider can be used.
    user_agent: string, User agent of your application, default to
                None.
    message: Message to display if there are problems with the
             OAuth 2.0 configuration. The message may contain HTML and
             will be presented on the web interface for any method that
             uses the decorator.
    callback_path: string, The absolute path to use as the callback
                   URI. Note that this must match up with the URI given
                   when registering the application in the APIs
                   Console.
    token_response_param: string. If provided, the full JSON response
                          to the access token request will be encoded
                          and included in this query parameter in the
                          callback URI. This is useful with providers
                          (e.g. wordpress.com) that include extra
                          fields that the client may want.
    _storage_class: "Protected" keyword argument not typically provided
                    to this constructor. A storage class to aid in
                    storing a Credentials object for a user in the
                    datastore. Defaults to StorageByKeyName.
    _credentials_class: "Protected" keyword argument not typically
                        provided to this constructor. A db or ndb Model
                        class to hold credentials. Defaults to
                        CredentialsModel.
    _credentials_property_name: "Protected" keyword argument not
                                typically provided to this constructor.
                                A string indicating the name of the
                                field on the _credentials_class where a
                                Credentials object will be stored.
                                Defaults to 'credentials'.
    **kwargs: dict, Keyword arguments are passed along as kwargs to
              the OAuth2WebServerFlow constructor.
NF)	threadinglocalr   r   r   
_client_id_client_secretr
   r>   _scope	_auth_uri
_token_uri_revoke_uri_user_agentr@   _message	_in_error_callback_path_token_response_param_storage_class_credentials_class_credentials_property_name)rD   	client_idclient_secretr?   auth_uri	token_uri
revoke_uri
user_agentmessagecallback_pathtoken_response_paramr
  r  r  rE   s                  r   rC   OAuth2Decorator.__init__  s    | OO%		#+++E2!#%%+%9","4*D'r   c                    UR                   R                  R                  S5        UR                   R                  R                  [        U R                  5      5        UR                   R                  R                  S5        g )Nz<html><body>z</body></html>)responseoutwriter   r  )rD   r   s     r   _display_error_message&OAuth2Decorator._display_error_message_  sZ      $$**>:  $$**:dmm+DE  $$**+;<r   c                    ^ ^ UU 4S jnU$ )zDecorator that starts the OAuth 2.0 dance.

Starts the OAuth dance for the logged in user if they haven't already
granted access for this application.

Args:
    method: callable, to be decorated method of a webapp.RequestHandler
            instance.
c                   > TR                   (       a  TR                  U 5        g [        R                  " 5       nU(       d:  U R	                  [        R
                  " U R                  R                  5      5        g TR                  U 5        [        X5      TR                  R                  S'   TR                  TR                  S TR                  US9R                  5       Tl        TR#                  5       (       d  U R	                  TR%                  5       5      $  T" U /UQ70 UD6n S Tl        U$ ! [&        R(                   a)    U R	                  TR%                  5       5      s S Tl        $ f = f! S Tl        f = fNr   r   )r  r  r   get_current_userredirectcreate_login_urlr   r   _create_flowr   r   paramsr
  r  r  r0   r   has_credentialsauthorize_urlr   rT   r   argsrE   r   respmethodrD   s        r   check_oauth3OAuth2Decorator.oauth_required.<locals>.check_oautho  sX   ~~++O<))+D (()?)?#++//*1 2o. );)'DIIW%#22''//d  3  <<?CE  ''))&//0B0B0DEE(o??? $( K	 11 F&//0B0B0DEE#' F $( s$   D2 23E/%E2 .E//E2 2	E;r   )rD   r+  r,  s   `` r   oauth_requiredOAuth2Decorator.oauth_requiredd  s    	@ r   c           	      P   U R                   c  UR                  R                  U R                  5      n[        R
                  " U R                  U R                  U R                  4X R                  U R                  U R                  U R                  S.U R                  D6U l         gg)a%  Create the Flow object.

The Flow is calculated lazily since we don't know where this app is
running until it receives a request, at which point redirect_uri can be
calculated and then the Flow object can be constructed.

Args:
    request_handler: webapp.RequestHandler, the request handler.
N)redirect_urir  r  r  r  )r   r   relative_urlr  r   OAuth2WebServerFlowr   r   r  r  r  r  r  r@   )rD   r   r1  s      r   r$  OAuth2Decorator._create_flow  s     99*22??##%L22!4!4dkk=)6F6F4??++	= 04||	=DI r   c                    ^ ^ UU 4S jnU$ )a  Decorator that sets up for OAuth 2.0 dance, but doesn't do it.

Does all the setup for the OAuth dance, but doesn't initiate it.
This decorator is useful if you want to create a page that knows
whether or not the user has granted access to this application.
From within a method decorated with @oauth_aware the has_credentials()
and authorize_url() methods can be called.

Args:
    method: callable, to be decorated method of a webapp.RequestHandler
            instance.
c                   > TR                   (       a  TR                  U 5        g [        R                  " 5       nU(       d:  U R	                  [        R
                  " U R                  R                  5      5        g TR                  U 5        [        U U5      TR                  R                  S'   TR                  TR                  S TR                  US9R                  5       Tl         T" U /UQ70 UD6nS Tl        U$ ! S Tl        f = fr  )r  r  r   r!  r"  r#  r   r   r$  r   r   r%  r
  r  r  r0   r   r(  s        r   setup_oauth0OAuth2Decorator.oauth_aware.<locals>.setup_oauth  s    ~~++O<))+D (()?)?#++//*1 2o.(:?;?)ADIIW%#22''//d  3  <<?CE (o???#' K $( s   )C> >	Dr   )rD   r+  r7  s   `` r   oauth_awareOAuth2Decorator.oauth_aware  s    	2 r   c                 b    U R                   SL=(       a    U R                   R                  (       + $ )zTrue if for the logged in user there are valid access Credentials.

Must only be called from with a webapp.RequestHandler subclassed method
that had been decorated with either @oauth_required or @oauth_aware.
N)r   invalidr_   s    r   r&  OAuth2Decorator.has_credentials  s)     t+LD4D4D4L4L0LLr   c                 L    U R                   R                  5       n[        U5      $ )zReturns the URL to start the OAuth dance.

Must only be called from with a webapp.RequestHandler subclassed method
that had been decorated with either @oauth_required or @oauth_aware.
)r   step1_get_authorize_urlr6   )rD   r   s     r   r'  OAuth2Decorator.authorize_url  s     ii//13xr   c                 `    U R                   R                  [        R                  " U0 UD65      $ )aU  Returns an authorized http instance.

Must only be called from within an @oauth_required decorated method, or
from within an @oauth_aware decorated method where has_credentials()
returns True.

Args:
    *args: Positional arguments passed to httplib2.Http constructor.
    **kwargs: Positional arguments passed to httplib2.Http constructor.
)r   	authorizehttplib2Http)rD   r)  rE   s      r   httpOAuth2Decorator.http  s)     ))(--*H*HIIr   c                     U R                   $ )zThe absolute path where the callback will occur.

Note this is the absolute path, not the absolute URI, that will be
calculated by the decorator at runtime. See callback_handler() for how
this should be used.

Returns:
    The callback path as a string.
)r  r_   s    r   r  OAuth2Decorator.callback_path  s     """r   c                 D   ^ U m " U4S jS[         R                  5      nU$ )aN  RequestHandler for the OAuth 2.0 redirect callback.

Usage::

    app = webapp.WSGIApplication([
        ('/index', MyIndexHandler),
        ...,
        (decorator.callback_path, decorator.callback_handler())
    ])

Returns:
    A webapp.RequestHandler that handles the redirect back from the
    server during the OAuth 2.0 dance.
c                   0   > \ rS rSrSr\U 4S j5       rSrg)7OAuth2Decorator.callback_handler.<locals>.OAuth2Handleri	  z4Handler for the redirect_uri of the OAuth 2.0 dance.c                   > U R                   R                  S5      nU(       aZ  U R                   R                  SU5      nU R                  R                  R	                  SR                  [        U5      5      5        g [        R                  " 5       nTR                  U 5        TR                  R                  U R                   R                  5      nTR                  TR                  S TR                  US9R!                  U5        [#        [%        U R                   R                  S5      5      U5      nUc&  U R                  R                  R	                  S5        g TR&                  (       aS  UR(                  (       aB  [*        R,                  " UR(                  5      n[.        R0                  " UTR&                  U5      nU R3                  U5        g )Nerrorerror_descriptionz%The authorization request failed: {0}r   r   z The authorization request failed)r   r0   r  r  r  r   r   r   r!  r$  r   step2_exchanger%  r
  r  r  r4   r   r6   r	  token_responserI   r}   r
   _add_query_parameterr"  )rD   rM  errormsgr   r   r1  	resp_json	decorators          r   r0   ;OAuth2Decorator.callback_handler.<locals>.OAuth2Handler.get  sn   ((1#||//0CUKHMM%%++?FF&x023 !113D**40"+.."?"?++#-K,,!44d!<<! - # $'3{#3#5DLL,,W56$>L#+))//>@!77'66$(JJ{/I/I$J	'+'@'@()*I*I%(' MM,/r   r   N)r   r   r   r    r!   r   r0   r$   )rT  s   r   OAuth2HandlerrK  	  s    F0 0r   rV  )webappRequestHandler)rD   rV  rT  s     @r   callback_handler OAuth2Decorator.callback_handler  s%     	"	0F11 "	0H r   c                 d    [         R                  " U R                  U R                  5       4/5      $ )a  WSGI application for handling the OAuth 2.0 redirect callback.

If you need finer grained control use `callback_handler` which returns
just the webapp.RequestHandler.

Returns:
    A webapp.WSGIApplication that handles the redirect back from the
    server during the OAuth 2.0 dance.
)rW  WSGIApplicationr  rY  r_   s    r   callback_application$OAuth2Decorator.callback_application/  s3     %%!6!6!89'
  	r   )r  r  r   r   r  r  r  r@   r  r  r  r
  r   r	  r  r  r   r   ) r   r   r   r    r!   r   r   rs   r   r   r   r   r
   rq   oauth2clientGOOGLE_AUTH_URIGOOGLE_TOKEN_URIGOOGLE_REVOKE_URIr   r   rC   r  r.  r$  r9  r&  r'  rE  r  rY  r]  r$   r   r   r   r   r     s    *,7 ?O<K0 Hh'D	__Q&66'88(:: 0&* 0$4,9NE NE`=
+Z=&'RMJ 
# 
#5nr   r   c                   Z   ^  \ rS rSrSr\R                  " S5      SU 4S jj5       rSrU =r	$ ) OAuth2DecoratorFromClientSecretsi>  aJ  An OAuth2Decorator that builds from a clientsecrets file.

Uses a clientsecrets file as the source for all the information when
constructing an OAuth2Decorator.

::

    decorator = OAuth2DecoratorFromClientSecrets(
        os.path.join(os.path.dirname(__file__), 'client_secrets.json')
        scope='https://www.googleapis.com/auth/plus')

    class MainHandler(webapp.RequestHandler):
        @decorator.oauth_required
        def get(self):
            http = decorator.http()
            # http is authorized with the user's Credentials and can be
            # used in API calls

   c                   > [         R                  " UUS9u  pgU[         R                  [         R                  4;  a  [         R                  " S5      e[        U5      nUR                  US   US   US.5        UR                  S5      n	U	b  XS'   [        [        U ]*  " US   US	   U40 UD6  Ub  X0l        gS
U l        g)a  Constructor

Args:
    filename: string, File name of client secrets.
    scope: string or iterable of strings, scope(s) of the credentials
           being requested.
    message: string, A friendly string to display to the user if the
             clientsecrets file is missing or invalid. The message may
             contain HTML and will be presented on the web interface
             for any method that uses the decorator.
    cache: An optional cache service client that implements get() and
           set()
    methods. See clientsecrets.loadfile() for details.
    **kwargs: dict, Keyword arguments are passed along as kwargs to
              the OAuth2WebServerFlow constructor.
)r   z4OAuth2Decorator doesn't support this OAuth 2.0 flow.r  r  )r  r  r  r  Nr  r  z0Please configure your application for OAuth 2.0.)r	   loadfileTYPE_WEBTYPE_INSTALLEDInvalidClientSecretsErrordictupdater0   rB   rd  rC   r  )rD   filenamer?   r  r   rE   client_typeclient_infoconstructor_kwargsr  rF   s             r   rC   )OAuth2DecoratorFromClientSecrets.__init__S  s    $ $1#9#9(@E$G }55,;;= =99FH H "&\!!#J/$[1#
 	
 !__\2
!/9|,.>$k/&B	)'	) #MNDMr   )r  r   )
r   r   r   r    r!   r
   rq   rC   r$   rt   ru   s   @r   rd  rd  >  s'    ( 
__Q'O 'Or   rd  r;   c                     [        XX#S9$ )a  Creates an OAuth2Decorator populated from a clientsecrets file.

Args:
    filename: string, File name of client secrets.
    scope: string or list of strings, scope(s) of the credentials being
           requested.
    message: string, A friendly string to display to the user if the
             clientsecrets file is missing or invalid. The message may
             contain HTML and will be presented on the web interface for
             any method that uses the decorator.
    cache: An optional cache service client that implements get() and set()
           methods. See clientsecrets.loadfile() for details.

Returns: An OAuth2Decorator
)r  r   )rd  )rm  r?   r  r   s       r   "oauth2decorator_from_clientsecretsrs  ~  s    $ ,H4;J Jr   r   )<r!   r   rI   loggingr(   r|   r   google.appengine.apir   r   r   google.appengine.extr    google.appengine.ext.webapp.utilr   rC  webapp2rW  r_  r   r	   r
   oauth2client.contribr   r   ImportError
__author__	getLoggerr   r   r2   r1   CredentialsNDBModelCredentialsNDBPropertyFlowNDBPropertyr   r   SiteXsrfSecretKeyNDBNDB_KEY	NDB_MODELr   r   r   r+   r   AssertionCredentialsr9   Propertyrw   r   Storager   r   r   r   objectr   rd  rq   rs  r   r   r   <module>r     s  
    	   - ) & # ;     &  )3
 4
			8	$* $ !OHJ(<<+BB$44O%%H))J)>>	8! !(
.c+f99 c+L2;; B)"++ )X|v~~ |~(rxx (&(af aH=O =O@ ;?J Jg  Ns   F FF