Skip to content

Commit 036dac4

Browse files
ohmayrgcf-owl-bot[bot]clundin25
authoredJul 16, 2024··
feat: implement base classes for credentials and request sessions (#1551)
* implement base classes for credentials and request sessions * remove public methods apply and before_request from base credentials * move MTLS logic back to requests * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * minor fix * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * address PR comments * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * address PR comments * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * chore: Refresh system test creds. * revert copyright date * fix import statements order --------- Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com> Co-authored-by: Carl Lundin <108372512+clundin25@users.noreply.github.com> Co-authored-by: Carl Lundin <clundin@google.com>
1 parent 61c2432 commit 036dac4

File tree

5 files changed

+133
-9
lines changed

5 files changed

+133
-9
lines changed
 

‎google/auth/_credentials_base.py

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Copyright 2024 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
16+
"""Interface for base credentials."""
17+
18+
import abc
19+
20+
from google.auth import _helpers
21+
22+
23+
class _BaseCredentials(metaclass=abc.ABCMeta):
24+
"""Base class for all credentials.
25+
26+
All credentials have a :attr:`token` that is used for authentication and
27+
may also optionally set an :attr:`expiry` to indicate when the token will
28+
no longer be valid.
29+
30+
Most credentials will be :attr:`invalid` until :meth:`refresh` is called.
31+
Credentials can do this automatically before the first HTTP request in
32+
:meth:`before_request`.
33+
34+
Although the token and expiration will change as the credentials are
35+
:meth:`refreshed <refresh>` and used, credentials should be considered
36+
immutable. Various credentials will accept configuration such as private
37+
keys, scopes, and other options. These options are not changeable after
38+
construction. Some classes will provide mechanisms to copy the credentials
39+
with modifications such as :meth:`ScopedCredentials.with_scopes`.
40+
"""
41+
42+
def __init__(self):
43+
self.token = None
44+
"""str: The bearer token that can be used in HTTP headers to make
45+
authenticated requests."""
46+
47+
@abc.abstractmethod
48+
def refresh(self, request):
49+
"""Refreshes the access token.
50+
51+
Args:
52+
request (google.auth.transport.Request): The object used to make
53+
HTTP requests.
54+
55+
Raises:
56+
google.auth.exceptions.RefreshError: If the credentials could
57+
not be refreshed.
58+
"""
59+
# pylint: disable=missing-raises-doc
60+
# (pylint doesn't recognize that this is abstract)
61+
raise NotImplementedError("Refresh must be implemented")
62+
63+
def _apply(self, headers, token=None):
64+
"""Apply the token to the authentication header.
65+
66+
Args:
67+
headers (Mapping): The HTTP request headers.
68+
token (Optional[str]): If specified, overrides the current access
69+
token.
70+
"""
71+
headers["authorization"] = "Bearer {}".format(
72+
_helpers.from_bytes(token or self.token)
73+
)

‎google/auth/credentials.py

+5-7
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@
2222
from google.auth import _helpers, environment_vars
2323
from google.auth import exceptions
2424
from google.auth import metrics
25+
from google.auth._credentials_base import _BaseCredentials
2526
from google.auth._refresh_worker import RefreshThreadManager
2627

2728
DEFAULT_UNIVERSE_DOMAIN = "googleapis.com"
2829

2930

30-
class Credentials(metaclass=abc.ABCMeta):
31+
class Credentials(_BaseCredentials):
3132
"""Base class for all credentials.
3233
3334
All credentials have a :attr:`token` that is used for authentication and
@@ -47,9 +48,8 @@ class Credentials(metaclass=abc.ABCMeta):
4748
"""
4849

4950
def __init__(self):
50-
self.token = None
51-
"""str: The bearer token that can be used in HTTP headers to make
52-
authenticated requests."""
51+
super(Credentials, self).__init__()
52+
5353
self.expiry = None
5454
"""Optional[datetime]: When the token expires and is no longer valid.
5555
If this is None, the token is assumed to never expire."""
@@ -167,9 +167,7 @@ def apply(self, headers, token=None):
167167
token (Optional[str]): If specified, overrides the current access
168168
token.
169169
"""
170-
headers["authorization"] = "Bearer {}".format(
171-
_helpers.from_bytes(token or self.token)
172-
)
170+
self._apply(headers, token=token)
173171
"""Trust boundary value will be a cached value from global lookup.
174172
175173
The response of trust boundary will be a list of regions and a hex
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Copyright 2024 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Transport adapter for Base Requests."""
16+
17+
18+
import abc
19+
20+
21+
_DEFAULT_TIMEOUT = 120 # in second
22+
23+
24+
class _BaseAuthorizedSession(metaclass=abc.ABCMeta):
25+
"""Base class for a Request Session with credentials. This class is intended to capture
26+
the common logic between synchronous and asynchronous request sessions and is not intended to
27+
be instantiated directly.
28+
29+
Args:
30+
credentials (google.auth._credentials_base.BaseCredentials): The credentials to
31+
add to the request.
32+
"""
33+
34+
def __init__(self, credentials):
35+
self.credentials = credentials
36+
37+
@abc.abstractmethod
38+
def request(
39+
self,
40+
method,
41+
url,
42+
data=None,
43+
headers=None,
44+
max_allowed_time=None,
45+
timeout=_DEFAULT_TIMEOUT,
46+
**kwargs
47+
):
48+
raise NotImplementedError("Request must be implemented")
49+
50+
@abc.abstractmethod
51+
def close(self):
52+
raise NotImplementedError("Close must be implemented")

‎google/auth/transport/requests.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
from google.auth import exceptions
3939
from google.auth import transport
4040
import google.auth.transport._mtls_helper
41+
from google.auth.transport._requests_base import _BaseAuthorizedSession
4142
from google.oauth2 import service_account
4243

4344
_LOGGER = logging.getLogger(__name__)
@@ -292,7 +293,7 @@ def proxy_manager_for(self, *args, **kwargs):
292293
return super(_MutualTlsOffloadAdapter, self).proxy_manager_for(*args, **kwargs)
293294

294295

295-
class AuthorizedSession(requests.Session):
296+
class AuthorizedSession(requests.Session, _BaseAuthorizedSession):
296297
"""A Requests Session class with credentials.
297298
298299
This class is used to perform requests to API endpoints that require
@@ -389,7 +390,7 @@ def __init__(
389390
default_host=None,
390391
):
391392
super(AuthorizedSession, self).__init__()
392-
self.credentials = credentials
393+
_BaseAuthorizedSession.__init__(self, credentials)
393394
self._refresh_status_codes = refresh_status_codes
394395
self._max_refresh_attempts = max_refresh_attempts
395396
self._refresh_timeout = refresh_timeout

‎system_tests/secrets.tar.enc

0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)
Please sign in to comment.