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 2022-06-09 14:09:24 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-google-auth (Old) and /work/SRC/openSUSE:Factory/.python-google-auth.new.1548 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-google-auth" Thu Jun 9 14:09:24 2022 rev:20 rq:981276 version:2.7.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-google-auth/python-google-auth.changes 2022-06-06 11:10:15.771285073 +0200 +++ /work/SRC/openSUSE:Factory/.python-google-auth.new.1548/python-google-auth.changes 2022-06-09 14:09:32.484346933 +0200 @@ -1,0 +2,22 @@ +Wed Jun 8 08:53:02 UTC 2022 - pgaj...@suse.com + +- version update to 2.7.0 + ## [2.7.0] + * add experimental enterprise cert support + * add experimental GDCH support + * Pluggable auth support + * validate urls for external accounts + * pluggable auth support [#995] + * revert experimental GDCH support + * fix changelog header to consistent size + ## [2.6.6] + * silence TypeError during tear down stage + ## [2.6.5] + * add additional missing import in _default.py + ## [2.6.4] + * fix missing import in _default.py +- added patches + fix https://github.com/googleapis/google-auth-library-python/issues/1055 + + python-google-auth-no-mock.patch + +------------------------------------------------------------------- Old: ---- google-auth-2.6.6.tar.gz New: ---- google-auth-2.7.0.tar.gz python-google-auth-no-mock.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-google-auth.spec ++++++ --- /var/tmp/diff_new_pack.MwljlN/_old 2022-06-09 14:09:33.032347667 +0200 +++ /var/tmp/diff_new_pack.MwljlN/_new 2022-06-09 14:09:33.036347673 +0200 @@ -19,19 +19,20 @@ %define skip_python2 1 %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-google-auth -Version: 2.6.6 +Version: 2.7.0 Release: 0 Summary: Google Authentication Library License: Apache-2.0 URL: https://github.com/googleapis/google-auth-library-python Source: https://files.pythonhosted.org/packages/source/g/google-auth/google-auth-%{version}.tar.gz Patch0: ga_python-executable-name.patch +# https://github.com/googleapis/google-auth-library-python/issues/1055 +Patch1: python-google-auth-no-mock.patch BuildRequires: %{python_module Flask} # START TESTING SECTION BuildRequires: %{python_module aiohttp >= 3.6.2} BuildRequires: %{python_module cachetools >= 2.0.0} BuildRequires: %{python_module freezegun} -BuildRequires: %{python_module mock} BuildRequires: %{python_module pyOpenSSL >= 20.0.0} BuildRequires: %{python_module pyasn1-modules >= 0.2.1} BuildRequires: %{python_module pytest-localserver} @@ -64,6 +65,7 @@ %prep %setup -q -n google-auth-%{version} %patch0 -p1 +%patch1 -p1 %build %python_build ++++++ google-auth-2.6.6.tar.gz -> google-auth-2.7.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.6.6/PKG-INFO new/google-auth-2.7.0/PKG-INFO --- old/google-auth-2.6.6/PKG-INFO 2022-04-22 01:30:09.619063000 +0200 +++ new/google-auth-2.7.0/PKG-INFO 2022-06-07 23:30:54.583676000 +0200 @@ -1,13 +1,12 @@ Metadata-Version: 2.1 Name: google-auth -Version: 2.6.6 +Version: 2.7.0 Summary: Google Authentication Library Home-page: https://github.com/googleapis/google-auth-library-python Author: Google Cloud Platform Author-email: googleapis-packa...@google.com License: Apache 2.0 Keywords: google auth oauth client -Platform: UNKNOWN Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 @@ -26,6 +25,7 @@ Provides-Extra: aiohttp Provides-Extra: pyopenssl Provides-Extra: reauth +Provides-Extra: enterprise_cert License-File: LICENSE Google Auth Python Library @@ -95,5 +95,3 @@ Apache 2.0 - See `the LICENSE`_ for more information. .. _the LICENSE: https://github.com/googleapis/google-auth-library-python/blob/main/LICENSE - - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.6.6/google/auth/credentials.py new/google-auth-2.7.0/google/auth/credentials.py --- old/google-auth-2.6.6/google/auth/credentials.py 2022-04-22 01:27:38.000000000 +0200 +++ new/google-auth-2.7.0/google/auth/credentials.py 2022-06-07 23:28:22.000000000 +0200 @@ -63,7 +63,7 @@ if not self.expiry: return False - # Remove 10 seconds from expiry to err on the side of reporting + # Remove some threshold from expiry to err on the side of reporting # expiration early so that we avoid the 401-refresh-retry loop. skewed_expiry = self.expiry - _helpers.REFRESH_THRESHOLD return _helpers.utcnow() >= skewed_expiry diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.6.6/google/auth/external_account.py new/google-auth-2.7.0/google/auth/external_account.py --- old/google-auth-2.6.6/google/auth/external_account.py 2022-04-22 01:27:38.000000000 +0200 +++ new/google-auth-2.7.0/google/auth/external_account.py 2022-06-07 23:28:22.000000000 +0200 @@ -34,6 +34,7 @@ import re import six +from urllib3.util import parse_url from google.auth import _helpers from google.auth import credentials @@ -114,6 +115,12 @@ self._default_scopes = default_scopes self._workforce_pool_user_project = workforce_pool_user_project + Credentials.validate_token_url(token_url) + if service_account_impersonation_url: + Credentials.validate_service_account_impersonation_url( + service_account_impersonation_url + ) + if self._client_id: self._client_auth = utils.ClientAuthentication( utils.ClientAuthType.basic, self._client_id, self._client_secret @@ -413,3 +420,51 @@ quota_project_id=self._quota_project_id, iam_endpoint_override=self._service_account_impersonation_url, ) + + @staticmethod + def validate_token_url(token_url): + _TOKEN_URL_PATTERNS = [ + "^[^\\.\\s\\/\\\\]+\\.sts\\.googleapis\\.com$", + "^sts\\.googleapis\\.com$", + "^sts\\.[^\\.\\s\\/\\\\]+\\.googleapis\\.com$", + "^[^\\.\\s\\/\\\\]+\\-sts\\.googleapis\\.com$", + ] + + if not Credentials.is_valid_url(_TOKEN_URL_PATTERNS, token_url): + raise ValueError("The provided token URL is invalid.") + + @staticmethod + def validate_service_account_impersonation_url(url): + _SERVICE_ACCOUNT_IMPERSONATION_URL_PATTERNS = [ + "^[^\\.\\s\\/\\\\]+\\.iamcredentials\\.googleapis\\.com$", + "^iamcredentials\\.googleapis\\.com$", + "^iamcredentials\\.[^\\.\\s\\/\\\\]+\\.googleapis\\.com$", + "^[^\\.\\s\\/\\\\]+\\-iamcredentials\\.googleapis\\.com$", + ] + + if not Credentials.is_valid_url( + _SERVICE_ACCOUNT_IMPERSONATION_URL_PATTERNS, url + ): + raise ValueError( + "The provided service account impersonation URL is invalid." + ) + + @staticmethod + def is_valid_url(patterns, url): + """ + Returns True if the provided URL's scheme is HTTPS and the host comforms to at least one of the provided patterns. + """ + # Check specifically for whitespcaces: + # Some python3.6 will parse the space character into %20 and pass the regex check which shouldn't be passed + if not url or len(str(url).split()) > 1: + return False + + try: + uri = parse_url(url) + except Exception: + return False + + if not uri.scheme or uri.scheme != "https" or not uri.hostname: + return False + + return any(re.compile(p).match(uri.hostname.lower()) for p in patterns) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.6.6/google/auth/transport/_custom_tls_signer.py new/google-auth-2.7.0/google/auth/transport/_custom_tls_signer.py --- old/google-auth-2.6.6/google/auth/transport/_custom_tls_signer.py 1970-01-01 01:00:00.000000000 +0100 +++ new/google-auth-2.7.0/google/auth/transport/_custom_tls_signer.py 2022-06-07 23:28:22.000000000 +0200 @@ -0,0 +1,235 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# 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. + +""" +Code for configuring client side TLS to offload the signing operation to +signing libraries. +""" + +import ctypes +import json +import logging +import os +import sys + +import cffi # type: ignore +import six + +from google.auth import exceptions + +_LOGGER = logging.getLogger(__name__) + +# C++ offload lib requires google-auth lib to provide the following callback: +# using SignFunc = int (*)(unsigned char *sig, size_t *sig_len, +# const unsigned char *tbs, size_t tbs_len) +# The bytes to be signed and the length are provided via `tbs` and `tbs_len`, +# the callback computes the signature, and write the signature and its length +# into `sig` and `sig_len`. +# If the signing is successful, the callback returns 1, otherwise it returns 0. +SIGN_CALLBACK_CTYPE = ctypes.CFUNCTYPE( + ctypes.c_int, # return type + ctypes.POINTER(ctypes.c_ubyte), # sig + ctypes.POINTER(ctypes.c_size_t), # sig_len + ctypes.POINTER(ctypes.c_ubyte), # tbs + ctypes.c_size_t, # tbs_len +) + + +# Cast SSL_CTX* to void* +def _cast_ssl_ctx_to_void_p(ssl_ctx): + return ctypes.cast(int(cffi.FFI().cast("intptr_t", ssl_ctx)), ctypes.c_void_p) + + +# Load offload library and set up the function types. +def load_offload_lib(offload_lib_path): + _LOGGER.debug("loading offload library from %s", offload_lib_path) + + # winmode parameter is only available for python 3.8+. + lib = ( + ctypes.CDLL(offload_lib_path, winmode=0) + if sys.version_info >= (3, 8) and os.name == "nt" + else ctypes.CDLL(offload_lib_path) + ) + + # Set up types for: + # int ConfigureSslContext(SignFunc sign_func, const char *cert, SSL_CTX *ctx) + lib.ConfigureSslContext.argtypes = [ + SIGN_CALLBACK_CTYPE, + ctypes.c_char_p, + ctypes.c_void_p, + ] + lib.ConfigureSslContext.restype = ctypes.c_int + + return lib + + +# Load signer library and set up the function types. +# See: https://github.com/googleapis/enterprise-certificate-proxy/blob/main/cshared/main.go +def load_signer_lib(signer_lib_path): + _LOGGER.debug("loading signer library from %s", signer_lib_path) + + # winmode parameter is only available for python 3.8+. + lib = ( + ctypes.CDLL(signer_lib_path, winmode=0) + if sys.version_info >= (3, 8) and os.name == "nt" + else ctypes.CDLL(signer_lib_path) + ) + + # Set up types for: + # func GetCertPemForPython(configFilePath *C.char, certHolder *byte, certHolderLen int) + lib.GetCertPemForPython.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_int] + # Returns: certLen + lib.GetCertPemForPython.restype = ctypes.c_int + + # Set up types for: + # func SignForPython(configFilePath *C.char, digest *byte, digestLen int, + # sigHolder *byte, sigHolderLen int) + lib.SignForPython.argtypes = [ + ctypes.c_char_p, + ctypes.c_char_p, + ctypes.c_int, + ctypes.c_char_p, + ctypes.c_int, + ] + # Returns: the signature length + lib.SignForPython.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 + + data = ctypes.string_at(to_be_signed, to_be_signed_len) + hash = hashes.Hash(hashes.SHA256()) + hash.update(data) + return hash.finalize() + + +# Create the signing callback. The actual signing work is done by the +# `SignForPython` method from the signer lib. +def get_sign_callback(signer_lib, config_file_path): + def sign_callback(sig, sig_len, tbs, tbs_len): + _LOGGER.debug("calling sign callback...") + + digest = _compute_sha256_digest(tbs, tbs_len) + digestArray = ctypes.c_char * len(digest) + + # reserve 2000 bytes for the signature, shoud be more then enough. + # RSA signature is 256 bytes, EC signature is 70~72. + sig_holder_len = 2000 + sig_holder = ctypes.create_string_buffer(sig_holder_len) + + signature_len = signer_lib.SignForPython( + config_file_path.encode(), # configFilePath + digestArray.from_buffer(bytearray(digest)), # digest + len(digest), # digestLen + sig_holder, # sigHolder + sig_holder_len, # sigHolderLen + ) + + if signature_len == 0: + # signing failed, return 0 + return 0 + + sig_len[0] = signature_len + bs = bytearray(sig_holder) + for i in range(signature_len): + sig[i] = bs[i] + + return 1 + + return SIGN_CALLBACK_CTYPE(sign_callback) + + +# Obtain the certificate bytes by calling the `GetCertPemForPython` method from +# the signer lib. The method is called twice, the first time is to compute the +# cert length, then we create a buffer to hold the cert, and call it again to +# fill the buffer. +def get_cert(signer_lib, config_file_path): + # First call to calculate the cert length + cert_len = signer_lib.GetCertPemForPython( + config_file_path.encode(), # configFilePath + None, # certHolder + 0, # certHolderLen + ) + if cert_len == 0: + raise exceptions.MutualTLSChannelError("failed to get certificate") + + # Then we create an array to hold the cert, and call again to fill the cert + cert_holder = ctypes.create_string_buffer(cert_len) + signer_lib.GetCertPemForPython( + config_file_path.encode(), # configFilePath + cert_holder, # certHolder + cert_len, # certHolderLen + ) + return bytes(cert_holder) + + +class CustomTlsSigner(object): + def __init__(self, enterprise_cert_file_path): + """ + This class loads the offload and signer library, and calls APIs from + these libraries to obtain the cert and a signing callback, and attach + them to SSL context. The cert and the signing callback will be used + for client authentication in TLS handshake. + + Args: + enterprise_cert_file_path (str): the path to a enterprise cert JSON + file. The file should contain the following field: + + { + "libs": { + "signer_library": "...", + "offload_library": "..." + } + } + """ + self._enterprise_cert_file_path = enterprise_cert_file_path + self._cert = None + self._sign_callback = 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["signer_library"] + offload_library = libs["offload_library"] + except (KeyError, ValueError) as caught_exc: + new_exc = exceptions.MutualTLSChannelError( + "enterprise cert file is invalid", caught_exc + ) + six.raise_from(new_exc, caught_exc) + self._offload_lib = load_offload_lib(offload_library) + self._signer_lib = load_signer_lib(signer_library) + + def set_up_custom_key(self): + # We need to keep a reference of the cert and sign callback so it won't + # be garbage collected, otherwise it will crash when used by signer lib. + self._cert = get_cert(self._signer_lib, self._enterprise_cert_file_path) + self._sign_callback = get_sign_callback( + self._signer_lib, self._enterprise_cert_file_path + ) + + 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") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.6.6/google/auth/transport/requests.py new/google-auth-2.7.0/google/auth/transport/requests.py --- old/google-auth-2.6.6/google/auth/transport/requests.py 2022-04-22 01:27:38.000000000 +0200 +++ new/google-auth-2.7.0/google/auth/transport/requests.py 2022-06-07 23:28:22.000000000 +0200 @@ -245,6 +245,65 @@ return super(_MutualTlsAdapter, self).proxy_manager_for(*args, **kwargs) +class _MutualTlsOffloadAdapter(requests.adapters.HTTPAdapter): + """ + A TransportAdapter that enables mutual TLS and offloads the client side + signing operation to the signing library. + + Args: + enterprise_cert_file_path (str): the path to a enterprise cert JSON + file. The file should contain the following field: + + { + "libs": { + "signer_library": "...", + "offload_library": "..." + } + } + + Raises: + ImportError: if certifi or pyOpenSSL is not installed + google.auth.exceptions.MutualTLSChannelError: If mutual TLS channel + creation failed for any reason. + """ + + def __init__(self, enterprise_cert_file_path): + import certifi + import urllib3.contrib.pyopenssl + + from google.auth.transport import _custom_tls_signer + + # Call inject_into_urllib3 to activate certificate checking. See the + # following links for more info: + # (1) doc: https://github.com/urllib3/urllib3/blob/cb9ebf8aac5d75f64c8551820d760b72b619beff/src/urllib3/contrib/pyopenssl.py#L31-L32 + # (2) mTLS example: https://github.com/urllib3/urllib3/issues/474#issuecomment-253168415 + urllib3.contrib.pyopenssl.inject_into_urllib3() + + 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()) + self.signer.attach_to_ssl_context(poolmanager) + self._ctx_poolmanager = poolmanager + + proxymanager = create_urllib3_context() + proxymanager.load_verify_locations(cafile=certifi.where()) + self.signer.attach_to_ssl_context(proxymanager) + self._ctx_proxymanager = proxymanager + + super(_MutualTlsOffloadAdapter, self).__init__() + + def init_poolmanager(self, *args, **kwargs): + kwargs["ssl_context"] = self._ctx_poolmanager + super(_MutualTlsOffloadAdapter, self).init_poolmanager(*args, **kwargs) + + def proxy_manager_for(self, *args, **kwargs): + kwargs["ssl_context"] = self._ctx_proxymanager + return super(_MutualTlsOffloadAdapter, self).proxy_manager_for(*args, **kwargs) + + class AuthorizedSession(requests.Session): """A Requests Session class with credentials. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.6.6/google/auth/version.py new/google-auth-2.7.0/google/auth/version.py --- old/google-auth-2.6.6/google/auth/version.py 2022-04-22 01:27:38.000000000 +0200 +++ new/google-auth-2.7.0/google/auth/version.py 2022-06-07 23:28:22.000000000 +0200 @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.6.6" +__version__ = "2.7.0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.6.6/google_auth.egg-info/PKG-INFO new/google-auth-2.7.0/google_auth.egg-info/PKG-INFO --- old/google-auth-2.6.6/google_auth.egg-info/PKG-INFO 2022-04-22 01:30:08.000000000 +0200 +++ new/google-auth-2.7.0/google_auth.egg-info/PKG-INFO 2022-06-07 23:30:53.000000000 +0200 @@ -1,13 +1,12 @@ Metadata-Version: 2.1 Name: google-auth -Version: 2.6.6 +Version: 2.7.0 Summary: Google Authentication Library Home-page: https://github.com/googleapis/google-auth-library-python Author: Google Cloud Platform Author-email: googleapis-packa...@google.com License: Apache 2.0 Keywords: google auth oauth client -Platform: UNKNOWN Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 @@ -26,6 +25,7 @@ Provides-Extra: aiohttp Provides-Extra: pyopenssl Provides-Extra: reauth +Provides-Extra: enterprise_cert License-File: LICENSE Google Auth Python Library @@ -95,5 +95,3 @@ Apache 2.0 - See `the LICENSE`_ for more information. .. _the LICENSE: https://github.com/googleapis/google-auth-library-python/blob/main/LICENSE - - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.6.6/google_auth.egg-info/SOURCES.txt new/google-auth-2.7.0/google_auth.egg-info/SOURCES.txt --- old/google-auth-2.6.6/google_auth.egg-info/SOURCES.txt 2022-04-22 01:30:09.000000000 +0200 +++ new/google-auth-2.7.0/google_auth.egg-info/SOURCES.txt 2022-06-07 23:30:54.000000000 +0200 @@ -37,6 +37,7 @@ google/auth/crypt/rsa.py google/auth/transport/__init__.py google/auth/transport/_aiohttp_requests.py +google/auth/transport/_custom_tls_signer.py google/auth/transport/_http_client.py google/auth/transport/_mtls_helper.py google/auth/transport/grpc.py @@ -94,6 +95,8 @@ tests/data/client_secrets.json tests/data/cloud_sdk_config.json tests/data/context_aware_metadata.json +tests/data/enterprise_cert_invalid.json +tests/data/enterprise_cert_valid.json tests/data/es256_privatekey.pem tests/data/es256_public_cert.pem tests/data/es256_publickey.pem @@ -122,6 +125,7 @@ tests/oauth2/test_utils.py tests/transport/__init__.py tests/transport/compliance.py +tests/transport/test__custom_tls_signer.py tests/transport/test__http_client.py tests/transport/test__mtls_helper.py tests/transport/test_grpc.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.6.6/google_auth.egg-info/requires.txt new/google-auth-2.7.0/google_auth.egg-info/requires.txt --- old/google-auth-2.6.6/google_auth.egg-info/requires.txt 2022-04-22 01:30:09.000000000 +0200 +++ new/google-auth-2.7.0/google_auth.egg-info/requires.txt 2022-06-07 23:30:54.000000000 +0200 @@ -17,6 +17,10 @@ [aiohttp:python_version >= "3.6"] aiohttp<4.0.0dev,>=3.6.2 +[enterprise_cert] +cryptography==36.0.2 +pyopenssl==22.0.0 + [pyopenssl] pyopenssl>=20.0.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.6.6/setup.py new/google-auth-2.7.0/setup.py --- old/google-auth-2.6.6/setup.py 2022-04-22 01:27:38.000000000 +0200 +++ new/google-auth-2.7.0/setup.py 2022-06-07 23:28:22.000000000 +0200 @@ -38,6 +38,9 @@ ], "pyopenssl": "pyopenssl>=20.0.0", "reauth": "pyu2f>=0.1.5", + # Enterprise cert only works for OpenSSL 1.1.1. Newer versions of these + # dependencies are built with OpenSSL 3.0 so we need to fix the version. + "enterprise_cert": ["cryptography==36.0.2", "pyopenssl==22.0.0"], } with io.open("README.rst", "r") as fh: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.6.6/tests/data/enterprise_cert_invalid.json new/google-auth-2.7.0/tests/data/enterprise_cert_invalid.json --- old/google-auth-2.6.6/tests/data/enterprise_cert_invalid.json 1970-01-01 01:00:00.000000000 +0100 +++ new/google-auth-2.7.0/tests/data/enterprise_cert_invalid.json 2022-06-07 23:28:22.000000000 +0200 @@ -0,0 +1,3 @@ +{ + "libs": {} +} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.6.6/tests/data/enterprise_cert_valid.json new/google-auth-2.7.0/tests/data/enterprise_cert_valid.json --- old/google-auth-2.6.6/tests/data/enterprise_cert_valid.json 1970-01-01 01:00:00.000000000 +0100 +++ new/google-auth-2.7.0/tests/data/enterprise_cert_valid.json 2022-06-07 23:28:22.000000000 +0200 @@ -0,0 +1,6 @@ +{ + "libs": { + "signer_library": "/path/to/signer/lib", + "offload_library": "/path/to/offload/lib" + } +} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.6.6/tests/test_external_account.py new/google-auth-2.7.0/tests/test_external_account.py --- old/google-auth-2.6.6/tests/test_external_account.py 2022-04-22 01:27:38.000000000 +0200 +++ new/google-auth-2.7.0/tests/test_external_account.py 2022-06-07 23:28:22.000000000 +0200 @@ -275,9 +275,110 @@ assert request_kwargs["headers"] == headers assert "body" not in request_kwargs + def test_valid_token_url_shall_pass_validation(self): + valid_urls = [ + "https://sts.googleapis.com", + "https://us-east-1.sts.googleapis.com", + "https://US-EAST-1.sts.googleapis.com", + "https://sts.us-east-1.googleapis.com", + "https://sts.US-WEST-1.googleapis.com", + "https://us-east-1-sts.googleapis.com", + "https://US-WEST-1-sts.googleapis.com", + "https://us-west-1-sts.googleapis.com/path?query", + ] + + for url in valid_urls: + # A valid url shouldn't throw exception and a None value should be returned + external_account.Credentials.validate_token_url(url) + + def test_invalid_token_url_shall_throw_exceptions(self): + invalid_urls = [ + "https://iamcredentials.googleapis.com", + "sts.googleapis.com", + "https://", + "http://sts.googleapis.com", + "https://st.s.googleapis.com", + "https://us-eas\t-1.sts.googleapis.com", + "https:/us-east-1.sts.googleapis.com", + "https://US-WE/ST-1-sts.googleapis.com", + "https://sts-us-east-1.googleapis.com", + "https://sts-US-WEST-1.googleapis.com", + "testhttps://us-east-1.sts.googleapis.com", + "https://us-east-1.sts.googleapis.comevil.com", + "https://us-east-1.us-east-1.sts.googleapis.com", + "https://us-ea.s.t.sts.googleapis.com", + "https://sts.googleapis.comevil.com", + "hhttps://us-east-1.sts.googleapis.com", + "https://us- -1.sts.googleapis.com", + "https://-sts.googleapis.com", + "https://us-east-1.sts.googleapis.com.evil.com", + ] + + for url in invalid_urls: + # An invalid url should throw a ValueError exception + with pytest.raises(ValueError) as excinfo: + external_account.Credentials.validate_token_url(url) + + assert excinfo.match("The provided token URL is invalid.") + + def test_valid_service_account_impersonation_url_shall_pass_validation(self): + valid_urls = [ + "https://iamcredentials.googleapis.com", + "https://us-east-1.iamcredentials.googleapis.com", + "https://US-EAST-1.iamcredentials.googleapis.com", + "https://iamcredentials.us-east-1.googleapis.com", + "https://iamcredentials.US-WEST-1.googleapis.com", + "https://us-east-1-iamcredentials.googleapis.com", + "https://US-WEST-1-iamcredentials.googleapis.com", + "https://us-west-1-iamcredentials.googleapis.com/path?query", + ] + + for url in valid_urls: + # A valid url shouldn't throw exception and a None value should be returned + external_account.Credentials.validate_service_account_impersonation_url(url) + + def test_invalid_service_account_impersonate_url_shall_throw_exceptions(self): + invalid_urls = [ + "https://sts.googleapis.com", + "iamcredentials.googleapis.com", + "https://", + "http://iamcredentials.googleapis.com", + "https://iamcre.dentials.googleapis.com", + "https://us-eas\t-1.iamcredentials.googleapis.com", + "https:/us-east-1.iamcredentials.googleapis.com", + "https://US-WE/ST-1-iamcredentials.googleapis.com", + "https://iamcredentials-us-east-1.googleapis.com", + "https://iamcredentials-US-WEST-1.googleapis.com", + "testhttps://us-east-1.iamcredentials.googleapis.com", + "https://us-east-1.iamcredentials.googleapis.comevil.com", + "https://us-east-1.us-east-1.iamcredentials.googleapis.com", + "https://us-ea.s.t.iamcredentials.googleapis.com", + "https://iamcredentials.googleapis.comevil.com", + "hhttps://us-east-1.iamcredentials.googleapis.com", + "https://us- -1.iamcredentials.googleapis.com", + "https://-iamcredentials.googleapis.com", + "https://us-east-1.iamcredentials.googleapis.com.evil.com", + ] + + for url in invalid_urls: + # An invalid url should throw a ValueError exception + with pytest.raises(ValueError) as excinfo: + external_account.Credentials.validate_service_account_impersonation_url( + url + ) + + assert excinfo.match( + "The provided service account impersonation URL is invalid." + ) + def test_default_state(self): - credentials = self.make_credentials() + credentials = self.make_credentials( + service_account_impersonation_url=self.SERVICE_ACCOUNT_IMPERSONATION_URL + ) + # Token url and service account impersonation url should be set + assert credentials._token_url + assert credentials._service_account_impersonation_url # Not token acquired yet assert not credentials.token assert not credentials.valid @@ -289,6 +390,31 @@ assert credentials.requires_scopes assert not credentials.quota_project_id + def test_invalid_token_url(self): + with pytest.raises(ValueError) as excinfo: + CredentialsImpl( + audience=self.AUDIENCE, + subject_token_type=self.SUBJECT_TOKEN_TYPE, + token_url="https:///v1/token", + credential_source=self.CREDENTIAL_SOURCE, + ) + + assert excinfo.match("The provided token URL is invalid.") + + def test_invalid_service_account_impersonate_url(self): + with pytest.raises(ValueError) as excinfo: + CredentialsImpl( + audience=self.AUDIENCE, + subject_token_type=self.SUBJECT_TOKEN_TYPE, + token_url=self.TOKEN_URL, + credential_source=self.CREDENTIAL_SOURCE, + service_account_impersonation_url=12345, # create an exception by sending to parse url + ) + + assert excinfo.match( + "The provided service account impersonation URL is invalid." + ) + def test_nonworkforce_with_workforce_pool_user_project(self): with pytest.raises(ValueError) as excinfo: CredentialsImpl( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.6.6/tests/transport/test__custom_tls_signer.py new/google-auth-2.7.0/tests/transport/test__custom_tls_signer.py --- old/google-auth-2.6.6/tests/transport/test__custom_tls_signer.py 1970-01-01 01:00:00.000000000 +0100 +++ new/google-auth-2.7.0/tests/transport/test__custom_tls_signer.py 2022-06-07 23:28:22.000000000 +0200 @@ -0,0 +1,234 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# 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 + +import mock +import pytest # type: ignore +from requests.packages.urllib3.util.ssl_ import create_urllib3_context # type: ignore +import urllib3.contrib.pyopenssl # type: ignore + +from google.auth import exceptions +from google.auth.transport import _custom_tls_signer + +urllib3.contrib.pyopenssl.inject_into_urllib3() + +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" +) +INVALID_ENTERPRISE_CERT_FILE = os.path.join( + os.path.dirname(__file__), "../data/enterprise_cert_invalid.json" +) + + +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") + + assert lib.ConfigureSslContext.argtypes == [ + _custom_tls_signer.SIGN_CALLBACK_CTYPE, + ctypes.c_char_p, + ctypes.c_void_p, + ] + assert lib.ConfigureSslContext.restype == ctypes.c_int + + +def test_load_signer_lib(): + with mock.patch("ctypes.CDLL", return_value=mock.MagicMock()): + lib = _custom_tls_signer.load_signer_lib("/path/to/signer/lib") + + assert lib.SignForPython.restype == ctypes.c_int + assert lib.SignForPython.argtypes == [ + ctypes.c_char_p, + ctypes.c_char_p, + ctypes.c_int, + ctypes.c_char_p, + ctypes.c_int, + ] + + assert lib.GetCertPemForPython.restype == ctypes.c_int + assert lib.GetCertPemForPython.argtypes == [ + ctypes.c_char_p, + ctypes.c_char_p, + ctypes.c_int, + ] + + +def test__compute_sha256_digest(): + to_be_signed = ctypes.create_string_buffer(b"foo") + sig = _custom_tls_signer._compute_sha256_digest(to_be_signed, 4) + + assert ( + base64.b64encode(sig).decode() == "RG5gyEH8CAAh3lxgbt2PLPAHPO8p6i9+cn5dqHfUUYM=" + ) + + +def test_get_sign_callback(): + # mock signer lib's SignForPython function + mock_sig_len = 10 + mock_signer_lib = mock.MagicMock() + mock_signer_lib.SignForPython.return_value = mock_sig_len + + # create a sign callback. The callback calls signer lib's SignForPython method + sign_callback = _custom_tls_signer.get_sign_callback( + mock_signer_lib, FAKE_ENTERPRISE_CERT_FILE_PATH + ) + + # mock the parameters used to call the sign callback + to_be_signed = ctypes.POINTER(ctypes.c_ubyte)() + to_be_signed_len = 4 + returned_sig_array = ctypes.c_ubyte() + mock_sig_array = ctypes.byref(returned_sig_array) + returned_sign_len = ctypes.c_ulong() + mock_sig_len_array = ctypes.byref(returned_sign_len) + + # call the callback, make sure the signature len is returned via mock_sig_len_array[0] + assert sign_callback( + mock_sig_array, mock_sig_len_array, to_be_signed, to_be_signed_len + ) + assert returned_sign_len.value == mock_sig_len + + +def test_get_sign_callback_failed_to_sign(): + # mock signer lib's SignForPython function. Set the sig len to be 0 to + # indicate the signing failed. + mock_sig_len = 0 + mock_signer_lib = mock.MagicMock() + mock_signer_lib.SignForPython.return_value = mock_sig_len + + # create a sign callback. The callback calls signer lib's SignForPython method + sign_callback = _custom_tls_signer.get_sign_callback( + mock_signer_lib, FAKE_ENTERPRISE_CERT_FILE_PATH + ) + + # mock the parameters used to call the sign callback + to_be_signed = ctypes.POINTER(ctypes.c_ubyte)() + to_be_signed_len = 4 + returned_sig_array = ctypes.c_ubyte() + mock_sig_array = ctypes.byref(returned_sig_array) + returned_sign_len = ctypes.c_ulong() + mock_sig_len_array = ctypes.byref(returned_sign_len) + sign_callback(mock_sig_array, mock_sig_len_array, to_be_signed, to_be_signed_len) + + # sign callback should return 0 + assert not sign_callback( + mock_sig_array, mock_sig_len_array, to_be_signed, to_be_signed_len + ) + + +def test_get_cert_no_cert(): + # mock signer lib's GetCertPemForPython function to return 0 to indicts + # the cert doesn't exit (cert len = 0) + mock_signer_lib = mock.MagicMock() + mock_signer_lib.GetCertPemForPython.return_value = 0 + + # call the get cert method + with pytest.raises(exceptions.MutualTLSChannelError) as excinfo: + _custom_tls_signer.get_cert(mock_signer_lib, FAKE_ENTERPRISE_CERT_FILE_PATH) + + assert excinfo.match("failed to get certificate") + + +def test_get_cert(): + # mock signer lib's GetCertPemForPython function + mock_cert_len = 10 + mock_signer_lib = mock.MagicMock() + mock_signer_lib.GetCertPemForPython.return_value = mock_cert_len + + # call the get cert method + mock_cert = _custom_tls_signer.get_cert( + mock_signer_lib, FAKE_ENTERPRISE_CERT_FILE_PATH + ) + + # make sure the signer lib's GetCertPemForPython is called twice, and the + # mock_cert has length mock_cert_len + assert mock_signer_lib.GetCertPemForPython.call_count == 2 + assert len(mock_cert) == mock_cert_len + + +def test_custom_tls_signer(): + offload_lib = mock.MagicMock() + signer_lib = mock.MagicMock() + + # Test load_libraries method + 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() + assert signer_object._cert is None + 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_failed_to_load_libraries(): + # Test load_libraries method + 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() + + 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 + + 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") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/google-auth-2.6.6/tests/transport/test_requests.py new/google-auth-2.7.0/tests/transport/test_requests.py --- old/google-auth-2.6.6/tests/transport/test_requests.py 2022-04-22 01:27:38.000000000 +0200 +++ new/google-auth-2.7.0/tests/transport/test_requests.py 2022-06-07 23:28:22.000000000 +0200 @@ -28,6 +28,7 @@ from google.auth import environment_vars from google.auth import exceptions import google.auth.credentials +import google.auth.transport._custom_tls_signer import google.auth.transport._mtls_helper import google.auth.transport.requests from google.oauth2 import service_account @@ -535,3 +536,40 @@ ) authed_session.close() # no raise + + +class TestMutualTlsOffloadAdapter(object): + @mock.patch.object(requests.adapters.HTTPAdapter, "init_poolmanager") + @mock.patch.object(requests.adapters.HTTPAdapter, "proxy_manager_for") + @mock.patch.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, + ): + enterprise_cert_file_path = "/path/to/enterprise/cert/json" + adapter = google.auth.transport.requests._MutualTlsOffloadAdapter( + enterprise_cert_file_path + ) + + 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() + mock_init_poolmanager.assert_called_with(ssl_context=adapter._ctx_poolmanager) + + adapter.proxy_manager_for() + mock_proxy_manager_for.assert_called_with(ssl_context=adapter._ctx_proxymanager) ++++++ python-google-auth-no-mock.patch ++++++ diff -upr google-auth-2.7.0.orig/tests/compute_engine/test_credentials.py google-auth-2.7.0/tests/compute_engine/test_credentials.py --- google-auth-2.7.0.orig/tests/compute_engine/test_credentials.py 2022-06-08 10:35:11.954473507 +0200 +++ google-auth-2.7.0/tests/compute_engine/test_credentials.py 2022-06-08 10:35:11.970473600 +0200 @@ -14,7 +14,7 @@ import base64 import datetime -import mock +from unittest import mock import pytest # type: ignore import responses # type: ignore diff -upr google-auth-2.7.0.orig/tests/compute_engine/test__metadata.py google-auth-2.7.0/tests/compute_engine/test__metadata.py --- google-auth-2.7.0.orig/tests/compute_engine/test__metadata.py 2022-06-08 10:35:11.954473507 +0200 +++ google-auth-2.7.0/tests/compute_engine/test__metadata.py 2022-06-08 10:35:11.970473600 +0200 @@ -16,7 +16,7 @@ import datetime import json import os -import mock +from unittest import mock import pytest # type: ignore from six.moves import http_client from six.moves import reload_module diff -upr google-auth-2.7.0.orig/tests/conftest.py google-auth-2.7.0/tests/conftest.py --- google-auth-2.7.0.orig/tests/conftest.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/conftest.py 2022-06-08 10:35:11.970473600 +0200 @@ -15,7 +15,7 @@ import os import sys -import mock +from unittest import mock import pytest # type: ignore diff -upr google-auth-2.7.0.orig/tests/crypt/test__python_rsa.py google-auth-2.7.0/tests/crypt/test__python_rsa.py --- google-auth-2.7.0.orig/tests/crypt/test__python_rsa.py 2022-06-08 10:35:11.954473507 +0200 +++ google-auth-2.7.0/tests/crypt/test__python_rsa.py 2022-06-08 10:35:11.970473600 +0200 @@ -15,7 +15,7 @@ import json import os -import mock +from unittest import mock from pyasn1_modules import pem # type: ignore import pytest # type: ignore import rsa # type: ignore diff -upr google-auth-2.7.0.orig/tests/oauth2/test_challenges.py google-auth-2.7.0/tests/oauth2/test_challenges.py --- google-auth-2.7.0.orig/tests/oauth2/test_challenges.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/oauth2/test_challenges.py 2022-06-08 10:35:11.970473600 +0200 @@ -17,7 +17,7 @@ import base64 import sys -import mock +from unittest import mock import pytest # type: ignore import pyu2f # type: ignore diff -upr google-auth-2.7.0.orig/tests/oauth2/test__client.py google-auth-2.7.0/tests/oauth2/test__client.py --- google-auth-2.7.0.orig/tests/oauth2/test__client.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/oauth2/test__client.py 2022-06-08 10:35:11.970473600 +0200 @@ -16,7 +16,7 @@ import datetime import json import os -import mock +from unittest import mock import pytest # type: ignore import six from six.moves import http_client diff -upr google-auth-2.7.0.orig/tests/oauth2/test_credentials.py google-auth-2.7.0/tests/oauth2/test_credentials.py --- google-auth-2.7.0.orig/tests/oauth2/test_credentials.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/oauth2/test_credentials.py 2022-06-08 10:35:11.970473600 +0200 @@ -18,7 +18,7 @@ import os import pickle import sys -import mock +from unittest import mock import pytest # type: ignore from google.auth import _helpers diff -upr google-auth-2.7.0.orig/tests/oauth2/test_id_token.py google-auth-2.7.0/tests/oauth2/test_id_token.py --- google-auth-2.7.0.orig/tests/oauth2/test_id_token.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/oauth2/test_id_token.py 2022-06-08 10:35:11.970473600 +0200 @@ -15,7 +15,7 @@ import json import os -import mock +from unittest import mock import pytest # type: ignore from google.auth import environment_vars diff -upr google-auth-2.7.0.orig/tests/oauth2/test_reauth.py google-auth-2.7.0/tests/oauth2/test_reauth.py --- google-auth-2.7.0.orig/tests/oauth2/test_reauth.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/oauth2/test_reauth.py 2022-06-08 10:35:11.970473600 +0200 @@ -14,7 +14,7 @@ import copy -import mock +from unittest import mock import pytest # type: ignore from google.auth import exceptions diff -upr google-auth-2.7.0.orig/tests/oauth2/test_service_account.py google-auth-2.7.0/tests/oauth2/test_service_account.py --- google-auth-2.7.0.orig/tests/oauth2/test_service_account.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/oauth2/test_service_account.py 2022-06-08 10:35:11.970473600 +0200 @@ -16,7 +16,7 @@ import datetime import json import os -import mock +from unittest import mock from google.auth import _helpers from google.auth import crypt diff -upr google-auth-2.7.0.orig/tests/oauth2/test_sts.py google-auth-2.7.0/tests/oauth2/test_sts.py --- google-auth-2.7.0.orig/tests/oauth2/test_sts.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/oauth2/test_sts.py 2022-06-08 10:35:11.974473623 +0200 @@ -14,7 +14,7 @@ import json -import mock +from unittest import mock import pytest # type: ignore from six.moves import http_client from six.moves import urllib diff -upr google-auth-2.7.0.orig/tests/test_app_engine.py google-auth-2.7.0/tests/test_app_engine.py --- google-auth-2.7.0.orig/tests/test_app_engine.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/test_app_engine.py 2022-06-08 10:35:11.974473623 +0200 @@ -14,7 +14,7 @@ import datetime -import mock +from unittest import mock import pytest # type: ignore from google.auth import app_engine diff -upr google-auth-2.7.0.orig/tests/test_aws.py google-auth-2.7.0/tests/test_aws.py --- google-auth-2.7.0.orig/tests/test_aws.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/test_aws.py 2022-06-08 10:35:11.974473623 +0200 @@ -15,7 +15,7 @@ import datetime import json -import mock +from unittest import mock import pytest # type: ignore from six.moves import http_client from six.moves import urllib diff -upr google-auth-2.7.0.orig/tests/test__cloud_sdk.py google-auth-2.7.0/tests/test__cloud_sdk.py --- google-auth-2.7.0.orig/tests/test__cloud_sdk.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/test__cloud_sdk.py 2022-06-08 10:35:11.978473646 +0200 @@ -17,7 +17,7 @@ import json import os import subprocess -import mock +from unittest import mock import pytest # type: ignore from google.auth import _cloud_sdk diff -upr google-auth-2.7.0.orig/tests/test__default.py google-auth-2.7.0/tests/test__default.py --- google-auth-2.7.0.orig/tests/test__default.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/test__default.py 2022-06-08 10:35:11.974473623 +0200 @@ -15,7 +15,7 @@ import json import os -import mock +from unittest import mock import pytest # type: ignore from google.auth import _default diff -upr google-auth-2.7.0.orig/tests/test_downscoped.py google-auth-2.7.0/tests/test_downscoped.py --- google-auth-2.7.0.orig/tests/test_downscoped.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/test_downscoped.py 2022-06-08 10:35:11.974473623 +0200 @@ -15,7 +15,7 @@ import datetime import json -import mock +from unittest import mock import pytest # type: ignore from six.moves import http_client from six.moves import urllib diff -upr google-auth-2.7.0.orig/tests/test_external_account.py google-auth-2.7.0/tests/test_external_account.py --- google-auth-2.7.0.orig/tests/test_external_account.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/test_external_account.py 2022-06-08 10:35:11.974473623 +0200 @@ -15,7 +15,7 @@ import datetime import json -import mock +from unittest import mock import pytest # type: ignore from six.moves import http_client from six.moves import urllib diff -upr google-auth-2.7.0.orig/tests/test_iam.py google-auth-2.7.0/tests/test_iam.py --- google-auth-2.7.0.orig/tests/test_iam.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/test_iam.py 2022-06-08 10:35:11.974473623 +0200 @@ -16,7 +16,7 @@ import base64 import datetime import json -import mock +from unittest import mock import pytest # type: ignore from six.moves import http_client diff -upr google-auth-2.7.0.orig/tests/test_identity_pool.py google-auth-2.7.0/tests/test_identity_pool.py --- google-auth-2.7.0.orig/tests/test_identity_pool.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/test_identity_pool.py 2022-06-08 10:35:11.974473623 +0200 @@ -16,7 +16,7 @@ import datetime import json import os -import mock +from unittest import mock import pytest # type: ignore from six.moves import http_client from six.moves import urllib diff -upr google-auth-2.7.0.orig/tests/test_impersonated_credentials.py google-auth-2.7.0/tests/test_impersonated_credentials.py --- google-auth-2.7.0.orig/tests/test_impersonated_credentials.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/test_impersonated_credentials.py 2022-06-08 10:35:11.974473623 +0200 @@ -19,7 +19,7 @@ import os # Because Python 2.7 # from typing import List -import mock +from unittest import mock import pytest # type: ignore from six.moves import http_client diff -upr google-auth-2.7.0.orig/tests/test_jwt.py google-auth-2.7.0/tests/test_jwt.py --- google-auth-2.7.0.orig/tests/test_jwt.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/test_jwt.py 2022-06-08 10:35:11.974473623 +0200 @@ -17,7 +17,7 @@ import datetime import json import os -import mock +from unittest import mock import pytest # type: ignore from google.auth import _helpers diff -upr google-auth-2.7.0.orig/tests/test__oauth2client.py google-auth-2.7.0/tests/test__oauth2client.py --- google-auth-2.7.0.orig/tests/test__oauth2client.py 2022-06-08 10:35:11.958473530 +0200 +++ google-auth-2.7.0/tests/test__oauth2client.py 2022-06-08 10:35:11.974473623 +0200 @@ -16,7 +16,7 @@ import datetime import os import sys -import mock +from unittest import mock import oauth2client.client # type: ignore import oauth2client.contrib.gce # type: ignore import oauth2client.service_account # type: ignore diff -upr google-auth-2.7.0.orig/tests/transport/test__custom_tls_signer.py google-auth-2.7.0/tests/transport/test__custom_tls_signer.py --- google-auth-2.7.0.orig/tests/transport/test__custom_tls_signer.py 2022-06-08 10:35:11.954473507 +0200 +++ google-auth-2.7.0/tests/transport/test__custom_tls_signer.py 2022-06-08 10:35:11.978473646 +0200 @@ -16,7 +16,7 @@ import base64 import ctypes import os -import mock +from unittest import mock import pytest # type: ignore from requests.packages.urllib3.util.ssl_ import create_urllib3_context # type: ignore import urllib3.contrib.pyopenssl # type: ignore diff -upr google-auth-2.7.0.orig/tests/transport/test_grpc.py google-auth-2.7.0/tests/transport/test_grpc.py --- google-auth-2.7.0.orig/tests/transport/test_grpc.py 2022-06-08 10:35:11.954473507 +0200 +++ google-auth-2.7.0/tests/transport/test_grpc.py 2022-06-08 10:35:11.978473646 +0200 @@ -16,7 +16,7 @@ import datetime import os import time -import mock +from unittest import mock import pytest # type: ignore from google.auth import _helpers diff -upr google-auth-2.7.0.orig/tests/transport/test__mtls_helper.py google-auth-2.7.0/tests/transport/test__mtls_helper.py --- google-auth-2.7.0.orig/tests/transport/test__mtls_helper.py 2022-06-08 10:35:11.954473507 +0200 +++ google-auth-2.7.0/tests/transport/test__mtls_helper.py 2022-06-08 10:35:11.978473646 +0200 @@ -15,7 +15,7 @@ import os import re -import mock +from unittest import mock from OpenSSL import crypto import pytest # type: ignore diff -upr google-auth-2.7.0.orig/tests/transport/test_mtls.py google-auth-2.7.0/tests/transport/test_mtls.py --- google-auth-2.7.0.orig/tests/transport/test_mtls.py 2022-06-08 10:35:11.954473507 +0200 +++ google-auth-2.7.0/tests/transport/test_mtls.py 2022-06-08 10:35:11.978473646 +0200 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import mock +from unittest import mock import pytest # type: ignore from google.auth import exceptions diff -upr google-auth-2.7.0.orig/tests/transport/test_requests.py google-auth-2.7.0/tests/transport/test_requests.py --- google-auth-2.7.0.orig/tests/transport/test_requests.py 2022-06-08 10:35:11.954473507 +0200 +++ google-auth-2.7.0/tests/transport/test_requests.py 2022-06-08 10:35:11.978473646 +0200 @@ -18,7 +18,7 @@ import os import sys import freezegun -import mock +from unittest import mock import OpenSSL import pytest # type: ignore import requests diff -upr google-auth-2.7.0.orig/tests/transport/test_urllib3.py google-auth-2.7.0/tests/transport/test_urllib3.py --- google-auth-2.7.0.orig/tests/transport/test_urllib3.py 2022-06-08 10:35:11.954473507 +0200 +++ google-auth-2.7.0/tests/transport/test_urllib3.py 2022-06-08 10:35:11.978473646 +0200 @@ -15,7 +15,7 @@ import os import sys -import mock +from unittest import mock import OpenSSL import pytest # type: ignore from six.moves import http_client