
    n                         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 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
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             ;platform/bq/third_party/oauth2client_4_0/service_account.pyr   z"ServiceAccountCredentials.__init__`   se     	'7Z9! 	8 	# '<#008-"%    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_4_0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 -	$(()9)J)JLI%)),*:*L*LN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loadrA   )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.
        rD   )rA   )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   r9   OpenSSLSignerNotImplementedError_PKCS12_ERRORr:   r   _private_key_password)	r<   r   private_key_pkcs12private_key_passwordr   r   r   r   r@   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rU   r   r   r   )rE   readrV   )	r<   r   rH   rU   r   r   r   rI   rT   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.
        rY   )rZ   rV   )r<   r   file_bufferrU   r   r   r   rT   s           r"   from_p12_keyfile_bufferz1ServiceAccountCredentials.from_p12_keyfile_bufferQ  s;    > )--/--!#5!5fJ . 8 	8r#   c                 8   t        t        j                               }t        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timer6   r7   r   MAX_TOKEN_LIFETIME_SECSr   updater   r   make_signed_jwtr   r   )r   nowpayloads      r"   _generate_assertionz-ServiceAccountCredentials._generate_assertionv  s{    $))+#44\\555..
 	t||$$$T\\7,0,@,@B 	Br#   c                 P    | j                   | j                  j                  |      fS )aY  Cryptographically sign a blob (of bytes).

        Implements abstract method
        :meth:`oauth2client_4_0.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)r0   r2   r   r3   r   )r   r   r;   r   rt   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;   rS   r   r   r   r   r   r   r   r   r   r   invalidaccess_tokenr   r   token_expiry)
isinstancedictrF   loadsr   _from_bytesr(   r)   r   r9   r:   r*   	b64decoder;   r   rS   rz   r{   r   r   datetimestrptimer   EXPIRY_FORMATr|   )r<   	json_datar?   r.   passwordr   r@   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   rt   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 )Nry   )r!   r   r   r   r   r   r   r   r   r;   r   rS   )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.
        ry   )r~   r   rj   r!   r   r   r   r   r   r   r   r   r;   r   rS   )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__ri   	frozensetr   AssertionCredentialsNON_SERIALIZED_MEMBERSr;   r   rS   r6   r7   r8   r   r,   classmethodrA   rK   rM   rV   r[   r^   rn   rr   propertyr   rw   r   r   r   r   r   __classcell__r!   s   @r"   r
   r
   +   s   $L #; 	9+##::	;  K " 
  $ +<<,>>..2 =A/ /b 57:>D D> 9;:>D D:  9=R-=-N-N.>.P.P	( (T .22#3#D#D$4$F$F#8 #8J 59"*:*K*K+;+M+M"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   rt   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   rS   )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)zRefreshes 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)_refreshr   s     r"   r   z_JWTAccessCredentials.refresh  s     	dr#   c                 >    | j                         \  | _        | _        y)zXRefreshes the access_token.

        Args:
            http: unused HTTP object
        N)r   r{   r|   r   s     r"   r   z_JWTAccessCredentials._refresh  s     04/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   )rb   rc   rd   r   re   ascii)r   _UTCNOWr   	timedeltar   r   r   rj   r   r   rk   r   r   decode)r   r   rl   lifetimeexpiryrm   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   r6   r7   r8   r   r   r   r   r   r   r   r   r   r   r   s   @r"   r   r   )  sy      $;
  $ +<<,>>#'!,$L* /?.O.O!1!C!C(	D+r#   r   )r   r*   r&   r   rF   rh   r6   r   r   r   r   rO   r)   rR   r   r
   r   r   r   r#   r"   <module>r      se     6       % # " & ! #s5 ; ; s5l8E+5 E+r#   