o
    $                    @   s  d Z ddlmZ ddlmZ ddlm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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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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dl(m*Z* ddl+m,Z- ddl.Z.dZ/dZ0dZ1dZ2dZ3dZ4dZ5dZ6dZ7dZ8dZ9d Z:G d!d" d"ej;Z;G d#d$ d$e;Z<G d%d& d&e;Z=G d'd( d(e;Z>G d)d* d*e;Z?d+d, Z@d-d. ZAd/d0 ZBd1d2 ZCd3d4 ZDd5d6 ZEd7d8 ZFd9d: ZGd;d< ZHd=d> ZId?d@ ZJdAdB ZKdCdD ZLdEdF ZMddHdIZNdJdK ZOdLdM ZPdNdO ZQG dPdQ dQeRZSe.TejUG dRdS dSeRZVdTZWG dUdV dVeRZXG dWdX dXeVZYdYZZG dZd[ d[eRZ[G d\d] d]e)j\Z]G d^d_ d_eRZ^	dd`daZ_	bddcddZ`G dedf dfeVZa			bddgdhZbG didj dje
jcZdG dkdl dle
jcZedmdn Zfdodp Zgdqdr Zhdsdt Zidudv Zjdwdx Zkdydz Zl			bdd{d|Zmdd}d~Zndd ZodddZpG dd deRZqdd Zrdd ZsdZt	dddZudd Zvdawejxd Zydd ZzdS )z Utilities to manage credentials.    )absolute_import)division)unicode_literalsN)compute_enginecredentials)
exceptions)external_account) external_account_authorized_user)impersonated_credentials)config)log)
properties)devshell)
introspect)files)clientservice_account)gcequota_project_idz$https://oauth2.googleapis.com/revokeunknownauthorized_userr   service_account_p12r   r   impersonated_accountr	   external_account_userr
   c                   @      e Zd ZdZdS )ErrorzExceptions for this module.N__name__
__module____qualname____doc__ r#   r#   B/tmp/google-cloud-sdk/lib/googlecloudsdk/core/credentials/creds.pyr   D       r   c                   @   r   )UnknownCredentialsTypezCAn error for when we fail to determine the type of the credentials.Nr   r#   r#   r#   r$   r&   H   r%   r&   c                   @   r   )InvalidCredentialsErrorzGException for when the provided credentials are invalid or unsupported.Nr   r#   r#   r#   r$   r'   L   r%   r'   c                   @   r   )CredentialFileSaveErrorz4An error for when we fail to save a credential file.Nr   r#   r#   r#   r$   r(   P   r%   r(   c                   @   r   )ADCErrorz9An error when processing application default credentials.Nr   r#   r#   r#   r$   r)   T   r%   r)   c                 C      t | tjS N)
isinstancer   OAuth2Credentialscredsr#   r#   r$   IsOauth2ClientCredentialsX      r0   c                 C   r*   r+   )r,   google_auth_credsCredentialsr.   r#   r#   r$   IsGoogleAuthCredentials\   r1   r4   c                 C   r*   r+   )r,   google_auth_compute_enginer3   r.   r#   r#   r$   IsGoogleAuthGceCredentials`   r1   r6   c                 C   ,   t | jrdS t rt | t jkS dS NTF)CredentialTypeFromCredentialsis_user
c_devshellIsDevshellEnvironmentGCEr.   r#   r#   r$   %_IsUserAccountCredentialsOauth2clientd   s
   r?   c                 C   r7   r8   )CredentialTypeGoogleAuthr:   r;   r<   r=   r>   r.   r#   r#   r$   #_IsUserAccountCredentialsGoogleAuthm   s   rA   c                 C   s   t | rt| S t| S r+   )r0   r?   rA   r.   r#   r#   r$   IsUserAccountCredentialsw   s   rB   c                 C   s   t | t jkS r+   )r9   r:   P12_SERVICE_ACCOUNTr.   r#   r#   r$   #IsOauth2clientP12AccountCredentials~   s   rD   c                 C   s<   t | rt| }|tjtjfv S t| }|tjtjfv S r+   )r0   r9   r:   SERVICE_ACCOUNTrC   r@   r/   	cred_typer#   r#   r$   IsServiceAccountCredentials   s   

rH   c                 C      t | rt| tjkS dS NF)r4   r@   r:   EXTERNAL_ACCOUNTr.   r#   r#   r$   IsExternalAccountCredentials   
   rL   c                 C   rI   rJ   )r4   r@   r:   EXTERNAL_ACCOUNT_USERr.   r#   r#   r$    IsExternalAccountUserCredentials   rM   rO   c                 C   rI   rJ   )r4   r@   r:    EXTERNAL_ACCOUNT_AUTHORIZED_USERr.   r#   r#   r$   *IsExternalAccountAuthorizedUserCredentials   rM   rQ   c                 C   rI   rJ   )r4   r@   r:   IMPERSONATED_ACCOUNTr.   r#   r#   r$    IsImpersonatedAccountCredentials   rM   rS   c                 C   s   t | r| jtjjjjkS dS )a  Check if the given credential has default universe domain.

  For google-auth credential, we check its universe_domain property. The
  deprecated oauth2client credentials only work in default universe domain so
  we return True (Note that they are no longer used in gcloud, but not yet
  removed from the code base).

  Args:
    credentials: google.auth.credentials.Credentials or
      client.OAuth2Credentials, the credentials to be checked.

  Returns:
    bool, Whether or not the given credential has default universe domain.
  T)r4   universe_domainr   VALUEScoredefaultr   r#   r#   r$   HasDefaultUniverseDomain   s   
rX   c                   C   s2   t jjj rt jjjjddS t jjjjddS )zEGet default token URI for credential based on context aware settings.T)required)	r   rU   context_awareuse_client_certificateGetBoolauthmtls_token_hostGet
token_hostr#   r#   r#   r$   GetDefaultTokenUri   s   ra   	token_uric                 C   sb   t jjj rt jjj S | |r.| |t jjjkr.| |t jjj kr.| |S t	 S )z5Get the effective token URI for the given credential.)
r   rU   r]   r`   IsExplicitlySetr_   getDEFAULT_TOKEN_HOSTr^   ra   )	cred_jsonkeyr#   r#   r$   GetEffectiveTokenUriFromCreds   s   
rh   c                 C   sP   t | }|t jkrdS | jtjjjjkrdS tjjj	
 r dS t s&dS dS )a  Check if self signed jwt should be used.

  Only use self signed jwt for google-auth service account creds, and only when
  service_account_use_self_signed_jwt property is true or the universe is not
  the default one.

  Args:
    creds: google.auth.credentials.Credentials, The credentials to check if
      self signed jwt should be used.

  Returns:
    bool, Whether or not self signed jwt should be used.
  FT)r@   r:   rE   rT   r   rU   rV   rW   r]   #service_account_use_self_signed_jwtr\   IsDefaultUniverserF   r#   r#   r$   UseSelfSignedJwt   s   

rk   c                 C   s    t | rd| _| d  d S d S )NT)rk   _always_use_jwt_access_create_self_signed_jwtr.   r#   r#   r$   EnableSelfSignedJwtIfApplicable   s   rn   c                 C   s"   t | }|t jkr| |} | S )aV  Add user account to credential.

  The user account field is used to determine ADC caching.
  Only User Account credential types will be modified.

  Args:
    creds: google.auth.credentials.Credentials, The credentials to add the
      account field
    account: str, the authorized user email

  Returns:
    google_auth_creds.Credential
  )r@   r:   USER_ACCOUNTwith_account)r/   accountrG   r#   r#   r$   WithAccount   s   


rr   c                   @   s*   e Zd ZdZedd ZedddZdS )_AccountIdFormattera  Account ID formatter.

  In this file, when we say "account id" or "account_id", it means principal;
  when we say "formatted_account_id" or "formatted account id", it means:
    - the account_id or principal, if the universe domain is GDU
    - the "account_id#universe_domain" string, otherwise

  In credentials and access token sqlite3 database, the account_id column saves
  the formatted account id.

  This class provides utility functions to handle the formatting.
  c                 C   sB   |  d}|d }t|dkrtjjjj}||fS |d }||fS )zGet account_id/principal and universe domain from formatted account id.

    Args:
      formatted_account_id: str, the formatted account id string.

    Returns:
      tuple: The principal and universe domain tuple.
    #r      )splitlenr   rU   rV   rT   rW   )formatted_account_idsplits	principalrT   r#   r#   r$   GetAccountIdAndUniverseDomain  s   

z1_AccountIdFormatter.GetAccountIdAndUniverseDomainNc                 C   sB   t jjj}|rt|dr|j}n| }||jkr| S | d | S )a,  Calculate the formatted account id.

    If the universe_domain is GDU, return the account_id as is; otherwise,
    return "account_id#universe_domain". Here the universe_domain value comes
    from the credentials if it's provided, otherwise it comes from the
    core/universe_domain property.

    Args:
      account_id: str, the account id or principal string.
      credentials: google.auth.credentials.Credentials, The optional credentials
        provided to derive the universe_domain value.

    Returns:
      str: The formatted account id.
    rT   rt   )r   rU   rV   rT   hasattrr_   rW   )
account_idr   universe_domain_propertyrT   r#   r#   r$   GetFormattedAccountId/  s   

z)_AccountIdFormatter.GetFormattedAccountIdr+   )r   r    r!   r"   staticmethodr{   r   r#   r#   r#   r$   rs     s    
rs   c                   @   sH   e Zd ZdZejdd Zejdd Zejdd Zejdd	 Z	d
S )CredentialStorez(Abstract definition of credential store.c                 C      t S )zpGet all accounts that have credentials stored for the CloudSDK.

    Returns:
      {str}, Set of accounts.
    NotImplementedselfr#   r#   r$   GetAccountsQ  s   zCredentialStore.GetAccountsc                 C   r   r+   r   r   r}   r#   r#   r$   LoadZ     zCredentialStore.Loadc                 C   r   r+   r   )r   r}   r   r#   r#   r$   Store^  r   zCredentialStore.Storec                 C   r   r+   r   r   r#   r#   r$   Removeb  r   zCredentialStore.RemoveN)
r   r    r!   r"   abcabstractmethodr   r   r   r   r#   r#   r#   r$   r   M  s    


r   r   c                   @   0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )
_SqlCursorz'Context manager to access sqlite store.c                 C   s   || _ d | _d | _d S r+   )_store_file_connection_cursor)r   
store_filer#   r#   r$   __init__l  s   
z_SqlCursor.__init__c                 C   s*   t j| jdt jd dd| _| j | _| S )Ng      @T)timeoutdetect_typesisolation_levelcheck_same_thread)sqlite3connectr   PARSE_DECLTYPESr   cursorr   r   r#   r#   r$   	__enter__q  s   z_SqlCursor.__enter__c                 C   s   |s| j   | j   d S r+   )r   commitclose)r   exc_typeunused_valueunused_tracebackr#   r#   r$   __exit__  s   
z_SqlCursor.__exit__c                 G   s   | j j| S r+   )r   execute)r   argsr#   r#   r$   Execute  r1   z_SqlCursor.ExecuteN)r   r    r!   r"   r   r   r   r   r#   r#   r#   r$   r   i  s    r   c                   @   sR   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdddZ	dd Z
dd ZdS )SqliteCredentialStorez Sqllite backed credential store.c                 C   s<   t || _| dt t }|ds|   d S d S )NzICREATE TABLE IF NOT EXISTS "{}" (account_id TEXT PRIMARY KEY, value BLOB)cred_token_store_formatted)	r   r   _Executeformat_CREDENTIAL_TABLE_NAMEr   GetConfigStorer_   FormatAccountIdColumn)r   r   config_storer#   r#   r$   r     s   

zSqliteCredentialStore.__init__c                 G   s4   | j }|j| W  d    S 1 sw   Y  d S r+   r   r   r   r   curr#   r#   r$   r     s   $zSqliteCredentialStore._Executec           	      C   s   | j R}|dt }|D ]2}|d |d }}d|vrBt|}t||}||krB|dt|f |dt||f qt	 }|
dd W d	   d	S 1 sXw   Y  d	S )
zFormat the account id column.

    Before we introduce the formatted account id concept, the existing table
    uses the account id value as the key. Therefore we need to load the table
    and replace these account ids with formatted account ids.
    z"SELECT account_id, value FROM "{}"r   ru   rt   %DELETE FROM "{}" WHERE account_id = ?z1INSERT INTO "{}" (account_id, value) VALUES (?,?)r   TN)r   r   r   r   fetchallFromJsonGoogleAuthrs   r   r   r   Set)	r   r   tablerowr}   rf   r/   rx   r   r#   r#   r$   r     s<   "z+SqliteCredentialStore.FormatAccountIdColumnc                 C   sb   | j $}t }|dtD ]\}t|\}}|| qW d   |S 1 s*w   Y  |S )zJGet all accounts.

    Returns:
      set[str], A set of account ids.
    *SELECT account_id FROM "{}" ORDER BY rowidN)r   setr   r   r   rs   r{   add)r   r   accountsrx   r}   _r#   r#   r$   r     s    

z!SqliteCredentialStore.GetAccountsc                 C   sl   t t}| j$}|dtD ]}t|d \}}|| 	| qW d   |S 1 s/w   Y  |S )zGet all accounts and their corresponding universe domains.

    Returns:
      collections.defaultdict, A dictionary where the key is the account_id and
        the value is the universe domain list.
    r   r   N)
collectionsdefaultdictlistr   r   r   r   rs   r{   append)r   accounts_dictr   rx   r}   rT   r#   r#   r$   GetAccountsWithUniverseDomain  s"   

z3SqliteCredentialStore.GetAccountsWithUniverseDomainTc                 C   s  |s-| j }|dt|f }W d   n1 sw   Y  |du r'dS t|d S | j }|dt||d f }W d   n1 sJw   Y  |sSdS tjj	j
}g }d}|D ]\}	}t|	\}
}|| || krxt|}q^|stdj|| d|d|S )	a  Load the credentials for the account_id.

    Args:
      account_id: str, The account_id of the credential to load.
      use_google_auth: bool, Whether google-auth lib should be used. Default is
        True.

    Returns:
      google.auth.credentials.Credentials or client.OAuth2Credentials, The
        loaded credentials.

    Raises:
      googlecloudsdk.core.credentials.creds.InvalidCredentialsError: If problem
        happens when loading credentials.
    z+SELECT value FROM "{}" WHERE account_id = ?Nr   zLSELECT account_id, value FROM "{}" WHERE account_id = ? OR account_id LIKE ?z#%a^  The account [{account_id}] is available in the following universe domain(s): [{universe_domains}], but it is not available in [{universe_property}] which is specified by the [core/universe_domain] property. Update your active account to an account from {universe_property} or update the [core/universe_domain] property to one of [{universe_domains}].z, )r}   universe_propertyuniverse_domains)r   r   r   r   fetchoneFromJsonr   r   rU   rV   rT   rs   r{   r   r_   r   r'   join)r   r}   use_google_authr   rf   r   r~   r   r/   rx   r   rT   r#   r#   r$   r     s\   


zSqliteCredentialStore.Loadc                 C   sX   t |rt|}| dt||f dS t|}t||}| dt||f dS )a  Stores the input credentials to the record of account_id in the cache.

    Args:
      account_id: string, the account ID of the input credentials.
      credentials: google.auth.credentials.Credentials or
        client.OAuth2Credentials, the credentials to be stored.
    z2REPLACE INTO "{}" (account_id, value) VALUES (?,?)N)r0   ToJsonr   r   r   ToJsonGoogleAuthrs   r   )r   r}   r   valuerx   r#   r#   r$   r   .  s$   zSqliteCredentialStore.Storec                 C   s$   t |d }| dt|f d S )Nr   )rs   r   r   r   r   )r   r}   rx   r#   r#   r$   r   J  s   zSqliteCredentialStore.RemoveNT)r   r    r!   r"   r   r   r   r   r   r   r   r   r#   r#   r#   r$   r     s    
'
Dr   access_tokensc                   @   s:   e Zd ZdZdddZdd Zdd Zd	d
 Zdd ZdS )AccessTokenCachea  Sqlite implementation of for access token cache.

  AccessTokenCache uses formatted_account_id instead of account_id in its APIs.
  The reason is that AccessTokenCache is used by AccessTokenStoreGoogleAuth,
  which is tied to a specific credential object. Either we let
  AccessTokenStoreGoogleAuth pass the credential's universe_domain to
  AccessTokenCache, or pass the formatted account id (which contains
  universe_domain). The latter is better since it is backward compatible and
  there is no need to introduce a new universe_domain parameter to all
  AccessTokenCache Load/Store/Remove APIs.
  See go/gcloud-multi-universe-auth-cache section 3.2, 3.3 for more details.
  Fc                 C   s^   || _ t|| _| dt z| dt W d S  tjy.   | dt Y d S w )NzCREATE TABLE IF NOT EXISTS "{}" (account_id TEXT PRIMARY KEY, access_token TEXT, token_expiry TIMESTAMP, rapt_token TEXT, id_token TEXT)z!SELECT id_token FROM "{}" LIMIT 1z)ALTER TABLE "{}" ADD COLUMN id_token TEXT)_cache_only_raptr   r   r   r   _ACCESS_TOKEN_TABLEr   OperationalError)r   r   cache_only_raptr#   r#   r$   r   e  s   


zAccessTokenCache.__init__c                 G   s6   | j }|j|  W d    d S 1 sw   Y  d S r+   r   r   r#   r#   r$   r   y  s   "zAccessTokenCache._Executec                 C   sB   | j }|dt|f W  d   S 1 sw   Y  dS )zLoad the tokens from the access token cache.

    Args:
      formatted_account_id: str, The formatted account id.

    Returns:
      tuple: The access_token, token_expiry, rapt_token, id_token tuple.
    zVSELECT access_token, token_expiry, rapt_token, id_token FROM "{}" WHERE account_id = ?N)r   r   r   r   r   )r   rx   r   r#   r#   r$   r   }  s   	$zAccessTokenCache.Loadc           	   
   C   s   | j r| |}|r|\}}}}nd}d}d}z| dt|||||f W dS  tjyF } ztdt	| W Y d}~dS d}~ww )aW  Stores the tokens into the access token cache.

    Args:
      formatted_account_id: str, The formatted account id.
      access_token: str, The access token string to store.
      token_expiry: datetime.datetime, The token expiry.
      rapt_token: str, The rapt token string to store.
      id_token: str, The ID token string to store.
    NzcREPLACE INTO "{}" (account_id, access_token, token_expiry, rapt_token, id_token) VALUES (?,?,?,?,?)z)Could not store access token in cache: {})
r   r   r   r   r   r   r   r   warningstr)	r   rx   access_tokentoken_expiry
rapt_tokenid_tokenresultr   er#   r#   r$   r     s,   

"zAccessTokenCache.Storec              
   C   sX   z|  dt|f W dS  tjy+ } ztdt| W Y d}~dS d}~ww )zRemoves the tokens from the access token cache.

    Args:
      formatted_account_id: str, The formatted account id to remove.
    r   z,Could not delete access token from cache: {}N)r   r   r   r   r   r   r   r   )r   rx   r   r#   r#   r$   r     s   
"zAccessTokenCache.RemoveNF)	r   r    r!   r"   r   r   r   r   r   r#   r#   r#   r$   r   W  s    
.r   c                       s8   e Zd ZdZ fddZdd Zdd Zdd	 Z  ZS )
AccessTokenStorea  Oauth2client adapted for access token cache.

  This class works with Oauth2client model where access token is part of
  credential serialization format and get captured as part of that.
  By extending client.Storage this class pretends to serialize credentials, but
  only serializes access token.

  When fetching the more recent credentials from the cache, this does not return
  token_response, as it is now out of date.
  c                    s(   t t| jdd || _|| _|| _dS )a&  Sets up token store for given acount.

    Args:
      access_token_cache: AccessTokenCache, cache for access tokens.
      account_id: str, account for which token is stored.
      credentials: oauth2client.client.OAuth2Credentials, they are auto-updated
        with cached access token.
    N)lock)superr   r   _access_token_cache_account_id_credentialsr   access_token_cacher}   r   	__class__r#   r$   r     s   	
zAccessTokenStore.__init__c                 C   sT   | j | j}|r'|\}}}}|| j_|| j_|d ur|| j_|| j_d | j_| jS r+   )	r   r   r   r   r   r   r   id_tokenb64token_responser   
token_datar   r   r   r   r#   r#   r$   
locked_get  s   zAccessTokenStore.locked_getc              	   C   sN   t | jdr| jjdd }nd }| j| j| jj| jjt | jdd | d S )Nr   r   r   )	getattrr   r   rd   r   r   r   r   r   )r   r   r   r#   r#   r$   
locked_put  s   zAccessTokenStore.locked_putc                 C   s   | j | j d S r+   )r   r   r   r   r#   r#   r$   locked_delete  s   zAccessTokenStore.locked_delete)	r   r    r!   r"   r   r   r   r   __classcell__r#   r#   r   r$   r     s    r   c                   @   r   )AccessTokenStoreGoogleAuthzgoogle-auth adapted for access token cache.

  This class works with google-auth credentials and serializes its short lived
  tokens, including access token, token expiry, rapt token, id token into the
  access token cache.
  c                 C   s   || _ t||| _|| _dS )a  Sets up token store for given account.

    Args:
      access_token_cache: AccessTokenCache, cache for access tokens.
      account_id: str, account for which token is stored.
      credentials: google.auth.credentials.Credentials, credentials of account
        of account_id.
    N)r   rs   r   _formatted_account_idr   r   r#   r#   r$   r   	  s
   	
z#AccessTokenStoreGoogleAuth.__init__c                 C   sp   | j | j}|r5|\}}}}t| jr!d| j_d| j_d| j_n|| j_|| j_|| j_|| j_|| j_	| jS )a  Gets credentials with short lived tokens from the internal cache.

    Retrieves the short lived tokens from the internal access token cache,
    populates the credentials with these tokens and returns the credentials.

    Returns:
       google.auth.credentials.Credentials
    N)
r   r   r   rk   r   tokenexpiry_rapt_token	_id_tokenr   r   r#   r#   r$   r_     s   	

zAccessTokenStoreGoogleAuth.Getc                 C   s   t | jddpt | jdd}t | jdd}t | jdd}t | jdd}t| jr=d}d}d}| j| j}|r=|\}}}}| j| j|||| dS )zEPuts the short lived tokens of the credentials to the internal cache.r   Nr   r   r   r   )r   r   rk   r   r   r   r   )r   r   r   r   r   r   r   r#   r#   r$   Put6  s    

zAccessTokenStoreGoogleAuth.Putc                 C   s   | j | j dS )z:Removes the tokens of the account from the internal cache.N)r   r   r   r   r#   r#   r$   DeleteR  s   z!AccessTokenStoreGoogleAuth.DeleteN)r   r    r!   r"   r   r_   r   r   r#   r#   r#   r$   r     s    r   c                 C   sd   | j dur| S t| dd}|stt| j }t|p!t	
 j}t||| }| | | S )a  Attaches access token cache to given credentials if no store set.

  Note that credentials themselves will not be persisted only access token. Use
  this whenever access token caching is desired, yet credentials themselves
  should not be persisted.

  Args:
    credentials: oauth2client.client.OAuth2Credentials.
    access_token_file: str, optional path to use for access token storage.
  Returns:
    oauth2client.client.OAuth2Credentials, reloaded credentials.
  Nservice_account_email)storer   hashlibsha256sixensure_binaryrefresh_token	hexdigestr   r   Pathsaccess_token_db_pathr   	set_storerd   )r   access_token_filer}   r   r   r#   r#   r$    MaybeAttachAccessTokenCacheStoreW  s   

r  Fc                    s   t  dd}|st tjst tjrt }n|s'tt	
 j }t|p.t j|d}t||    j fdd}| _ S )a  Attaches access token cache to given credentials if no store set.

  Note that credentials themselves will not be persisted only access token. Use
  this whenever access token caching is desired, yet credentials themselves
  should not be persisted.

  For external account and external account authorized user non-impersonated
  credentials, the provided credentials should have been instantiated with
  the client_id and client_secret in order to retrieve the account ID from the
  3PI token instrospection endpoint.

  Args:
    credentials: google.auth.credentials.Credentials.
    access_token_file: str, optional path to use for access token storage.
    cache_only_rapt: bool, True to only cache RAPT token.

  Returns:
    google.auth.credentials.Credentials, reloaded credentials.
  r   N)r   c                    s"   |  t  dd  _  d S )Nr   )r   r   r   requestr   orig_refreshr   r#   r$   _WrappedRefresh  s   zCMaybeAttachAccessTokenCacheStoreGoogleAuth.<locals>._WrappedRefresh)r   r,   google_auth_external_accountr3   ,google_auth_external_account_authorized_userc_introspectGetExternalAccountIdr   r   r   r   r   r   r   r   r   r  r   r_   refresh)r   r  r   r}   r   r	  r#   r  r$   *MaybeAttachAccessTokenCacheStoreGoogleAutht  s6   
r  c                   @   sJ   e Zd ZdZdd Zdd Zdd Zdd	 ZdddZdd Z	dd Z
dS )CredentialStoreWithCachea  Implements CredentialStore for caching credentials information.

  Static credentials information, such as client ID and service account email,
  are stored in credentials.db. The short lived credentials tokens, such as
  access token, are cached in access_tokens.db.
  c                 C   s   || _ || _dS )aJ  Sets up credentials store for caching credentials.

    Args:
      credential_store: SqliteCredentialStore, for caching static credentials
        information, such as client ID, service account email, etc.
      access_token_cache: AccessTokenCache, for caching short lived credentials
        tokens, such as access token.
    N)_credential_storer   )r   credential_storer   r#   r#   r$   r     s   	
z!CredentialStoreWithCache.__init__c                    s   |j   fdd}||_ |S )a  Wraps the refresh method of credentials with auto caching logic.

    For auto caching short lived tokens of google-auth credentials, such as
    access token, on credentials refresh.

    Args:
      credentials: google.auth.credentials.Credentials, the credentials updated
        by this method.
      store: AccessTokenStoreGoogleAuth, the store that caches the tokens of the
        input credentials.

    Returns:
      google.auth.credentials.Credentials, the updated credentials.
    c                    s    |     d S r+   )r   r  r  r   r#   r$   r	    s   zXCredentialStoreWithCache._WrapCredentialsRefreshWithAutoCaching.<locals>._WrappedRefreshr  )r   r   r   r	  r#   r  r$   &_WrapCredentialsRefreshWithAutoCaching  s   z?CredentialStoreWithCache._WrapCredentialsRefreshWithAutoCachingc                 C   
   | j  S )z-Returns all the accounts stored in the cache.)r  r   r   r#   r#   r$   r        
z$CredentialStoreWithCache.GetAccountsc                 C   r  )zHReturns all the accounts stored in the cache with their universe domain.)r  r   r   r#   r#   r$   r     r  z6CredentialStoreWithCache.GetAccountsWithUniverseDomainTc                 C   sd   | j ||}|du rdS t|r!t| j||}|| | S t| j||}| }| 	||S )a  Loads the credentials of account_id from the cache.

    Args:
      account_id: string, ID of the account to load.
      use_google_auth: bool, True to load google-auth credentials if the type of
        the credentials is supported by the cache. False to load oauth2client
        credentials.

    Returns:
      1. None, if credentials are not found in the cache.
      2. google.auth.credentials.Credentials, if use_google_auth is true.
      3. client.OAuth2Credentials.
    N)
r  r   r0   r   r   r  rd   r   r_   r  )r   r}   r   r   r   r#   r#   r$   r     s   
zCredentialStoreWithCache.Loadc                 C   sT   t |rt| j||}|| || nt| j||}|  | j|| dS )a,  Stores credentials into the cache with account of account_id.

    Args:
      account_id: string, the account that will be associated with credentials
        in the cache.
      credentials: google.auth.credentials.Credentials or
        client.OAuth2Credentials, the credentials to be stored.
    N)	r0   r   r   r  putr   r   r  r   )r   r}   r   r   r#   r#   r$   r     s   

zCredentialStoreWithCache.Storec                 C   s"   | j | | jt| dS )z1Removes credentials of account_id from the cache.N)r  r   r   rs   r   r   r#   r#   r$   r     s   zCredentialStoreWithCache.RemoveNr   )r   r    r!   r"   r   r  r   r   r   r   r   r#   r#   r#   r$   r    s    
"r  c                 C   s   t | ||S )a  Constructs credential store.

  Args:
    store_file: str, optional path to use for storage. If not specified
      config.Paths().credentials_path will be used.
    access_token_file: str, optional path to use for access token storage. Note
      that some implementations use store_file to also store access_tokens, in
      which case this argument is ignored.
    cache_only_rapt: bool, True to only cache RAPT token.

  Returns:
    CredentialStore object.
  )_GetSqliteStoreWithCache)r   r  r   r#   r#   r$   GetCredentialStore$  s   r  c                   @   sx   e Zd ZdZdeddfZdeddfZdeddfZ	de
ddfZdeddfZd	eddfZd
d Zedd Zedd ZdS )r9   z8Enum of oauth2client credential types managed by gcloud.r   Fru   T            c                 C      || _ || _|| _|| _d S r+   type_idrg   is_serializabler;   r   r!  rg   r"  r;   r#   r#   r$   r   E  s   
zCredentialType.__init__c                 C   "   t D ]}|j| kr|  S qt jS r+   )r9   rg   UNKNOWNrg   rG   r#   r#   r$   FromTypeKeyM  s
   
zCredentialType.FromTypeKeyc                 C   sV   t | tjr	tjS t | tjrt| dd d urtjS tj	S t| dd d ur(tj
S tjS )N_private_key_pkcs12r   )r,   oauth2client_gceAppAssertionCredentialsr9   r>   r   ServiceAccountCredentialsr   rC   rE   ro   r%  r.   r#   r#   r$   r:   T  s   zCredentialType.FromCredentialsN)r   r    r!   r"   UNKNOWN_CREDS_NAMEr%  USER_ACCOUNT_CREDS_NAMEro   SERVICE_ACCOUNT_CREDS_NAMErE   P12_SERVICE_ACCOUNT_CREDS_NAMErC   DEVSHELL_CREDS_NAMEDEVSHELLGCE_CREDS_NAMEr>   r   r   r'  r:   r#   r#   r#   r$   r9   ;  s    
r9   c                   @   s   e Zd ZdZdeddfZdeddfZdeddfZ	de
ddfZdeddfZd	eddfZd
eddfZdeddfZdeddfZdeddfZdd Zedd Zedd ZdS )r@   z7Enum of google-auth credential types managed by gcloud.r   Fru   Tr  r  r  r           	   c                 C   s   || _ || _|| _|| _dS )a  Builds a credentials type instance given the credentials information.

    Args:
      type_id: string, ID for the credentials type, based on the enum constant
        value of the type.
      key: string, key of the credentials type, based on the enum constant value
        of the type.
      is_serializable: bool, whether the type of the credentials is
        serializable, based on the enum constant value of the type.
      is_user: bool, True if the credentials are of user account. False
        otherwise.

    Returns:
      CredentialTypeGoogleAuth, an instance of CredentialTypeGoogleAuth which
        is a gcloud internal representation of type of the google-auth
        credentials.
    Nr   r#  r#   r#   r$   r   y  s   
z!CredentialTypeGoogleAuth.__init__c                 C   r$  )z4Returns the credentials type based on the input key.)r@   rg   r%  r&  r#   r#   r$   r'    s
   
z$CredentialTypeGoogleAuth.FromTypeKeyc                 C   s   t | tjr	tjS t | tjrtjS t | tjr| jstj	S t | tjr*| jr*tj
S t | tjr3tjS ddlm} ddlm} t | |jrHtjS t | |jrQtjS t| dddur\tjS tjS )z<Returns the credentials type based on the input credentials.r   r   p12_service_accountr   N)r,   r5   r3   r@   r>   google_auth_impersonatedrR   r
  r;   rK   rN   r  rP   google.oauth2r   googlecloudsdk.core.credentialsr8  rC   rE   r   ro   r%  )r/   google_auth_service_accountgoogle_auth_p12_service_accountr#   r#   r$   r:     s2   z(CredentialTypeGoogleAuth.FromCredentialsN)r   r    r!   r"   r,  r%  r-  ro   r.  rE   r/  rC   r0  r1  r2  r>   IMPERSONATED_ACCOUNT_CREDS_NAMErR   EXTERNAL_ACCOUNT_CREDS_NAMErK    EXTERNAL_ACCOUNT_USER_CREDS_NAMErN   +EXTERNAL_ACCOUNT_AUTHORIZED_USER_CREDS_NAMErP   r   r   r'  r:   r#   r#   r#   r$   r@   a  s$    
r@   c                 C   s   t | }|t jkr0|j| j| j| jd}dD ]}t| |d}|r.t|t	r*t
|}|||< qn$|t jkr9| j}n|t jkrP| j|jt| jd| jd}nt|tj|dddd	S )
zFGiven Oauth2client credentials return library independent json for it.)type	client_idclient_secretr   )r   invalid
revoke_uriscopesr   rb   
user_agentr   Nascii)client_emailrB  private_keypasswordTr  ,z: 	sort_keysindent
separators)r9   r:   ro   rg   rC  rD  r   r   r,   r   r   rE   serialization_datarC   _service_account_emailbase64	b64encoder(  decode_private_key_passwordr&   jsondumps)r   
creds_type
creds_dictfieldr   r#   r#   r$   r     s8   



	

r   c                 C   s<  t | }|t jkr|j| j| j| j| j| j| j	d}nt|t j
ks&|t jkr7| j}| jr6t| dr6| j|d< nY|t jkrN|j| j| j| j| j| j| jd}nB|t jkrd|j| j| j| jt| j| jd}n,|t jkr{|j| jt| jd| jd}n|t j kr|j| jd}nt!d	"|j| j#|d
< t$j%|ddddS )zFGiven google-auth credentials, return library independent json for it.)rB  rJ  private_key_idrK  rC  rb   
project_idinteractiveexternal_account_id)rB  audiencerC  rD  r   	token_urltoken_info_url)rB  rC  rD  r   rF  rG  rb   rI  )rB  rJ  rK  rL  )rB  r   =Google auth does not support serialization of {} credentials.rT   Tr  rM  rO  )&r@   r:   rE   rg   r   r^  rK  rC  
_token_urir_  rK   rN   infois_workforce_poolr|   ra  rP   rb  rD  r   rc  rd  ro   _REVOKE_URI_scopesrb   rC   rU  rV  private_key_pkcs12rW  private_key_passwordr>   r&   r   rT   rY  rZ  )r   r[  r\  r#   r#   r$   r     sj   






	
	


r   c                 C   s   t | }tj|ddddS )a  Given google-auth credentials, return serialized json string.

  This method is added because google-auth credentials are not serializable
  natively.

  Args:
    credentials: google-auth credential object.

  Returns:
    Json string representation of the credential.
  Tr  rM  rO  )ToDictGoogleAuthrY  rZ  )r   r\  r#   r#   r$   SerializeCredsGoogleAuth,  s   rn  c              	      s   t | }|jstd|jd|ji}dd t| D   fdd D }t|}|D ]K}t| |rxt	| |}t
|}|tjkrH|d}n,t|tjr^zt|}W n ty]   Y q-w |durtt|tjst|tttttttfvrtq-|||< q-|S )a  Given google-auth credentials, recursively return dict representation.

  This method is added because google-auth credentials are not serializable
  natively.

  Args:
    credentials: google-auth credential object.

  Returns:
    Dict representation of the credential.

  Raises:
    UnknownCredentialsType: An error for when we fail to determine the type
    of the credentials.
  re  rB  c                 S   s"   g | ]}| d s|dvr|qS )__)signer_abc_negative_cache_version
startswith.0attrr#   r#   r$   
<listcomp>[  s    z$ToDictGoogleAuth.<locals>.<listcomp>c                    s*   g | ]}| d r|dd  vr|qS )r   ru   Nrr  rt  filtered_listr#   r$   rw  `  s    z%m-%d-%Y %H:%M:%SN)r@   r:   r"  r&   r   rg   dirsortedr|   r   rB  datetimestrftime
issubclassr2   r3   rm  r,   r   string_typesintfloatboolr   r   dicttuple)r   r[  r\  	attr_listrv  valval_typer#   rx  r$   rm  =  s:   




rm  c                 C   s  t | }t|d }t||d< |tjkr)tjj|t	j
d}t	j |_|_|S |tjkr`tjd|d |d |d d|d|d|d	|d
|d|d|d|dd}|S |tjkrtjj|d t|d |d |d t	j
d}t	j |_|_|S t|d )zFReturns Oauth2client credentials from library independent json format.rB  rb   rG  NrC  rD  r   rH  rF  r   r   rG  token_info_urir   )r   rC  rD  r   r   rb   rH  rF  r   r   rG  r  r   rJ  rK  rL  )r   rk  rl  rb   rG  )rY  loadsr9   r'  rh   rE   r   r+  from_json_keyfile_dictr   CLOUDSDK_SCOPESCLOUDSDK_USER_AGENTrH  _user_agentro   r   r-   rd   rC   _from_p12_keyfile_contentsrU  	b64decoder&   )
json_valuejson_keyrG   credr#   r#   r$   r   x  sJ   



r   c              
   C   s  t | }t|d }|tjkr@t||d< ddlm} |jj	}||t
jd}|d|_|d|_|d|_t| |S |tjkrit||d< dd	lm} |jt|d |d
 |d |d t
jd}|S |tjkrd|vr}t
j|d< t
j|d< zt|ddkrddlm} |jj|t
jd}nS|ddur|dddurddlm} |dd}	|jj|t
jd}|jr|	drd|_t |d|dpd nddlm!}
 |
jj|t
jd}W t'|S W t'|S W t'|S  t"t#t$j%fy   t&dw |tj(kr3t
j|d< t
j|d< t
j)|d< zt*j|}W t'|S  t"t#t$j%fy2   t&dw |tj+krWt||d< ddlm,} |jj-||dd}|d |_.|S |tj/krut0j|d  d!}|d"t1j2j3j4j5|_6d|_7|S t8d#9|d )$a  Returns google-auth credentials from library independent json format.

  The type of the credentials could be service account, external account
  (workload identity pool or workforce pool), external account authorized user
  (workforce), user account, p12 service account, or compute engine.

  Args:
    json_value: string, A string of the JSON representation of the credentials.

  Returns:
    google.auth.credentials.Credentials if the credentials type is supported
    by this method.

  Raises:
    UnknownCredentialsType: when the type of the credentials is not service
      account, user account or external account.
    InvalidCredentialsError: when the provided credentials are malformed or
      unsupported external account credentials.
  rB  rb   r   r   r  rK  r^  rC  r7  rL  rJ  )r   rb   rG  !service_account_impersonation_urlrD  subject_token_typez+urn:ietf:params:aws:token-type:aws4_request)awscredential_sourceN
executable)	pluggableinteractive_timeout_millisT_tokeninfo_usernamera   )identity_poolzDThe provided external account credentials are invalid or unsupportedrG  zTThe provided external account authorized user credentials are invalid or unsupported)google_auth_credentialsr   )r   rT   z?Google auth does not support deserialization of {} credentials.):rY  r  r@   r'  rE   rh   r:  r   r3   from_service_account_infor   r  rd   rK  r^  rC  rn   rC   r;  r8  CreateP12ServiceAccountrU  r  rK   CLOUDSDK_CLIENT_IDCLOUDSDK_CLIENT_NOTSOSECRETgoogle.authr  	from_infor  rh  r`  setattrr  
ValueError	TypeErrorgoogle_auth_exceptionsRefreshErrorr'   $WrapGoogleAuthExternalAccountRefreshrP    CLOUDSDK_EXTERNAL_ACCOUNT_SCOPESr  ro   r  from_authorized_user_inforf  r>   r5   r   rU   rV   rT   rW   _universe_domain_universe_domain_cachedr&   r   )r  r  rG   r<  service_account_credentialsr  r8  r  r  r  r  c_google_authr#   r#   r$   r     s   


	


 




r   c                    s   | j   fdd}|| _ | S )a  Returns a wrapped External Account credentials.

  We wrap the refresh method to make sure that any errors raised can be caught
  in a consistent way by downstream consumers.

  Args:
    cred: google.auth.credentials.Credentials

  Returns:
    google.auth.credentials.Credentials
  c              
      s:   z |  W d S  t ttjfy } zt|d }~ww r+   )r  r  r  r  c_exceptionsTokenRefreshError)r  r   r  r#   r$   r	  B  s   
z=WrapGoogleAuthExternalAccountRefresh.<locals>._WrappedRefreshr  )r  r	  r#   r  r$   r  3  s   r  c                 C   s4   t | }|p
t j}t| t||}t||S )z$Get a sqlite-based Credential Store.)_GetSqliteStorer   r   r  r   PrivatizeFiler   r  )sqlite_credential_filesqlite_access_token_filer   r  r   r#   r#   r$   r  L  s   

r  c                 C   s$   | pt  j} t|  t| }|S )zFGet a sqlite-based Credential Store with using the access token cache.)r   r   credentials_db_pathr   r  r   )r  r  r#   r#   r$   r  ^  s   
r  c                 C   s   | t jjjt jjjfv S r+   )r   rU   billingCURRENT_PROJECTCURRENT_PROJECT_WITH_FALLBACK)quota_projectr#   r#   r$   _QuotaProjectIsCurrentProjectg  s   r  c                 C   sd   | du rdS t jjj }t|rt| rt jjj S dS |t jjj	kr0|r.t jjj S dS |S )a  Gets the value to use for the X-Goog-User-Project header.

  Args:
    credentials: The credentials that are going to be used for requests.
    force_resource_quota: bool, If true, resource project quota will be used
      even if gcloud is set to use legacy mode for quota. This should be set
      when calling newer APIs that would not work without resource quota.

  Returns:
    str, The project id to send in the header or None to not populate the
    header.
  N)
r   rU   r  r  r_   r  rB   rV   projectLEGACY)r   force_resource_quotar  r#   r#   r$   GetQuotaProjectm  s   r  c                   @   sT   e Zd ZdZ			dddZedd Zedd Zdd	d
ZdddZ	dd Z
dS )ADCz&Application default credential object.Nc                 C   r  r+   )r   _impersonated_service_account
_delegatesrj  )r   r   impersonated_service_account	delegatesrG  r#   r#   r$   r     s   
zADC.__init__c                 C   s   t | jo	| jd u S r+   )rB   r   r  r   r#   r#   r$   r;     s   
zADC.is_userc                 C   s   t | j| j| j| jS )z/Json representation of the credentials for ADC.)_ConvertCredentialsToADCr   r  r  rj  r   r#   r#   r$   adc  s
   zADC.adcc                 C   s   |pt  }t| j|S )z+Dumps the credentials to the ADC json file.)r   ADCFilePath_DumpADCJsonToFiler  )r   	file_pathr#   r#   r$   DumpADCToFile  s   zADC.DumpADCToFilec                 C   s@   | j std|pt }|st| jdd}| |}t||S )zADumps the credentials and the quota project to the ADC json file.zoThe credential is not a user credential, so we cannot insert a quota project to application default credential.T)r  )r;   r(   r   r  r  r   _ExtendADCWithQuotaProjectr  )r   r  r  extended_adcr#   r#   r$   DumpExtendedADCToFile  s   

zADC.DumpExtendedADCToFilec                 C   s*   t | j}|r||t< |S td |S )z'Add quota_project_id field to ADC json.zCannot find a project to insert into application default credentials (ADC) as a quota project.
Run $gcloud auth application-default set-quota-project to insert a quota project to ADC.)copydeepcopyr  ADC_QUOTA_PROJECT_FIELD_NAMEr   r   )r   r  r  r#   r#   r$   r    s   zADC._ExtendADCWithQuotaProject)NNNr+   )NN)r   r    r!   r"   r   propertyr;   r  r  r  r  r#   r#   r#   r$   r    s    





r  c              
   C   sn   zt j| dddd}tj||dd W n tjy0 } ztj|dd tdt	| d}~ww t
j|S )	zDumps ADC json object to file.Tr  rM  rO  )private)exc_infoz.Error saving Application Default Credentials: N)rY  rZ  r   WriteFileContentsr   r   debugr(   r   	text_typeospathabspath)r  r  contentsr   r#   r#   r$   r    s   r  c              
   C   sd   t | }|t jt jfvrtdt| |t jkr/t| j	| j
| j| j| j| j| j| j} | jS )zHConverts an oauth2client credentials to application default credentials.ICannot convert credentials of type {} to application default credentials.)r9   r:   ro   rE   r)   r   rB  r   GoogleCredentialsr   rC  rD  r   r   rb   rH  rF  rS  )r   r[  r#   r#   r$   $_ConvertOauth2ClientCredentialsToADC  s   


r  zNhttps://iamcredentials.{}/v1/projects/-/serviceAccounts/{}:generateAccessTokenc                 C   sj   t | r	t| }nt| }|s|S t| dr| j}ntjjjj}|t	
|||p)g dd}|r3||d< |S )z<Convert credentials with impersonation to a json dictionary.rT   r  )source_credentialsr  r  rB  rG  )r0   r  "_ConvertGoogleAuthCredentialsToADCr|   rT   r   rU   rV   rW   IMPERSONATION_TOKEN_URLr   )r   r  r  rG  r\  rT   impersonated_creds_dictr#   r#   r$   r    s&   

r  c                 C   s   t | }|t jkr| jdd}t|}|j|d< |S |t jkr2|j| j| j	| j
| j| j| jdS |t jks<|t jkrM| j}|dd |dd |S |t jkrl| jdd}t|}t| d	ddurj| j|d	< |S td
t| )zFConverts a google-auth credentials to application default credentials.)r   rb   rG  r   )striprB  )rB  rJ  r^  rK  rC  rb   rT   rC  NrD  )r   r   rG  rT   r  )r@   r:   ro   to_jsonrY  r  rg   rE   r   r^  rK  rC  rf  rT   rK   rN   rg  poprP   r   r)   r   rB  )r   r[  r  adc_jsonr#   r#   r$   r    s<   





	




r  nonec                  C   sB   t rt S ddlm}  ddl}|jdtdd | jt | a t	 S )an  Get the google.auth._default module.

  All messages from logging and warnings are muted because they are for
  ADC consumers (client libraries). The message are irrelevant and confusing to
  gcloud auth application-default users. gcloud auth application-default
  are the ADC producer.

  Returns:
    The google.auth._default module with logging/warnings muted.
  r   )_defaultNignorezgoogle.auth._default)categorymodule)
GOOGLE_AUTH_DEFAULTr  r  warningsfilterwarningsWarning_LOGGERsetLevelVERBOSITY_MUTEDGetGoogleAuthDefault)r  r  r#   r#   r$   r  1  s   r  )rb   r+   rJ   )NNFr   ){r"   
__future__r   r   r   r   rU  r   r  r|  enumr   rY  r  r   r  r   r5   r   r2   r   r  r	   r
  r
   r  r   r9  googlecloudsdk.corer   r   r   r;  r   r<   r  r   r  googlecloudsdk.core.utilr   oauth2clientr   r   oauth2client.contribr   r)  r   r  ri  r,  r-  r.  r/  r0  r2  r>  r?  r@  rA  r   r&   r'   r(   r)   r0   r4   r6   r?   rA   rB   rD   rH   rL   rO   rQ   rS   rX   ra   rh   rk   rn   rr   objectrs   add_metaclassABCMetar   r   r   r   r   r   Storager   r   r  r  r  r  Enumr9   r@   r   r   rn  rm  r   r   r  r  r  r  r  r  r  r  r  r  r  r  VALID_VERBOSITY_STRINGSr  r  r#   r#   r#   r$   <module>   s   	


>  Ls7W

9x
&X)J;' 

	
:
#&
