o
    +3                     @   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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ZG dd dejZG dd deZG dd deZdd ZdddZdd ZG dd deZG dd dejZdS ) z%Utilities for the iamcredentials API.    )absolute_import)division)unicode_literalsN
exceptions)http_wrapper)apis_internal)
properties)	resources)	transport)clientz&https://iamcredentials.googleapis.com/c                   @      e Zd ZdZdS )Errorz*Exception that are defined by this module.N__name__
__module____qualname____doc__ r   r   G/tmp/google-cloud-sdk/lib/googlecloudsdk/api_lib/iamcredentials/util.pyr   '       r   c                   @   r   )InvalidImpersonationAccountz1Exception when the service account id is invalid.Nr   r   r   r   r   r   +   r   r   c                   @   r   )&ImpersonatedCredGoogleAuthRefreshErrorzAException for google auth impersonated credentials refresh error.Nr   r   r   r   r   r   /   r   r   c              
   C   s   ddl m} tjj| dd| dd}|jdtjdd}tj	d	d
|d}z|j
|jj| |jj|dd}|W S  tjyS } ztj|dj|j| ddd}~w tjyd } zt|d}~ww )z8Generates an access token for the given service account.r   
transportsiamcredentials.serviceAccounts-
projectsIdserviceAccountsId
collectionparamsFenable_resource_quotaresponse_encodingallow_account_impersonationiamcredentialsv1http_client)scope)namegenerateAccessTokenRequestzError {code} (Forbidden) - failed to impersonate [{service_acc}]. Make sure the account that's trying to impersonate it has access to the service account itself and the "roles/iam.serviceAccountTokenCreator" role.)codeservice_accerror_formatN)googlecloudsdk.core.credentialsr   r
   REGISTRYParseGetApitoolsTransportr   ENCODINGr   _GetClientInstanceprojects_serviceAccountsGenerateAccessTokenMESSAGES_MODULE?IamcredentialsProjectsServiceAccountsGenerateAccessTokenRequestRelativeNameGenerateAccessTokenRequestapitools_exceptionsHttpForbiddenErrorr   HttpExceptionformatstatus_code	HttpError)service_account_idscopesr   service_account_refr*   
iam_clientresponseer   r   r   r9   3   sJ   
r9   Fc                 C   st   ddl m} tjj| dd| dd}|jdtjdd}tj	d	d
|d}|j
|jj| |jj||dd}|jS )z4Generates an id token for the given service account.r   r   r   r   r   r    Fr#   r'   r(   r)   )audienceincludeEmail)r,   generateIdTokenRequest)r2   r   r
   r3   r4   r5   r   r6   r   r7   r8   GenerateIdTokenr:   ;IamcredentialsProjectsServiceAccountsGenerateIdTokenRequestr<   GenerateIdTokenRequesttoken)rD   rJ   include_emailr   rF   r*   rG   rH   r   r   r   rM   [   s.   rM   c                  C   sH   t jjj rt jjj S t jjj} |  | jkr"t	
d|  S t	S )a  Returns the effective IAM endpoint.

  (1) If the [api_endpoint_overrides/iamcredentials] property is explicitly set,
  return the property value.
  (2) Otherwise if [core/universe_domain] value is not default, return
  "https://iamcredentials.{universe_domain_value}/".
  (3) Otherise return "https://iamcredentials.googleapis.com/"

  Returns:
    str: The effective IAM endpoint.
  zgoogleapis.com)r	   VALUESapi_endpoint_overridesr'   IsExplicitlySetGetcoreuniverse_domaindefaultIAM_ENDPOINT_GDUreplace)universe_domain_propertyr   r   r   GetEffectiveIamEndpointw   s   
r\   c                   @   sH   e Zd ZdZdd Zdd Zdd Zdd	 Zed
d Z	edd Z
dS ) ImpersonationAccessTokenProviderzzA token provider for service account elevation.

  This supports the interface required by the core/credentials module.
  c                 C   s,   d|v rt dt||}t||j|j|S )N,zMore than one service accounts were specified, which is not supported. If being set, please unset the auth/disable_load_google_auth property and retry.)r   r9   ImpersonationCredentialsaccessToken
expireTime)selfrD   rE   rH   r   r   r   GetElevationAccessToken   s   
z8ImpersonationAccessTokenProvider.GetElevationAccessTokenc                 C   s   t |||S N)rM   )rb   rD   rJ   rQ   r   r   r   GetElevationIdToken   s   z4ImpersonationAccessTokenProvider.GetElevationIdTokenc                 C   s  ddl m} ddl m} ddlm} | }|| |j||||d}	|   z|	| W |	S  |j	y }
 zNdj
|d}d}z/t|
jd	 }|d
 |d d  |d d< tjd|d d it|dd}tj|}W n	 tyy   Y nw |rtj|ddt|d}
~
ww )zCCreates a fresh impersonation credential using google-auth library.r   r   impersonated_credentialsrequests)source_credentialstarget_principaltarget_scopes	delegateszFailed to impersonate [{service_acc}]. Make sure the account that's trying to impersonate it has access to the service account itself and the "roles/iam.serviceAccountTokenCreator" role.)r/   N    errormessagestatusr.   )infocontentrequest_urlz{message} {details?
{?}}r0   )google.authr   rg   googlecloudsdk.coreri   GoogleAuthRequestrefreshCredentialsPerformIamEndpointsOverrideRefreshErrorrA   jsonloadsargsr   Responsedumpsr>   rC   FromResponse	Exceptionr@   r   )rb   rj   rk   rm   rE   google_auth_exceptions$google_auth_impersonated_credentialscore_requestsrequest_clientcredrI   original_message
http_errorrt   http_responser   r   r   !GetElevationAccessTokenGoogleAuth   sT   
.	
zBImpersonationAccessTokenProvider.GetElevationAccessTokenGoogleAuthc                 C   sF   ddl m} ddlm} |j|||d}| }|   || |S )z=Creates an ID token credentials for impersonated credentials.r   rf   rh   )target_audiencerQ   )rv   rg   rw   ri   IDTokenCredentialsrx   r{   ry   )rb   %google_auth_impersonation_credentialsrJ   rQ   r   r   r   r   r   r   r   GetElevationIdTokenGoogleAuth   s   
z>ImpersonationAccessTokenProvider.GetElevationIdTokenGoogleAuthc                 C   s"   ddl m} t|tpt||jS )Nr   rf   )rv   rg   
isinstancer_   rz   )clsr   r   r   r   r   IsImpersonationCredential   s   z:ImpersonationAccessTokenProvider.IsImpersonationCredentialc                 C   sF   ddl m} t }|jt||_|jt||_|jt||_dS )a.  Perform IAM endpoint override if needed.

    We will override IAM generateAccessToken, signBlob, and generateIdToken
    endpoint under the following conditions.
    (1) If the [api_endpoint_overrides/iamcredentials] property is explicitly
    set, we replace "https://iamcredentials.googleapis.com/" with the given
    property value in these endpoints.
    (2) If the property above is not set, and the [core/universe_domain] value
    is not default, we replace "googleapis.com" with the [core/universe_domain]
    property value in these endpoints.
    r   )iamN)rv   r   r\   _IAM_ENDPOINTrZ   rY   _IAM_SIGN_ENDPOINT_IAM_IDTOKEN_ENDPOINT)r   google_auth_iameffective_iam_endpointr   r   r   r{     s"   z<ImpersonationAccessTokenProvider.PerformIamEndpointsOverrideN)r   r   r   r   rc   re   r   r   classmethodr   r{   r   r   r   r   r]      s    
I
r]   c                       s4   e Zd ZdZdZ fddZdd Zdd Z  ZS )	r_   zNImplementation of a credential that refreshes using the iamcredentials API.
  z%Y-%m-%dT%H:%M:%SZc              
      s4   || _ | |}tt| j|d d d |d d |d d S )N)rE   )_service_account_id_ConvertExpiryTimesuperr_   __init__)rb   rD   access_tokentoken_expiryrE   	__class__r   r   r   /  s
   


z!ImpersonationCredentials.__init__c                 C   s,   t | jt| j}|j| _| |j| _d S rd   )	r9   r   listrE   r`   r   r   ra   r   )rb   httprH   r   r   r   _refresh5  s   z!ImpersonationCredentials._refreshc                 C   s   t j |tjS rd   )datetimestrptimer_   _EXPIRY_FORMAT)rb   valuer   r   r   r   <  s   z+ImpersonationCredentials._ConvertExpiryTime)	r   r   r   r   r   r   r   r   __classcell__r   r   r   r   r_   *  s    r_   )F)r   
__future__r   r   r   r   r}   apitools.base.pyr   r>   r   googlecloudsdk.api_lib.utilr   rw   core_exceptionsr	   r
   r   oauth2clientr   rY   r   r   r   r9   rM   r\   objectr]   OAuth2Credentialsr_   r   r   r   r   <module>   s2   
( 