aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/google-auth/py3
diff options
context:
space:
mode:
authorAlexSm <alex@ydb.tech>2023-12-27 23:31:58 +0100
committerGitHub <noreply@github.com>2023-12-27 23:31:58 +0100
commitd67bfb4b4b7549081543e87a31bc6cb5c46ac973 (patch)
tree8674f2f1570877cb653e7ddcff37ba00288de15a /contrib/python/google-auth/py3
parent1f6bef05ed441c3aa2d565ac792b26cded704ac7 (diff)
downloadydb-d67bfb4b4b7549081543e87a31bc6cb5c46ac973.tar.gz
Import libs 4 (#758)
Diffstat (limited to 'contrib/python/google-auth/py3')
-rw-r--r--contrib/python/google-auth/py3/.dist-info/METADATA38
-rw-r--r--contrib/python/google-auth/py3/README.rst12
-rw-r--r--contrib/python/google-auth/py3/google/auth/__init__.py20
-rw-r--r--contrib/python/google-auth/py3/google/auth/_helpers.py40
-rw-r--r--contrib/python/google-auth/py3/google/auth/compute_engine/__init__.py3
-rw-r--r--contrib/python/google-auth/py3/google/auth/compute_engine/_metadata.py58
-rw-r--r--contrib/python/google-auth/py3/google/auth/compute_engine/credentials.py13
-rw-r--r--contrib/python/google-auth/py3/google/auth/credentials.py20
-rw-r--r--contrib/python/google-auth/py3/google/auth/crypt/_cryptography_rsa.py15
-rw-r--r--contrib/python/google-auth/py3/google/auth/crypt/es256.py15
-rw-r--r--contrib/python/google-auth/py3/google/auth/external_account.py21
-rw-r--r--contrib/python/google-auth/py3/google/auth/transport/_custom_tls_signer.py79
-rw-r--r--contrib/python/google-auth/py3/google/auth/transport/requests.py1
-rw-r--r--contrib/python/google-auth/py3/google/auth/transport/urllib3.py9
-rw-r--r--contrib/python/google-auth/py3/google/auth/version.py2
-rw-r--r--contrib/python/google-auth/py3/google/oauth2/__init__.py21
-rw-r--r--contrib/python/google-auth/py3/google/oauth2/_credentials_async.py6
-rw-r--r--contrib/python/google-auth/py3/google/oauth2/credentials.py55
-rw-r--r--contrib/python/google-auth/py3/google/oauth2/service_account.py35
-rw-r--r--contrib/python/google-auth/py3/tests/compute_engine/test__metadata.py79
-rw-r--r--contrib/python/google-auth/py3/tests/compute_engine/test_credentials.py24
-rw-r--r--contrib/python/google-auth/py3/tests/conftest.py11
-rw-r--r--contrib/python/google-auth/py3/tests/crypt/test__cryptography_rsa.py19
-rw-r--r--contrib/python/google-auth/py3/tests/crypt/test__python_rsa.py4
-rw-r--r--contrib/python/google-auth/py3/tests/crypt/test_crypt.py4
-rw-r--r--contrib/python/google-auth/py3/tests/crypt/test_es256.py17
-rw-r--r--contrib/python/google-auth/py3/tests/data/enterprise_cert_valid_provider.json6
-rw-r--r--contrib/python/google-auth/py3/tests/oauth2/test__client.py4
-rw-r--r--contrib/python/google-auth/py3/tests/oauth2/test_credentials.py33
-rw-r--r--contrib/python/google-auth/py3/tests/oauth2/test_gdch_credentials.py4
-rw-r--r--contrib/python/google-auth/py3/tests/oauth2/test_id_token.py10
-rw-r--r--contrib/python/google-auth/py3/tests/oauth2/test_service_account.py29
-rw-r--r--contrib/python/google-auth/py3/tests/test__cloud_sdk.py7
-rw-r--r--contrib/python/google-auth/py3/tests/test__default.py4
-rw-r--r--contrib/python/google-auth/py3/tests/test__helpers.py26
-rw-r--r--contrib/python/google-auth/py3/tests/test__oauth2client.py4
-rw-r--r--contrib/python/google-auth/py3/tests/test__service_account_info.py4
-rw-r--r--contrib/python/google-auth/py3/tests/test_aws.py4
-rw-r--r--contrib/python/google-auth/py3/tests/test_credentials.py18
-rw-r--r--contrib/python/google-auth/py3/tests/test_external_account.py51
-rw-r--r--contrib/python/google-auth/py3/tests/test_identity_pool.py6
-rw-r--r--contrib/python/google-auth/py3/tests/test_impersonated_credentials.py4
-rw-r--r--contrib/python/google-auth/py3/tests/test_jwt.py4
-rw-r--r--contrib/python/google-auth/py3/tests/transport/test__custom_tls_signer.py108
-rw-r--r--contrib/python/google-auth/py3/tests/transport/test__mtls_helper.py11
-rw-r--r--contrib/python/google-auth/py3/tests/transport/test_grpc.py4
-rw-r--r--contrib/python/google-auth/py3/tests/transport/test_requests.py5
-rw-r--r--contrib/python/google-auth/py3/tests/ya.make5
-rw-r--r--contrib/python/google-auth/py3/ya.make4
49 files changed, 758 insertions, 218 deletions
diff --git a/contrib/python/google-auth/py3/.dist-info/METADATA b/contrib/python/google-auth/py3/.dist-info/METADATA
index 23841a2ee7..f86d77d41b 100644
--- a/contrib/python/google-auth/py3/.dist-info/METADATA
+++ b/contrib/python/google-auth/py3/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: google-auth
-Version: 2.23.0
+Version: 2.25.2
Summary: Google Authentication Library
Home-page: https://github.com/googleapis/google-auth-library-python
Author: Google Cloud Platform
@@ -13,6 +13,7 @@ Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
@@ -23,23 +24,22 @@ Classifier: Operating System :: OS Independent
Classifier: Topic :: Internet :: WWW/HTTP
Requires-Python: >=3.7
License-File: LICENSE
-Requires-Dist: cachetools (<6.0,>=2.0.0)
-Requires-Dist: pyasn1-modules (>=0.2.1)
-Requires-Dist: rsa (<5,>=3.1.4)
-Requires-Dist: urllib3 (<2.0)
+Requires-Dist: cachetools <6.0,>=2.0.0
+Requires-Dist: pyasn1-modules >=0.2.1
+Requires-Dist: rsa <5,>=3.1.4
Provides-Extra: aiohttp
-Requires-Dist: aiohttp (<4.0.0.dev0,>=3.6.2) ; extra == 'aiohttp'
-Requires-Dist: requests (<3.0.0.dev0,>=2.20.0) ; extra == 'aiohttp'
+Requires-Dist: aiohttp <4.0.0.dev0,>=3.6.2 ; extra == 'aiohttp'
+Requires-Dist: requests <3.0.0.dev0,>=2.20.0 ; extra == 'aiohttp'
Provides-Extra: enterprise_cert
-Requires-Dist: cryptography (==36.0.2) ; extra == 'enterprise_cert'
-Requires-Dist: pyopenssl (==22.0.0) ; extra == 'enterprise_cert'
+Requires-Dist: cryptography ==36.0.2 ; extra == 'enterprise_cert'
+Requires-Dist: pyopenssl ==22.0.0 ; extra == 'enterprise_cert'
Provides-Extra: pyopenssl
-Requires-Dist: pyopenssl (>=20.0.0) ; extra == 'pyopenssl'
-Requires-Dist: cryptography (>=38.0.3) ; extra == 'pyopenssl'
+Requires-Dist: pyopenssl >=20.0.0 ; extra == 'pyopenssl'
+Requires-Dist: cryptography >=38.0.3 ; extra == 'pyopenssl'
Provides-Extra: reauth
-Requires-Dist: pyu2f (>=0.1.5) ; extra == 'reauth'
+Requires-Dist: pyu2f >=0.1.5 ; extra == 'reauth'
Provides-Extra: requests
-Requires-Dist: requests (<3.0.0.dev0,>=2.20.0) ; extra == 'requests'
+Requires-Dist: requests <3.0.0.dev0,>=2.20.0 ; extra == 'requests'
Google Auth Python Library
==========================
@@ -63,7 +63,7 @@ You can install using `pip`_::
For more information on setting up your Python development environment, please refer to `Python Development Environment Setup Guide`_ for Google Cloud Platform.
-.. _`Python Development Environment Setup Guide`: https://cloud.google.com/python/setup
+.. _`Python Development Environment Setup Guide`: https://cloud.google.com/python/docs/setup
Extras
------
@@ -80,6 +80,16 @@ Supported Python Versions
^^^^^^^^^^^^^^^^^^^^^^^^^
Python >= 3.7
+**NOTE**:
+Python 3.7 was marked as `unsupported`_ by the python community in June 2023.
+We recommend that all developers upgrade to Python 3.8 and newer as soon as
+they can. Support for Python 3.7 will be removed from this library after
+January 1 2024. Previous releases that support Python 3.7 will continue to be available
+for download, but releases after January 1 2024 will only target Python 3.8 and
+newer.
+
+.. _unsupported: https://devguide.python.org/versions/#unsupported-versions
+
Unsupported Python Versions
^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Python == 2.7: The last version of this library with support for Python 2.7
diff --git a/contrib/python/google-auth/py3/README.rst b/contrib/python/google-auth/py3/README.rst
index cdd19bed50..e058f24713 100644
--- a/contrib/python/google-auth/py3/README.rst
+++ b/contrib/python/google-auth/py3/README.rst
@@ -20,7 +20,7 @@ You can install using `pip`_::
For more information on setting up your Python development environment, please refer to `Python Development Environment Setup Guide`_ for Google Cloud Platform.
-.. _`Python Development Environment Setup Guide`: https://cloud.google.com/python/setup
+.. _`Python Development Environment Setup Guide`: https://cloud.google.com/python/docs/setup
Extras
------
@@ -37,6 +37,16 @@ Supported Python Versions
^^^^^^^^^^^^^^^^^^^^^^^^^
Python >= 3.7
+**NOTE**:
+Python 3.7 was marked as `unsupported`_ by the python community in June 2023.
+We recommend that all developers upgrade to Python 3.8 and newer as soon as
+they can. Support for Python 3.7 will be removed from this library after
+January 1 2024. Previous releases that support Python 3.7 will continue to be available
+for download, but releases after January 1 2024 will only target Python 3.8 and
+newer.
+
+.. _unsupported: https://devguide.python.org/versions/#unsupported-versions
+
Unsupported Python Versions
^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Python == 2.7: The last version of this library with support for Python 2.7
diff --git a/contrib/python/google-auth/py3/google/auth/__init__.py b/contrib/python/google-auth/py3/google/auth/__init__.py
index 2875772b37..765bbd7058 100644
--- a/contrib/python/google-auth/py3/google/auth/__init__.py
+++ b/contrib/python/google-auth/py3/google/auth/__init__.py
@@ -15,6 +15,8 @@
"""Google Auth Library for Python."""
import logging
+import sys
+import warnings
from google.auth import version as google_auth_version
from google.auth._default import (
@@ -29,5 +31,23 @@ __version__ = google_auth_version.__version__
__all__ = ["default", "load_credentials_from_file", "load_credentials_from_dict"]
+
+class Python37DeprecationWarning(DeprecationWarning): # pragma: NO COVER
+ """
+ Deprecation warning raised when Python 3.7 runtime is detected.
+ Python 3.7 support will be dropped after January 1, 2024.
+ """
+
+ pass
+
+
+# Checks if the current runtime is Python 3.7.
+if sys.version_info.major == 3 and sys.version_info.minor == 7: # pragma: NO COVER
+ message = (
+ "After January 1, 2024, new releases of this library will drop support "
+ "for Python 3.7."
+ )
+ warnings.warn(message, Python37DeprecationWarning)
+
# Set default logging handler to avoid "No handler found" warnings.
logging.getLogger(__name__).addHandler(logging.NullHandler())
diff --git a/contrib/python/google-auth/py3/google/auth/_helpers.py b/contrib/python/google-auth/py3/google/auth/_helpers.py
index ad2c095f28..a6c07f7d82 100644
--- a/contrib/python/google-auth/py3/google/auth/_helpers.py
+++ b/contrib/python/google-auth/py3/google/auth/_helpers.py
@@ -17,16 +17,15 @@
import base64
import calendar
import datetime
+from email.message import Message
import sys
import urllib
from google.auth import exceptions
-# Token server doesn't provide a new a token when doing refresh unless the
-# token is expiring within 30 seconds, so refresh threshold should not be
-# more than 30 seconds. Otherwise auth lib will send tons of refresh requests
-# until 30 seconds before the expiration, and cause a spike of CPU usage.
-REFRESH_THRESHOLD = datetime.timedelta(seconds=20)
+# The smallest MDS cache used by this library stores tokens until 4 minutes from
+# expiry.
+REFRESH_THRESHOLD = datetime.timedelta(minutes=3, seconds=45)
def copy_docstring(source_class):
@@ -63,13 +62,42 @@ def copy_docstring(source_class):
return decorator
+def parse_content_type(header_value):
+ """Parse a 'content-type' header value to get just the plain media-type (without parameters).
+
+ This is done using the class Message from email.message as suggested in PEP 594
+ (because the cgi is now deprecated and will be removed in python 3.13,
+ see https://peps.python.org/pep-0594/#cgi).
+
+ Args:
+ header_value (str): The value of a 'content-type' header as a string.
+
+ Returns:
+ str: A string with just the lowercase media-type from the parsed 'content-type' header.
+ If the provided content-type is not parsable, returns 'text/plain',
+ the default value for textual files.
+ """
+ m = Message()
+ m["content-type"] = header_value
+ return (
+ m.get_content_type()
+ ) # Despite the name, actually returns just the media-type
+
+
def utcnow():
"""Returns the current UTC datetime.
Returns:
datetime: The current time in UTC.
"""
- return datetime.datetime.utcnow()
+ # We used datetime.utcnow() before, since it's deprecated from python 3.12,
+ # we are using datetime.now(timezone.utc) now. "utcnow()" is offset-native
+ # (no timezone info), but "now()" is offset-aware (with timezone info).
+ # This will cause datetime comparison problem. For backward compatibility,
+ # we need to remove the timezone info.
+ now = datetime.datetime.now(datetime.timezone.utc)
+ now = now.replace(tzinfo=None)
+ return now
def datetime_to_secs(value):
diff --git a/contrib/python/google-auth/py3/google/auth/compute_engine/__init__.py b/contrib/python/google-auth/py3/google/auth/compute_engine/__init__.py
index 5c84234e93..7e1206fc1b 100644
--- a/contrib/python/google-auth/py3/google/auth/compute_engine/__init__.py
+++ b/contrib/python/google-auth/py3/google/auth/compute_engine/__init__.py
@@ -14,8 +14,9 @@
"""Google Compute Engine authentication."""
+from google.auth.compute_engine._metadata import detect_gce_residency_linux
from google.auth.compute_engine.credentials import Credentials
from google.auth.compute_engine.credentials import IDTokenCredentials
-__all__ = ["Credentials", "IDTokenCredentials"]
+__all__ = ["Credentials", "IDTokenCredentials", "detect_gce_residency_linux"]
diff --git a/contrib/python/google-auth/py3/google/auth/compute_engine/_metadata.py b/contrib/python/google-auth/py3/google/auth/compute_engine/_metadata.py
index 04abe178f5..1c884c3c43 100644
--- a/contrib/python/google-auth/py3/google/auth/compute_engine/_metadata.py
+++ b/contrib/python/google-auth/py3/google/auth/compute_engine/_metadata.py
@@ -156,6 +156,7 @@ def get(
recursive=False,
retry_count=5,
headers=None,
+ return_none_for_not_found_error=False,
):
"""Fetch a resource from the metadata server.
@@ -173,6 +174,8 @@ def get(
retry_count (int): How many times to attempt connecting to metadata
server using above timeout.
headers (Optional[Mapping[str, str]]): Headers for the request.
+ return_none_for_not_found_error (Optional[bool]): If True, returns None
+ for 404 error instead of throwing an exception.
Returns:
Union[Mapping, str]: If the metadata server returns JSON, a mapping of
@@ -216,9 +219,21 @@ def get(
"metadata service. Compute Engine Metadata server unavailable".format(url)
)
+ content = _helpers.from_bytes(response.data)
+
+ if response.status == http_client.NOT_FOUND and return_none_for_not_found_error:
+ _LOGGER.info(
+ "Compute Engine Metadata server call to %s returned 404, reason: %s",
+ path,
+ content,
+ )
+ return None
+
if response.status == http_client.OK:
- content = _helpers.from_bytes(response.data)
- if response.headers["content-type"] == "application/json":
+ if (
+ _helpers.parse_content_type(response.headers["content-type"])
+ == "application/json"
+ ):
try:
return json.loads(content)
except ValueError as caught_exc:
@@ -229,14 +244,14 @@ def get(
raise new_exc from caught_exc
else:
return content
- else:
- raise exceptions.TransportError(
- "Failed to retrieve {} from the Google Compute Engine "
- "metadata service. Status: {} Response:\n{}".format(
- url, response.status, response.data
- ),
- response,
- )
+
+ raise exceptions.TransportError(
+ "Failed to retrieve {} from the Google Compute Engine "
+ "metadata service. Status: {} Response:\n{}".format(
+ url, response.status, response.data
+ ),
+ response,
+ )
def get_project_id(request):
@@ -256,6 +271,29 @@ def get_project_id(request):
return get(request, "project/project-id")
+def get_universe_domain(request):
+ """Get the universe domain value from the metadata server.
+
+ Args:
+ request (google.auth.transport.Request): A callable used to make
+ HTTP requests.
+
+ Returns:
+ str: The universe domain value. If the universe domain endpoint is not
+ not found, return the default value, which is googleapis.com
+
+ Raises:
+ google.auth.exceptions.TransportError: if an error other than
+ 404 occurs while retrieving metadata.
+ """
+ universe_domain = get(
+ request, "universe/universe_domain", return_none_for_not_found_error=True
+ )
+ if not universe_domain:
+ return "googleapis.com"
+ return universe_domain
+
+
def get_service_account_info(request, service_account="default"):
"""Get information about a service account from the metadata server.
diff --git a/contrib/python/google-auth/py3/google/auth/compute_engine/credentials.py b/contrib/python/google-auth/py3/google/auth/compute_engine/credentials.py
index 7ae673880f..a035c7697a 100644
--- a/contrib/python/google-auth/py3/google/auth/compute_engine/credentials.py
+++ b/contrib/python/google-auth/py3/google/auth/compute_engine/credentials.py
@@ -28,6 +28,7 @@ from google.auth import iam
from google.auth import jwt
from google.auth import metrics
from google.auth.compute_engine import _metadata
+from google.auth.transport import requests as google_auth_requests
from google.oauth2 import _client
@@ -73,6 +74,8 @@ class Credentials(credentials.Scoped, credentials.CredentialsWithQuotaProject):
self._quota_project_id = quota_project_id
self._scopes = scopes
self._default_scopes = default_scopes
+ self._universe_domain_cached = False
+ self._universe_domain_request = google_auth_requests.Request()
def _retrieve_info(self, request):
"""Retrieve information about the service account.
@@ -131,6 +134,16 @@ class Credentials(credentials.Scoped, credentials.CredentialsWithQuotaProject):
def requires_scopes(self):
return not self._scopes
+ @property
+ def universe_domain(self):
+ if self._universe_domain_cached:
+ return self._universe_domain
+ self._universe_domain = _metadata.get_universe_domain(
+ self._universe_domain_request
+ )
+ self._universe_domain_cached = True
+ return self._universe_domain
+
@_helpers.copy_docstring(credentials.CredentialsWithQuotaProject)
def with_quota_project(self, quota_project_id):
return self.__class__(
diff --git a/contrib/python/google-auth/py3/google/auth/credentials.py b/contrib/python/google-auth/py3/google/auth/credentials.py
index 80a2a5c0b4..800781c408 100644
--- a/contrib/python/google-auth/py3/google/auth/credentials.py
+++ b/contrib/python/google-auth/py3/google/auth/credentials.py
@@ -52,8 +52,9 @@ class Credentials(metaclass=abc.ABCMeta):
self._quota_project_id = None
"""Optional[str]: Project to use for quota and billing purposes."""
self._trust_boundary = None
- """Optional[str]: Encoded string representation of credentials trust
- boundary."""
+ """Optional[dict]: Cache of a trust boundary response which has a list
+ of allowed regions and an encoded string representation of credentials
+ trust boundary."""
self._universe_domain = "googleapis.com"
"""Optional[str]: The universe domain value, default is googleapis.com
"""
@@ -135,8 +136,21 @@ class Credentials(metaclass=abc.ABCMeta):
headers["authorization"] = "Bearer {}".format(
_helpers.from_bytes(token or self.token)
)
+ """Trust boundary value will be a cached value from global lookup.
+
+ The response of trust boundary will be a list of regions and a hex
+ encoded representation.
+
+ An example of global lookup response:
+ {
+ "locations": [
+ "us-central1", "us-east1", "europe-west1", "asia-east1"
+ ]
+ "encoded_locations": "0xA30"
+ }
+ """
if self._trust_boundary is not None:
- headers["x-identity-trust-boundary"] = self._trust_boundary
+ headers["x-allowed-locations"] = self._trust_boundary["encoded_locations"]
if self.quota_project_id:
headers["x-goog-user-project"] = self.quota_project_id
diff --git a/contrib/python/google-auth/py3/google/auth/crypt/_cryptography_rsa.py b/contrib/python/google-auth/py3/google/auth/crypt/_cryptography_rsa.py
index 4f2d611666..1a3e9ff52c 100644
--- a/contrib/python/google-auth/py3/google/auth/crypt/_cryptography_rsa.py
+++ b/contrib/python/google-auth/py3/google/auth/crypt/_cryptography_rsa.py
@@ -134,3 +134,18 @@ class RSASigner(base.Signer, base.FromServiceAccountMixin):
key, password=None, backend=_BACKEND
)
return cls(private_key, key_id=key_id)
+
+ def __getstate__(self):
+ """Pickle helper that serializes the _key attribute."""
+ state = self.__dict__.copy()
+ state["_key"] = self._key.private_bytes(
+ encoding=serialization.Encoding.PEM,
+ format=serialization.PrivateFormat.PKCS8,
+ encryption_algorithm=serialization.NoEncryption(),
+ )
+ return state
+
+ def __setstate__(self, state):
+ """Pickle helper that deserializes the _key attribute."""
+ state["_key"] = serialization.load_pem_private_key(state["_key"], None)
+ self.__dict__.update(state)
diff --git a/contrib/python/google-auth/py3/google/auth/crypt/es256.py b/contrib/python/google-auth/py3/google/auth/crypt/es256.py
index 7920cc7ffb..820e4becce 100644
--- a/contrib/python/google-auth/py3/google/auth/crypt/es256.py
+++ b/contrib/python/google-auth/py3/google/auth/crypt/es256.py
@@ -158,3 +158,18 @@ class ES256Signer(base.Signer, base.FromServiceAccountMixin):
key, password=None, backend=_BACKEND
)
return cls(private_key, key_id=key_id)
+
+ def __getstate__(self):
+ """Pickle helper that serializes the _key attribute."""
+ state = self.__dict__.copy()
+ state["_key"] = self._key.private_bytes(
+ encoding=serialization.Encoding.PEM,
+ format=serialization.PrivateFormat.PKCS8,
+ encryption_algorithm=serialization.NoEncryption(),
+ )
+ return state
+
+ def __setstate__(self, state):
+ """Pickle helper that deserializes the _key attribute."""
+ state["_key"] = serialization.load_pem_private_key(state["_key"], None)
+ self.__dict__.update(state)
diff --git a/contrib/python/google-auth/py3/google/auth/external_account.py b/contrib/python/google-auth/py3/google/auth/external_account.py
index c45e6f2133..e7fed8695a 100644
--- a/contrib/python/google-auth/py3/google/auth/external_account.py
+++ b/contrib/python/google-auth/py3/google/auth/external_account.py
@@ -132,7 +132,10 @@ class Credentials(
self._default_scopes = default_scopes
self._workforce_pool_user_project = workforce_pool_user_project
self._universe_domain = universe_domain or _DEFAULT_UNIVERSE_DOMAIN
- self._trust_boundary = "0" # expose a placeholder trust boundary value.
+ self._trust_boundary = {
+ "locations": [],
+ "encoded_locations": "0x0",
+ } # expose a placeholder trust boundary value.
if self._client_id:
self._client_auth = utils.ClientAuthentication(
@@ -412,6 +415,22 @@ class Credentials(
new_cred._metrics_options = self._metrics_options
return new_cred
+ def with_universe_domain(self, universe_domain):
+ """Create a copy of these credentials with the given universe domain.
+
+ Args:
+ universe_domain (str): The universe domain value.
+
+ Returns:
+ google.auth.external_account.Credentials: A new credentials
+ instance.
+ """
+ kwargs = self._constructor_args()
+ kwargs.update(universe_domain=universe_domain)
+ new_cred = self.__class__(**kwargs)
+ new_cred._metrics_options = self._metrics_options
+ return new_cred
+
def _initialize_impersonated_credentials(self):
"""Generates an impersonated credentials.
diff --git a/contrib/python/google-auth/py3/google/auth/transport/_custom_tls_signer.py b/contrib/python/google-auth/py3/google/auth/transport/_custom_tls_signer.py
index 07f14df02d..57a563d03b 100644
--- a/contrib/python/google-auth/py3/google/auth/transport/_custom_tls_signer.py
+++ b/contrib/python/google-auth/py3/google/auth/transport/_custom_tls_signer.py
@@ -107,6 +107,22 @@ def load_signer_lib(signer_lib_path):
return lib
+def load_provider_lib(provider_lib_path):
+ _LOGGER.debug("loading provider library from %s", provider_lib_path)
+
+ # winmode parameter is only available for python 3.8+.
+ lib = (
+ ctypes.CDLL(provider_lib_path, winmode=0)
+ if sys.version_info >= (3, 8) and os.name == "nt"
+ else ctypes.CDLL(provider_lib_path)
+ )
+
+ lib.ECP_attach_to_ctx.argtypes = [ctypes.c_void_p, ctypes.c_char_p]
+ lib.ECP_attach_to_ctx.restype = ctypes.c_int
+
+ return lib
+
+
# Computes SHA256 hash.
def _compute_sha256_digest(to_be_signed, to_be_signed_len):
from cryptography.hazmat.primitives import hashes
@@ -199,21 +215,31 @@ class CustomTlsSigner(object):
self._enterprise_cert_file_path = enterprise_cert_file_path
self._cert = None
self._sign_callback = None
+ self._provider_lib = None
def load_libraries(self):
- try:
- with open(self._enterprise_cert_file_path, "r") as f:
- enterprise_cert_json = json.load(f)
- libs = enterprise_cert_json["libs"]
- signer_library = libs["ecp_client"]
- offload_library = libs["tls_offload"]
- except (KeyError, ValueError) as caught_exc:
- new_exc = exceptions.MutualTLSChannelError(
- "enterprise cert file is invalid", caught_exc
- )
- raise new_exc from caught_exc
- self._offload_lib = load_offload_lib(offload_library)
- self._signer_lib = load_signer_lib(signer_library)
+ with open(self._enterprise_cert_file_path, "r") as f:
+ enterprise_cert_json = json.load(f)
+ libs = enterprise_cert_json.get("libs", {})
+
+ signer_library = libs.get("ecp_client", None)
+ offload_library = libs.get("tls_offload", None)
+ provider_library = libs.get("ecp_provider", None)
+
+ # Using newer provider implementation. This is mutually exclusive to the
+ # offload implementation.
+ if provider_library:
+ self._provider_lib = load_provider_lib(provider_library)
+ return
+
+ # Using old offload implementation
+ if offload_library and signer_library:
+ self._offload_lib = load_offload_lib(offload_library)
+ self._signer_lib = load_signer_lib(signer_library)
+ self.set_up_custom_key()
+ return
+
+ raise exceptions.MutualTLSChannelError("enterprise cert file is invalid")
def set_up_custom_key(self):
# We need to keep a reference of the cert and sign callback so it won't
@@ -224,11 +250,22 @@ class CustomTlsSigner(object):
)
def attach_to_ssl_context(self, ctx):
- # In the TLS handshake, the signing operation will be done by the
- # sign_callback.
- if not self._offload_lib.ConfigureSslContext(
- self._sign_callback,
- ctypes.c_char_p(self._cert),
- _cast_ssl_ctx_to_void_p(ctx._ctx._context),
- ):
- raise exceptions.MutualTLSChannelError("failed to configure SSL context")
+ if self._provider_lib:
+ if not self._provider_lib.ECP_attach_to_ctx(
+ _cast_ssl_ctx_to_void_p(ctx._ctx._context),
+ self._enterprise_cert_file_path.encode("ascii"),
+ ):
+ raise exceptions.MutualTLSChannelError(
+ "failed to configure ECP Provider SSL context"
+ )
+ elif self._offload_lib and self._signer_lib:
+ if not self._offload_lib.ConfigureSslContext(
+ self._sign_callback,
+ ctypes.c_char_p(self._cert),
+ _cast_ssl_ctx_to_void_p(ctx._ctx._context),
+ ):
+ raise exceptions.MutualTLSChannelError(
+ "failed to configure ECP Offload SSL context"
+ )
+ else:
+ raise exceptions.MutualTLSChannelError("Invalid ECP configuration.")
diff --git a/contrib/python/google-auth/py3/google/auth/transport/requests.py b/contrib/python/google-auth/py3/google/auth/transport/requests.py
index b9bcad359f..aa16113226 100644
--- a/contrib/python/google-auth/py3/google/auth/transport/requests.py
+++ b/contrib/python/google-auth/py3/google/auth/transport/requests.py
@@ -274,7 +274,6 @@ class _MutualTlsOffloadAdapter(requests.adapters.HTTPAdapter):
self.signer = _custom_tls_signer.CustomTlsSigner(enterprise_cert_file_path)
self.signer.load_libraries()
- self.signer.set_up_custom_key()
poolmanager = create_urllib3_context()
poolmanager.load_verify_locations(cafile=certifi.where())
diff --git a/contrib/python/google-auth/py3/google/auth/transport/urllib3.py b/contrib/python/google-auth/py3/google/auth/transport/urllib3.py
index 053d6f7b72..63144f5fff 100644
--- a/contrib/python/google-auth/py3/google/auth/transport/urllib3.py
+++ b/contrib/python/google-auth/py3/google/auth/transport/urllib3.py
@@ -40,11 +40,18 @@ except ImportError as caught_exc: # pragma: NO COVER
"urllib3 package to use the urllib3 transport."
) from caught_exc
+from packaging import version # type: ignore
+
from google.auth import environment_vars
from google.auth import exceptions
from google.auth import transport
from google.oauth2 import service_account
+if version.parse(urllib3.__version__) >= version.parse("2.0.0"): # pragma: NO COVER
+ RequestMethods = urllib3._request_methods.RequestMethods # type: ignore
+else: # pragma: NO COVER
+ RequestMethods = urllib3.request.RequestMethods # type: ignore
+
_LOGGER = logging.getLogger(__name__)
@@ -179,7 +186,7 @@ def _make_mutual_tls_http(cert, key):
return http
-class AuthorizedHttp(urllib3.request.RequestMethods):
+class AuthorizedHttp(RequestMethods): # type: ignore
"""A urllib3 HTTP class with credentials.
This class is used to perform requests to API endpoints that require
diff --git a/contrib/python/google-auth/py3/google/auth/version.py b/contrib/python/google-auth/py3/google/auth/version.py
index 491187e6d7..31cc30242a 100644
--- a/contrib/python/google-auth/py3/google/auth/version.py
+++ b/contrib/python/google-auth/py3/google/auth/version.py
@@ -12,4 +12,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-__version__ = "2.23.0"
+__version__ = "2.25.2"
diff --git a/contrib/python/google-auth/py3/google/oauth2/__init__.py b/contrib/python/google-auth/py3/google/oauth2/__init__.py
index 4fb71fd1ad..accae96579 100644
--- a/contrib/python/google-auth/py3/google/oauth2/__init__.py
+++ b/contrib/python/google-auth/py3/google/oauth2/__init__.py
@@ -13,3 +13,24 @@
# limitations under the License.
"""Google OAuth 2.0 Library for Python."""
+
+import sys
+import warnings
+
+
+class Python37DeprecationWarning(DeprecationWarning): # pragma: NO COVER
+ """
+ Deprecation warning raised when Python 3.7 runtime is detected.
+ Python 3.7 support will be dropped after January 1, 2024.
+ """
+
+ pass
+
+
+# Checks if the current runtime is Python 3.7.
+if sys.version_info.major == 3 and sys.version_info.minor == 7: # pragma: NO COVER
+ message = (
+ "After January 1, 2024, new releases of this library will drop support "
+ "for Python 3.7."
+ )
+ warnings.warn(message, Python37DeprecationWarning)
diff --git a/contrib/python/google-auth/py3/google/oauth2/_credentials_async.py b/contrib/python/google-auth/py3/google/oauth2/_credentials_async.py
index e7b9637c82..b5561aae02 100644
--- a/contrib/python/google-auth/py3/google/oauth2/_credentials_async.py
+++ b/contrib/python/google-auth/py3/google/oauth2/_credentials_async.py
@@ -96,6 +96,12 @@ class Credentials(oauth2_credentials.Credentials):
)
)
+ @_helpers.copy_docstring(credentials.Credentials)
+ async def before_request(self, request, method, url, headers):
+ if not self.valid:
+ await self.refresh(request)
+ self.apply(headers)
+
class UserAccessTokenCredentials(oauth2_credentials.UserAccessTokenCredentials):
"""Access token credentials for user account.
diff --git a/contrib/python/google-auth/py3/google/oauth2/credentials.py b/contrib/python/google-auth/py3/google/oauth2/credentials.py
index 4643fdbea6..a5c93ecc2f 100644
--- a/contrib/python/google-auth/py3/google/oauth2/credentials.py
+++ b/contrib/python/google-auth/py3/google/oauth2/credentials.py
@@ -49,13 +49,15 @@ _LOGGER = logging.getLogger(__name__)
# The Google OAuth 2.0 token endpoint. Used for authorized user credentials.
_GOOGLE_OAUTH2_TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token"
+_DEFAULT_UNIVERSE_DOMAIN = "googleapis.com"
class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaProject):
"""Credentials using OAuth 2.0 access and refresh tokens.
- The credentials are considered immutable. If you want to modify the
- quota project, use :meth:`with_quota_project` or ::
+ The credentials are considered immutable except the tokens and the token
+ expiry, which are updated after refresh. If you want to modify the quota
+ project, use :meth:`with_quota_project` or ::
credentials = credentials.with_quota_project('myproject-123')
@@ -84,6 +86,7 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr
enable_reauth_refresh=False,
granted_scopes=None,
trust_boundary=None,
+ universe_domain=_DEFAULT_UNIVERSE_DOMAIN,
):
"""
Args:
@@ -125,6 +128,9 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr
granted_scopes (Optional[Sequence[str]]): The scopes that were consented/granted by the user.
This could be different from the requested scopes and it could be empty if granted
and requested scopes were same.
+ trust_boundary (str): String representation of trust boundary meta.
+ universe_domain (Optional[str]): The universe domain. The default
+ universe domain is googleapis.com.
"""
super(Credentials, self).__init__()
self.token = token
@@ -142,6 +148,7 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr
self.refresh_handler = refresh_handler
self._enable_reauth_refresh = enable_reauth_refresh
self._trust_boundary = trust_boundary
+ self._universe_domain = universe_domain or _DEFAULT_UNIVERSE_DOMAIN
def __getstate__(self):
"""A __getstate__ method must exist for the __setstate__ to be called
@@ -173,7 +180,7 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr
self._rapt_token = d.get("_rapt_token")
self._enable_reauth_refresh = d.get("_enable_reauth_refresh")
self._trust_boundary = d.get("_trust_boundary")
- self._universe_domain = d.get("_universe_domain")
+ self._universe_domain = d.get("_universe_domain") or _DEFAULT_UNIVERSE_DOMAIN
# The refresh_handler setter should be used to repopulate this.
self._refresh_handler = None
@@ -272,6 +279,7 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr
rapt_token=self.rapt_token,
enable_reauth_refresh=self._enable_reauth_refresh,
trust_boundary=self._trust_boundary,
+ universe_domain=self._universe_domain,
)
@_helpers.copy_docstring(credentials.CredentialsWithTokenUri)
@@ -291,6 +299,34 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr
rapt_token=self.rapt_token,
enable_reauth_refresh=self._enable_reauth_refresh,
trust_boundary=self._trust_boundary,
+ universe_domain=self._universe_domain,
+ )
+
+ def with_universe_domain(self, universe_domain):
+ """Create a copy of the credential with the given universe domain.
+
+ Args:
+ universe_domain (str): The universe domain value.
+
+ 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=universe_domain,
)
def _metric_header_for_usage(self):
@@ -298,6 +334,17 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr
@_helpers.copy_docstring(credentials.Credentials)
def refresh(self, request):
+ if self._universe_domain != _DEFAULT_UNIVERSE_DOMAIN:
+ raise exceptions.RefreshError(
+ "User credential refresh is only supported in the default "
+ "googleapis.com universe domain, but the current universe "
+ "domain is {}. If you created the credential with an access "
+ "token, it's likely that the provided token is expired now, "
+ "please update your code with a valid token.".format(
+ self._universe_domain
+ )
+ )
+
scopes = self._scopes if self._scopes is not None else self._default_scopes
# Use refresh handler if available and no refresh token is
# available. This is useful in general when tokens are obtained by calling
@@ -427,6 +474,7 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr
expiry=expiry,
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
)
@classmethod
@@ -470,6 +518,7 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr
"client_secret": self.client_secret,
"scopes": self.scopes,
"rapt_token": self.rapt_token,
+ "universe_domain": self._universe_domain,
}
if self.expiry: # flatten expiry timestamp
prep["expiry"] = self.expiry.isoformat() + "Z"
diff --git a/contrib/python/google-auth/py3/google/oauth2/service_account.py b/contrib/python/google-auth/py3/google/oauth2/service_account.py
index e08899f8e5..68db41af40 100644
--- a/contrib/python/google-auth/py3/google/oauth2/service_account.py
+++ b/contrib/python/google-auth/py3/google/oauth2/service_account.py
@@ -182,10 +182,7 @@ class Credentials(
self._quota_project_id = quota_project_id
self._token_uri = token_uri
self._always_use_jwt_access = always_use_jwt_access
- if not universe_domain:
- self._universe_domain = _DEFAULT_UNIVERSE_DOMAIN
- else:
- self._universe_domain = universe_domain
+ self._universe_domain = universe_domain or _DEFAULT_UNIVERSE_DOMAIN
if universe_domain != _DEFAULT_UNIVERSE_DOMAIN:
self._always_use_jwt_access = True
@@ -196,7 +193,7 @@ class Credentials(
self._additional_claims = additional_claims
else:
self._additional_claims = {}
- self._trust_boundary = "0"
+ self._trust_boundary = {"locations": [], "encoded_locations": "0x0"}
@classmethod
def _from_signer_and_info(cls, signer, info, **kwargs):
@@ -328,6 +325,22 @@ class Credentials(
cred._always_use_jwt_access = always_use_jwt_access
return cred
+ def with_universe_domain(self, universe_domain):
+ """Create a copy of these credentials with the given universe domain.
+
+ Args:
+ universe_domain (str): The universe domain value.
+
+ Returns:
+ google.auth.service_account.Credentials: A new credentials
+ instance.
+ """
+ cred = self._make_copy()
+ cred._universe_domain = universe_domain
+ if universe_domain != _DEFAULT_UNIVERSE_DOMAIN:
+ cred._always_use_jwt_access = True
+ return cred
+
def with_subject(self, subject):
"""Create a copy of these credentials with the specified subject.
@@ -417,13 +430,11 @@ class Credentials(
@_helpers.copy_docstring(credentials.Credentials)
def refresh(self, request):
- if (
- self._universe_domain != _DEFAULT_UNIVERSE_DOMAIN
- and not self._jwt_credentials
- ):
- raise exceptions.RefreshError(
- "self._jwt_credentials is missing for non-default universe domain"
- )
+ if self._always_use_jwt_access and not self._jwt_credentials:
+ # If self signed jwt should be used but jwt credential is not
+ # created, try to create one with scopes
+ self._create_self_signed_jwt(None)
+
if self._universe_domain != _DEFAULT_UNIVERSE_DOMAIN and self._subject:
raise exceptions.RefreshError(
"domain wide delegation is not supported for non-default universe domain"
diff --git a/contrib/python/google-auth/py3/tests/compute_engine/test__metadata.py b/contrib/python/google-auth/py3/tests/compute_engine/test__metadata.py
index ddf84596af..5e037a940b 100644
--- a/contrib/python/google-auth/py3/tests/compute_engine/test__metadata.py
+++ b/contrib/python/google-auth/py3/tests/compute_engine/test__metadata.py
@@ -63,6 +63,7 @@ def make_request(data, status=http_client.OK, headers=None, retry=False):
return request
+@pytest.mark.xfail
def test_detect_gce_residency_linux_success():
_metadata._GCE_PRODUCT_NAME_FILE = SMBIOS_PRODUCT_NAME_FILE
assert _metadata.detect_gce_residency_linux()
@@ -89,6 +90,7 @@ def test_is_on_gce_windows_success():
assert not _metadata.is_on_gce(request)
+@pytest.mark.xfail
@mock.patch("os.name", new="posix")
def test_is_on_gce_linux_success():
request = make_request("", headers={_metadata._METADATA_FLAVOR_HEADER: "meep"})
@@ -176,6 +178,24 @@ def test_get_success_json():
assert result[key] == value
+def test_get_success_json_content_type_charset():
+ key, value = "foo", "bar"
+
+ data = json.dumps({key: value})
+ request = make_request(
+ data, headers={"content-type": "application/json; charset=UTF-8"}
+ )
+
+ result = _metadata.get(request, PATH)
+
+ request.assert_called_once_with(
+ method="GET",
+ url=_metadata._METADATA_ROOT + PATH,
+ headers=_metadata._METADATA_HEADERS,
+ )
+ assert result[key] == value
+
+
def test_get_success_retry():
key, value = "foo", "bar"
@@ -307,6 +327,18 @@ def test_get_failure():
)
+def test_get_return_none_for_not_found_error():
+ request = make_request("Metadata error", status=http_client.NOT_FOUND)
+
+ assert _metadata.get(request, PATH, return_none_for_not_found_error=True) is None
+
+ request.assert_called_once_with(
+ method="GET",
+ url=_metadata._METADATA_ROOT + PATH,
+ headers=_metadata._METADATA_HEADERS,
+ )
+
+
def test_get_failure_connection_failed():
request = make_request("")
request.side_effect = exceptions.TransportError()
@@ -353,6 +385,53 @@ def test_get_project_id():
assert project_id == project
+def test_get_universe_domain_success():
+ request = make_request(
+ "fake_universe_domain", headers={"content-type": "text/plain"}
+ )
+
+ universe_domain = _metadata.get_universe_domain(request)
+
+ request.assert_called_once_with(
+ method="GET",
+ url=_metadata._METADATA_ROOT + "universe/universe_domain",
+ headers=_metadata._METADATA_HEADERS,
+ )
+ assert universe_domain == "fake_universe_domain"
+
+
+def test_get_universe_domain_not_found():
+ # Test that if the universe domain endpoint returns 404 error, we should
+ # use googleapis.com as the universe domain
+ request = make_request("not found", status=http_client.NOT_FOUND)
+
+ universe_domain = _metadata.get_universe_domain(request)
+
+ request.assert_called_once_with(
+ method="GET",
+ url=_metadata._METADATA_ROOT + "universe/universe_domain",
+ headers=_metadata._METADATA_HEADERS,
+ )
+ assert universe_domain == "googleapis.com"
+
+
+def test_get_universe_domain_other_error():
+ # Test that if the universe domain endpoint returns an error other than 404
+ # we should throw the error
+ request = make_request("unauthorized", status=http_client.UNAUTHORIZED)
+
+ with pytest.raises(exceptions.TransportError) as excinfo:
+ _metadata.get_universe_domain(request)
+
+ assert excinfo.match(r"unauthorized")
+
+ request.assert_called_once_with(
+ method="GET",
+ url=_metadata._METADATA_ROOT + "universe/universe_domain",
+ headers=_metadata._METADATA_HEADERS,
+ )
+
+
@mock.patch(
"google.auth.metrics.token_request_access_token_mds",
return_value=ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE,
diff --git a/contrib/python/google-auth/py3/tests/compute_engine/test_credentials.py b/contrib/python/google-auth/py3/tests/compute_engine/test_credentials.py
index 507fea9fcc..5d6ccdcdec 100644
--- a/contrib/python/google-auth/py3/tests/compute_engine/test_credentials.py
+++ b/contrib/python/google-auth/py3/tests/compute_engine/test_credentials.py
@@ -208,6 +208,30 @@ class TestCredentials(object):
assert headers["authorization"] == "Bearer token"
assert headers["x-goog-api-client"] == "cred-type/mds"
+ @mock.patch(
+ "google.auth.compute_engine._metadata.get_universe_domain",
+ 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"
+
+ # calling the universe_domain property should trigger a call to
+ # get_universe_domain to fetch the value. The value should be cached.
+ assert self.credentials.universe_domain == "fake_universe_domain"
+ assert self.credentials._universe_domain == "fake_universe_domain"
+ assert self.credentials._universe_domain_cached
+ get_universe_domain.assert_called_once_with(
+ self.credentials._universe_domain_request
+ )
+
+ # calling the universe_domain property the second time should use the
+ # cached value instead of calling get_universe_domain
+ assert self.credentials.universe_domain == "fake_universe_domain"
+ get_universe_domain.assert_called_once_with(
+ self.credentials._universe_domain_request
+ )
+
class TestIDTokenCredentials(object):
credentials = None
diff --git a/contrib/python/google-auth/py3/tests/conftest.py b/contrib/python/google-auth/py3/tests/conftest.py
index 08896b0f82..7658d8f456 100644
--- a/contrib/python/google-auth/py3/tests/conftest.py
+++ b/contrib/python/google-auth/py3/tests/conftest.py
@@ -21,9 +21,14 @@ import pytest # type: ignore
def pytest_configure():
"""Load public certificate and private key."""
- import __res
- pytest.private_key_bytes = __res.find("data/privatekey.pem")
- pytest.public_cert_bytes = __res.find("data/public_cert.pem")
+ import yatest.common as yc
+ pytest.data_dir = os.path.join(os.path.dirname(yc.source_path("contrib/python/google-auth/py3/tests/conftest.py")), "data")
+
+ with open(os.path.join(pytest.data_dir, "privatekey.pem"), "rb") as fh:
+ pytest.private_key_bytes = fh.read()
+
+ with open(os.path.join(pytest.data_dir, "public_cert.pem"), "rb") as fh:
+ pytest.public_cert_bytes = fh.read()
@pytest.fixture
diff --git a/contrib/python/google-auth/py3/tests/crypt/test__cryptography_rsa.py b/contrib/python/google-auth/py3/tests/crypt/test__cryptography_rsa.py
index d19154b61b..2c4cebe0d7 100644
--- a/contrib/python/google-auth/py3/tests/crypt/test__cryptography_rsa.py
+++ b/contrib/python/google-auth/py3/tests/crypt/test__cryptography_rsa.py
@@ -14,6 +14,7 @@
import json
import os
+import pickle
from cryptography.hazmat.primitives.asymmetric import rsa
import pytest # type: ignore
@@ -23,8 +24,8 @@ from google.auth.crypt import _cryptography_rsa
from google.auth.crypt import base
-import yatest.common
-DATA_DIR = os.path.join(yatest.common.test_source_path(), "data")
+import yatest.common as yc
+DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "..", "data")
# To generate privatekey.pem, privatekey.pub, and public_cert.pem:
# $ openssl req -new -newkey rsa:1024 -x509 -nodes -out public_cert.pem \
@@ -160,3 +161,17 @@ class TestRSASigner(object):
assert signer.key_id == SERVICE_ACCOUNT_INFO[base._JSON_FILE_PRIVATE_KEY_ID]
assert isinstance(signer._key, rsa.RSAPrivateKey)
+
+ def test_pickle(self):
+ signer = _cryptography_rsa.RSASigner.from_service_account_file(
+ SERVICE_ACCOUNT_JSON_FILE
+ )
+
+ assert signer.key_id == SERVICE_ACCOUNT_INFO[base._JSON_FILE_PRIVATE_KEY_ID]
+ assert isinstance(signer._key, rsa.RSAPrivateKey)
+
+ pickled_signer = pickle.dumps(signer)
+ signer = pickle.loads(pickled_signer)
+
+ assert signer.key_id == SERVICE_ACCOUNT_INFO[base._JSON_FILE_PRIVATE_KEY_ID]
+ assert isinstance(signer._key, rsa.RSAPrivateKey)
diff --git a/contrib/python/google-auth/py3/tests/crypt/test__python_rsa.py b/contrib/python/google-auth/py3/tests/crypt/test__python_rsa.py
index 592b523d92..75dcb314f7 100644
--- a/contrib/python/google-auth/py3/tests/crypt/test__python_rsa.py
+++ b/contrib/python/google-auth/py3/tests/crypt/test__python_rsa.py
@@ -26,8 +26,8 @@ from google.auth.crypt import _python_rsa
from google.auth.crypt import base
-import yatest.common
-DATA_DIR = os.path.join(yatest.common.test_source_path(), "data")
+import yatest.common as yc
+DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "..", "data")
# To generate privatekey.pem, privatekey.pub, and public_cert.pem:
# $ openssl req -new -newkey rsa:1024 -x509 -nodes -out public_cert.pem \
diff --git a/contrib/python/google-auth/py3/tests/crypt/test_crypt.py b/contrib/python/google-auth/py3/tests/crypt/test_crypt.py
index 97c2abc257..30de18a5dd 100644
--- a/contrib/python/google-auth/py3/tests/crypt/test_crypt.py
+++ b/contrib/python/google-auth/py3/tests/crypt/test_crypt.py
@@ -17,8 +17,8 @@ import os
from google.auth import crypt
-import yatest.common
-DATA_DIR = os.path.join(yatest.common.test_source_path(), "data")
+import yatest.common as yc
+DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "..", "data")
# To generate privatekey.pem, privatekey.pub, and public_cert.pem:
# $ openssl req -new -newkey rsa:1024 -x509 -nodes -out public_cert.pem \
diff --git a/contrib/python/google-auth/py3/tests/crypt/test_es256.py b/contrib/python/google-auth/py3/tests/crypt/test_es256.py
index 1a43a2f01b..3ba5b64fad 100644
--- a/contrib/python/google-auth/py3/tests/crypt/test_es256.py
+++ b/contrib/python/google-auth/py3/tests/crypt/test_es256.py
@@ -15,6 +15,7 @@
import base64
import json
import os
+import pickle
from cryptography.hazmat.primitives.asymmetric import ec
import pytest # type: ignore
@@ -24,8 +25,8 @@ from google.auth.crypt import base
from google.auth.crypt import es256
-import yatest.common
-DATA_DIR = os.path.join(yatest.common.test_source_path(), "data")
+import yatest.common as yc
+DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "..", "data")
# To generate es256_privatekey.pem, es256_privatekey.pub, and
# es256_public_cert.pem:
@@ -142,3 +143,15 @@ class TestES256Signer(object):
assert signer.key_id == SERVICE_ACCOUNT_INFO[base._JSON_FILE_PRIVATE_KEY_ID]
assert isinstance(signer._key, ec.EllipticCurvePrivateKey)
+
+ def test_pickle(self):
+ signer = es256.ES256Signer.from_service_account_file(SERVICE_ACCOUNT_JSON_FILE)
+
+ assert signer.key_id == SERVICE_ACCOUNT_INFO[base._JSON_FILE_PRIVATE_KEY_ID]
+ assert isinstance(signer._key, ec.EllipticCurvePrivateKey)
+
+ pickled_signer = pickle.dumps(signer)
+ signer = pickle.loads(pickled_signer)
+
+ assert signer.key_id == SERVICE_ACCOUNT_INFO[base._JSON_FILE_PRIVATE_KEY_ID]
+ assert isinstance(signer._key, ec.EllipticCurvePrivateKey)
diff --git a/contrib/python/google-auth/py3/tests/data/enterprise_cert_valid_provider.json b/contrib/python/google-auth/py3/tests/data/enterprise_cert_valid_provider.json
new file mode 100644
index 0000000000..9b7adf8bc3
--- /dev/null
+++ b/contrib/python/google-auth/py3/tests/data/enterprise_cert_valid_provider.json
@@ -0,0 +1,6 @@
+{
+ "libs": {
+ "ecp_client": "/path/to/signer/lib",
+ "ecp_provider": "/path/to/provider/lib"
+ }
+}
diff --git a/contrib/python/google-auth/py3/tests/oauth2/test__client.py b/contrib/python/google-auth/py3/tests/oauth2/test__client.py
index 54179269bd..444232f396 100644
--- a/contrib/python/google-auth/py3/tests/oauth2/test__client.py
+++ b/contrib/python/google-auth/py3/tests/oauth2/test__client.py
@@ -29,8 +29,8 @@ from google.auth import transport
from google.oauth2 import _client
-import yatest.common
-DATA_DIR = os.path.join(yatest.common.test_source_path(), "data")
+import yatest.common as yc
+DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "..", "data")
with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh:
PRIVATE_KEY_BYTES = fh.read()
diff --git a/contrib/python/google-auth/py3/tests/oauth2/test_credentials.py b/contrib/python/google-auth/py3/tests/oauth2/test_credentials.py
index f2604a5f18..d6a1915862 100644
--- a/contrib/python/google-auth/py3/tests/oauth2/test_credentials.py
+++ b/contrib/python/google-auth/py3/tests/oauth2/test_credentials.py
@@ -27,8 +27,8 @@ from google.auth import transport
from google.oauth2 import credentials
-import yatest.common
-DATA_DIR = os.path.join(yatest.common.test_source_path(), "data")
+import yatest.common as yc
+DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "..", "data")
AUTH_USER_JSON_FILE = os.path.join(DATA_DIR, "authorized_user.json")
@@ -123,6 +123,17 @@ class TestCredentials(object):
assert excinfo.match("The provided refresh_handler is not a callable or None.")
+ def test_refresh_with_non_default_universe_domain(self):
+ creds = credentials.Credentials(
+ token="token", universe_domain="dummy_universe.com"
+ )
+ with pytest.raises(exceptions.RefreshError) as excinfo:
+ creds.refresh(mock.Mock())
+
+ assert excinfo.match(
+ "refresh is only supported in the default googleapis.com universe domain"
+ )
+
@mock.patch("google.oauth2.reauth.refresh_grant", autospec=True)
@mock.patch(
"google.auth._helpers.utcnow",
@@ -775,6 +786,12 @@ class TestCredentials(object):
creds.apply(headers)
assert "x-goog-user-project" in headers
+ def test_with_universe_domain(self):
+ creds = credentials.Credentials(token="token")
+ assert creds.universe_domain == "googleapis.com"
+ new_creds = creds.with_universe_domain("dummy_universe.com")
+ assert new_creds.universe_domain == "dummy_universe.com"
+
def test_with_token_uri(self):
info = AUTH_USER_INFO.copy()
@@ -869,6 +886,7 @@ class TestCredentials(object):
assert json_asdict.get("scopes") == creds.scopes
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
# Test with a `strip` arg
json_output = creds.to_json(strip=["client_secret"])
@@ -896,6 +914,17 @@ class TestCredentials(object):
for attr in list(creds.__dict__):
assert getattr(creds, attr) == getattr(unpickled, attr)
+ def test_pickle_and_unpickle_universe_domain(self):
+ # old version of auth lib doesn't have _universe_domain, so the pickled
+ # cred doesn't have such a field.
+ creds = self.make_credentials()
+ del creds._universe_domain
+
+ unpickled = pickle.loads(pickle.dumps(creds))
+
+ # make sure the unpickled cred sets _universe_domain to default.
+ assert unpickled.universe_domain == "googleapis.com"
+
def test_pickle_and_unpickle_with_refresh_handler(self):
expected_expiry = _helpers.utcnow() + datetime.timedelta(seconds=2800)
refresh_handler = mock.Mock(return_value=("TOKEN", expected_expiry))
diff --git a/contrib/python/google-auth/py3/tests/oauth2/test_gdch_credentials.py b/contrib/python/google-auth/py3/tests/oauth2/test_gdch_credentials.py
index 1ff61d8683..9a67a07345 100644
--- a/contrib/python/google-auth/py3/tests/oauth2/test_gdch_credentials.py
+++ b/contrib/python/google-auth/py3/tests/oauth2/test_gdch_credentials.py
@@ -27,7 +27,7 @@ import google.auth.transport.requests
from google.oauth2 import gdch_credentials
from google.oauth2.gdch_credentials import ServiceAccountCredentials
-import yatest.common
+import yatest.common as yc
class TestServiceAccountCredentials(object):
@@ -39,7 +39,7 @@ class TestServiceAccountCredentials(object):
TOKEN_URI = "https://service-identity.<Domain>/authenticate"
JSON_PATH = os.path.join(
- yatest.common.test_source_path(), "data", "gdch_service_account.json"
+ os.path.dirname(yc.source_path(__file__)), "..", "data", "gdch_service_account.json"
)
with open(JSON_PATH, "rb") as fh:
INFO = json.load(fh)
diff --git a/contrib/python/google-auth/py3/tests/oauth2/test_id_token.py b/contrib/python/google-auth/py3/tests/oauth2/test_id_token.py
index 861f76ce4f..8657bdfb7e 100644
--- a/contrib/python/google-auth/py3/tests/oauth2/test_id_token.py
+++ b/contrib/python/google-auth/py3/tests/oauth2/test_id_token.py
@@ -24,9 +24,9 @@ from google.auth import transport
from google.oauth2 import id_token
from google.oauth2 import service_account
-import yatest.common
+import yatest.common as yc
SERVICE_ACCOUNT_FILE = os.path.join(
- yatest.common.test_source_path(), "data/service_account.json"
+ os.path.dirname(yc.source_path(__file__)), "../data/service_account.json"
)
ID_TOKEN_AUDIENCE = "https://pubsub.googleapis.com"
@@ -263,7 +263,7 @@ def test_fetch_id_token_credentials_no_cred_exists(monkeypatch):
def test_fetch_id_token_credentials_invalid_cred_file_type(monkeypatch):
user_credentials_file = os.path.join(
- yatest.common.test_source_path(), "data/authorized_user.json"
+ os.path.dirname(yc.source_path(__file__)), "../data/authorized_user.json"
)
monkeypatch.setenv(environment_vars.CREDENTIALS, user_credentials_file)
@@ -276,7 +276,7 @@ def test_fetch_id_token_credentials_invalid_cred_file_type(monkeypatch):
def test_fetch_id_token_credentials_invalid_json(monkeypatch):
- not_json_file = os.path.join(yatest.common.test_source_path(), "data/public_cert.pem")
+ not_json_file = os.path.join(os.path.dirname(yc.source_path(__file__)), "../data/public_cert.pem")
monkeypatch.setenv(environment_vars.CREDENTIALS, not_json_file)
with pytest.raises(exceptions.DefaultCredentialsError) as excinfo:
@@ -287,7 +287,7 @@ def test_fetch_id_token_credentials_invalid_json(monkeypatch):
def test_fetch_id_token_credentials_invalid_cred_path(monkeypatch):
- not_json_file = os.path.join(yatest.common.test_source_path(), "data/not_exists.json")
+ not_json_file = os.path.join(os.path.dirname(yc.source_path(__file__)), "../data/not_exists.json")
monkeypatch.setenv(environment_vars.CREDENTIALS, not_json_file)
with pytest.raises(exceptions.DefaultCredentialsError) as excinfo:
diff --git a/contrib/python/google-auth/py3/tests/oauth2/test_service_account.py b/contrib/python/google-auth/py3/tests/oauth2/test_service_account.py
index c474c90e6b..8dd5f219be 100644
--- a/contrib/python/google-auth/py3/tests/oauth2/test_service_account.py
+++ b/contrib/python/google-auth/py3/tests/oauth2/test_service_account.py
@@ -27,8 +27,8 @@ from google.auth import transport
from google.oauth2 import service_account
-import yatest.common
-DATA_DIR = os.path.join(yatest.common.test_source_path(), "data")
+import yatest.common as yc
+DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "..", "data")
with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh:
PRIVATE_KEY_BYTES = fh.read()
@@ -206,6 +206,17 @@ class TestCredentials(object):
creds_with_new_token_uri = credentials.with_token_uri(new_token_uri)
assert creds_with_new_token_uri._token_uri == new_token_uri
+ def test_with_universe_domain(self):
+ credentials = self.make_credentials()
+
+ new_credentials = credentials.with_universe_domain("dummy_universe.com")
+ assert new_credentials.universe_domain == "dummy_universe.com"
+ assert new_credentials._always_use_jwt_access
+
+ new_credentials = credentials.with_universe_domain("googleapis.com")
+ assert new_credentials.universe_domain == "googleapis.com"
+ assert not new_credentials._always_use_jwt_access
+
def test__with_always_use_jwt_access(self):
credentials = self.make_credentials()
assert not credentials._always_use_jwt_access
@@ -558,12 +569,16 @@ class TestCredentials(object):
assert jwt_grant.called
assert not self_signed_jwt_refresh.called
- def test_refresh_non_gdu_missing_jwt_credentials(self):
- credentials = self.make_credentials(universe_domain="foo")
+ def test_refresh_missing_jwt_credentials(self):
+ credentials = self.make_credentials()
+ credentials = credentials.with_scopes(["foo", "bar"])
+ credentials = credentials.with_always_use_jwt_access(True)
+ assert not credentials._jwt_credentials
- with pytest.raises(exceptions.RefreshError) as excinfo:
- credentials.refresh(None)
- assert excinfo.match("self._jwt_credentials is missing")
+ credentials.refresh(mock.Mock())
+
+ # jwt credentials should have been automatically created with scopes
+ assert credentials._jwt_credentials is not None
def test_refresh_non_gdu_domain_wide_delegation_not_supported(self):
credentials = self.make_credentials(universe_domain="foo")
diff --git a/contrib/python/google-auth/py3/tests/test__cloud_sdk.py b/contrib/python/google-auth/py3/tests/test__cloud_sdk.py
index 18ac18fa35..d46621a7f3 100644
--- a/contrib/python/google-auth/py3/tests/test__cloud_sdk.py
+++ b/contrib/python/google-auth/py3/tests/test__cloud_sdk.py
@@ -26,8 +26,8 @@ from google.auth import environment_vars
from google.auth import exceptions
-import yatest.common
-DATA_DIR = os.path.join(yatest.common.test_source_path(), "data")
+import yatest.common as yc
+DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "data")
AUTHORIZED_USER_FILE = os.path.join(DATA_DIR, "authorized_user.json")
with io.open(AUTHORIZED_USER_FILE, "rb") as fh:
@@ -66,8 +66,7 @@ def test_get_project_id_call_error(check_output):
assert check_output.called
-@pytest.mark.xfail
-def test__run_subprocess_ignore_stderr():
+def _test__run_subprocess_ignore_stderr():
command = [
sys.executable,
"-c",
diff --git a/contrib/python/google-auth/py3/tests/test__default.py b/contrib/python/google-auth/py3/tests/test__default.py
index 29904ec7aa..d619614790 100644
--- a/contrib/python/google-auth/py3/tests/test__default.py
+++ b/contrib/python/google-auth/py3/tests/test__default.py
@@ -36,8 +36,8 @@ from google.oauth2 import service_account
import google.oauth2.credentials
-import yatest.common
-DATA_DIR = os.path.join(yatest.common.test_source_path(), "data")
+import yatest.common as yc
+DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "data")
AUTHORIZED_USER_FILE = os.path.join(DATA_DIR, "authorized_user.json")
with open(AUTHORIZED_USER_FILE) as fh:
diff --git a/contrib/python/google-auth/py3/tests/test__helpers.py b/contrib/python/google-auth/py3/tests/test__helpers.py
index c1f1d812e5..c9a3847ac4 100644
--- a/contrib/python/google-auth/py3/tests/test__helpers.py
+++ b/contrib/python/google-auth/py3/tests/test__helpers.py
@@ -51,6 +51,32 @@ def test_copy_docstring_non_existing():
_helpers.copy_docstring(SourceClass)(func2)
+def test_parse_content_type_plain():
+ assert _helpers.parse_content_type("text/html") == "text/html"
+ assert _helpers.parse_content_type("application/xml") == "application/xml"
+ assert _helpers.parse_content_type("application/json") == "application/json"
+
+
+def test_parse_content_type_with_parameters():
+ content_type_html = "text/html; charset=UTF-8"
+ content_type_xml = "application/xml; charset=UTF-16; version=1.0"
+ content_type_json = "application/json; charset=UTF-8; indent=2"
+ assert _helpers.parse_content_type(content_type_html) == "text/html"
+ assert _helpers.parse_content_type(content_type_xml) == "application/xml"
+ assert _helpers.parse_content_type(content_type_json) == "application/json"
+
+
+def test_parse_content_type_missing_or_broken():
+ content_type_foo = None
+ content_type_bar = ""
+ content_type_baz = "1234"
+ content_type_qux = " ; charset=UTF-8"
+ assert _helpers.parse_content_type(content_type_foo) == "text/plain"
+ assert _helpers.parse_content_type(content_type_bar) == "text/plain"
+ assert _helpers.parse_content_type(content_type_baz) == "text/plain"
+ assert _helpers.parse_content_type(content_type_qux) == "text/plain"
+
+
def test_utcnow():
assert isinstance(_helpers.utcnow(), datetime.datetime)
diff --git a/contrib/python/google-auth/py3/tests/test__oauth2client.py b/contrib/python/google-auth/py3/tests/test__oauth2client.py
index 72db6535bc..1db595fd9a 100644
--- a/contrib/python/google-auth/py3/tests/test__oauth2client.py
+++ b/contrib/python/google-auth/py3/tests/test__oauth2client.py
@@ -33,8 +33,8 @@ except ImportError: # pragma: NO COVER
from google.auth import _oauth2client
-import yatest.common
-DATA_DIR = os.path.join(yatest.common.test_source_path(), "data")
+import yatest.common as yc
+DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "data")
SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, "service_account.json")
diff --git a/contrib/python/google-auth/py3/tests/test__service_account_info.py b/contrib/python/google-auth/py3/tests/test__service_account_info.py
index db8106081c..2335765bb4 100644
--- a/contrib/python/google-auth/py3/tests/test__service_account_info.py
+++ b/contrib/python/google-auth/py3/tests/test__service_account_info.py
@@ -21,8 +21,8 @@ from google.auth import _service_account_info
from google.auth import crypt
-import yatest.common
-DATA_DIR = os.path.join(yatest.common.test_source_path(), "data")
+import yatest.common as yc
+DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "data")
SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, "service_account.json")
GDCH_SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, "gdch_service_account.json")
diff --git a/contrib/python/google-auth/py3/tests/test_aws.py b/contrib/python/google-auth/py3/tests/test_aws.py
index 39138ab12e..db2e984100 100644
--- a/contrib/python/google-auth/py3/tests/test_aws.py
+++ b/contrib/python/google-auth/py3/tests/test_aws.py
@@ -1969,7 +1969,7 @@ class TestCredentials(object):
"authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]),
"x-goog-user-project": QUOTA_PROJECT_ID,
"x-goog-api-client": IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE,
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
impersonation_request_data = {
"delegates": None,
@@ -2066,7 +2066,7 @@ class TestCredentials(object):
"authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]),
"x-goog-user-project": QUOTA_PROJECT_ID,
"x-goog-api-client": IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE,
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
impersonation_request_data = {
"delegates": None,
diff --git a/contrib/python/google-auth/py3/tests/test_credentials.py b/contrib/python/google-auth/py3/tests/test_credentials.py
index 99235cda61..d64f3abb50 100644
--- a/contrib/python/google-auth/py3/tests/test_credentials.py
+++ b/contrib/python/google-auth/py3/tests/test_credentials.py
@@ -55,9 +55,7 @@ def test_expired_and_valid():
# Set the expiration to one second more than now plus the clock skew
# accomodation. These credentials should be valid.
credentials.expiry = (
- datetime.datetime.utcnow()
- + _helpers.REFRESH_THRESHOLD
- + datetime.timedelta(seconds=1)
+ _helpers.utcnow() + _helpers.REFRESH_THRESHOLD + datetime.timedelta(seconds=1)
)
assert credentials.valid
@@ -65,7 +63,7 @@ def test_expired_and_valid():
# Set the credentials expiration to now. Because of the clock skew
# accomodation, these credentials should report as expired.
- credentials.expiry = datetime.datetime.utcnow()
+ credentials.expiry = _helpers.utcnow()
assert not credentials.valid
assert credentials.expired
@@ -81,7 +79,7 @@ def test_before_request():
assert credentials.valid
assert credentials.token == "token"
assert headers["authorization"] == "Bearer token"
- assert "x-identity-trust-boundary" not in headers
+ assert "x-allowed-locations" not in headers
request = "token2"
headers = {}
@@ -91,13 +89,13 @@ def test_before_request():
assert credentials.valid
assert credentials.token == "token"
assert headers["authorization"] == "Bearer token"
- assert "x-identity-trust-boundary" not in headers
+ assert "x-allowed-locations" not in headers
def test_before_request_with_trust_boundary():
- DUMMY_BOUNDARY = "00110101"
+ DUMMY_BOUNDARY = "0xA30"
credentials = CredentialsImpl()
- credentials._trust_boundary = DUMMY_BOUNDARY
+ credentials._trust_boundary = {"locations": [], "encoded_locations": DUMMY_BOUNDARY}
request = "token"
headers = {}
@@ -106,7 +104,7 @@ def test_before_request_with_trust_boundary():
assert credentials.valid
assert credentials.token == "token"
assert headers["authorization"] == "Bearer token"
- assert headers["x-identity-trust-boundary"] == DUMMY_BOUNDARY
+ assert headers["x-allowed-locations"] == DUMMY_BOUNDARY
request = "token2"
headers = {}
@@ -116,7 +114,7 @@ def test_before_request_with_trust_boundary():
assert credentials.valid
assert credentials.token == "token"
assert headers["authorization"] == "Bearer token"
- assert headers["x-identity-trust-boundary"] == DUMMY_BOUNDARY
+ assert headers["x-allowed-locations"] == DUMMY_BOUNDARY
def test_before_request_metrics():
diff --git a/contrib/python/google-auth/py3/tests/test_external_account.py b/contrib/python/google-auth/py3/tests/test_external_account.py
index 0b165bc70b..5225dcf342 100644
--- a/contrib/python/google-auth/py3/tests/test_external_account.py
+++ b/contrib/python/google-auth/py3/tests/test_external_account.py
@@ -505,6 +505,11 @@ class TestCredentials(object):
credentials = self.make_credentials()
assert credentials.universe_domain == external_account._DEFAULT_UNIVERSE_DOMAIN
+ def test_with_universe_domain(self):
+ credentials = self.make_credentials()
+ new_credentials = credentials.with_universe_domain("dummy_universe.com")
+ assert new_credentials.universe_domain == "dummy_universe.com"
+
def test_info_workforce_pool(self):
credentials = self.make_workforce_pool_credentials(
workforce_pool_user_project=self.WORKFORCE_POOL_USER_PROJECT
@@ -833,7 +838,7 @@ class TestCredentials(object):
"Content-Type": "application/json",
"authorization": "Bearer {}".format(token_response["access_token"]),
"x-goog-api-client": IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE,
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
impersonation_request_data = {
"delegates": None,
@@ -915,7 +920,7 @@ class TestCredentials(object):
"Content-Type": "application/json",
"authorization": "Bearer {}".format(token_response["access_token"]),
"x-goog-api-client": IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE,
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
impersonation_request_data = {
"delegates": None,
@@ -1134,7 +1139,7 @@ class TestCredentials(object):
"Content-Type": "application/json",
"authorization": "Bearer {}".format(token_response["access_token"]),
"x-goog-api-client": IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE,
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
impersonation_request_data = {
"delegates": None,
@@ -1218,7 +1223,7 @@ class TestCredentials(object):
"Content-Type": "application/json",
"authorization": "Bearer {}".format(token_response["access_token"]),
"x-goog-api-client": IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE,
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
impersonation_request_data = {
"delegates": None,
@@ -1274,7 +1279,7 @@ class TestCredentials(object):
assert headers == {
"authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]),
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
def test_apply_workforce_without_quota_project_id(self):
@@ -1291,7 +1296,7 @@ class TestCredentials(object):
assert headers == {
"authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]),
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
def test_apply_impersonation_without_quota_project_id(self):
@@ -1323,7 +1328,7 @@ class TestCredentials(object):
assert headers == {
"authorization": "Bearer {}".format(impersonation_response["accessToken"]),
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
def test_apply_with_quota_project_id(self):
@@ -1340,7 +1345,7 @@ class TestCredentials(object):
"other": "header-value",
"authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]),
"x-goog-user-project": self.QUOTA_PROJECT_ID,
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
def test_apply_impersonation_with_quota_project_id(self):
@@ -1375,7 +1380,7 @@ class TestCredentials(object):
"other": "header-value",
"authorization": "Bearer {}".format(impersonation_response["accessToken"]),
"x-goog-user-project": self.QUOTA_PROJECT_ID,
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
def test_before_request(self):
@@ -1391,7 +1396,7 @@ class TestCredentials(object):
assert headers == {
"other": "header-value",
"authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]),
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
# Second call shouldn't call refresh.
@@ -1400,7 +1405,7 @@ class TestCredentials(object):
assert headers == {
"other": "header-value",
"authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]),
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
def test_before_request_workforce(self):
@@ -1418,7 +1423,7 @@ class TestCredentials(object):
assert headers == {
"other": "header-value",
"authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]),
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
# Second call shouldn't call refresh.
@@ -1427,7 +1432,7 @@ class TestCredentials(object):
assert headers == {
"other": "header-value",
"authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]),
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
def test_before_request_impersonation(self):
@@ -1458,7 +1463,7 @@ class TestCredentials(object):
assert headers == {
"other": "header-value",
"authorization": "Bearer {}".format(impersonation_response["accessToken"]),
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
# Second call shouldn't call refresh.
@@ -1467,7 +1472,7 @@ class TestCredentials(object):
assert headers == {
"other": "header-value",
"authorization": "Bearer {}".format(impersonation_response["accessToken"]),
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
@mock.patch("google.auth._helpers.utcnow")
@@ -1495,7 +1500,7 @@ class TestCredentials(object):
# Cached token should be used.
assert headers == {
"authorization": "Bearer token",
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
# Next call should simulate 1 second passed.
@@ -1509,7 +1514,7 @@ class TestCredentials(object):
# New token should be retrieved.
assert headers == {
"authorization": "Bearer {}".format(self.SUCCESS_RESPONSE["access_token"]),
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
@mock.patch("google.auth._helpers.utcnow")
@@ -1552,7 +1557,7 @@ class TestCredentials(object):
# Cached token should be used.
assert headers == {
"authorization": "Bearer token",
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
# Next call should simulate 1 second passed. This will trigger the expiration
@@ -1567,7 +1572,7 @@ class TestCredentials(object):
# New token should be retrieved.
assert headers == {
"authorization": "Bearer {}".format(impersonation_response["accessToken"]),
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
@pytest.mark.parametrize(
@@ -1666,7 +1671,7 @@ class TestCredentials(object):
"x-goog-user-project": self.QUOTA_PROJECT_ID,
"authorization": "Bearer {}".format(token_response["access_token"]),
"x-goog-api-client": IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE,
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
impersonation_request_data = {
"delegates": None,
@@ -1720,7 +1725,7 @@ class TestCredentials(object):
"authorization": "Bearer {}".format(
impersonation_response["accessToken"]
),
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
},
)
@@ -1792,7 +1797,7 @@ class TestCredentials(object):
"authorization": "Bearer {}".format(
self.SUCCESS_RESPONSE["access_token"]
),
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
},
)
@@ -1842,7 +1847,7 @@ class TestCredentials(object):
"Content-Type": "application/json",
"authorization": "Bearer {}".format(token_response["access_token"]),
"x-goog-api-client": IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE,
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
impersonation_request_data = {
"delegates": None,
diff --git a/contrib/python/google-auth/py3/tests/test_identity_pool.py b/contrib/python/google-auth/py3/tests/test_identity_pool.py
index d126a579bd..2d10a5d268 100644
--- a/contrib/python/google-auth/py3/tests/test_identity_pool.py
+++ b/contrib/python/google-auth/py3/tests/test_identity_pool.py
@@ -45,8 +45,8 @@ SERVICE_ACCOUNT_IMPERSONATION_URL = (
QUOTA_PROJECT_ID = "QUOTA_PROJECT_ID"
SCOPES = ["scope1", "scope2"]
-import yatest.common
-DATA_DIR = os.path.join(yatest.common.test_source_path(), "data")
+import yatest.common as yc
+DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "data")
SUBJECT_TOKEN_TEXT_FILE = os.path.join(DATA_DIR, "external_subject_token.txt")
SUBJECT_TOKEN_JSON_FILE = os.path.join(DATA_DIR, "external_subject_token.json")
SUBJECT_TOKEN_FIELD_NAME = "access_token"
@@ -320,7 +320,7 @@ class TestCredentials(object):
"Content-Type": "application/json",
"authorization": "Bearer {}".format(token_response["access_token"]),
"x-goog-api-client": metrics_header_value,
- "x-identity-trust-boundary": "0",
+ "x-allowed-locations": "0x0",
}
impersonation_request_data = {
"delegates": None,
diff --git a/contrib/python/google-auth/py3/tests/test_impersonated_credentials.py b/contrib/python/google-auth/py3/tests/test_impersonated_credentials.py
index d63d2d5d3b..9696e823ff 100644
--- a/contrib/python/google-auth/py3/tests/test_impersonated_credentials.py
+++ b/contrib/python/google-auth/py3/tests/test_impersonated_credentials.py
@@ -29,8 +29,8 @@ from google.auth.impersonated_credentials import Credentials
from google.oauth2 import credentials
from google.oauth2 import service_account
-import yatest.common
-DATA_DIR = os.path.join(yatest.common.test_source_path(), "data")
+import yatest.common as yc
+DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "data")
with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh:
PRIVATE_KEY_BYTES = fh.read()
diff --git a/contrib/python/google-auth/py3/tests/test_jwt.py b/contrib/python/google-auth/py3/tests/test_jwt.py
index 62f310606d..ff8fd67da6 100644
--- a/contrib/python/google-auth/py3/tests/test_jwt.py
+++ b/contrib/python/google-auth/py3/tests/test_jwt.py
@@ -26,8 +26,8 @@ from google.auth import exceptions
from google.auth import jwt
-import yatest.common
-DATA_DIR = os.path.join(yatest.common.test_source_path(), "data")
+import yatest.common as yc
+DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "data")
with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh:
PRIVATE_KEY_BYTES = fh.read()
diff --git a/contrib/python/google-auth/py3/tests/transport/test__custom_tls_signer.py b/contrib/python/google-auth/py3/tests/transport/test__custom_tls_signer.py
index 5836b325ad..d2907bad29 100644
--- a/contrib/python/google-auth/py3/tests/transport/test__custom_tls_signer.py
+++ b/contrib/python/google-auth/py3/tests/transport/test__custom_tls_signer.py
@@ -11,7 +11,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-
import base64
import ctypes
import os
@@ -30,11 +29,19 @@ FAKE_ENTERPRISE_CERT_FILE_PATH = "/path/to/enterprise/cert/file"
ENTERPRISE_CERT_FILE = os.path.join(
os.path.dirname(__file__), "../data/enterprise_cert_valid.json"
)
+ENTERPRISE_CERT_FILE_PROVIDER = os.path.join(
+ os.path.dirname(__file__), "../data/enterprise_cert_valid_provider.json"
+)
INVALID_ENTERPRISE_CERT_FILE = os.path.join(
os.path.dirname(__file__), "../data/enterprise_cert_invalid.json"
)
+def test_load_provider_lib():
+ with mock.patch("ctypes.CDLL", return_value=mock.MagicMock()):
+ _custom_tls_signer.load_provider_lib("/path/to/provider/lib")
+
+
def test_load_offload_lib():
with mock.patch("ctypes.CDLL", return_value=mock.MagicMock()):
lib = _custom_tls_signer.load_offload_lib("/path/to/offload/lib")
@@ -173,62 +180,81 @@ def test_custom_tls_signer():
) as load_offload_lib:
load_offload_lib.return_value = offload_lib
load_signer_lib.return_value = signer_lib
- signer_object = _custom_tls_signer.CustomTlsSigner(ENTERPRISE_CERT_FILE)
- signer_object.load_libraries()
- assert signer_object._cert is None
+ with mock.patch(
+ "google.auth.transport._custom_tls_signer.get_cert"
+ ) as get_cert:
+ with mock.patch(
+ "google.auth.transport._custom_tls_signer.get_sign_callback"
+ ) as get_sign_callback:
+ get_cert.return_value = b"mock_cert"
+ signer_object = _custom_tls_signer.CustomTlsSigner(
+ ENTERPRISE_CERT_FILE
+ )
+ signer_object.load_libraries()
+ signer_object.attach_to_ssl_context(create_urllib3_context())
+ get_cert.assert_called_once()
+ get_sign_callback.assert_called_once()
+ offload_lib.ConfigureSslContext.assert_called_once()
assert signer_object._enterprise_cert_file_path == ENTERPRISE_CERT_FILE
assert signer_object._offload_lib == offload_lib
assert signer_object._signer_lib == signer_lib
load_signer_lib.assert_called_with("/path/to/signer/lib")
load_offload_lib.assert_called_with("/path/to/offload/lib")
- # Test set_up_custom_key and set_up_ssl_context methods
- with mock.patch("google.auth.transport._custom_tls_signer.get_cert") as get_cert:
- with mock.patch(
- "google.auth.transport._custom_tls_signer.get_sign_callback"
- ) as get_sign_callback:
- get_cert.return_value = b"mock_cert"
- signer_object.set_up_custom_key()
- signer_object.attach_to_ssl_context(create_urllib3_context())
- get_cert.assert_called_once()
- get_sign_callback.assert_called_once()
- offload_lib.ConfigureSslContext.assert_called_once()
+def test_custom_tls_signer_provider():
+ provider_lib = mock.MagicMock()
-def test_custom_tls_signer_failed_to_load_libraries():
# Test load_libraries method
+ with mock.patch(
+ "google.auth.transport._custom_tls_signer.load_provider_lib"
+ ) as load_provider_lib:
+ load_provider_lib.return_value = provider_lib
+ signer_object = _custom_tls_signer.CustomTlsSigner(
+ ENTERPRISE_CERT_FILE_PROVIDER
+ )
+ signer_object.load_libraries()
+ signer_object.attach_to_ssl_context(mock.MagicMock())
+
+ assert signer_object._enterprise_cert_file_path == ENTERPRISE_CERT_FILE_PROVIDER
+ assert signer_object._provider_lib == provider_lib
+ load_provider_lib.assert_called_with("/path/to/provider/lib")
+
+
+def test_custom_tls_signer_failed_to_load_libraries():
with pytest.raises(exceptions.MutualTLSChannelError) as excinfo:
signer_object = _custom_tls_signer.CustomTlsSigner(INVALID_ENTERPRISE_CERT_FILE)
signer_object.load_libraries()
assert excinfo.match("enterprise cert file is invalid")
-def test_custom_tls_signer_fail_to_offload():
- offload_lib = mock.MagicMock()
- signer_lib = mock.MagicMock()
+def test_custom_tls_signer_failed_to_attach():
+ with pytest.raises(exceptions.MutualTLSChannelError) as excinfo:
+ signer_object = _custom_tls_signer.CustomTlsSigner(ENTERPRISE_CERT_FILE)
+ signer_object._offload_lib = mock.MagicMock()
+ signer_object._signer_lib = mock.MagicMock()
+ signer_object._sign_callback = mock.MagicMock()
+ signer_object._cert = b"mock cert"
+ signer_object._offload_lib.ConfigureSslContext.return_value = False
+ signer_object.attach_to_ssl_context(mock.MagicMock())
+ assert excinfo.match("failed to configure ECP Offload SSL context")
- with mock.patch(
- "google.auth.transport._custom_tls_signer.load_signer_lib"
- ) as load_signer_lib:
- with mock.patch(
- "google.auth.transport._custom_tls_signer.load_offload_lib"
- ) as load_offload_lib:
- load_offload_lib.return_value = offload_lib
- load_signer_lib.return_value = signer_lib
- signer_object = _custom_tls_signer.CustomTlsSigner(ENTERPRISE_CERT_FILE)
- signer_object.load_libraries()
- # set the return value to be 0 which indicts offload fails
- offload_lib.ConfigureSslContext.return_value = 0
+def test_custom_tls_signer_failed_to_attach_provider():
+ with pytest.raises(exceptions.MutualTLSChannelError) as excinfo:
+ signer_object = _custom_tls_signer.CustomTlsSigner(
+ ENTERPRISE_CERT_FILE_PROVIDER
+ )
+ signer_object._provider_lib = mock.MagicMock()
+ signer_object._provider_lib.ECP_attach_to_ctx.return_value = False
+ signer_object.attach_to_ssl_context(mock.MagicMock())
+ assert excinfo.match("failed to configure ECP Provider SSL context")
+
+def test_custom_tls_signer_failed_to_attach_no_libs():
with pytest.raises(exceptions.MutualTLSChannelError) as excinfo:
- with mock.patch(
- "google.auth.transport._custom_tls_signer.get_cert"
- ) as get_cert:
- with mock.patch(
- "google.auth.transport._custom_tls_signer.get_sign_callback"
- ):
- get_cert.return_value = b"mock_cert"
- signer_object.set_up_custom_key()
- signer_object.attach_to_ssl_context(create_urllib3_context())
- assert excinfo.match("failed to configure SSL context")
+ signer_object = _custom_tls_signer.CustomTlsSigner(ENTERPRISE_CERT_FILE)
+ signer_object._offload_lib = None
+ signer_object._signer_lib = None
+ signer_object.attach_to_ssl_context(mock.MagicMock())
+ assert excinfo.match("Invalid ECP configuration.")
diff --git a/contrib/python/google-auth/py3/tests/transport/test__mtls_helper.py b/contrib/python/google-auth/py3/tests/transport/test__mtls_helper.py
index 642283a5c5..1621a05302 100644
--- a/contrib/python/google-auth/py3/tests/transport/test__mtls_helper.py
+++ b/contrib/python/google-auth/py3/tests/transport/test__mtls_helper.py
@@ -22,9 +22,6 @@ import pytest # type: ignore
from google.auth import exceptions
from google.auth.transport import _mtls_helper
-import yatest.common
-DATA_DIR = os.path.join(yatest.common.test_source_path(), "data")
-
CONTEXT_AWARE_METADATA = {"cert_provider_command": ["some command"]}
ENCRYPTED_EC_PRIVATE_KEY = b"""-----BEGIN ENCRYPTED PRIVATE KEY-----
@@ -116,26 +113,26 @@ class TestCertAndKeyRegex(object):
class TestCheckaMetadataPath(object):
def test_success(self):
- metadata_path = os.path.join(DATA_DIR, "context_aware_metadata.json")
+ metadata_path = os.path.join(pytest.data_dir, "context_aware_metadata.json")
returned_path = _mtls_helper._check_dca_metadata_path(metadata_path)
assert returned_path is not None
def test_failure(self):
- metadata_path = os.path.join(DATA_DIR, "not_exists.json")
+ metadata_path = os.path.join(pytest.data_dir, "not_exists.json")
returned_path = _mtls_helper._check_dca_metadata_path(metadata_path)
assert returned_path is None
class TestReadMetadataFile(object):
def test_success(self):
- metadata_path = os.path.join(DATA_DIR, "context_aware_metadata.json")
+ metadata_path = os.path.join(pytest.data_dir, "context_aware_metadata.json")
metadata = _mtls_helper._read_dca_metadata_file(metadata_path)
assert "cert_provider_command" in metadata
def test_file_not_json(self):
# read a file which is not json format.
- metadata_path = os.path.join(DATA_DIR, "privatekey.pem")
+ metadata_path = os.path.join(pytest.data_dir, "privatekey.pem")
with pytest.raises(exceptions.ClientCertError):
_mtls_helper._read_dca_metadata_file(metadata_path)
diff --git a/contrib/python/google-auth/py3/tests/transport/test_grpc.py b/contrib/python/google-auth/py3/tests/transport/test_grpc.py
index 05dc5fad0e..29fae4cdf6 100644
--- a/contrib/python/google-auth/py3/tests/transport/test_grpc.py
+++ b/contrib/python/google-auth/py3/tests/transport/test_grpc.py
@@ -35,8 +35,8 @@ try:
except ImportError: # pragma: NO COVER
HAS_GRPC = False
-import yatest.common
-DATA_DIR = os.path.join(yatest.common.test_source_path(), "data")
+import yatest.common as yc
+DATA_DIR = os.path.join(os.path.dirname(yc.source_path(__file__)), "..", "data")
METADATA_PATH = os.path.join(DATA_DIR, "context_aware_metadata.json")
with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh:
PRIVATE_KEY_BYTES = fh.read()
diff --git a/contrib/python/google-auth/py3/tests/transport/test_requests.py b/contrib/python/google-auth/py3/tests/transport/test_requests.py
index d962814346..aadc1ddbfd 100644
--- a/contrib/python/google-auth/py3/tests/transport/test_requests.py
+++ b/contrib/python/google-auth/py3/tests/transport/test_requests.py
@@ -545,16 +545,12 @@ class TestMutualTlsOffloadAdapter(object):
google.auth.transport._custom_tls_signer.CustomTlsSigner, "load_libraries"
)
@mock.patch.object(
- google.auth.transport._custom_tls_signer.CustomTlsSigner, "set_up_custom_key"
- )
- @mock.patch.object(
google.auth.transport._custom_tls_signer.CustomTlsSigner,
"attach_to_ssl_context",
)
def test_success(
self,
mock_attach_to_ssl_context,
- mock_set_up_custom_key,
mock_load_libraries,
mock_proxy_manager_for,
mock_init_poolmanager,
@@ -565,7 +561,6 @@ class TestMutualTlsOffloadAdapter(object):
)
mock_load_libraries.assert_called_once()
- mock_set_up_custom_key.assert_called_once()
assert mock_attach_to_ssl_context.call_count == 2
adapter.init_poolmanager()
diff --git a/contrib/python/google-auth/py3/tests/ya.make b/contrib/python/google-auth/py3/tests/ya.make
index e7a1b3b272..dfcabf5bfb 100644
--- a/contrib/python/google-auth/py3/tests/ya.make
+++ b/contrib/python/google-auth/py3/tests/ya.make
@@ -67,11 +67,6 @@ TEST_SRCS(
# transport/test_urllib3.py
)
-RESOURCE(
- data/privatekey.pem data/privatekey.pem
- data/public_cert.pem data/public_cert.pem
-)
-
NO_LINT()
END()
diff --git a/contrib/python/google-auth/py3/ya.make b/contrib/python/google-auth/py3/ya.make
index 77b6e5f741..ec71907cc6 100644
--- a/contrib/python/google-auth/py3/ya.make
+++ b/contrib/python/google-auth/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(2.23.0)
+VERSION(2.25.2)
LICENSE(Apache-2.0)
@@ -10,10 +10,10 @@ PEERDIR(
contrib/python/cachetools
contrib/python/cryptography
contrib/python/grpcio
+ contrib/python/packaging
contrib/python/pyasn1-modules
contrib/python/requests
contrib/python/rsa
- contrib/python/urllib3
)
NO_LINT()