Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

refactor: split 'with_quota_project' into separate base class #561

Merged
merged 3 commits into from
Sep 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions google/auth/app_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ def get_project_id():
return app_identity.get_application_id()


class Credentials(credentials.Scoped, credentials.Signing, credentials.Credentials):
class Credentials(
credentials.Scoped, credentials.Signing, credentials.CredentialsWithQuotaProject
):
"""App Engine standard environment credentials.

These credentials use the App Engine App Identity API to obtain access
Expand Down Expand Up @@ -145,7 +147,7 @@ def with_scopes(self, scopes):
quota_project_id=self.quota_project_id,
)

@_helpers.copy_docstring(credentials.Credentials)
@_helpers.copy_docstring(credentials.CredentialsWithQuotaProject)
def with_quota_project(self, quota_project_id):
return self.__class__(
scopes=self._scopes,
Expand Down
8 changes: 4 additions & 4 deletions google/auth/compute_engine/credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from google.oauth2 import _client


class Credentials(credentials.ReadOnlyScoped, credentials.Credentials):
class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaProject):
"""Compute Engine Credentials.

These credentials use the Google Compute Engine metadata server to obtain
Expand Down Expand Up @@ -118,7 +118,7 @@ def requires_scopes(self):
"""False: Compute Engine credentials can not be scoped."""
return False

@_helpers.copy_docstring(credentials.Credentials)
@_helpers.copy_docstring(credentials.CredentialsWithQuotaProject)
def with_quota_project(self, quota_project_id):
return self.__class__(
service_account_email=self._service_account_email,
Expand All @@ -130,7 +130,7 @@ def with_quota_project(self, quota_project_id):
_DEFAULT_TOKEN_URI = "https://www.googleapis.com/oauth2/v4/token"


class IDTokenCredentials(credentials.Credentials, credentials.Signing):
class IDTokenCredentials(credentials.CredentialsWithQuotaProject, credentials.Signing):
"""Open ID Connect ID Token-based service account credentials.

These credentials relies on the default service account of a GCE instance.
Expand Down Expand Up @@ -254,7 +254,7 @@ def with_target_audience(self, target_audience):
quota_project_id=self._quota_project_id,
)

@_helpers.copy_docstring(credentials.Credentials)
@_helpers.copy_docstring(credentials.CredentialsWithQuotaProject)
def with_quota_project(self, quota_project_id):

# since the signer is already instantiated,
Expand Down
9 changes: 5 additions & 4 deletions google/auth/credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ def before_request(self, request, method, url, headers):
self.refresh(request)
self.apply(headers)


class CredentialsWithQuotaProject(Credentials):
"""Abstract base for credentials supporting ``with_quota_project`` factory"""

def with_quota_project(self, quota_project_id):
"""Returns a copy of these credentials with a modified quota project

Expand All @@ -143,7 +147,7 @@ def with_quota_project(self, quota_project_id):
Returns:
google.oauth2.credentials.Credentials: A new credentials instance.
"""
raise NotImplementedError("This class does not support quota project.")
raise NotImplementedError("This credential does not support quota project.")


class AnonymousCredentials(Credentials):
Expand Down Expand Up @@ -182,9 +186,6 @@ def apply(self, headers, token=None):
def before_request(self, request, method, url, headers):
"""Anonymous credentials do nothing to the request."""

def with_quota_project(self, quota_project_id):
raise ValueError("Anonymous credentials don't support quota project.")


@six.add_metaclass(abc.ABCMeta)
class ReadOnlyScoped(object):
Expand Down
8 changes: 4 additions & 4 deletions google/auth/impersonated_credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def _make_iam_token_request(request, principal, headers, body):
six.raise_from(new_exc, caught_exc)


class Credentials(credentials.Credentials, credentials.Signing):
class Credentials(credentials.CredentialsWithQuotaProject, credentials.Signing):
"""This module defines impersonated credentials which are essentially
impersonated identities.

Expand Down Expand Up @@ -293,7 +293,7 @@ def service_account_email(self):
def signer(self):
return self

@_helpers.copy_docstring(credentials.Credentials)
@_helpers.copy_docstring(credentials.CredentialsWithQuotaProject)
def with_quota_project(self, quota_project_id):
return self.__class__(
self._source_credentials,
Expand All @@ -305,7 +305,7 @@ def with_quota_project(self, quota_project_id):
)


class IDTokenCredentials(credentials.Credentials):
class IDTokenCredentials(credentials.CredentialsWithQuotaProject):
"""Open ID Connect ID Token-based service account credentials.

"""
Expand Down Expand Up @@ -359,7 +359,7 @@ def with_include_email(self, include_email):
quota_project_id=self._quota_project_id,
)

@_helpers.copy_docstring(credentials.Credentials)
@_helpers.copy_docstring(credentials.CredentialsWithQuotaProject)
def with_quota_project(self, quota_project_id):
return self.__class__(
target_credentials=self._target_credentials,
Expand Down
10 changes: 6 additions & 4 deletions google/auth/jwt.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,9 @@ def decode(token, certs=None, verify=True, audience=None):
return payload


class Credentials(google.auth.credentials.Signing, google.auth.credentials.Credentials):
class Credentials(
google.auth.credentials.Signing, google.auth.credentials.CredentialsWithQuotaProject
):
"""Credentials that use a JWT as the bearer token.

These credentials require an "audience" claim. This claim identifies the
Expand Down Expand Up @@ -493,7 +495,7 @@ def with_claims(
quota_project_id=self._quota_project_id,
)

@_helpers.copy_docstring(google.auth.credentials.Credentials)
@_helpers.copy_docstring(google.auth.credentials.CredentialsWithQuotaProject)
def with_quota_project(self, quota_project_id):
return self.__class__(
self._signer,
Expand Down Expand Up @@ -554,7 +556,7 @@ def signer(self):


class OnDemandCredentials(
google.auth.credentials.Signing, google.auth.credentials.Credentials
google.auth.credentials.Signing, google.auth.credentials.CredentialsWithQuotaProject
):
"""On-demand JWT credentials.

Expand Down Expand Up @@ -721,7 +723,7 @@ def with_claims(self, issuer=None, subject=None, additional_claims=None):
quota_project_id=self._quota_project_id,
)

@_helpers.copy_docstring(google.auth.credentials.Credentials)
@_helpers.copy_docstring(google.auth.credentials.CredentialsWithQuotaProject)
def with_quota_project(self, quota_project_id):

return self.__class__(
Expand Down
8 changes: 4 additions & 4 deletions google/oauth2/credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
_GOOGLE_OAUTH2_TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token"


class Credentials(credentials.ReadOnlyScoped, credentials.Credentials):
class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaProject):
"""Credentials using OAuth 2.0 access and refresh tokens.

The credentials are considered immutable. If you want to modify the
Expand Down Expand Up @@ -161,7 +161,7 @@ def requires_scopes(self):
the initial token is requested and can not be changed."""
return False

@_helpers.copy_docstring(credentials.Credentials)
@_helpers.copy_docstring(credentials.CredentialsWithQuotaProject)
def with_quota_project(self, quota_project_id):

return self.__class__(
Expand Down Expand Up @@ -305,7 +305,7 @@ def to_json(self, strip=None):
return json.dumps(prep)


class UserAccessTokenCredentials(credentials.Credentials):
class UserAccessTokenCredentials(credentials.CredentialsWithQuotaProject):
"""Access token credentials for user account.

Obtain the access token for a given user account or the current active
Expand Down Expand Up @@ -336,7 +336,7 @@ def with_account(self, account):
"""
return self.__class__(account=account, quota_project_id=self._quota_project_id)

@_helpers.copy_docstring(credentials.Credentials)
@_helpers.copy_docstring(credentials.CredentialsWithQuotaProject)
def with_quota_project(self, quota_project_id):
return self.__class__(account=self._account, quota_project_id=quota_project_id)

Expand Down
10 changes: 6 additions & 4 deletions google/oauth2/service_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@
_DEFAULT_TOKEN_LIFETIME_SECS = 3600 # 1 hour in seconds


class Credentials(credentials.Signing, credentials.Scoped, credentials.Credentials):
class Credentials(
credentials.Signing, credentials.Scoped, credentials.CredentialsWithQuotaProject
):
"""Service account credentials

Usually, you'll create these credentials with one of the helper
Expand Down Expand Up @@ -306,7 +308,7 @@ def with_claims(self, additional_claims):
additional_claims=new_additional_claims,
)

@_helpers.copy_docstring(credentials.Credentials)
@_helpers.copy_docstring(credentials.CredentialsWithQuotaProject)
def with_quota_project(self, quota_project_id):

return self.__class__(
Expand Down Expand Up @@ -375,7 +377,7 @@ def signer_email(self):
return self._service_account_email


class IDTokenCredentials(credentials.Signing, credentials.Credentials):
class IDTokenCredentials(credentials.Signing, credentials.CredentialsWithQuotaProject):
"""Open ID Connect ID Token-based service account credentials.

These credentials are largely similar to :class:`.Credentials`, but instead
Expand Down Expand Up @@ -533,7 +535,7 @@ def with_target_audience(self, target_audience):
quota_project_id=self.quota_project_id,
)

@_helpers.copy_docstring(credentials.Credentials)
@_helpers.copy_docstring(credentials.CredentialsWithQuotaProject)
def with_quota_project(self, quota_project_id):
return self.__class__(
self._signer,
Expand Down
2 changes: 1 addition & 1 deletion tests/test__default.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
with open(SERVICE_ACCOUNT_FILE) as fh:
SERVICE_ACCOUNT_FILE_DATA = json.load(fh)

MOCK_CREDENTIALS = mock.Mock(spec=credentials.Credentials)
MOCK_CREDENTIALS = mock.Mock(spec=credentials.CredentialsWithQuotaProject)
MOCK_CREDENTIALS.with_quota_project.return_value = MOCK_CREDENTIALS

LOAD_FILE_PATCH = mock.patch(
Expand Down
6 changes: 0 additions & 6 deletions tests/test_credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,6 @@ def test_anonymous_credentials_before_request():
assert headers == {}


def test_anonymous_credentials_with_quota_project():
with pytest.raises(ValueError):
anon = credentials.AnonymousCredentials()
anon.with_quota_project("project-foo")


class ReadOnlyScopedCredentialsImpl(credentials.ReadOnlyScoped, CredentialsImpl):
@property
def requires_scopes(self):
Expand Down