Skip to content

Commit ee07053

Browse files
BigTailWolfgcf-owl-bot[bot]
andauthoredMay 22, 2023
feat: expose universe_domain for external account creds (#1296)
* feat: expose for external account creds * add universe_domain as info property * fix info error * adding coverage of explicit universe_domain assigning * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
1 parent 8c8d4e4 commit ee07053

5 files changed

+39
-1
lines changed
 

‎google/auth/external_account.py

+8
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
# Cloud resource manager URL used to retrieve project information.
5353
_CLOUD_RESOURCE_MANAGER = "https://cloudresourcemanager.googleapis.com/v1/projects/"
5454

55+
_DEFAULT_UNIVERSE_DOMAIN = "googleapis.com"
56+
5557

5658
@six.add_metaclass(abc.ABCMeta)
5759
class Credentials(
@@ -82,6 +84,7 @@ def __init__(
8284
scopes=None,
8385
default_scopes=None,
8486
workforce_pool_user_project=None,
87+
universe_domain=_DEFAULT_UNIVERSE_DOMAIN,
8588
):
8689
"""Instantiates an external account credentials object.
8790
@@ -105,6 +108,8 @@ def __init__(
105108
a workload identity pool. The underlying principal must still have
106109
serviceusage.services.use IAM permission to use the project for
107110
billing/quota.
111+
universe_domain (str): The universe domain. The default universe
112+
domain is googleapis.com.
108113
Raises:
109114
google.auth.exceptions.RefreshError: If the generateAccessToken
110115
endpoint returned an error.
@@ -125,6 +130,7 @@ def __init__(
125130
self._scopes = scopes
126131
self._default_scopes = default_scopes
127132
self._workforce_pool_user_project = workforce_pool_user_project
133+
self._universe_domain = universe_domain or _DEFAULT_UNIVERSE_DOMAIN
128134

129135
if self._client_id:
130136
self._client_auth = utils.ClientAuthentication(
@@ -186,6 +192,7 @@ def _constructor_args(self):
186192
"workforce_pool_user_project": self._workforce_pool_user_project,
187193
"scopes": self._scopes,
188194
"default_scopes": self._default_scopes,
195+
"universe_domain": self._universe_domain,
189196
}
190197
if not self.is_workforce_pool:
191198
args.pop("workforce_pool_user_project")
@@ -458,6 +465,7 @@ def from_info(cls, info, **kwargs):
458465
credential_source=info.get("credential_source"),
459466
quota_project_id=info.get("quota_project_id"),
460467
workforce_pool_user_project=info.get("workforce_pool_user_project"),
468+
universe_domain=info.get("universe_domain", _DEFAULT_UNIVERSE_DOMAIN),
461469
**kwargs
462470
)
463471

‎tests/test_aws.py

+7
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
# Each tuple contains the following entries:
7070
# region, time, credentials, original_request, signed_request
7171

72+
DEFAULT_UNIVERSE_DOMAIN = "googleapis.com"
7273
VALID_TOKEN_URLS = [
7374
"https://sts.googleapis.com",
7475
"https://us-east-1.sts.googleapis.com",
@@ -925,6 +926,7 @@ def test_from_info_full_options(self, mock_init):
925926
credential_source=self.CREDENTIAL_SOURCE,
926927
quota_project_id=QUOTA_PROJECT_ID,
927928
workforce_pool_user_project=None,
929+
universe_domain=DEFAULT_UNIVERSE_DOMAIN,
928930
)
929931

930932
@mock.patch.object(aws.Credentials, "__init__", return_value=None)
@@ -952,6 +954,7 @@ def test_from_info_required_options_only(self, mock_init):
952954
credential_source=self.CREDENTIAL_SOURCE,
953955
quota_project_id=None,
954956
workforce_pool_user_project=None,
957+
universe_domain=DEFAULT_UNIVERSE_DOMAIN,
955958
)
956959

957960
@mock.patch.object(aws.Credentials, "__init__", return_value=None)
@@ -967,6 +970,7 @@ def test_from_file_full_options(self, mock_init, tmpdir):
967970
"client_secret": CLIENT_SECRET,
968971
"quota_project_id": QUOTA_PROJECT_ID,
969972
"credential_source": self.CREDENTIAL_SOURCE,
973+
"universe_domain": DEFAULT_UNIVERSE_DOMAIN,
970974
}
971975
config_file = tmpdir.join("config.json")
972976
config_file.write(json.dumps(info))
@@ -986,6 +990,7 @@ def test_from_file_full_options(self, mock_init, tmpdir):
986990
credential_source=self.CREDENTIAL_SOURCE,
987991
quota_project_id=QUOTA_PROJECT_ID,
988992
workforce_pool_user_project=None,
993+
universe_domain=DEFAULT_UNIVERSE_DOMAIN,
989994
)
990995

991996
@mock.patch.object(aws.Credentials, "__init__", return_value=None)
@@ -1014,6 +1019,7 @@ def test_from_file_required_options_only(self, mock_init, tmpdir):
10141019
credential_source=self.CREDENTIAL_SOURCE,
10151020
quota_project_id=None,
10161021
workforce_pool_user_project=None,
1022+
universe_domain=DEFAULT_UNIVERSE_DOMAIN,
10171023
)
10181024

10191025
def test_constructor_invalid_credential_source(self):
@@ -1067,6 +1073,7 @@ def test_info(self):
10671073
"token_url": TOKEN_URL,
10681074
"token_info_url": TOKEN_INFO_URL,
10691075
"credential_source": self.CREDENTIAL_SOURCE,
1076+
"universe_domain": DEFAULT_UNIVERSE_DOMAIN,
10701077
}
10711078

10721079
def test_token_info_url(self):

‎tests/test_external_account.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ def make_credentials(
144144
default_scopes=None,
145145
service_account_impersonation_url=None,
146146
service_account_impersonation_options={},
147+
universe_domain=external_account._DEFAULT_UNIVERSE_DOMAIN,
147148
):
148149
return CredentialsImpl(
149150
audience=cls.AUDIENCE,
@@ -158,6 +159,7 @@ def make_credentials(
158159
quota_project_id=quota_project_id,
159160
scopes=scopes,
160161
default_scopes=default_scopes,
162+
universe_domain=universe_domain,
161163
)
162164

163165
@classmethod
@@ -378,6 +380,7 @@ def test_with_scopes_full_options_propagated(self):
378380
quota_project_id=self.QUOTA_PROJECT_ID,
379381
scopes=["email"],
380382
default_scopes=["default2"],
383+
universe_domain=external_account._DEFAULT_UNIVERSE_DOMAIN,
381384
)
382385

383386
def test_with_token_uri(self):
@@ -465,6 +468,7 @@ def test_with_quota_project_full_options_propagated(self):
465468
quota_project_id="project-foo",
466469
scopes=self.SCOPES,
467470
default_scopes=["default1"],
471+
universe_domain=external_account._DEFAULT_UNIVERSE_DOMAIN,
468472
)
469473

470474
def test_with_invalid_impersonation_target_principal(self):
@@ -478,14 +482,15 @@ def test_with_invalid_impersonation_target_principal(self):
478482
)
479483

480484
def test_info(self):
481-
credentials = self.make_credentials()
485+
credentials = self.make_credentials(universe_domain="dummy_universe.com")
482486

483487
assert credentials.info == {
484488
"type": "external_account",
485489
"audience": self.AUDIENCE,
486490
"subject_token_type": self.SUBJECT_TOKEN_TYPE,
487491
"token_url": self.TOKEN_URL,
488492
"credential_source": self.CREDENTIAL_SOURCE.copy(),
493+
"universe_domain": "dummy_universe.com",
489494
}
490495

491496
def test_info_workforce_pool(self):
@@ -500,6 +505,7 @@ def test_info_workforce_pool(self):
500505
"token_url": self.TOKEN_URL,
501506
"credential_source": self.CREDENTIAL_SOURCE.copy(),
502507
"workforce_pool_user_project": self.WORKFORCE_POOL_USER_PROJECT,
508+
"universe_domain": external_account._DEFAULT_UNIVERSE_DOMAIN,
503509
}
504510

505511
def test_info_with_full_options(self):
@@ -524,6 +530,7 @@ def test_info_with_full_options(self):
524530
"quota_project_id": self.QUOTA_PROJECT_ID,
525531
"client_id": CLIENT_ID,
526532
"client_secret": CLIENT_SECRET,
533+
"universe_domain": external_account._DEFAULT_UNIVERSE_DOMAIN,
527534
}
528535

529536
def test_service_account_email_without_impersonation(self):

‎tests/test_identity_pool.py

+10
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
WORKFORCE_SUBJECT_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:id_token"
6767
WORKFORCE_POOL_USER_PROJECT = "WORKFORCE_POOL_USER_PROJECT_NUMBER"
6868

69+
DEFAULT_UNIVERSE_DOMAIN = "googleapis.com"
6970

7071
VALID_TOKEN_URLS = [
7172
"https://sts.googleapis.com",
@@ -410,6 +411,7 @@ def test_from_info_full_options(self, mock_init):
410411
credential_source=self.CREDENTIAL_SOURCE_TEXT,
411412
quota_project_id=QUOTA_PROJECT_ID,
412413
workforce_pool_user_project=None,
414+
universe_domain=DEFAULT_UNIVERSE_DOMAIN,
413415
)
414416

415417
@mock.patch.object(identity_pool.Credentials, "__init__", return_value=None)
@@ -437,6 +439,7 @@ def test_from_info_required_options_only(self, mock_init):
437439
credential_source=self.CREDENTIAL_SOURCE_TEXT,
438440
quota_project_id=None,
439441
workforce_pool_user_project=None,
442+
universe_domain=DEFAULT_UNIVERSE_DOMAIN,
440443
)
441444

442445
@mock.patch.object(identity_pool.Credentials, "__init__", return_value=None)
@@ -465,6 +468,7 @@ def test_from_info_workforce_pool(self, mock_init):
465468
credential_source=self.CREDENTIAL_SOURCE_TEXT,
466469
quota_project_id=None,
467470
workforce_pool_user_project=WORKFORCE_POOL_USER_PROJECT,
471+
universe_domain=DEFAULT_UNIVERSE_DOMAIN,
468472
)
469473

470474
@mock.patch.object(identity_pool.Credentials, "__init__", return_value=None)
@@ -499,6 +503,7 @@ def test_from_file_full_options(self, mock_init, tmpdir):
499503
credential_source=self.CREDENTIAL_SOURCE_TEXT,
500504
quota_project_id=QUOTA_PROJECT_ID,
501505
workforce_pool_user_project=None,
506+
universe_domain=DEFAULT_UNIVERSE_DOMAIN,
502507
)
503508

504509
@mock.patch.object(identity_pool.Credentials, "__init__", return_value=None)
@@ -527,6 +532,7 @@ def test_from_file_required_options_only(self, mock_init, tmpdir):
527532
credential_source=self.CREDENTIAL_SOURCE_TEXT,
528533
quota_project_id=None,
529534
workforce_pool_user_project=None,
535+
universe_domain=DEFAULT_UNIVERSE_DOMAIN,
530536
)
531537

532538
@mock.patch.object(identity_pool.Credentials, "__init__", return_value=None)
@@ -556,6 +562,7 @@ def test_from_file_workforce_pool(self, mock_init, tmpdir):
556562
credential_source=self.CREDENTIAL_SOURCE_TEXT,
557563
quota_project_id=None,
558564
workforce_pool_user_project=WORKFORCE_POOL_USER_PROJECT,
565+
universe_domain=DEFAULT_UNIVERSE_DOMAIN,
559566
)
560567

561568
def test_constructor_nonworkforce_with_workforce_pool_user_project(self):
@@ -639,6 +646,7 @@ def test_info_with_workforce_pool_user_project(self):
639646
"token_info_url": TOKEN_INFO_URL,
640647
"credential_source": self.CREDENTIAL_SOURCE_TEXT_URL,
641648
"workforce_pool_user_project": WORKFORCE_POOL_USER_PROJECT,
649+
"universe_domain": DEFAULT_UNIVERSE_DOMAIN,
642650
}
643651

644652
def test_info_with_file_credential_source(self):
@@ -653,6 +661,7 @@ def test_info_with_file_credential_source(self):
653661
"token_url": TOKEN_URL,
654662
"token_info_url": TOKEN_INFO_URL,
655663
"credential_source": self.CREDENTIAL_SOURCE_TEXT_URL,
664+
"universe_domain": DEFAULT_UNIVERSE_DOMAIN,
656665
}
657666

658667
def test_info_with_url_credential_source(self):
@@ -667,6 +676,7 @@ def test_info_with_url_credential_source(self):
667676
"token_url": TOKEN_URL,
668677
"token_info_url": TOKEN_INFO_URL,
669678
"credential_source": self.CREDENTIAL_SOURCE_JSON_URL,
679+
"universe_domain": DEFAULT_UNIVERSE_DOMAIN,
670680
}
671681

672682
def test_retrieve_subject_token_missing_subject_token(self, tmpdir):

‎tests/test_pluggable.py

+6
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
TOKEN_INFO_URL = "https://sts.googleapis.com/v1/introspect"
5454
SUBJECT_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:jwt"
5555
AUDIENCE = "//iam.googleapis.com/projects/123456/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID"
56+
DEFAULT_UNIVERSE_DOMAIN = "googleapis.com"
5657

5758
VALID_TOKEN_URLS = [
5859
"https://sts.googleapis.com",
@@ -278,6 +279,7 @@ def test_from_info_full_options(self, mock_init):
278279
credential_source=self.CREDENTIAL_SOURCE,
279280
quota_project_id=QUOTA_PROJECT_ID,
280281
workforce_pool_user_project=None,
282+
universe_domain=DEFAULT_UNIVERSE_DOMAIN,
281283
)
282284

283285
@mock.patch.object(pluggable.Credentials, "__init__", return_value=None)
@@ -305,6 +307,7 @@ def test_from_info_required_options_only(self, mock_init):
305307
credential_source=self.CREDENTIAL_SOURCE,
306308
quota_project_id=None,
307309
workforce_pool_user_project=None,
310+
universe_domain=DEFAULT_UNIVERSE_DOMAIN,
308311
)
309312

310313
@mock.patch.object(pluggable.Credentials, "__init__", return_value=None)
@@ -339,6 +342,7 @@ def test_from_file_full_options(self, mock_init, tmpdir):
339342
credential_source=self.CREDENTIAL_SOURCE,
340343
quota_project_id=QUOTA_PROJECT_ID,
341344
workforce_pool_user_project=None,
345+
universe_domain=DEFAULT_UNIVERSE_DOMAIN,
342346
)
343347

344348
@mock.patch.object(pluggable.Credentials, "__init__", return_value=None)
@@ -367,6 +371,7 @@ def test_from_file_required_options_only(self, mock_init, tmpdir):
367371
credential_source=self.CREDENTIAL_SOURCE,
368372
quota_project_id=None,
369373
workforce_pool_user_project=None,
374+
universe_domain=DEFAULT_UNIVERSE_DOMAIN,
370375
)
371376

372377
def test_constructor_invalid_options(self):
@@ -395,6 +400,7 @@ def test_info_with_credential_source(self):
395400
"token_url": TOKEN_URL,
396401
"token_info_url": TOKEN_INFO_URL,
397402
"credential_source": self.CREDENTIAL_SOURCE,
403+
"universe_domain": DEFAULT_UNIVERSE_DOMAIN,
398404
}
399405

400406
def test_token_info_url(self):

0 commit comments

Comments
 (0)
Please sign in to comment.