Exemple #1
0
def Store(credentials, account=None, scopes=None):
    """Store credentials according for an account address.

  Args:
    credentials: oauth2client.client.Credentials, The credentials to be stored.
    account: str, The account address of the account they're being stored for.
        If None, the account stored in the core.account property is used.
    scopes: tuple, Custom auth scopes to request. By default CLOUDSDK_SCOPES
        are requested.

  Raises:
    NoActiveAccountException: If account is not provided and there is no
        active account.
  """

    cred_type = creds.CredentialType.FromCredentials(credentials)
    if not cred_type.is_serializable:
        return

    if not account:
        account = properties.VALUES.core.account.Get()
    if not account:
        raise NoActiveAccountException()

    store = creds.GetCredentialStore()
    store.Store(account, credentials)
    _LegacyGenerator(account, credentials, scopes).WriteTemplate()
Exemple #2
0
  def testCredentialStoreChangesToPrivate(self):
    """Tests that reading credentials turns the credential files private."""
    store_file = os.path.join(self.temp_path, 'credentials.db')
    access_token_file = os.path.join(self.temp_path, 'access_token.db')
    creds.GetCredentialStore(store_file, access_token_file)

    for path in (store_file, access_token_file):
      # Open up the permissions to verify that they get changed back
      os.chmod(path, 0o777)

    creds.GetCredentialStore(store_file, access_token_file)

    for path in (store_file, access_token_file):
      self.assertEqual(
          os.stat(store_file).st_mode & 0o777, 0o600,
          'File [{}] should be changed back to 0o600 permissions'.format(
              os.path.basename(path)))
Exemple #3
0
def Revoke(account=None):
    """Revoke credentials and clean up related files.

  Args:
    account: str, The account address for the credentials to be revoked. If
        None, the currently active account is used.

  Returns:
    'True' if this call revoked the account; 'False' if the account was already
    revoked.

  Raises:
    NoActiveAccountException: If account is not provided and there is no
        active account.
    NoCredentialsForAccountException: If the provided account is not tied to any
        known credentials.
    RevokeError: If there was a more general problem revoking the account.
  """
    if not account:
        account = properties.VALUES.core.account.Get()
    if not account:
        raise NoActiveAccountException()

    if account in c_gce.Metadata().Accounts():
        raise RevokeError('Cannot revoke GCE-provided credentials.')

    credentials = Load(account, prevent_refresh=True)
    if not credentials:
        raise NoCredentialsForAccountException(account)

    if isinstance(credentials, c_devshell.DevshellCredentials):
        raise RevokeError(
            'Cannot revoke the automatically provisioned Cloud Shell credential.'
            'This comes from your browser session and will not persist outside'
            'of your connected Cloud Shell session.')

    rv = False
    try:
        if not account.endswith('.gserviceaccount.com'):
            RevokeCredentials(credentials)
            rv = True
    except client.TokenRevokeError as e:
        if e.args[0] == 'invalid_token':
            # Malformed or already revoked
            pass
        elif e.args[0] == 'invalid_request':
            # Service account token
            pass
        else:
            raise

    store = creds.GetCredentialStore()
    store.Remove(account)

    _LegacyGenerator(account, credentials).Clean()
    files.RmTree(config.Paths().LegacyCredentialsDir(account))
    return rv
Exemple #4
0
  def SetUp(self):
    store_file = os.path.join(self.temp_path, 'credentials.db')
    access_token_file = os.path.join(self.temp_path, 'access_token.db')
    self.store = creds.GetCredentialStore(store_file, access_token_file)
    self.fake_account = 'test_account'

    # Mocks the refresh of oauth2client credentials.
    self.StartObjectPatch(
        httplib2.Http,
        'request',
        return_value=_MakeFakeOauth2clientCredsRefreshResponse())
Exemple #5
0
def _Load(account, scopes, prevent_refresh):
    """Helper for Load()."""
    # If a credential file is set, just use that and ignore the active account
    # and whatever is in the credential store.
    cred_file_override = properties.VALUES.auth.credential_file_override.Get()
    if cred_file_override:
        log.info('Using alternate credentials from file: [%s]',
                 cred_file_override)
        try:
            cred = client.GoogleCredentials.from_stream(cred_file_override)
        except client.Error as e:
            raise InvalidCredentialFileException(cred_file_override, e)

        if cred.create_scoped_required():
            if scopes is None:
                scopes = config.CLOUDSDK_SCOPES
            cred = cred.create_scoped(scopes)

        # Set token_uri after scopes since token_uri needs to be explicitly
        # preserved when scopes are applied.
        token_uri_override = properties.VALUES.auth.token_host.Get()
        if token_uri_override:
            cred_type = creds.CredentialType.FromCredentials(cred)
            if cred_type in (creds.CredentialType.SERVICE_ACCOUNT,
                             creds.CredentialType.P12_SERVICE_ACCOUNT):
                cred.token_uri = token_uri_override
        # The credential override is not stored in credential store, but we still
        # want to cache access tokens between invocations.
        return creds.MaybeAttachAccessTokenCacheStore(cred)

    if not account:
        account = properties.VALUES.core.account.Get()

    if not account:
        raise NoActiveAccountException(
            named_configs.ActiveConfig(False).file_path)

    cred = STATIC_CREDENTIAL_PROVIDERS.GetCredentials(account)
    if cred is not None:
        return cred

    store = creds.GetCredentialStore()
    cred = store.Load(account)
    if not cred:
        raise NoCredentialsForAccountException(account)

    # cred.token_expiry is in UTC time.
    if (not prevent_refresh
            and (not cred.token_expiry
                 or cred.token_expiry < cred.token_expiry.utcnow())):
        Refresh(cred)

    return cred
Exemple #6
0
def AvailableAccounts():
    """Get all accounts that have credentials stored for the CloudSDK.

  This function will also ping the GCE metadata server to see if GCE credentials
  are available.

  Returns:
    [str], List of the accounts.

  """
    store = creds.GetCredentialStore()
    accounts = store.GetAccounts() | STATIC_CREDENTIAL_PROVIDERS.GetAccounts()

    return sorted(accounts)
Exemple #7
0
  def testCredentialStoreCreatedPrivate(self):
    """Tests that reading credentials creates the credential files private."""
    store_file = os.path.join(self.temp_path, 'credentials.db')
    access_token_file = os.path.join(self.temp_path, 'access_token.db')
    for path in (store_file, access_token_file):
      self.assertFalse(
          os.path.exists(path),
          'File [{}] should not exist already (test error)'.format(
              os.path.basename(path)))

    creds.GetCredentialStore(store_file, access_token_file)

    for path in (store_file, access_token_file):
      self.assertEqual(
          os.stat(store_file).st_mode & 0o777, 0o600,
          'File [{}] file should be created with 0o600 permissions'.format(
              os.path.basename(path)))
Exemple #8
0
def AvailableAccounts():
    """Get all accounts that have credentials stored for the CloudSDK.

  This function will also ping the GCE metadata server to see if GCE credentials
  are available.

  Returns:
    [str], List of the accounts.

  """
    store = creds.GetCredentialStore()
    accounts = store.GetAccounts() | set(c_gce.Metadata().Accounts())

    devshell_creds = c_devshell.LoadDevshellCredentials()
    if devshell_creds:
        accounts.add(devshell_creds.devshell_response.user_email)

    return sorted(accounts)
Exemple #9
0
  def SetUp(self):
    store_file = os.path.join(self.temp_path, 'credentials.db')
    access_token_file = os.path.join(self.temp_path, 'access_token.db')
    self.store = creds.GetCredentialStore(store_file, access_token_file)
    self.fake_account = 'test_account'

    # Mocks the refresh of oauth2client credentials.
    self.StartObjectPatch(
        httplib2.Http,
        'request',
        return_value=_MakeFakeOauth2clientCredsRefreshResponse())

    # Mocks the signer of oauth2client credentials.
    signer = self.StartPatch('oauth2client.crypt.Signer', autospec=True)
    self.StartObjectPatch(crypt, 'OpenSSLSigner', new=signer)
    self.StartObjectPatch(
        crypt, 'make_signed_jwt', return_value=b'fake_assertion')

    # Mocks the signer of google-auth credentials.
    self.StartObjectPatch(google_auth_crypt.RSASigner,
                          'from_service_account_info')
    self.StartObjectPatch(jwt, 'encode', return_value=b'fake_assertion')
Exemple #10
0
def Store(credentials, account=None, scopes=None):
    """Store credentials according for an account address.

  gcloud only stores user account credentials, service account credentials and
  p12 service account credentials. GCE, IAM impersonation, and Devshell
  credentials are generated in runtime.

  Args:
    credentials: oauth2client.client.Credentials or
      google.auth.credentials.Credentials, The credentials to be stored.
    account: str, The account address of the account they're being stored for.
        If None, the account stored in the core.account property is used.
    scopes: tuple, Custom auth scopes to request. By default CLOUDSDK_SCOPES
        are requested.

  Raises:
    NoActiveAccountException: If account is not provided and there is no
        active account.
  """

    if c_creds.IsOauth2ClientCredentials(credentials):
        cred_type = c_creds.CredentialType.FromCredentials(credentials)
    else:
        cred_type = c_creds.CredentialTypeGoogleAuth.FromCredentials(
            credentials)

    if not cred_type.is_serializable:
        return

    if not account:
        account = properties.VALUES.core.account.Get()
    if not account:
        raise NoActiveAccountException()

    store = c_creds.GetCredentialStore()
    store.Store(account, credentials)

    _LegacyGenerator(account, credentials, scopes).WriteTemplate()
Exemple #11
0
def Store(credentials, account=None, scopes=None):
    """Store credentials according for an account address.

  Args:
    credentials: oauth2client.client.Credentials or
      google.auth.credentials.Credentials, The credentials to be stored.
    account: str, The account address of the account they're being stored for.
        If None, the account stored in the core.account property is used.
    scopes: tuple, Custom auth scopes to request. By default CLOUDSDK_SCOPES
        are requested.

  Raises:
    NoActiveAccountException: If account is not provided and there is no
        active account.
  """

    if isinstance(credentials, client.OAuth2Credentials):
        cred_type = creds.CredentialType.FromCredentials(credentials)
    else:
        cred_type = creds.CredentialTypeGoogleAuth.FromCredentials(credentials)

    if not cred_type.is_serializable:
        return

    if not account:
        account = properties.VALUES.core.account.Get()
    if not account:
        raise NoActiveAccountException()

    store = creds.GetCredentialStore()
    store.Store(account, credentials)

    # TODO(b/151574510): Removes this if check once _LegacyGenerator supports
    # google-auth credentials.
    if isinstance(credentials, client.OAuth2Credentials):
        _LegacyGenerator(account, credentials, scopes).WriteTemplate()
 def RemoveServiceAccount(self):
     c_store = c_creds.GetCredentialStore()
     c_store.Remove(_SERVICE_ACCOUNT_EMAIL)
Exemple #13
0
def Revoke(account=None, use_google_auth=False):
    """Revoke credentials and clean up related files.

  Args:
    account: str, The account address for the credentials to be revoked. If
        None, the currently active account is used.
    use_google_auth: bool, True to revoke the credentials as google auth
        credentials. False to revoke the credentials as oauth2client
        credentials.

  Returns:
    True if this call revoked the account; False if the account was already
    revoked.

  Raises:
    NoActiveAccountException: If account is not provided and there is no
        active account.
    NoCredentialsForAccountException: If the provided account is not tied to any
        known credentials.
    RevokeError: If there was a more general problem revoking the account.
  """
    # 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 googlecloudsdk.core.credentials import google_auth_credentials as c_google_auth
    # pylint: enable=g-import-not-at-top
    if not account:
        account = properties.VALUES.core.account.Get()
    if not account:
        raise NoActiveAccountException()

    if account in c_gce.Metadata().Accounts():
        raise RevokeError('Cannot revoke GCE-provided credentials.')

    credentials = Load(account,
                       prevent_refresh=True,
                       use_google_auth=use_google_auth)
    if not credentials:
        raise NoCredentialsForAccountException(account)

    if (isinstance(credentials, c_devshell.DevshellCredentials) or isinstance(
            credentials, c_devshell.DevShellCredentialsGoogleAuth)):
        raise RevokeError(
            'Cannot revoke the automatically provisioned Cloud Shell credential.'
            'This comes from your browser session and will not persist outside'
            'of your connected Cloud Shell session.')

    rv = False
    try:
        if not account.endswith('.gserviceaccount.com'):
            RevokeCredentials(credentials)
            rv = True
    except (client.TokenRevokeError, c_google_auth.TokenRevokeError) as e:
        if e.args[0] == 'invalid_token':
            # Malformed or already revoked
            pass
        elif e.args[0] == 'invalid_request':
            # Service account token
            pass
        else:
            raise

    store = c_creds.GetCredentialStore()
    store.Remove(account)

    _LegacyGenerator(account, credentials).Clean()
    legacy_creds_dir = config.Paths().LegacyCredentialsDir(account)
    if os.path.isdir(legacy_creds_dir):
        files.RmTree(legacy_creds_dir)
    return rv
Exemple #14
0
def Load(account=None, scopes=None, prevent_refresh=False):
    """Get the credentials associated with the provided account.

  This loads credentials regardless of whether credentials have been disabled
  via properties. Only use this when the functionality of the caller absolutely
  requires credentials (like printing out a token) vs logically requiring
  credentials (like for an http request).

  Args:
    account: str, The account address for the credentials being fetched. If
        None, the account stored in the core.account property is used.
    scopes: tuple, Custom auth scopes to request. By default CLOUDSDK_SCOPES
        are requested.
    prevent_refresh: bool, If True, do not refresh the access token even if it
        is out of date. (For use with operations that do not require a current
        access token, such as credential revocation.)

  Returns:
    oauth2client.client.Credentials, The specified credentials.

  Raises:
    NoActiveAccountException: If account is not provided and there is no
        active account.
    NoCredentialsForAccountException: If there are no valid credentials
        available for the provided or active account.
    c_gce.CannotConnectToMetadataServerException: If the metadata server cannot
        be reached.
    TokenRefreshError: If the credentials fail to refresh.
    TokenRefreshReauthError: If the credentials fail to refresh due to reauth.
  """
    # If a credential file is set, just use that and ignore the active account
    # and whatever is in the credential store.
    cred_file_override = properties.VALUES.auth.credential_file_override.Get()
    if cred_file_override:
        log.info('Using alternate credentials from file: [%s]',
                 cred_file_override)
        try:
            cred = client.GoogleCredentials.from_stream(cred_file_override)
        except client.Error as e:
            raise InvalidCredentialFileException(cred_file_override, e)

        if cred.create_scoped_required():
            if scopes is None:
                scopes = config.CLOUDSDK_SCOPES
            cred = cred.create_scoped(scopes)

        # Set token_uri after scopes since token_uri needs to be explicitly
        # preserved when scopes are applied.
        token_uri_override = properties.VALUES.auth.token_host.Get()
        if token_uri_override:
            cred_type = creds.CredentialType.FromCredentials(cred)
            if cred_type in (creds.CredentialType.SERVICE_ACCOUNT,
                             creds.CredentialType.P12_SERVICE_ACCOUNT):
                cred.token_uri = token_uri_override
        # The credential override is not stored in credential store, but we still
        # want to cache access tokens between invocations.
        return creds.MaybeAttachAccessTokenCacheStore(cred)

    if not account:
        account = properties.VALUES.core.account.Get()

    if not account:
        raise NoActiveAccountException()

    cred = STATIC_CREDENTIAL_PROVIDERS.GetCredentials(account)
    if cred is not None:
        return cred

    store = creds.GetCredentialStore()
    cred = store.Load(account)
    if not cred:
        raise NoCredentialsForAccountException(account)

    # cred.token_expiry is in UTC time.
    if (not prevent_refresh
            and (not cred.token_expiry
                 or cred.token_expiry < cred.token_expiry.utcnow())):
        Refresh(cred)

    return cred
Exemple #15
0
 def testSqliteBusyTimeoutSetting(self):
   store = creds.GetCredentialStore()
   with store._access_token_cache._cursor as cur:
     time_out = cur.Execute('PRAGMA busy_timeout;').fetchone()[0]
   self.assertEqual(1000, time_out)
Exemple #16
0
 def testNoWarnMessage(self):
   creds.GetCredentialStore()
   self.AssertErrEquals('')
Exemple #17
0
def Load(account=None, scopes=None, prevent_refresh=False):
    """Get the credentials associated with the provided account.

  Args:
    account: str, The account address for the credentials being fetched. If
        None, the account stored in the core.account property is used.
    scopes: tuple, Custom auth scopes to request. By default CLOUDSDK_SCOPES
        are requested.
    prevent_refresh: bool, If True, do not refresh the access token even if it
        is out of date. (For use with operations that do not require a current
        access token, such as credential revocation.)

  Returns:
    oauth2client.client.Credentials, The specified credentials.

  Raises:
    NoActiveAccountException: If account is not provided and there is no
        active account.
    NoCredentialsForAccountException: If there are no valid credentials
        available for the provided or active account.
    c_gce.CannotConnectToMetadataServerException: If the metadata server cannot
        be reached.
    TokenRefreshError: If the credentials fail to refresh.
    TokenRefreshReauthError: If the credentials fail to refresh due to reauth.
  """
    # If a credential file is set, just use that and ignore the active account
    # and whatever is in the credential store.
    cred_file_override = properties.VALUES.auth.credential_file_override.Get()
    if cred_file_override:
        log.info('Using alternate credentials from file: [%s]',
                 cred_file_override)
        try:
            cred = client.GoogleCredentials.from_stream(cred_file_override)
        except client.Error as e:
            raise InvalidCredentialFileException(cred_file_override, e)

        if cred.create_scoped_required():
            if scopes is None:
                scopes = config.CLOUDSDK_SCOPES
            cred = cred.create_scoped(scopes)

        # Set token_uri after scopes since token_uri needs to be explicitly
        # preserved when scopes are applied.
        token_uri_override = properties.VALUES.auth.token_host.Get()
        if token_uri_override:
            cred_type = creds.CredentialType.FromCredentials(cred)
            if cred_type in (creds.CredentialType.SERVICE_ACCOUNT,
                             creds.CredentialType.P12_SERVICE_ACCOUNT):
                cred.token_uri = token_uri_override
        return cred

    if not account:
        account = properties.VALUES.core.account.Get()

    if not account:
        raise NoActiveAccountException()

    devshell_creds = c_devshell.LoadDevshellCredentials()
    if devshell_creds and (devshell_creds.devshell_response.user_email
                           == account):
        return devshell_creds

    if account in c_gce.Metadata().Accounts():
        return AcquireFromGCE(account)

    store = creds.GetCredentialStore()
    cred = store.Load(account)
    if not cred:
        raise NoCredentialsForAccountException(account)

    # cred.token_expiry is in UTC time.
    if (not prevent_refresh
            and (not cred.token_expiry
                 or cred.token_expiry < cred.token_expiry.utcnow())):
        Refresh(cred)

    return cred