Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-google-auth for openSUSE:Factory checked in at 2024-02-06 16:32:24 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-google-auth (Old) and /work/SRC/openSUSE:Factory/.python-google-auth.new.1815 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-google-auth" Tue Feb 6 16:32:24 2024 rev:40 rq:1143977 version:2.27.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-google-auth/python-google-auth.changes 2024-01-12 23:45:00.917694256 +0100 +++ /work/SRC/openSUSE:Factory/.python-google-auth.new.1815/python-google-auth.changes 2024-02-06 16:32:28.470528862 +0100 @@ -1,0 +2,10 @@ +Sun Feb 4 10:13:37 UTC 2024 - Dirk Müller <dmuel...@suse.com> + +- update to 2.27.0: + * Add optional account association for Authorized User + credentials. + * Allow custom universe domain for gce creds + * Conditionally import requests only if no request was passed + by the caller. + +------------------------------------------------------------------- Old: ---- google-auth-2.26.2.tar.gz New: ---- google-auth-2.27.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-google-auth.spec ++++++ --- /var/tmp/diff_new_pack.E4vMqP/_old 2024-02-06 16:32:29.138553180 +0100 +++ /var/tmp/diff_new_pack.E4vMqP/_new 2024-02-06 16:32:29.138553180 +0100 @@ -18,7 +18,7 @@ %{?sle15_python_module_pythons} Name: python-google-auth -Version: 2.26.2 +Version: 2.27.0 Release: 0 Summary: Google Authentication Library License: Apache-2.0 ++++++ google-auth-2.26.2.tar.gz -> google-auth-2.27.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.26.2/PKG-INFO new/google-auth-2.27.0/PKG-INFO --- old/google-auth-2.26.2/PKG-INFO 2024-01-11 07:12:20.189150600 +0100 +++ new/google-auth-2.27.0/PKG-INFO 2024-01-24 19:47:18.428056500 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: google-auth -Version: 2.26.2 +Version: 2.27.0 Summary: Google Authentication Library Home-page: https://github.com/googleapis/google-auth-library-python Author: Google Cloud Platform diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.26.2/google/auth/compute_engine/credentials.py new/google-auth-2.27.0/google/auth/compute_engine/credentials.py --- old/google-auth-2.26.2/google/auth/compute_engine/credentials.py 2024-01-11 07:09:11.000000000 +0100 +++ new/google-auth-2.27.0/google/auth/compute_engine/credentials.py 2024-01-24 19:44:33.000000000 +0100 @@ -32,7 +32,11 @@ from google.oauth2 import _client -class Credentials(credentials.Scoped, credentials.CredentialsWithQuotaProject): +class Credentials( + credentials.Scoped, + credentials.CredentialsWithQuotaProject, + credentials.CredentialsWithUniverseDomain, +): """Compute Engine Credentials. These credentials use the Google Compute Engine metadata server to obtain @@ -57,6 +61,7 @@ quota_project_id=None, scopes=None, default_scopes=None, + universe_domain=None, ): """ Args: @@ -68,6 +73,10 @@ scopes (Optional[Sequence[str]]): The list of scopes for the credentials. default_scopes (Optional[Sequence[str]]): Default scopes passed by a Google client library. Use 'scopes' for user-defined scopes. + universe_domain (Optional[str]): The universe domain. If not + provided or None, credential will attempt to fetch the value + from metadata server. If metadata server doesn't have universe + domain endpoint, then the default googleapis.com will be used. """ super(Credentials, self).__init__() self._service_account_email = service_account_email @@ -76,6 +85,9 @@ self._default_scopes = default_scopes self._universe_domain_cached = False self._universe_domain_request = google_auth_requests.Request() + if universe_domain: + self._universe_domain = universe_domain + self._universe_domain_cached = True def _retrieve_info(self, request): """Retrieve information about the service account. @@ -146,23 +158,40 @@ @_helpers.copy_docstring(credentials.CredentialsWithQuotaProject) def with_quota_project(self, quota_project_id): - return self.__class__( + creds = self.__class__( service_account_email=self._service_account_email, quota_project_id=quota_project_id, scopes=self._scopes, + default_scopes=self._default_scopes, ) + creds._universe_domain = self._universe_domain + creds._universe_domain_cached = self._universe_domain_cached + return creds @_helpers.copy_docstring(credentials.Scoped) def with_scopes(self, scopes, default_scopes=None): # Compute Engine credentials can not be scoped (the metadata service # ignores the scopes parameter). App Engine, Cloud Run and Flex support # requesting scopes. - return self.__class__( + creds = self.__class__( scopes=scopes, default_scopes=default_scopes, service_account_email=self._service_account_email, quota_project_id=self._quota_project_id, ) + creds._universe_domain = self._universe_domain + creds._universe_domain_cached = self._universe_domain_cached + return creds + + @_helpers.copy_docstring(credentials.CredentialsWithUniverseDomain) + def with_universe_domain(self, universe_domain): + return self.__class__( + scopes=self._scopes, + default_scopes=self._default_scopes, + service_account_email=self._service_account_email, + quota_project_id=self._quota_project_id, + universe_domain=universe_domain, + ) _DEFAULT_TOKEN_LIFETIME_SECS = 3600 # 1 hour in seconds diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.26.2/google/auth/version.py new/google-auth-2.27.0/google/auth/version.py --- old/google-auth-2.26.2/google/auth/version.py 2024-01-11 07:09:11.000000000 +0100 +++ new/google-auth-2.27.0/google/auth/version.py 2024-01-24 19:44:33.000000000 +0100 @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.26.2" +__version__ = "2.27.0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.26.2/google/oauth2/credentials.py new/google-auth-2.27.0/google/oauth2/credentials.py --- old/google-auth-2.26.2/google/oauth2/credentials.py 2024-01-11 07:09:11.000000000 +0100 +++ new/google-auth-2.27.0/google/oauth2/credentials.py 2024-01-24 19:44:33.000000000 +0100 @@ -87,6 +87,7 @@ granted_scopes=None, trust_boundary=None, universe_domain=_DEFAULT_UNIVERSE_DOMAIN, + account=None, ): """ Args: @@ -131,6 +132,7 @@ trust_boundary (str): String representation of trust boundary meta. universe_domain (Optional[str]): The universe domain. The default universe domain is googleapis.com. + account (Optional[str]): The account associated with the credential. """ super(Credentials, self).__init__() self.token = token @@ -149,6 +151,7 @@ self._enable_reauth_refresh = enable_reauth_refresh self._trust_boundary = trust_boundary self._universe_domain = universe_domain or _DEFAULT_UNIVERSE_DOMAIN + self._account = account or "" def __getstate__(self): """A __getstate__ method must exist for the __setstate__ to be called @@ -189,6 +192,7 @@ self._refresh_handler = None self._refresh_worker = None self._use_non_blocking_refresh = d.get("_use_non_blocking_refresh", False) + self._account = d.get("_account", "") @property def refresh_token(self): @@ -268,6 +272,11 @@ raise TypeError("The provided refresh_handler is not a callable or None.") self._refresh_handler = value + @property + def account(self): + """str: The user account associated with the credential. If the account is unknown an empty string is returned.""" + return self._account + @_helpers.copy_docstring(credentials.CredentialsWithQuotaProject) def with_quota_project(self, quota_project_id): @@ -286,6 +295,7 @@ enable_reauth_refresh=self._enable_reauth_refresh, trust_boundary=self._trust_boundary, universe_domain=self._universe_domain, + account=self._account, ) @_helpers.copy_docstring(credentials.CredentialsWithTokenUri) @@ -306,6 +316,35 @@ enable_reauth_refresh=self._enable_reauth_refresh, trust_boundary=self._trust_boundary, universe_domain=self._universe_domain, + account=self._account, + ) + + def with_account(self, account): + """Returns a copy of these credentials with a modified account. + + Args: + account (str): The account to set + + Returns: + google.oauth2.credentials.Credentials: A new credentials instance. + """ + + return self.__class__( + self.token, + refresh_token=self.refresh_token, + id_token=self.id_token, + token_uri=self._token_uri, + client_id=self.client_id, + client_secret=self.client_secret, + scopes=self.scopes, + default_scopes=self.default_scopes, + granted_scopes=self.granted_scopes, + quota_project_id=self.quota_project_id, + rapt_token=self.rapt_token, + enable_reauth_refresh=self._enable_reauth_refresh, + trust_boundary=self._trust_boundary, + universe_domain=self._universe_domain, + account=account, ) @_helpers.copy_docstring(credentials.CredentialsWithUniverseDomain) @@ -326,6 +365,7 @@ enable_reauth_refresh=self._enable_reauth_refresh, trust_boundary=self._trust_boundary, universe_domain=universe_domain, + account=self._account, ) def _metric_header_for_usage(self): @@ -474,6 +514,7 @@ rapt_token=info.get("rapt_token"), # may not exist trust_boundary=info.get("trust_boundary"), # may not exist universe_domain=info.get("universe_domain"), # may not exist + account=info.get("account", ""), # may not exist ) @classmethod @@ -518,6 +559,7 @@ "scopes": self.scopes, "rapt_token": self.rapt_token, "universe_domain": self._universe_domain, + "account": self._account, } if self.expiry: # flatten expiry timestamp prep["expiry"] = self.expiry.isoformat() + "Z" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.26.2/google/oauth2/id_token.py new/google-auth-2.27.0/google/oauth2/id_token.py --- old/google-auth-2.26.2/google/oauth2/id_token.py 2024-01-11 07:09:11.000000000 +0100 +++ new/google-auth-2.27.0/google/oauth2/id_token.py 2024-01-24 19:44:33.000000000 +0100 @@ -62,7 +62,6 @@ from google.auth import environment_vars from google.auth import exceptions from google.auth import jwt -import google.auth.transport.requests # The URL that provides public certificates for verifying ID tokens issued @@ -282,6 +281,8 @@ # Create a request object if not provided. if not request: + import google.auth.transport.requests + request = google.auth.transport.requests.Request() if _metadata.ping(request): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.26.2/google_auth.egg-info/PKG-INFO new/google-auth-2.27.0/google_auth.egg-info/PKG-INFO --- old/google-auth-2.26.2/google_auth.egg-info/PKG-INFO 2024-01-11 07:12:20.000000000 +0100 +++ new/google-auth-2.27.0/google_auth.egg-info/PKG-INFO 2024-01-24 19:47:18.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: google-auth -Version: 2.26.2 +Version: 2.27.0 Summary: Google Authentication Library Home-page: https://github.com/googleapis/google-auth-library-python Author: Google Cloud Platform diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.26.2/tests/compute_engine/test_credentials.py new/google-auth-2.27.0/tests/compute_engine/test_credentials.py --- old/google-auth-2.26.2/tests/compute_engine/test_credentials.py 2024-01-11 07:09:11.000000000 +0100 +++ new/google-auth-2.27.0/tests/compute_engine/test_credentials.py 2024-01-24 19:44:33.000000000 +0100 @@ -50,13 +50,27 @@ "gl-python/3.7 auth/1.1 auth-request-type/it cred-type/mds" ) +FAKE_SERVICE_ACCOUNT_EMAIL = "f...@bar.com" +FAKE_QUOTA_PROJECT_ID = "fake-quota-project" +FAKE_SCOPES = ["scope1", "scope2"] +FAKE_DEFAULT_SCOPES = ["scope3", "scope4"] +FAKE_UNIVERSE_DOMAIN = "fake-universe-domain" + class TestCredentials(object): credentials = None + credentials_with_all_fields = None @pytest.fixture(autouse=True) def credentials_fixture(self): self.credentials = credentials.Credentials() + self.credentials_with_all_fields = credentials.Credentials( + service_account_email=FAKE_SERVICE_ACCOUNT_EMAIL, + quota_project_id=FAKE_QUOTA_PROJECT_ID, + scopes=FAKE_SCOPES, + default_scopes=FAKE_DEFAULT_SCOPES, + universe_domain=FAKE_UNIVERSE_DOMAIN, + ) def test_default_state(self): assert not self.credentials.valid @@ -68,6 +82,9 @@ assert self.credentials.service_account_email == "default" # No quota project assert not self.credentials._quota_project_id + # Universe domain is the default and not cached + assert self.credentials._universe_domain == "googleapis.com" + assert not self.credentials._universe_domain_cached @mock.patch( "google.auth._helpers.utcnow", @@ -187,17 +204,35 @@ assert self.credentials.valid def test_with_quota_project(self): - quota_project_creds = self.credentials.with_quota_project("project-foo") + creds = self.credentials_with_all_fields.with_quota_project("project-foo") - assert quota_project_creds._quota_project_id == "project-foo" + assert creds._quota_project_id == "project-foo" + assert creds._service_account_email == FAKE_SERVICE_ACCOUNT_EMAIL + assert creds._scopes == FAKE_SCOPES + assert creds._default_scopes == FAKE_DEFAULT_SCOPES + assert creds.universe_domain == FAKE_UNIVERSE_DOMAIN + assert creds._universe_domain_cached def test_with_scopes(self): - assert self.credentials._scopes is None - scopes = ["one", "two"] - self.credentials = self.credentials.with_scopes(scopes) + creds = self.credentials_with_all_fields.with_scopes(scopes) - assert self.credentials._scopes == scopes + assert creds._scopes == scopes + assert creds._quota_project_id == FAKE_QUOTA_PROJECT_ID + assert creds._service_account_email == FAKE_SERVICE_ACCOUNT_EMAIL + assert creds._default_scopes is None + assert creds.universe_domain == FAKE_UNIVERSE_DOMAIN + assert creds._universe_domain_cached + + def test_with_universe_domain(self): + creds = self.credentials_with_all_fields.with_universe_domain("universe_domain") + + assert creds._scopes == FAKE_SCOPES + assert creds._quota_project_id == FAKE_QUOTA_PROJECT_ID + assert creds._service_account_email == FAKE_SERVICE_ACCOUNT_EMAIL + assert creds._default_scopes == FAKE_DEFAULT_SCOPES + assert creds.universe_domain == "universe_domain" + assert creds._universe_domain_cached def test_token_usage_metrics(self): self.credentials.token = "token" @@ -213,8 +248,9 @@ return_value="fake_universe_domain", ) def test_universe_domain(self, get_universe_domain): - self.credentials._universe_domain_cached = False - self.credentials._universe_domain = "googleapis.com" + # Check the default state + assert not self.credentials._universe_domain_cached + assert self.credentials._universe_domain == "googleapis.com" # calling the universe_domain property should trigger a call to # get_universe_domain to fetch the value. The value should be cached. @@ -232,6 +268,15 @@ self.credentials._universe_domain_request ) + @mock.patch("google.auth.compute_engine._metadata.get_universe_domain") + def test_user_provided_universe_domain(self, get_universe_domain): + assert self.credentials_with_all_fields.universe_domain == FAKE_UNIVERSE_DOMAIN + assert self.credentials_with_all_fields._universe_domain_cached + + # Since user provided universe_domain, we will not call the universe + # domain endpoint. + get_universe_domain.assert_not_called() + class TestIDTokenCredentials(object): credentials = None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.26.2/tests/oauth2/test_credentials.py new/google-auth-2.27.0/tests/oauth2/test_credentials.py --- old/google-auth-2.26.2/tests/oauth2/test_credentials.py 2024-01-11 07:09:11.000000000 +0100 +++ new/google-auth-2.27.0/tests/oauth2/test_credentials.py 2024-01-24 19:44:33.000000000 +0100 @@ -793,6 +793,12 @@ new_creds = creds.with_universe_domain("dummy_universe.com") assert new_creds.universe_domain == "dummy_universe.com" + def test_with_account(self): + creds = credentials.Credentials(token="token") + assert creds.account == "" + new_creds = creds.with_account("m...@example.com") + assert new_creds.account == "m...@example.com" + def test_with_token_uri(self): info = AUTH_USER_INFO.copy() @@ -888,6 +894,7 @@ assert json_asdict.get("client_secret") == creds.client_secret assert json_asdict.get("expiry") == info["expiry"] assert json_asdict.get("universe_domain") == creds.universe_domain + assert json_asdict.get("account") == creds.account # Test with a `strip` arg json_output = creds.to_json(strip=["client_secret"])