Skip to content

Commit ebd5af7

Browse files
authoredMay 24, 2023
feat: add metrics (part 2) (#1303)
1 parent 246dd07 commit ebd5af7

8 files changed

+84
-3
lines changed
 

‎google/auth/compute_engine/credentials.py

+4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from google.auth import exceptions
2929
from google.auth import iam
3030
from google.auth import jwt
31+
from google.auth import metrics
3132
from google.auth.compute_engine import _metadata
3233
from google.oauth2 import _client
3334

@@ -94,6 +95,9 @@ def _retrieve_info(self, request):
9495
if self._scopes is None:
9596
self._scopes = info["scopes"]
9697

98+
def _metric_header_for_usage(self):
99+
return metrics.CRED_TYPE_SA_MDS
100+
97101
def refresh(self, request):
98102
"""Refresh the access token and scopes.
99103

‎google/auth/impersonated_credentials.py

+4
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from google.auth import credentials
3838
from google.auth import exceptions
3939
from google.auth import jwt
40+
from google.auth import metrics
4041

4142
_DEFAULT_TOKEN_LIFETIME_SECS = 3600 # 1 hour in seconds
4243

@@ -238,6 +239,9 @@ def __init__(
238239
self._quota_project_id = quota_project_id
239240
self._iam_endpoint_override = iam_endpoint_override
240241

242+
def _metric_header_for_usage(self):
243+
return metrics.CRED_TYPE_SA_IMPERSONATE
244+
241245
@_helpers.copy_docstring(credentials.Credentials)
242246
def refresh(self, request):
243247
self._update_token(request)

‎google/oauth2/credentials.py

+4
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
from google.auth import _helpers
4343
from google.auth import credentials
4444
from google.auth import exceptions
45+
from google.auth import metrics
4546
from google.oauth2 import reauth
4647

4748
_LOGGER = logging.getLogger(__name__)
@@ -287,6 +288,9 @@ def with_token_uri(self, token_uri):
287288
enable_reauth_refresh=self._enable_reauth_refresh,
288289
)
289290

291+
def _metric_header_for_usage(self):
292+
return metrics.CRED_TYPE_USER
293+
290294
@_helpers.copy_docstring(credentials.Credentials)
291295
def refresh(self, request):
292296
scopes = self._scopes if self._scopes is not None else self._default_scopes

‎google/oauth2/service_account.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
from google.auth import credentials
7979
from google.auth import exceptions
8080
from google.auth import jwt
81+
from google.auth import metrics
8182
from google.oauth2 import _client
8283

8384
_DEFAULT_TOKEN_LIFETIME_SECS = 3600 # 1 hour in seconds
@@ -400,6 +401,16 @@ def _make_authorization_grant_assertion(self):
400401

401402
return token
402403

404+
def _use_self_signed_jwt(self):
405+
# Since domain wide delegation doesn't work with self signed JWT. If
406+
# subject exists, then we should not use self signed JWT.
407+
return self._subject is None and self._jwt_credentials is not None
408+
409+
def _metric_header_for_usage(self):
410+
if self._use_self_signed_jwt():
411+
return metrics.CRED_TYPE_SA_JWT
412+
return metrics.CRED_TYPE_SA_ASSERTION
413+
403414
@_helpers.copy_docstring(credentials.Credentials)
404415
def refresh(self, request):
405416
if (
@@ -414,9 +425,7 @@ def refresh(self, request):
414425
"domain wide delegation is not supported for non-default universe domain"
415426
)
416427

417-
# Since domain wide delegation doesn't work with self signed JWT. If
418-
# subject exists, then we should not use self signed JWT.
419-
if self._subject is None and self._jwt_credentials is not None:
428+
if self._use_self_signed_jwt():
420429
self._jwt_credentials.refresh(request)
421430
self.token = self._jwt_credentials.token.decode()
422431
self.expiry = self._jwt_credentials.expiry

‎tests/compute_engine/test_credentials.py

+9
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,15 @@ def test_with_scopes(self):
185185

186186
assert self.credentials._scopes == scopes
187187

188+
def test_token_usage_metrics(self):
189+
self.credentials.token = "token"
190+
self.credentials.expiry = None
191+
192+
headers = {}
193+
self.credentials.before_request(mock.Mock(), None, None, headers)
194+
assert headers["authorization"] == "Bearer token"
195+
assert headers["x-goog-api-client"] == "cred-type/mds"
196+
188197

189198
class TestIDTokenCredentials(object):
190199
credentials = None

‎tests/oauth2/test_credentials.py

+10
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,16 @@ def test_default_state(self):
6969
assert credentials.rapt_token == self.RAPT_TOKEN
7070
assert credentials.refresh_handler is None
7171

72+
def test_token_usage_metrics(self):
73+
credentials = self.make_credentials()
74+
credentials.token = "token"
75+
credentials.expiry = None
76+
77+
headers = {}
78+
credentials.before_request(mock.Mock(), None, None, headers)
79+
assert headers["authorization"] == "Bearer token"
80+
assert headers["x-goog-api-client"] == "cred-type/u"
81+
7282
def test_refresh_handler_setter_and_getter(self):
7383
scopes = ["email", "profile"]
7484
original_refresh_handler = mock.Mock(return_value=("ACCESS_TOKEN_1", None))

‎tests/oauth2/test_service_account.py

+31
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,37 @@ def test__create_self_signed_jwt_always_use_jwt_access(self, jwt):
408408
credentials._create_self_signed_jwt(None)
409409
jwt.from_signing_credentials.assert_not_called()
410410

411+
def test_token_usage_metrics_assertion(self):
412+
credentials = service_account.Credentials(
413+
SIGNER,
414+
self.SERVICE_ACCOUNT_EMAIL,
415+
self.TOKEN_URI,
416+
always_use_jwt_access=False,
417+
)
418+
credentials.token = "token"
419+
credentials.expiry = None
420+
421+
headers = {}
422+
credentials.before_request(mock.Mock(), None, None, headers)
423+
assert headers["authorization"] == "Bearer token"
424+
assert headers["x-goog-api-client"] == "cred-type/sa"
425+
426+
def test_token_usage_metrics_self_signed_jwt(self):
427+
credentials = service_account.Credentials(
428+
SIGNER,
429+
self.SERVICE_ACCOUNT_EMAIL,
430+
self.TOKEN_URI,
431+
always_use_jwt_access=True,
432+
)
433+
credentials._create_self_signed_jwt("foo.googleapis.com")
434+
credentials.token = "token"
435+
credentials.expiry = None
436+
437+
headers = {}
438+
credentials.before_request(mock.Mock(), None, None, headers)
439+
assert headers["authorization"] == "Bearer token"
440+
assert headers["x-goog-api-client"] == "cred-type/jwt"
441+
411442
@mock.patch("google.oauth2._client.jwt_grant", autospec=True)
412443
def test_refresh_success(self, jwt_grant):
413444
credentials = self.make_credentials()

‎tests/test_impersonated_credentials.py

+10
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,16 @@ def make_request(
162162

163163
return request
164164

165+
def test_token_usage_metrics(self):
166+
credentials = self.make_credentials()
167+
credentials.token = "token"
168+
credentials.expiry = None
169+
170+
headers = {}
171+
credentials.before_request(mock.Mock(), None, None, headers)
172+
assert headers["authorization"] == "Bearer token"
173+
assert headers["x-goog-api-client"] == "cred-type/imp"
174+
165175
@pytest.mark.parametrize("use_data_bytes", [True, False])
166176
def test_refresh_success(self, use_data_bytes, mock_donor_credentials):
167177
credentials = self.make_credentials(lifetime=None)

0 commit comments

Comments
 (0)
Please sign in to comment.