
    l                         d Z ddlZddlZddlZddlZddlZddlZddlmZ ddlmZ ddlm	Z	 ddlm
Z
 ddlmZ dZd	Zd
Z G d dej                        Zd Z G d de      Zy)z/oauth2client Service account credentials class.    N)_helpers)client)crypt)	transport)util
notasecret_private_key_pkcs12a
  
This library only implements PKCS#12 support via the pyOpenSSL library.
Either install pyOpenSSL, or please convert the .p12 file
to .pem format:
    $ cat key.p12 | \
    >   openssl pkcs12 -nodes -nocerts -passin pass:notasecret | \
    >   openssl rsa > key.pem
c                       e Zd ZdZdZ	  edg      ej                  j                  z  Z	 dZ	dZ
dZddddej                  ej                  f fd	Zd fd	Ze	 dd       Ze	 	 dd	       Ze	 	 dd
       Zeddej                  ej                  fd       Zeddej                  ej                  fd       Zeddej                  ej                  fd       Zd Zd Zed        Zed        Zed        Zd Zd Zd Z d Z! xZ"S )ServiceAccountCredentialsa  Service Account credential for OAuth 2.0 signed JWT grants.

    Supports

    * JSON keyfile (typically contains a PKCS8 key stored as
      PEM text)
    * ``.p12`` key (stores PKCS12 key and certificate)

    Makes an assertion to server using a signed JWT assertion in exchange
    for an access token.

    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.

    Args:
        service_account_email: string, The email associated with the
                               service account.
        signer: ``crypt.Signer``, A signer which can be used to sign content.
        scopes: List or string, (Optional) Scopes to use when acquiring
                an access token.
        private_key_id: string, (Optional) Private key identifier. Typically
                        only used with a JSON keyfile. Can be sent in the
                        header of a JWT token assertion.
        client_id: string, (Optional) Client ID for the project that owns the
                   service account.
        user_agent: string, (Optional) User agent to use when sending
                    request.
        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.
        kwargs: dict, Extra key-value pairs (both strings) to send in the
                payload body when making an assertion.
      _signerN c	                     t         t        |   d |||       || _        || _        t        j                  |      | _        || _        || _	        || _
        |	| _        y )N)
user_agent	token_uri
revoke_uri)superr   __init___service_account_emailr   r   scopes_to_string_scopes_private_key_id	client_id_user_agent_kwargs)selfservice_account_emailsignerscopesprivate_key_idr   r   r   r   kwargs	__class__s             /lib/third_party/oauth2client/service_account.pyr   z"ServiceAccountCredentials.__init__`   se     	'7Z9! 	8 	# '<#,,V4-"%    c                     |t        j                   | j                        }|j                  t              }|t	        j
                  |      |t        <   t        t        | #  ||      S )ac  Utility function that creates JSON repr. of a credentials object.

        Over-ride is needed since PKCS#12 keys will not in general be JSON
        serializable.

        Args:
            strip: array, An array of names of members to exclude from the
                   JSON.
            to_serialize: dict, (Optional) The properties for this object
                          that will be serialized. This allows callers to
                          modify before serializing.

        Returns:
            string, a JSON representation of this instance, suitable to pass to
            from_json().
        )to_serialize)	copy__dict__get_PKCS12_KEYbase64	b64encoder   r   _to_json)r   stripr&   
pkcs12_valr"   s       r#   r-   z"ServiceAccountCredentials._to_jsonw   sg    " 99T]]3L!%%k2
!(.(8(8(DL%.> ? . 	.r$   c           	         |j                  d      }|t        j                  k7  rt        d|dt        j                        |d   }|d   }|d   }|d   }	|s |j                  dt        j
                        }|s |j                  d	t        j                        }t        j                  j                  |      }
 | ||
|||	||
      }||_
        |S )a	  Helper for factory constructors from JSON keyfile.

        Args:
            keyfile_dict: dict-like object, The parsed dictionary-like object
                          containing the contents of the JSON keyfile.
            scopes: List or string, Scopes to use when acquiring an
                    access token.
            token_uri: string, URI for OAuth 2.0 provider token endpoint.
                       If unset and not present in keyfile_dict, defaults
                       to Google's endpoints.
            revoke_uri: string, URI for OAuth 2.0 provider revoke endpoint.
                       If unset and not present in keyfile_dict, defaults
                       to Google's endpoints.

        Returns:
            ServiceAccountCredentials, a credentials object created from
            the keyfile contents.

        Raises:
            ValueError, if the credential type is not :data:`SERVICE_ACCOUNT`.
            KeyError, if one of the expected keys is not present in
                the keyfile.
        typezUnexpected credentials typeExpectedclient_emailprivate_keyr    r   r   r   )r   r    r   r   r   )r)   r   SERVICE_ACCOUNT
ValueErroroauth2clientGOOGLE_TOKEN_URIGOOGLE_REVOKE_URIr   Signerfrom_string_private_key_pkcs8_pem)clskeyfile_dictr   r   r   
creds_typer   private_key_pkcs8_pemr    r   r   credentialss               r#   _from_parsed_json_keyfilez3ServiceAccountCredentials._from_parsed_json_keyfile   s    4 "%%f-
///:J')?)?A A !-^ < ,] ;%&67 -	$(()5)F)FHI%)),*6*H*HJJ ))*?@/)7$-%/1 .C*r$   c                     t        |d      5 }t        j                  |      }ddd       | j                  |||      S # 1 sw Y   xY w)a  Factory constructor from JSON keyfile by name.

        Args:
            filename: string, The location of the keyfile.
            scopes: List or string, (Optional) Scopes to use when acquiring an
                    access token.
            token_uri: string, URI for OAuth 2.0 provider token endpoint.
                       If unset and not present in the key file, defaults
                       to Google's endpoints.
            revoke_uri: string, URI for OAuth 2.0 provider revoke endpoint.
                       If unset and not present in the key file, defaults
                       to Google's endpoints.

        Returns:
            ServiceAccountCredentials, a credentials object created from
            the keyfile.

        Raises:
            ValueError, if the credential type is not :data:`SERVICE_ACCOUNT`.
            KeyError, if one of the expected keys is not present in
                the keyfile.
        rNr   r   )openjsonloadrB   )r=   filenamer   r   r   file_objclient_credentialss          r#   from_json_keyfile_namez0ServiceAccountCredentials.from_json_keyfile_name   sR    4 (C H!%8!4 !,,-?7@8B - D 	D ! s   A  A	c                 ,    | j                  ||||      S )a  Factory constructor from parsed JSON keyfile.

        Args:
            keyfile_dict: dict-like object, The parsed dictionary-like object
                          containing the contents of the JSON keyfile.
            scopes: List or string, (Optional) Scopes to use when acquiring an
                    access token.
            token_uri: string, URI for OAuth 2.0 provider token endpoint.
                       If unset and not present in keyfile_dict, defaults
                       to Google's endpoints.
            revoke_uri: string, URI for OAuth 2.0 provider revoke endpoint.
                       If unset and not present in keyfile_dict, defaults
                       to Google's endpoints.

        Returns:
            ServiceAccountCredentials, a credentials object created from
            the keyfile.

        Raises:
            ValueError, if the credential type is not :data:`SERVICE_ACCOUNT`.
            KeyError, if one of the expected keys is not present in
                the keyfile.
        rE   )rB   )r=   r>   r   r   r   s        r#   from_json_keyfile_dictz0ServiceAccountCredentials.from_json_keyfile_dict   s(    4 ,,\67@8B - D 	Dr$   c                     |t         }t        j                  t        j                  urt	        t
              t        j                  j                  ||      } | |||||      }||_        ||_        |S )ax  Factory constructor from JSON keyfile.

        Args:
            service_account_email: string, The email associated with the
                                   service account.
            private_key_pkcs12: string, The contents of a PKCS#12 keyfile.
            private_key_password: string, (Optional) Password for PKCS#12
                                  private key. Defaults to ``notasecret``.
            scopes: List or string, (Optional) Scopes to use when acquiring an
                    access token.
            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.

        Returns:
            ServiceAccountCredentials, a credentials object created from
            the keyfile.

        Raises:
            NotImplementedError if pyOpenSSL is not installed / not the
            active crypto library.
        )r   r   r   )	_PASSWORD_DEFAULTr   r:   OpenSSLSignerNotImplementedError_PKCS12_ERRORr;   r	   _private_key_password)	r=   r   private_key_pkcs12private_key_passwordr   r   r   r   rA   s	            r#   _from_p12_keyfile_contentsz4ServiceAccountCredentials._from_p12_keyfile_contents   su    >  '#4 <<u222%m44))*<*>@/$-*F*<',@)r$   c                     t        |d      5 }|j                         }ddd       | j                  |||||      S # 1 sw Y    xY w)ap  Factory constructor from JSON keyfile.

        Args:
            service_account_email: string, The email associated with the
                                   service account.
            filename: string, The location of the PKCS#12 keyfile.
            private_key_password: string, (Optional) Password for PKCS#12
                                  private key. Defaults to ``notasecret``.
            scopes: List or string, (Optional) Scopes to use when acquiring an
                    access token.
            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.

        Returns:
            ServiceAccountCredentials, a credentials object created from
            the keyfile.

        Raises:
            NotImplementedError if pyOpenSSL is not installed / not the
            active crypto library.
        rbNrV   r   r   r   )rF   readrW   )	r=   r   rI   rV   r   r   r   rJ   rU   s	            r#   from_p12_keyfilez*ServiceAccountCredentials.from_p12_keyfile+  sR    > (D!X!) "--!#5!5fJ . 8 	8 "!s	   =Ac                 P    |j                         }| j                  ||||||      S )a  Factory constructor from JSON keyfile.

        Args:
            service_account_email: string, The email associated with the
                                   service account.
            file_buffer: stream, A buffer that implements ``read()``
                         and contains the PKCS#12 key contents.
            private_key_password: string, (Optional) Password for PKCS#12
                                  private key. Defaults to ``notasecret``.
            scopes: List or string, (Optional) Scopes to use when acquiring an
                    access token.
            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.

        Returns:
            ServiceAccountCredentials, a credentials object created from
            the keyfile.

        Raises:
            NotImplementedError if pyOpenSSL is not installed / not the
            active crypto library.
        rZ   )r[   rW   )r=   r   file_bufferrV   r   r   r   rU   s           r#   from_p12_keyfile_bufferz1ServiceAccountCredentials.from_p12_keyfile_bufferQ  s;    > )--/--!#5!5fJ . 8 	8r$   c                 0   t        t        j                               }| j                  | j                  ||| j                  z   | j
                  d}|j                  | j                         t        j                  | j                  || j                        S )z8Generate the assertion that will be used in the request.)audscopeiatexpisskey_id)inttimer   r   MAX_TOKEN_LIFETIME_SECSr   updater   r   make_signed_jwtr   r   )r   nowpayloads      r#   _generate_assertionz-ServiceAccountCredentials._generate_assertionv  sy    $))+>>\\555..
 	t||$$$T\\7,0,@,@B 	Br$   c                 P    | j                   | j                  j                  |      fS )aU  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   r   sign)r   blobs     r#   	sign_blobz#ServiceAccountCredentials.sign_blob  s$     ##T\\%6%6t%<<<r$   c                     | j                   S )zGet the email for the current service account.

        Returns:
            string, The email associated with the service account.
        )r   r   s    r#   r   z/ServiceAccountCredentials.service_account_email  s     ***r$   c                 b    d| j                   | j                  | j                  | j                  dS )Nservice_account)r1   r3   r    r4   r   )r   r   r<   r   ru   s    r#   serialization_dataz,ServiceAccountCredentials.serialization_data  s3     & 77"2266
 	
r$   c                    t        |t              s(t        j                  t	        j
                  |            }d}|j                  t              }d}|%|d   }t        j                  j                  |      }n:t        j                  |      }|d   }t        j                  j                  ||      } | |d   |f|d   |d   |d   |d   d	|d
   }|||_        |||_        |||_        |d   |_        |d   |_        |d   |_        |d   |_        |j                  dd      }|3t(        j(                  j+                  |t,        j.                        |_        |S )aM  Deserialize a JSON-serialized instance.

        Inverse to :meth:`to_json`.

        Args:
            json_data: dict or string, Serialized JSON (as a string or an
                       already parsed dictionary) representing a credential.

        Returns:
            ServiceAccountCredentials from the serialized data.
        Nr<   rT   r   r   r   r   r   r   r    r   r   r   invalidaccess_tokenr   r   token_expiry)
isinstancedictrG   loadsr   _from_bytesr)   r*   r   r:   r;   r+   	b64decoder<   r	   rT   r{   r|   r   r   datetimestrptimer   EXPIRY_FORMATr}   )r=   	json_datar@   r/   passwordr   rA   r}   s           r#   	from_jsonz#ServiceAccountCredentials.from_json  s    )T*

8#7#7	#BCI $]];/
$-.F$G!\\--.CDF
  ))*5J !89H\\--j(CF./
 Y'$%67, /
 	"
 !,1FK.!.8K+08K-'	2#,^#<  )+ 6!*<!8 }}^T:#'/'8'8'A'Af22(4K$r$   c                     | j                    S N)r   ru   s    r#   create_scoped_requiredz0ServiceAccountCredentials.create_scoped_required  s    <<r$   c                 Z    | j                   | j                  | j                  f|| j                  | j                  | j
                  d| j                  }| j                  |_        | j                  |_        | j                  |_	        | j                  |_
        | j                  |_        |S )Nrz   )r"   r   r   r   r   r   r   r   r   r<   r	   rT   )r   r   results      r#   create_scopedz'ServiceAccountCredentials.create_scoped  s     ; ; $0'-/3/C/C*...+/+;+;0 #',,0  >> OO(,(C(C%%)%=%="'+'A'A$r$   c                    t        | j                        }|j                  |        | j                  | j                  | j
                  f| j                  | j                  | j                  | j                  d|}| j                  |_
        | j                  |_        | j                  |_        | j                  |_        | j                  |_        |S )a<  Create credentials that specify additional claims.

        Args:
            claims: dict, key-value pairs for claims.

        Returns:
            ServiceAccountCredentials, a copy of the current service account
            credentials with updated claims to use when obtaining access
            tokens.
        rz   )r   r   rk   r"   r   r   r   r   r   r   r   r   r<   r	   rT   )r   claims
new_kwargsr   s       r#   create_with_claimsz,ServiceAccountCredentials.create_with_claims  s     $,,'
&! ; ; $.'+||/3/C/C*...+/+;+;. #-.  >> OO(,(C(C%%)%=%="'+'A'A$r$   c                 (    | j                  d|i      S )aY  Create credentials that act as domain-wide delegation of authority.

        Use the ``sub`` parameter as the subject to delegate on behalf of
        that user.

        For example::

          >>> account_sub = 'foo@email.com'
          >>> delegate_creds = creds.create_delegated(account_sub)

        Args:
            sub: string, An email address that this service account will
                 act on behalf of (via domain-wide delegation).

        Returns:
            ServiceAccountCredentials, a copy of the current service account
            updated to act on behalf of ``sub``.
        sub)r   )r   r   s     r#   create_delegatedz*ServiceAccountCredentials.create_delegated  s    & &&s|44r$   r   NN)r   NN)#__name__
__module____qualname____doc__rj   	frozensetr   AssertionCredentialsNON_SERIALIZED_MEMBERSr<   r	   rT   r7   r8   r9   r   r-   classmethodrB   rL   rN   rW   r\   r_   ro   rs   propertyr   rx   r   r   r   r   r   __classcell__r"   s   @r#   r   r   +   s   $L #; 	9+##::	;  K " 
  $ '88(::..2 =A/ /b 57:>D D> 9;:>D D:  9=R-9-J-J.:.L.L	( (T .22#/#@#@$0$B$B#8 #8J 59"*6*G*G+7+I+I"8 "8HB= + + 
 
 4 4l 65r$   r   c                 r    t        j                   ddd      }| |z
  }|j                  dz  |j                  z   S )Ni     iQ )r   daysseconds)utc_timeepoch
time_deltas      r#   _datetime_to_secsr   !  s<     dAq)EE!J??U"Z%7%777r$   c                        e Zd ZdZdZ	 ddddej                  ej                  df fd	Zd Z	ddZ
d Zd Zej                  ej                  fd	Zd
 Zd ZddZ xZS )_JWTAccessCredentialszSelf signed JWT credentials.

    Makes an assertion to server using a self signed JWT from service account
    credentials.  These credentials do NOT use OAuth 2.0 and instead
    authenticate directly.
    r   Nc
           	      D    |	i }	t        t        | 
  ||f|||||d|	 y )N)r    r   r   r   r   )r   r   r   )r   r   r   r   r    r   r   r   r   additional_claimsr"   s             r#   r   z_JWTAccessCredentials.__init__3  sG     $ "#T3!	! *!!	!  	!r$   c                 2    t        j                  | |       |S )a  Authorize an httplib2.Http instance with a JWT assertion.

        Unless specified, the 'aud' of the assertion will be the base
        uri of the request.

        Args:
            http: An instance of ``httplib2.Http`` or something that acts
                  like it.
        Returns:
            A modified instance of http that was passed in.
        Example::
            h = httplib2.Http()
            h = credentials.authorize(h)
        )r   wrap_http_for_jwt_accessr   https     r#   	authorizez_JWTAccessCredentials.authorizeI  s     	**46r$   c                     |X| j                   | j                  r| j                  d       t        j                  | j                   | j                               S | j                  |      \  }}t        j                  || j                        S )zCreate a signed jwt.

        Args:
            http: unused
            additional_claims: dict, additional claims to add to
                the payload of the JWT.
        Returns:
            An AccessTokenInfo with the signed jwt
        N)r|   
expires_in)r|   access_token_expiredrefreshr   AccessTokenInfo_expires_in_create_token_MAX_TOKEN_LIFETIME_SECS)r   r   r   tokenunused_expirys        r#   get_access_tokenz&_JWTAccessCredentials.get_access_token[  s     $  (D,E,ET")),,9I9I9KM M $(#5#56G#H E=)) T-J-JL Lr$   c                      y)z*Cannot revoke JWTAccessCredentials tokens.N r   s     r#   revokez_JWTAccessCredentials.revokep  s    r$   c                      y)NTr   ru   s    r#   r   z,_JWTAccessCredentials.create_scoped_requiredt  s    r$   c           
      T   t        | j                  | j                  f|| j                  | j                  | j
                  ||d| j                  }| j                  | j                  |_        | j                  | j                  |_        | j                  | j                  |_	        |S )N)r   r    r   r   r   r   )
r   r   r   r   r   r   r   r<   r	   rT   )r   r   r   r   r   s        r#   r   z#_JWTAccessCredentials.create_scopedx  s     +4+F+F+/<<;28:>:N:N59^^6:6F6F5>6@; .2\\; &&2,0,G,GF)##/)-)A)AF&%%1+/+E+EF(r$   c                 &    | j                  d        y r   )_refreshr   s     r#   r   z_JWTAccessCredentials.refresh  s    dr$   c                 >    | j                         \  | _        | _        y r   )r   r|   r}   )r   http_requests     r#   r   z_JWTAccessCredentials._refresh  s    /3/A/A/C,4,r$   c                    t        j                         }t        j                  | j                        }||z   }t        |      t        |      | j                  | j                  d}|j                  | j                         ||j                  |       t        j                  | j                  || j                        }|j                  d      |fS )N)r   )rc   rd   re   r   rf   ascii)r   _UTCNOWr   	timedeltar   r   r   rk   r   r   rl   r   r   decode)r   r   rm   lifetimeexpiryrn   jwts          r#   r   z#_JWTAccessCredentials._create_token  s    nn%%d.K.KLx$S)$V,....	
 	t||$(NN,-##DLL'+/+?+?Azz'"F**r$   r   r   )r   r   r   r   r   r7   r8   r9   r   r   r   r   r   r   r   r   r   r   r   s   @r#   r   r   )  sy      $;
  $ '88(::#'!,$L* /;.K.K!-!?!?(D+r$   r   )r   r+   r'   r   rG   ri   r7   r   r   r   r   r   rP   r*   rS   r   r   r   r   r   r$   r#   <module>r      sh    6       !   "  ! #s5 ; ; s5l8x+5 x+r$   