From a4135a3e9620a2cbf99957858c13780b92ff707c Mon Sep 17 00:00:00 2001 From: sai-sunder-s <4540365+sai-sunder-s@users.noreply.github.com> Date: Thu, 13 Jul 2023 09:43:01 -0700 Subject: [PATCH] fix: Skip checking projectid on cred if env var is set (#1349) * fix: Skip checking projectid on cred if env var is set * add test for legacy project --------- Co-authored-by: Carl Lundin <108372512+clundin25@users.noreply.github.com> --- google/auth/_default.py | 7 +++--- tests/test__default.py | 55 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/google/auth/_default.py b/google/auth/_default.py index f77fa1808..63009dfb8 100644 --- a/google/auth/_default.py +++ b/google/auth/_default.py @@ -660,24 +660,25 @@ def default(scopes=None, request=None, quota_project_id=None, default_scopes=Non credentials, scopes, default_scopes=default_scopes ) + effective_project_id = explicit_project_id or project_id + # For external account credentials, scopes are required to determine # the project ID. Try to get the project ID again if not yet # determined. - if not project_id and callable( + if not effective_project_id and callable( getattr(credentials, "get_project_id", None) ): if request is None: import google.auth.transport.requests request = google.auth.transport.requests.Request() - project_id = credentials.get_project_id(request=request) + effective_project_id = credentials.get_project_id(request=request) if quota_project_id and isinstance( credentials, CredentialsWithQuotaProject ): credentials = credentials.with_quota_project(quota_project_id) - effective_project_id = explicit_project_id or project_id if not effective_project_id: _LOGGER.warning( "No project ID could be determined. Consider running " diff --git a/tests/test__default.py b/tests/test__default.py index affbb7624..4f59c5497 100644 --- a/tests/test__default.py +++ b/tests/test__default.py @@ -1030,6 +1030,61 @@ def test_default_environ_external_credentials_identity_pool_impersonated( assert project_id is mock.sentinel.project_id assert credentials.scopes == ["https://www.google.com/calendar/feeds"] + # The credential.get_project_id should have been used in _get_external_account_credentials and default + assert get_project_id.call_count == 2 + + +@EXTERNAL_ACCOUNT_GET_PROJECT_ID_PATCH +@mock.patch.dict(os.environ) +def test_default_environ_external_credentials_project_from_env( + get_project_id, monkeypatch, tmpdir +): + project_from_env = "project_from_env" + os.environ[environment_vars.PROJECT] = project_from_env + + config_file = tmpdir.join("config.json") + config_file.write(json.dumps(IMPERSONATED_IDENTITY_POOL_DATA)) + monkeypatch.setenv(environment_vars.CREDENTIALS, str(config_file)) + + credentials, project_id = _default.default( + scopes=["https://www.google.com/calendar/feeds"] + ) + + assert isinstance(credentials, identity_pool.Credentials) + assert not credentials.is_user + assert not credentials.is_workforce_pool + assert project_id == project_from_env + assert credentials.scopes == ["https://www.google.com/calendar/feeds"] + + # The credential.get_project_id should have been used only in _get_external_account_credentials + assert get_project_id.call_count == 1 + + +@EXTERNAL_ACCOUNT_GET_PROJECT_ID_PATCH +@mock.patch.dict(os.environ) +def test_default_environ_external_credentials_legacy_project_from_env( + get_project_id, monkeypatch, tmpdir +): + project_from_env = "project_from_env" + os.environ[environment_vars.LEGACY_PROJECT] = project_from_env + + config_file = tmpdir.join("config.json") + config_file.write(json.dumps(IMPERSONATED_IDENTITY_POOL_DATA)) + monkeypatch.setenv(environment_vars.CREDENTIALS, str(config_file)) + + credentials, project_id = _default.default( + scopes=["https://www.google.com/calendar/feeds"] + ) + + assert isinstance(credentials, identity_pool.Credentials) + assert not credentials.is_user + assert not credentials.is_workforce_pool + assert project_id == project_from_env + assert credentials.scopes == ["https://www.google.com/calendar/feeds"] + + # The credential.get_project_id should have been used only in _get_external_account_credentials + assert get_project_id.call_count == 1 + @EXTERNAL_ACCOUNT_GET_PROJECT_ID_PATCH def test_default_environ_external_credentials_aws_impersonated(