Skip to content

Commit e691081

Browse files
committed
fetch token from default endpoint
1 parent 5f806c1 commit e691081

File tree

4 files changed

+104
-10
lines changed

4 files changed

+104
-10
lines changed

google/auth/compute_engine/credentials.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,23 @@ def __init__(
9090
def _metric_header_for_usage(self):
9191
return metrics.CRED_TYPE_SA_MDS
9292

93+
def _retrieve_info(self, request):
94+
"""Retrieve information about the service account.
95+
Updates the scopes and retrieves the full service account email.
96+
Args:
97+
request (google.auth.transport.Request): The object used to make
98+
HTTP requests.
99+
"""
100+
info = _metadata.get_service_account_info(
101+
request, service_account=self._service_account_email
102+
)
103+
104+
self._service_account_email = info["email"]
105+
106+
# Don't override scopes requested by the user.
107+
if self._scopes is None:
108+
self._scopes = info["scopes"]
109+
93110
def refresh(self, request):
94111
"""Refresh the access token and scopes.
95112
@@ -104,8 +121,10 @@ def refresh(self, request):
104121
"""
105122
scopes = self._scopes if self._scopes is not None else self._default_scopes
106123
try:
124+
self._retrieve_info(request)
125+
# Always fetch token with default service account email.
107126
self.token, self.expiry = _metadata.get_service_account_token(
108-
request, service_account=self._service_account_email, scopes=scopes
127+
request, service_account="default", scopes=scopes
109128
)
110129
except exceptions.TransportError as caught_exc:
111130
new_exc = exceptions.RefreshError(caught_exc)

system_tests/secrets.tar.enc

0 Bytes
Binary file not shown.

system_tests/system_tests_sync/test_compute_engine.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,17 @@ def check_gce_environment(http_request):
3535
pytest.skip("Compute Engine metadata service is not available.")
3636

3737

38-
def test_refresh(http_request):
38+
def test_refresh(http_request, token_info):
3939
credentials = compute_engine.Credentials()
4040

4141
credentials.refresh(http_request)
4242

4343
assert credentials.token is not None
4444
assert credentials.service_account_email is not None
4545

46-
assert credentials.scopes is None
47-
46+
info = token_info(credentials.token)
47+
info_scopes = _helpers.string_to_scopes(info["scope"])
48+
assert set(info_scopes) == set(credentials.scopes)
4849

4950
def test_default(verify_refresh):
5051
credentials, project_id = google.auth.default()

tests/compute_engine/test_credentials.py

Lines changed: 80 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,18 @@ def test_default_state(self):
9999
)
100100
@mock.patch("google.auth.compute_engine._metadata.get", autospec=True)
101101
def test_refresh_success(self, get, utcnow):
102-
get.side_effect = [{"access_token": "token", "expires_in": 500}]
102+
get.side_effect = [
103+
{
104+
# First request is for sevice account info.
105+
"email": "[email protected]",
106+
"scopes": ["one", "two"],
107+
},
108+
{
109+
# Second request is for the token.
110+
"access_token": "token",
111+
"expires_in": 500,
112+
},
113+
]
103114

104115
# Refresh credentials
105116
self.credentials.refresh(None)
@@ -109,8 +120,8 @@ def test_refresh_success(self, get, utcnow):
109120
assert self.credentials.expiry == (utcnow() + datetime.timedelta(seconds=500))
110121

111122
# Check the credential info
112-
assert self.credentials.service_account_email == "default"
113-
assert self.credentials._scopes is None
123+
assert self.credentials.service_account_email == "[email protected]"
124+
assert self.credentials._scopes == ["one", "two"]
114125

115126
# Check that the credentials are valid (have a token and are not
116127
# expired)
@@ -126,7 +137,18 @@ def test_refresh_success(self, get, utcnow):
126137
)
127138
@mock.patch("google.auth.compute_engine._metadata.get", autospec=True)
128139
def test_refresh_success_with_scopes(self, get, utcnow, mock_metrics_header_value):
129-
get.side_effect = [{"access_token": "token", "expires_in": 500}]
140+
get.side_effect = [
141+
{
142+
# First request is for sevice account info.
143+
"email": "[email protected]",
144+
"scopes": ["one", "two"],
145+
},
146+
{
147+
# Second request is for the token.
148+
"access_token": "token",
149+
"expires_in": 500,
150+
},
151+
]
130152

131153
# Refresh credentials
132154
scopes = ["three", "four"]
@@ -138,7 +160,7 @@ def test_refresh_success_with_scopes(self, get, utcnow, mock_metrics_header_valu
138160
assert self.credentials.expiry == (utcnow() + datetime.timedelta(seconds=500))
139161

140162
# Check the credential info
141-
assert self.credentials.service_account_email == "default"
163+
assert self.credentials.service_account_email == "[email protected]"
142164
assert self.credentials._scopes == scopes
143165

144166
# Check that the credentials are valid (have a token and are not
@@ -162,7 +184,18 @@ def test_refresh_error(self, get):
162184

163185
@mock.patch("google.auth.compute_engine._metadata.get", autospec=True)
164186
def test_before_request_refreshes(self, get):
165-
get.side_effect = [{"access_token": "token", "expires_in": 500}]
187+
get.side_effect = [
188+
{
189+
# First request is for sevice account info.
190+
"email": "[email protected]",
191+
"scopes": "one two",
192+
},
193+
{
194+
# Second request is for the token.
195+
"access_token": "token",
196+
"expires_in": 500,
197+
},
198+
]
166199

167200
# Credentials should start as invalid
168201
assert not self.credentials.valid
@@ -439,6 +472,19 @@ def test_with_target_audience_integration(self):
439472
Instead of mocking the methods, the HTTP responses
440473
have been mocked.
441474
"""
475+
# mock information about credentials
476+
responses.add(
477+
responses.GET,
478+
"http://metadata.google.internal/computeMetadata/v1/instance/"
479+
"service-accounts/default/?recursive=true",
480+
status=200,
481+
content_type="application/json",
482+
json={
483+
"scopes": "email",
484+
"email": "[email protected]",
485+
"aliases": ["default"],
486+
},
487+
)
442488

443489
# mock information about universe_domain
444490
responses.add(
@@ -450,6 +496,20 @@ def test_with_target_audience_integration(self):
450496
json={},
451497
)
452498

499+
# mock information about credentials
500+
responses.add(
501+
responses.GET,
502+
"http://metadata.google.internal/computeMetadata/v1/instance/"
503+
"service-accounts/default/?recursive=true",
504+
status=200,
505+
content_type="application/json",
506+
json={
507+
"scopes": "email",
508+
"email": "[email protected]",
509+
"aliases": ["default"],
510+
},
511+
)
512+
453513
# mock token for credentials
454514
responses.add(
455515
responses.GET,
@@ -594,6 +654,20 @@ def test_with_quota_project_integration(self):
594654
have been mocked.
595655
"""
596656

657+
# mock information about credentials
658+
responses.add(
659+
responses.GET,
660+
"http://metadata.google.internal/computeMetadata/v1/instance/"
661+
"service-accounts/default/?recursive=true",
662+
status=200,
663+
content_type="application/json",
664+
json={
665+
"scopes": "email",
666+
"email": "[email protected]",
667+
"aliases": ["default"],
668+
},
669+
)
670+
597671
# mock token for credentials
598672
responses.add(
599673
responses.GET,

0 commit comments

Comments
 (0)