Skip to content

Commit df07fce

Browse files
authored
feat(auth): implement in-place Regional Access Boundary configuration and add public RAB getters (#16987)
This PR makes the following changes: - Rename _with_regional_access_boundary to _set_regional_access_boundary and _with_blocking_regional_access_boundary_lookup to _set_blocking_regional_access_boundary_lookup. This is to ensure any expectation that "with_" methods return copies isn't violated. - Modify both methods to apply changes in-place on self and return self instead of making copies. - Add public getters regional_access_boundary and regional_access_boundary_expiry to CredentialsWithRegionalAccessBoundary. - Update and split unit tests to verify in-place mutation and getters independently.
1 parent 3e68df3 commit df07fce

5 files changed

Lines changed: 64 additions & 32 deletions

File tree

packages/google-auth/google/auth/credentials.py

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,16 @@ def __init__(self):
309309
_regional_access_boundary_utils._RegionalAccessBoundaryManager()
310310
)
311311

312+
@property
313+
def regional_access_boundary(self):
314+
"""Optional[str]: The encoded Regional Access Boundary locations."""
315+
return self._rab_manager._data.encoded_locations
316+
317+
@property
318+
def regional_access_boundary_expiry(self):
319+
"""Optional[datetime.datetime]: The expiration time of the Regional Access Boundary."""
320+
return self._rab_manager._data.expiry
321+
312322
@abc.abstractmethod
313323
def _perform_refresh_token(self, request):
314324
"""Refreshes the access token.
@@ -361,39 +371,37 @@ def _copy_regional_access_boundary_manager(self, target):
361371
new_manager._data = self._rab_manager._data
362372
target._rab_manager = new_manager
363373

364-
def _with_regional_access_boundary(self, seed):
365-
"""Returns a copy of these credentials with the the regional_access_boundary
366-
set to the provided seed. This is intended for internal use only as invalid
374+
def _set_regional_access_boundary(self, seed):
375+
"""Applies the regional_access_boundary provided via the seed on these
376+
credentials. This is intended for internal use only as invalid
367377
seeds would produce unexpected results until automatic recovery is supported.
368378
Currently this is used by the gcloud CLI and therefore changes to the
369379
contract MUST be backwards compatible (e.g. the method signature must be
370-
unchanged and a copy of the credenials with the RAB set must be returned).
380+
unchanged and the credentials with the RAB set must be returned).
371381
372382
373383
Returns:
374-
google.auth.credentials.Credentials: A new credentials instance.
384+
google.auth.credentials.Credentials: The credentials instance.
375385
"""
376-
creds = self._make_copy()
377-
creds._rab_manager.set_initial_regional_access_boundary(
386+
self._rab_manager.set_initial_regional_access_boundary(
378387
encoded_locations=seed.get("encodedLocations", None),
379388
expiry=seed.get("expiry", None),
380389
)
381-
return creds
390+
return self
382391

383-
def _with_blocking_regional_access_boundary_lookup(self):
384-
"""Returns a copy of these credentials with the blocking lookup mode enabled.
392+
def _set_blocking_regional_access_boundary_lookup(self):
393+
"""Enables the blocking lookup mode on these credentials.
385394
This is intended for internal use only as blocking lookup requires additional
386395
care and consideration. Currently this is used by the gcloud CLI and
387396
therefore changes to the contract MUST be backwards compatible (e.g. the
388-
method signature must be unchanged and a copy of the credentials with the
397+
method signature must be unchanged and the credentials with the
389398
blocking lookup flag set to true must be returned).
390399
391400
Returns:
392-
google.auth.credentials.Credentials: A new credentials instance.
401+
google.auth.credentials.Credentials: The credentials instance.
393402
"""
394-
creds = self._make_copy()
395-
creds._rab_manager.enable_blocking_lookup()
396-
return creds
403+
self._rab_manager.enable_blocking_lookup()
404+
return self
397405

398406
def _maybe_start_regional_access_boundary_refresh(self, request, url):
399407
"""

packages/google-auth/tests/compute_engine/test_credentials.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -451,13 +451,13 @@ def test_refresh_with_agent_identity_opt_out_or_not_agent(
451451
kwargs = mock_metadata_get.call_args[1]
452452
assert "bindCertificateFingerprint" not in kwargs.get("params", {})
453453

454-
def test_with_blocking_regional_access_boundary_lookup(self):
454+
def test_set_blocking_regional_access_boundary_lookup(self):
455455
creds = self.credentials
456456
assert not creds._rab_manager._use_blocking_regional_access_boundary_lookup
457457

458-
new_creds = creds._with_blocking_regional_access_boundary_lookup()
459-
assert new_creds._rab_manager._use_blocking_regional_access_boundary_lookup
460-
assert new_creds is not creds
458+
new_creds = creds._set_blocking_regional_access_boundary_lookup()
459+
assert creds._rab_manager._use_blocking_regional_access_boundary_lookup
460+
assert new_creds is creds
461461

462462

463463
class TestIDTokenCredentials(object):

packages/google-auth/tests/oauth2/test_credentials.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,13 @@ def test_default_state(self):
9696
assert credentials.rapt_token == self.RAPT_TOKEN
9797
assert credentials.refresh_handler is None
9898

99-
def test_with_blocking_regional_access_boundary_lookup(self):
99+
def test_set_blocking_regional_access_boundary_lookup(self):
100100
creds = self.make_credentials()
101101
assert not creds._rab_manager._use_blocking_regional_access_boundary_lookup
102102

103-
new_creds = creds._with_blocking_regional_access_boundary_lookup()
104-
assert new_creds._rab_manager._use_blocking_regional_access_boundary_lookup
105-
assert new_creds is not creds
103+
new_creds = creds._set_blocking_regional_access_boundary_lookup()
104+
assert creds._rab_manager._use_blocking_regional_access_boundary_lookup
105+
assert new_creds is creds
106106

107107
def test_get_cred_info(self):
108108
credentials = self.make_credentials()

packages/google-auth/tests/test__regional_access_boundary_utils.py

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -224,23 +224,47 @@ def test_apply_headers_removes_header_if_empty(self):
224224
creds._rab_manager.apply_headers(headers)
225225
assert headers == {}
226226

227-
def test_with_blocking_regional_access_boundary_lookup(self):
227+
def test_set_blocking_regional_access_boundary_lookup(self):
228228
creds = CredentialsImpl()
229229
assert not creds._rab_manager._use_blocking_regional_access_boundary_lookup
230230

231-
new_creds = creds._with_blocking_regional_access_boundary_lookup()
232-
assert new_creds._rab_manager._use_blocking_regional_access_boundary_lookup
231+
new_creds = creds._set_blocking_regional_access_boundary_lookup()
232+
assert new_creds is creds
233+
assert creds._rab_manager._use_blocking_regional_access_boundary_lookup
233234

234-
def test_with_regional_access_boundary(self):
235+
def test_set_regional_access_boundary(self):
235236
creds = CredentialsImpl()
236237
seed = {
237238
"encodedLocations": "0xABC",
238239
"expiry": _helpers.utcnow() + datetime.timedelta(hours=1),
239240
}
240-
new_creds = creds._with_regional_access_boundary(seed)
241-
assert new_creds._rab_manager._data.encoded_locations == "0xABC"
242-
assert new_creds._rab_manager._data.expiry == seed["expiry"]
243-
assert new_creds._rab_manager._data.cooldown_expiry is None
241+
new_creds = creds._set_regional_access_boundary(seed)
242+
assert new_creds is creds
243+
assert creds._rab_manager._data.encoded_locations == "0xABC"
244+
assert creds._rab_manager._data.expiry == seed["expiry"]
245+
assert creds._rab_manager._data.cooldown_expiry is None
246+
247+
def test_regional_access_boundary_getter(self):
248+
creds = CredentialsImpl()
249+
assert creds.regional_access_boundary is None
250+
251+
seed = {
252+
"encodedLocations": "0xABC",
253+
"expiry": _helpers.utcnow() + datetime.timedelta(hours=1),
254+
}
255+
creds._set_regional_access_boundary(seed)
256+
assert creds.regional_access_boundary == "0xABC"
257+
258+
def test_regional_access_boundary_expiry_getter(self):
259+
creds = CredentialsImpl()
260+
assert creds.regional_access_boundary_expiry is None
261+
262+
seed = {
263+
"encodedLocations": "0xABC",
264+
"expiry": _helpers.utcnow() + datetime.timedelta(hours=1),
265+
}
266+
creds._set_regional_access_boundary(seed)
267+
assert creds.regional_access_boundary_expiry == seed["expiry"]
244268

245269
def test_copy_regional_access_boundary_state(self):
246270
source_creds = CredentialsImpl()

packages/google-auth/tests/test_credentials.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ def test_before_request_triggers_rab_refresh():
403403
lookup.return_value = {"encodedLocations": "0xA30"}
404404

405405
creds = CredentialsImpl()
406-
creds = creds._with_blocking_regional_access_boundary_lookup()
406+
creds = creds._set_blocking_regional_access_boundary_lookup()
407407

408408
request = mock.Mock()
409409
headers = {}

0 commit comments

Comments
 (0)