def Run(self, args): """Run the helper command.""" impersonate_service_account = ( properties.VALUES.auth.impersonate_service_account.Get()) if impersonate_service_account: log.warning( "Impersonate service account '{}' is detected. This command cannot be" ' used to print the access token for an impersonate account. The ' "token below is still the application default credentials' access " 'token.'.format(impersonate_service_account)) try: creds, _ = google_auth_default.default( scopes=[auth_util.CLOUD_PLATFORM_SCOPE]) except google_auth_exceptions.DefaultCredentialsError as e: log.debug(e, exc_info=True) raise c_exc.ToolException(six.text_type(e)) # Converts the user credentials so that it can handle reauth during refresh. if isinstance(creds, google_auth_creds.Credentials): creds = c_google_auth.UserCredWithReauth.FromGoogleAuthUserCredentials( creds) with c_store.HandleGoogleAuthCredentialsRefreshError(for_adc=True): creds.refresh(http.GoogleAuthRequest()) return creds
def GetElevationAccessTokenGoogleAuth(self, source_credentials, service_account_id, scopes): """Creates a fresh impersonation credential using google-auth library.""" request_client = http_core.GoogleAuthRequest() # google-auth makes a shadow copy of the source_credentials and refresh # the copy instead of the original source_credentials. During the copying, # the monkey patch # (creds.CredentialStoreWithCache._WrapCredentialsRefreshWithAutoCaching) # is lost. Here, before passing to google-auth, we refresh # source_credentials. source_credentials.refresh(request_client) # Import only when necessary to decrease the startup time. Move it to # global once google-auth is ready to replace oauth2client. # pylint: disable=g-import-not-at-top from google.auth import impersonated_credentials as google_auth_impersonated_creds # pylint: enable=g-import-not-at-top cred = google_auth_impersonated_creds.Credentials( source_credentials, service_account_id, scopes) try: cred.refresh(request_client) except google_auth_exceptions.RefreshError: raise ImpersonatedCredGoogleAuthRefreshError( '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.'.format(service_acc=service_account_id)) return cred
def GetElevationIdTokenGoogleAuth(self, google_auth_impersonation_credentials, audience, include_email): cred = google_auth_impersonated_creds.IDTokenCredentials( google_auth_impersonation_credentials, target_audience=audience, include_email=include_email) request_client = http_core.GoogleAuthRequest() cred.refresh(request_client) return cred
def _RefreshCredentials(credentials): """Refreshes the input credentials. Different logic will be executed for oauth2client and google-auth credentials. Args: credentials: google.auth.credentials.Credentials or client.OAuth2Credentials, the credentials to refresh. """ if isinstance(credentials, client.OAuth2Credentials): credentials.refresh(httplib2.Http()) else: credentials.refresh(http.GoogleAuthRequest())
def GetElevationAccessTokenGoogleAuth(self, source_credentials, service_account_id, scopes): """Creates a fresh impersonation credential using google-auth library.""" request_client = http_core.GoogleAuthRequest() # google-auth makes a shadow copy of the source_credentials and refresh # the copy instead of the original source_credentials. During the copying, # the monkey patch # (creds.CredentialStoreWithCache._WrapCredentialsRefreshWithAutoCaching) # is lost. Here, before passing to google-auth, we refresh # source_credentials. source_credentials.refresh(request_client) cred = google_auth_impersonated_creds.Credentials( source_credentials, service_account_id, scopes) cred.refresh(request_client) return cred
def GetElevationIdTokenGoogleAuth(self, google_auth_impersonation_credentials, audience, include_email): """Creates an ID token credentials for impersonated credentials.""" # Import only when necessary to decrease the startup time. Move it to # global once google-auth is ready to replace oauth2client. # pylint: disable=g-import-not-at-top from google.auth import impersonated_credentials as google_auth_impersonated_creds # pylint: enable=g-import-not-at-top cred = google_auth_impersonated_creds.IDTokenCredentials( google_auth_impersonation_credentials, target_audience=audience, include_email=include_email) request_client = http_core.GoogleAuthRequest() cred.refresh(request_client) return cred
def RevokeCredentials(credentials): """Revokes the token on the server. Args: credentials: user account credentials from either google-auth or oauth2client. Raises: RevokeError: If credentials to revoke is not user account credentials. """ if not c_creds.IsUserAccountCredentials(credentials): raise RevokeError( 'The token cannot be revoked from server because it is ' 'not user account credentials.') http_client = http.Http() if c_creds.IsOauth2ClientCredentials(credentials): credentials.revoke(http_client) else: credentials.revoke(http.GoogleAuthRequest(http_client))
def GetElevationAccessTokenGoogleAuth(self, source_credentials, service_account_id, scopes): """Creates a fresh impersonation credential using google-auth library.""" request_client = http_core.GoogleAuthRequest() # google-auth makes a shadow copy of the source_credentials and refresh # the copy instead of the original source_credentials. During the copying, # the monkey patch # (creds.CredentialStoreWithCache._WrapCredentialsRefreshWithAutoCaching) # is lost. Here, before passing to google-auth, we refresh # source_credentials. source_credentials.refresh(request_client) # Import only when necessary to decrease the startup time. Move it to # global once google-auth is ready to replace oauth2client. # pylint: disable=g-import-not-at-top from google.auth import impersonated_credentials as google_auth_impersonated_creds # pylint: enable=g-import-not-at-top cred = google_auth_impersonated_creds.Credentials( source_credentials, service_account_id, scopes) cred.refresh(request_client) return cred
def refresh(self, http_client): # pylint: disable=invalid-name self.credentials.refresh(http.GoogleAuthRequest(http_client))
def _RefreshGoogleAuth(credentials, http_client=None, is_impersonated_credential=False, include_email=False, gce_token_format='standard', gce_include_license=False): """Refreshes google-auth credentials. Args: credentials: google.auth.credentials.Credentials, A google-auth credentials to refresh. http_client: httplib2.Http, The http transport to refresh with. is_impersonated_credential: bool, True treat provided credential as an impersonated service account credential. If False, treat as service account or user credential. Needed to avoid circular dependency on IMPERSONATION_TOKEN_PROVIDER. include_email: bool, Specifies whether or not the service account email is included in the identity token. Only applicable to impersonated service account. gce_token_format: str, Specifies whether or not the project and instance details are included in the identity token. Choices are "standard", "full". gce_include_license: bool, Specifies whether or not license codes for images associated with GCE instance are included in their identity tokens. Raises: AccountImpersonationError: if impersonation support is not available for gcloud, or if the provided credentials is not google auth impersonation credentials. """ request_client = http.GoogleAuthRequest(http_client) with HandleGoogleAuthCredentialsRefreshError(): credentials.refresh(request_client) id_token = None if is_impersonated_credential: if not IMPERSONATION_TOKEN_PROVIDER: raise AccountImpersonationError( 'gcloud is configured to impersonate a service account but ' 'impersonation support is not available.') if not isinstance(credentials, google_auth_impersonated_creds.Credentials): raise AccountImpersonationError( 'Invalid impersonation account for refresh {}'.format( credentials)) id_token_creds = IMPERSONATION_TOKEN_PROVIDER.GetElevationIdTokenGoogleAuth( credentials, config.CLOUDSDK_CLIENT_ID, include_email) id_token_creds.refresh(request_client) id_token = id_token_creds.token elif isinstance(credentials, google_auth_service_account.Credentials): id_token = _RefreshServiceAccountIdTokenGoogleAuth( credentials, request_client) elif isinstance(credentials, google_auth_gce.Credentials): id_token = c_gce.Metadata().GetIdToken( config.CLOUDSDK_CLIENT_ID, token_format=gce_token_format, include_license=gce_include_license) if id_token: # '_id_token' is the field supported in google-auth natively. gcloud # keeps an additional field 'id_tokenb64' to store this information # which is referenced in several places credentials._id_token = id_token # pylint: disable=protected-access credentials.id_tokenb64 = id_token