ó
‚¾^Yc           @   sÜ   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 Z d Z d	 Z d
 e j f d „  ƒ  YZ d „  Z d e f d „  ƒ  YZ d S(   s/   oauth2client Service account credentials class.iÿÿÿÿN(   t   _helpers(   t   client(   t   crypt(   t	   transportt
   notasecrett   _private_key_pkcs12s
  
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
t   ServiceAccountCredentialsc           B   sw  e  Z d  Z d Z e d g ƒ e j j BZ d Z	 d Z
 d Z d d d d e j e j d „ Z d d „ Z e d d d „ ƒ Z e d d d d „ ƒ Z e d d d d „ ƒ Z e d d e j e j d	 „ ƒ Z e d d e j e j d
 „ ƒ Z e d d e j e j d „ ƒ Z d „  Z d „  Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z d „  Z d „  Z d „  Z  d „  Z! RS(   sÅ  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.
    i  t   _signert    c	   
      K   st   t  t |  ƒ j d  d | d | d | ƒ| |  _ | |  _ t j | ƒ |  _ | |  _	 | |  _
 | |  _ |	 |  _ d  S(   Nt
   user_agentt	   token_urit
   revoke_uri(   t   superR   t   __init__t   Nonet   _service_account_emailR   R    t   scopes_to_stringt   _scopest   _private_key_idt	   client_idt   _user_agentt   _kwargs(
   t   selft   service_account_emailt   signert   scopest   private_key_idR   R	   R
   R   t   kwargs(    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyR   _   s    					c         C   sn   | d k r! t j |  j ƒ } n  | j t ƒ } | d k	 rR t j | ƒ | t <n  t t |  ƒ j	 | d | ƒS(   sc  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().
        t   to_serializeN(
   R   t   copyt   __dict__t   gett   _PKCS12_KEYt   base64t	   b64encodeR   R   t   _to_json(   R   t   stripR   t
   pkcs12_val(    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyR#   v   s    c         C   sé   | j  d ƒ } | t j k r9 t d | d t j ƒ ‚ n  | d } | d } | d } | d }	 | s | j  d t j ƒ } n  | s | j  d	 t j ƒ } n  t j j	 | ƒ }
 |  | |
 d
 | d | d |	 d | d	 | ƒ} | | _
 | S(   s	  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.
        t   types   Unexpected credentials typet   Expectedt   client_emailt   private_keyR   R   R
   R   R   (   R   R   t   SERVICE_ACCOUNTt
   ValueErrort   oauth2clientt   GOOGLE_TOKEN_URIt   GOOGLE_REVOKE_URIR   t   Signert   from_stringt   _private_key_pkcs8_pem(   t   clst   keyfile_dictR   R
   R   t
   creds_typeR   t   private_key_pkcs8_pemR   R   R   t   credentials(    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt   _from_parsed_json_keyfile   s*    	



				c         C   sC   t  | d ƒ  } t j | ƒ } Wd QX|  j | | d | d | ƒS(   s­  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.
        t   rNR
   R   (   t   opent   jsont   loadR7   (   R2   t   filenameR   R
   R   t   file_objt   client_credentials(    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt   from_json_keyfile_nameÁ   s
    c         C   s   |  j  | | d | d | ƒS(   s  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.
        R
   R   (   R7   (   R2   R3   R   R
   R   (    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt   from_json_keyfile_dictá   s    c   	   	   C   s‚   | d k r t } n  t j t j k	 r6 t t ƒ ‚ n  t j j | | ƒ } |  | | d | d | d | ƒ} | | _ | | _	 | S(   sx  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   N(
   R   t   _PASSWORD_DEFAULTR   R/   t   OpenSSLSignert   NotImplementedErrort   _PKCS12_ERRORR0   R   t   _private_key_password(	   R2   R   t   private_key_pkcs12t   private_key_passwordR   R
   R   R   R6   (    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt   _from_p12_keyfile_contentsÿ   s    				c   	      C   sL   t  | d ƒ  } | j ƒ  } Wd QX|  j | | d | d | d | d | ƒS(   sp  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.
        t   rbNRG   R   R
   R   (   R9   t   readRH   (	   R2   R   R<   RG   R   R
   R   R=   RF   (    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt   from_p12_keyfile*  s    	c         C   s4   | j  ƒ  } |  j | | d | d | d | d | ƒS(   s²  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.
        RG   R   R
   R   (   RJ   RH   (   R2   R   t   file_bufferRG   R   R
   R   RF   (    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt   from_p12_keyfile_bufferP  s
    	c         C   sw   t  t j ƒ  ƒ } i |  j d 6|  j d 6| d 6| |  j d 6|  j d 6} | j |  j ƒ t j	 |  j
 | d |  j ƒS(   s8   Generate the assertion that will be used in the request.t   audt   scopet   iatt   expt   isst   key_id(   t   intt   timeR
   R   t   MAX_TOKEN_LIFETIME_SECSR   t   updateR   R   t   make_signed_jwtR   R   (   R   t   nowt   payload(    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt   _generate_assertionu  s    

c         C   s   |  j  |  j j | ƒ f S(   sU  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   t   sign(   R   t   blob(    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt	   sign_blobƒ  s    c         C   s   |  j  S(   sŒ   Get the email for the current service account.

        Returns:
            string, The email associated with the service account.
        (   R   (   R   (    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyR   ’  s    c         C   s3   i d d 6|  j  d 6|  j d 6|  j d 6|  j d 6S(   Nt   service_accountR&   R(   R   R)   R   (   R   R   R1   R   (   R   (    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt   serialization_data›  s    


c         C   sœ  t  | t ƒ s* t j t j | ƒ ƒ } n  d } | j t ƒ } d } | d k rp | d } t	 j
 j | ƒ } n. t j | ƒ } | d } t	 j
 j | | ƒ } |  | d | d | d d | d d | d d	 | d
 | d } | d k	 rø | | _ n  | d k	 r| | _ n  | d k	 r(| | _ n  | d | _ | d | _ | d | _ | d | _ | j d d ƒ } | d k	 r˜t j j | t j ƒ | _ n  | S(   sM  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.
        R1   RE   R   R   R   R   R   R   R	   R   R   t   invalidt   access_tokenR
   R   t   token_expiryN(   t
   isinstancet   dictR:   t   loadsR    t   _from_bytesR   R   R    R   R/   R0   R!   t	   b64decodeR1   R   RE   Ra   Rb   R
   R   t   datetimet   strptimeR   t   EXPIRY_FORMATRc   (   R2   t	   json_dataR5   R%   t   passwordR   R6   Rc   (    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt	   from_json¦  sD    




	c         C   s   |  j  S(   N(   R   (   R   (    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt   create_scoped_requiredÝ  s    c         C   s   |  j  |  j |  j d | d |  j d |  j d |  j |  j } |  j | _ |  j | _ |  j	 | _	 |  j
 | _
 |  j | _ | S(   NR   R   R   R	   (   t	   __class__R   R   R   R   R   R   R
   R   R1   R   RE   (   R   R   t   result(    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt   create_scopedà  s    			c         C   s›   t  |  j ƒ } | j | ƒ |  j |  j |  j d |  j d |  j d |  j d |  j	 | } |  j
 | _
 |  j | _ |  j | _ |  j | _ |  j | _ | S(   s<  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.
        R   R   R   R	   (   Re   R   RW   Rp   R   R   R   R   R   R   R
   R   R1   R   RE   (   R   t   claimst
   new_kwargsRq   (    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt   create_with_claimsï  s    					c         C   s   |  j  i | d 6ƒ S(   sY  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``.
        t   sub(   Ru   (   R   Rv   (    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt   create_delegated
  s    N("   t   __name__t
   __module__t   __doc__RV   t	   frozensetR   t   AssertionCredentialst   NON_SERIALIZED_MEMBERSR   R1   R   RE   R,   R-   R.   R   R#   t   classmethodR7   R?   R@   RH   RK   RM   R[   R^   t   propertyR   R`   Rn   Ro   Rr   Ru   Rw   (    (    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyR   *   sV   %0&"!			7			c         C   s1   t  j  d d d ƒ } |  | } | j d | j S(   Ni²  i   i€Q (   Ri   t   dayst   seconds(   t   utc_timet   epocht
   time_delta(    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt   _datetime_to_secs   s    
t   _JWTAccessCredentialsc           B   s•   e  Z d  Z d Z d d d d e j e j d d „ Z d „  Z	 d d d „ Z
 d „  Z d „  Z e j e j d „ Z d „  Z d	 „  Z d d
 „ Z RS(   sÐ   Self 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.
    i  c
   
      C   sS   |	 d  k r i  }	 n  t t |  ƒ j | | d | d | d | d | d | |	 d  S(   NR   R   R	   R
   R   (   R   R   R†   R   (
   R   R   R   R   R   R   R	   R
   R   t   additional_claims(    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyR   2  s    
	c         C   s   t  j |  | ƒ | S(   sÁ  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   t   wrap_http_for_jwt_access(   R   t   http(    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt	   authorizeH  s    c         C   s…   | d k rS |  j d k s$ |  j r4 |  j d ƒ n  t j d |  j d |  j ƒ  ƒ S|  j | ƒ \ } } t j d | d |  j ƒ Sd S(   sò   Create 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
        Rb   t
   expires_inN(	   R   Rb   t   access_token_expiredt   refreshR   t   AccessTokenInfot   _expires_int   _create_tokent   _MAX_TOKEN_LIFETIME_SECS(   R   R‰   R‡   t   tokent   unused_expiry(    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt   get_access_tokenZ  s    
		c         C   s   d S(   s*   Cannot revoke JWTAccessCredentials tokens.N(    (   R   R‰   (    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt   revokeo  s    c         C   s   t  S(   N(   t   True(   R   (    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyRo   s  s    c         C   s¦   t  |  j |  j d | d |  j d |  j d |  j d | d | |  j } |  j d  k	 rf |  j | _ n  |  j	 d  k	 r„ |  j	 | _	 n  |  j
 d  k	 r¢ |  j
 | _
 n  | S(   NR   R   R   R	   R
   R   (   R   R   R   R   R   R   R   R1   R   R   RE   (   R   R   R
   R   Rq   (    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyRr   w  s     					c         C   s   |  j  d ƒ d S(   sÛ   Refreshes the access_token.

        The HTTP object is unused since no request needs to be made to
        get a new token, it can just be generated locally.

        Args:
            http: unused HTTP object
        N(   t   _refreshR   (   R   R‰   (    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyR   ‹  s    	c         C   s   |  j  ƒ  \ |  _ |  _ d S(   sX   Refreshes the access_token.

        Args:
            http: unused HTTP object
        N(   R   Rb   Rc   (   R   R‰   (    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyR—   –  s    c         C   s¼   t  j ƒ  } t j d |  j ƒ } | | } i t | ƒ d 6t | ƒ d 6|  j d 6|  j d 6} | j |  j ƒ | d  k	 r‹ | j | ƒ n  t
 j |  j | d |  j ƒ} | j d ƒ | f S(   NR   RP   RQ   RR   Rv   RS   t   ascii(   R   t   _UTCNOWRi   t	   timedeltaR‘   R…   R   RW   R   R   R   RX   R   R   t   decode(   R   R‡   RY   t   lifetimet   expiryRZ   t   jwt(    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyR   ž  s    

N(   Rx   Ry   Rz   R‘   R   R,   R-   R.   R   RŠ   R”   R•   Ro   Rr   R   R—   R   (    (    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyR†   (  s$   					(   Rz   R!   R   Ri   R:   RU   R,   R    R   R   R   RA   R    RD   R|   R   R…   R†   (    (    (    sB   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/service_account.pyt   <module>   s"   ÿ ÷	