|
31 | 31 | # Base64 encoding of "username:password"
|
32 | 32 | BASIC_AUTH_ENCODING = "dXNlcm5hbWU6cGFzc3dvcmQ="
|
33 | 33 | SERVICE_ACCOUNT_EMAIL = "service-1234@service-name.iam.gserviceaccount.com"
|
| 34 | +# List of valid workforce pool audiences. |
| 35 | +TEST_USER_AUDIENCES = [ |
| 36 | + "//iam.googleapis.com/locations/global/workforcePools/pool-id/providers/provider-id", |
| 37 | + "//iam.googleapis.com/locations/eu/workforcePools/pool-id/providers/provider-id", |
| 38 | + "//iam.googleapis.com/locations/eu/workforcePools/workloadIdentityPools/providers/provider-id", |
| 39 | +] |
34 | 40 |
|
35 | 41 |
|
36 | 42 | class CredentialsImpl(external_account.Credentials):
|
@@ -342,6 +348,116 @@ def test_with_invalid_impersonation_target_principal(self):
|
342 | 348 | r"Unable to determine target principal from service account impersonation URL."
|
343 | 349 | )
|
344 | 350 |
|
| 351 | + def test_info(self): |
| 352 | + credentials = self.make_credentials() |
| 353 | + |
| 354 | + assert credentials.info == { |
| 355 | + "type": "external_account", |
| 356 | + "audience": self.AUDIENCE, |
| 357 | + "subject_token_type": self.SUBJECT_TOKEN_TYPE, |
| 358 | + "token_url": self.TOKEN_URL, |
| 359 | + "credential_source": self.CREDENTIAL_SOURCE.copy(), |
| 360 | + } |
| 361 | + |
| 362 | + def test_info_with_full_options(self): |
| 363 | + credentials = self.make_credentials( |
| 364 | + client_id=CLIENT_ID, |
| 365 | + client_secret=CLIENT_SECRET, |
| 366 | + quota_project_id=self.QUOTA_PROJECT_ID, |
| 367 | + service_account_impersonation_url=self.SERVICE_ACCOUNT_IMPERSONATION_URL, |
| 368 | + ) |
| 369 | + |
| 370 | + assert credentials.info == { |
| 371 | + "type": "external_account", |
| 372 | + "audience": self.AUDIENCE, |
| 373 | + "subject_token_type": self.SUBJECT_TOKEN_TYPE, |
| 374 | + "token_url": self.TOKEN_URL, |
| 375 | + "service_account_impersonation_url": self.SERVICE_ACCOUNT_IMPERSONATION_URL, |
| 376 | + "credential_source": self.CREDENTIAL_SOURCE.copy(), |
| 377 | + "quota_project_id": self.QUOTA_PROJECT_ID, |
| 378 | + "client_id": CLIENT_ID, |
| 379 | + "client_secret": CLIENT_SECRET, |
| 380 | + } |
| 381 | + |
| 382 | + def test_service_account_email_without_impersonation(self): |
| 383 | + credentials = self.make_credentials() |
| 384 | + |
| 385 | + assert credentials.service_account_email is None |
| 386 | + |
| 387 | + def test_service_account_email_with_impersonation(self): |
| 388 | + credentials = self.make_credentials( |
| 389 | + service_account_impersonation_url=self.SERVICE_ACCOUNT_IMPERSONATION_URL |
| 390 | + ) |
| 391 | + |
| 392 | + assert credentials.service_account_email == SERVICE_ACCOUNT_EMAIL |
| 393 | + |
| 394 | + @pytest.mark.parametrize( |
| 395 | + "audience", |
| 396 | + # Workload identity pool audiences or invalid workforce pool audiences. |
| 397 | + [ |
| 398 | + # Legacy K8s audience format. |
| 399 | + "identitynamespace:1f12345:my_provider", |
| 400 | + ( |
| 401 | + "//iam.googleapis.com/projects/123456/locations/" |
| 402 | + "global/workloadIdentityPools/pool-id/providers/" |
| 403 | + "provider-id" |
| 404 | + ), |
| 405 | + ( |
| 406 | + "//iam.googleapis.com/projects/123456/locations/" |
| 407 | + "eu/workloadIdentityPools/pool-id/providers/" |
| 408 | + "provider-id" |
| 409 | + ), |
| 410 | + # Pool ID with workforcePools string. |
| 411 | + ( |
| 412 | + "//iam.googleapis.com/projects/123456/locations/" |
| 413 | + "global/workloadIdentityPools/workforcePools/providers/" |
| 414 | + "provider-id" |
| 415 | + ), |
| 416 | + # Unrealistic / incorrect workforce pool audiences. |
| 417 | + "//iamgoogleapis.com/locations/eu/workforcePools/pool-id/providers/provider-id", |
| 418 | + "//iam.googleapiscom/locations/eu/workforcePools/pool-id/providers/provider-id", |
| 419 | + "//iam.googleapis.com/locations/workforcePools/pool-id/providers/provider-id", |
| 420 | + "//iam.googleapis.com/locations/eu/workforcePool/pool-id/providers/provider-id", |
| 421 | + "//iam.googleapis.com/locations//workforcePool/pool-id/providers/provider-id", |
| 422 | + ], |
| 423 | + ) |
| 424 | + def test_is_user_with_non_users(self, audience): |
| 425 | + credentials = CredentialsImpl( |
| 426 | + audience=audience, |
| 427 | + subject_token_type=self.SUBJECT_TOKEN_TYPE, |
| 428 | + token_url=self.TOKEN_URL, |
| 429 | + credential_source=self.CREDENTIAL_SOURCE, |
| 430 | + ) |
| 431 | + |
| 432 | + assert credentials.is_user is False |
| 433 | + |
| 434 | + @pytest.mark.parametrize("audience", TEST_USER_AUDIENCES) |
| 435 | + def test_is_user_with_users(self, audience): |
| 436 | + credentials = CredentialsImpl( |
| 437 | + audience=audience, |
| 438 | + subject_token_type=self.SUBJECT_TOKEN_TYPE, |
| 439 | + token_url=self.TOKEN_URL, |
| 440 | + credential_source=self.CREDENTIAL_SOURCE, |
| 441 | + ) |
| 442 | + |
| 443 | + assert credentials.is_user is True |
| 444 | + |
| 445 | + @pytest.mark.parametrize("audience", TEST_USER_AUDIENCES) |
| 446 | + def test_is_user_with_users_and_impersonation(self, audience): |
| 447 | + # Initialize the credentials with service account impersonation. |
| 448 | + credentials = CredentialsImpl( |
| 449 | + audience=audience, |
| 450 | + subject_token_type=self.SUBJECT_TOKEN_TYPE, |
| 451 | + token_url=self.TOKEN_URL, |
| 452 | + credential_source=self.CREDENTIAL_SOURCE, |
| 453 | + service_account_impersonation_url=self.SERVICE_ACCOUNT_IMPERSONATION_URL, |
| 454 | + ) |
| 455 | + |
| 456 | + # Even though the audience is for a workforce pool, since service account |
| 457 | + # impersonation is used, the credentials will represent a service account and |
| 458 | + # not a user. |
| 459 | + assert credentials.is_user is False |
| 460 | + |
345 | 461 | @mock.patch("google.auth._helpers.utcnow", return_value=datetime.datetime.min)
|
346 | 462 | def test_refresh_without_client_auth_success(self, unused_utcnow):
|
347 | 463 | response = self.SUCCESS_RESPONSE.copy()
|
|
0 commit comments