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
예제 #2
0
 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
예제 #3
0
 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
예제 #4
0
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())
예제 #5
0
 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
예제 #6
0
 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
예제 #7
0
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))
예제 #8
0
 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
예제 #9
0
 def refresh(self, http_client):  # pylint: disable=invalid-name
   self.credentials.refresh(http.GoogleAuthRequest(http_client))
예제 #10
0
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