google-auth 2.49.0__tar.gz → 2.49.0.dev0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {google_auth-2.49.0/google_auth.egg-info → google_auth-2.49.0.dev0}/PKG-INFO +3 -15
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/aio/transport/aiohttp.py +7 -22
- google_auth-2.49.0.dev0/google/auth/aio/transport/sessions.py +268 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/crypt/rsa.py +6 -1
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/environment_vars.py +0 -12
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/iam.py +16 -7
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/transport/_mtls_helper.py +23 -43
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/transport/mtls.py +4 -9
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/version.py +1 -1
- {google_auth-2.49.0 → google_auth-2.49.0.dev0/google_auth.egg-info}/PKG-INFO +3 -15
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google_auth.egg-info/SOURCES.txt +1 -4
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google_auth.egg-info/top_level.txt +1 -1
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/setup.py +3 -3
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/crypt/test_rsa.py +1 -1
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/transport/aio/test_aiohttp.py +3 -4
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/transport/aio/test_sessions.py +0 -15
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/transport/test__mtls_helper.py +7 -109
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/transport/test_mtls.py +4 -4
- google_auth-2.49.0/google/auth/aio/transport/mtls.py +0 -197
- google_auth-2.49.0/google/auth/aio/transport/sessions.py +0 -576
- google_auth-2.49.0/tests/transport/aio/test_sessions_mtls.py +0 -142
- google_auth-2.49.0/tests/transport/test_aio_mtls_helper.py +0 -202
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/LICENSE +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/MANIFEST.in +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/README.rst +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/__init__.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/_agent_identity_utils.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/_cache.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/_cloud_sdk.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/_constants.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/_credentials_async.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/_credentials_base.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/_default.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/_default_async.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/_exponential_backoff.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/_helpers.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/_jwt_async.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/_oauth2client.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/_refresh_worker.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/_service_account_info.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/aio/__init__.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/aio/_helpers.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/aio/credentials.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/aio/transport/__init__.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/api_key.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/app_engine.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/aws.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/compute_engine/__init__.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/compute_engine/_metadata.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/compute_engine/_mtls.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/compute_engine/credentials.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/credentials.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/crypt/__init__.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/crypt/_cryptography_rsa.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/crypt/_helpers.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/crypt/_python_rsa.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/crypt/base.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/crypt/es.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/crypt/es256.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/downscoped.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/exceptions.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/external_account.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/external_account_authorized_user.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/identity_pool.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/impersonated_credentials.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/jwt.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/metrics.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/pluggable.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/py.typed +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/transport/__init__.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/transport/_aiohttp_requests.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/transport/_custom_tls_signer.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/transport/_http_client.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/transport/_requests_base.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/transport/grpc.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/transport/requests.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/auth/transport/urllib3.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/__init__.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/_client.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/_client_async.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/_credentials_async.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/_id_token_async.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/_reauth_async.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/_service_account_async.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/challenges.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/credentials.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/gdch_credentials.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/id_token.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/py.typed +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/reauth.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/service_account.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/sts.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/utils.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/webauthn_handler.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/webauthn_handler_factory.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google/oauth2/webauthn_types.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google_auth.egg-info/dependency_links.txt +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/google_auth.egg-info/requires.txt +1 -1
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/setup.cfg +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/__init__.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/aio/test__helpers.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/compute_engine/__init__.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/compute_engine/data/smbios_product_name +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/compute_engine/data/smbios_product_name_non_google +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/compute_engine/test__metadata.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/compute_engine/test__mtls.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/compute_engine/test_credentials.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/conftest.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/crypt/__init__.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/crypt/test__cryptography_rsa.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/crypt/test__python_rsa.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/crypt/test_crypt.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/crypt/test_es.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/crypt/test_es256.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/authorized_user.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/authorized_user_cloud_sdk.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/authorized_user_cloud_sdk_with_quota_project_id.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/authorized_user_with_rapt_token.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/client_secrets.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/context_aware_metadata.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/enterprise_cert_invalid.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/enterprise_cert_valid.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/enterprise_cert_valid_provider.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/es256_privatekey.pem +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/es256_public_cert.pem +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/es256_publickey.pem +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/es256_service_account.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/es384_privatekey.pem +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/es384_public_cert.pem +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/es384_publickey.pem +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/es384_service_account.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/external_account_authorized_user.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/external_account_authorized_user_non_gdu.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/external_subject_token.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/external_subject_token.txt +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/gdch_service_account.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/impersonated_service_account_authorized_user_source.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/impersonated_service_account_external_account_authorized_user_source.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/impersonated_service_account_service_account_source.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/impersonated_service_account_with_quota_project.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/old_oauth_credentials_py3.pickle +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/other_cert.pem +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/pem_from_pkcs12.pem +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/privatekey.p12 +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/privatekey.pem +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/privatekey.pub +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/public_cert.pem +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/service_account.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/service_account_non_gdu.json +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/trust_chain_with_leaf.pem +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/trust_chain_without_leaf.pem +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/data/trust_chain_wrong_order.pem +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/oauth2/__init__.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/oauth2/test__client.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/oauth2/test_challenges.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/oauth2/test_credentials.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/oauth2/test_gdch_credentials.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/oauth2/test_id_token.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/oauth2/test_reauth.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/oauth2/test_service_account.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/oauth2/test_sts.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/oauth2/test_utils.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/oauth2/test_webauthn_handler.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/oauth2/test_webauthn_handler_factory.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/oauth2/test_webauthn_types.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test__cache.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test__cloud_sdk.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test__default.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test__exponential_backoff.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test__helpers.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test__oauth2client.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test__refresh_worker.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test__service_account_info.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test_agent_identity_utils.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test_api_key.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test_app_engine.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test_aws.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test_credentials.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test_credentials_async.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test_downscoped.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test_exceptions.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test_external_account.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test_external_account_authorized_user.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test_iam.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test_identity_pool.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test_impersonated_credentials.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test_jwt.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test_metrics.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test_packaging.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test_pluggable.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/test_version_warnings.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/transport/__init__.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/transport/compliance.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/transport/test__custom_tls_signer.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/transport/test__http_client.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/transport/test_grpc.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/transport/test_requests.py +0 -0
- {google_auth-2.49.0 → google_auth-2.49.0.dev0}/tests/transport/test_urllib3.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
2
|
Name: google-auth
|
|
3
|
-
Version: 2.49.0
|
|
3
|
+
Version: 2.49.0.dev0
|
|
4
4
|
Summary: Google Authentication Library
|
|
5
5
|
Home-page: https://github.com/googleapis/google-auth-library-python
|
|
6
6
|
Author: Google Cloud Platform
|
|
@@ -27,7 +27,6 @@ Requires-Python: >=3.8
|
|
|
27
27
|
License-File: LICENSE
|
|
28
28
|
Requires-Dist: pyasn1-modules>=0.2.1
|
|
29
29
|
Requires-Dist: cryptography>=38.0.3
|
|
30
|
-
Requires-Dist: rsa<5,>=3.1.4
|
|
31
30
|
Provides-Extra: cryptography
|
|
32
31
|
Requires-Dist: cryptography>=38.0.3; extra == "cryptography"
|
|
33
32
|
Provides-Extra: aiohttp
|
|
@@ -63,21 +62,10 @@ Requires-Dist: aioresponses; extra == "testing"
|
|
|
63
62
|
Requires-Dist: pytest-asyncio; extra == "testing"
|
|
64
63
|
Requires-Dist: pyopenssl<24.3.0; extra == "testing"
|
|
65
64
|
Requires-Dist: aiohttp<3.10.0; extra == "testing"
|
|
65
|
+
Requires-Dist: rsa<5,>=3.1.4; extra == "testing"
|
|
66
66
|
Provides-Extra: urllib3
|
|
67
67
|
Requires-Dist: urllib3; extra == "urllib3"
|
|
68
68
|
Requires-Dist: packaging; extra == "urllib3"
|
|
69
|
-
Dynamic: author
|
|
70
|
-
Dynamic: author-email
|
|
71
|
-
Dynamic: classifier
|
|
72
|
-
Dynamic: description
|
|
73
|
-
Dynamic: home-page
|
|
74
|
-
Dynamic: keywords
|
|
75
|
-
Dynamic: license
|
|
76
|
-
Dynamic: license-file
|
|
77
|
-
Dynamic: provides-extra
|
|
78
|
-
Dynamic: requires-dist
|
|
79
|
-
Dynamic: requires-python
|
|
80
|
-
Dynamic: summary
|
|
81
69
|
|
|
82
70
|
Google Auth Python Library
|
|
83
71
|
==========================
|
|
@@ -12,11 +12,12 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
"""Transport adapter for Asynchronous HTTP Requests based on aiohttp.
|
|
15
|
+
"""Transport adapter for Asynchronous HTTP Requests based on aiohttp.
|
|
16
|
+
"""
|
|
16
17
|
|
|
17
18
|
import asyncio
|
|
18
19
|
import logging
|
|
19
|
-
from typing import AsyncGenerator, Mapping, Optional
|
|
20
|
+
from typing import AsyncGenerator, Mapping, Optional
|
|
20
21
|
|
|
21
22
|
try:
|
|
22
23
|
import aiohttp # type: ignore
|
|
@@ -30,15 +31,6 @@ from google.auth import exceptions
|
|
|
30
31
|
from google.auth.aio import _helpers as _helpers_async
|
|
31
32
|
from google.auth.aio import transport
|
|
32
33
|
|
|
33
|
-
if TYPE_CHECKING: # pragma: NO COVER
|
|
34
|
-
from aiohttp import ClientTimeout # type: ignore
|
|
35
|
-
|
|
36
|
-
else:
|
|
37
|
-
try:
|
|
38
|
-
from aiohttp import ClientTimeout
|
|
39
|
-
except (ImportError, AttributeError):
|
|
40
|
-
ClientTimeout = None
|
|
41
|
-
|
|
42
34
|
_LOGGER = logging.getLogger(__name__)
|
|
43
35
|
|
|
44
36
|
|
|
@@ -121,7 +113,7 @@ class Request(transport.Request):
|
|
|
121
113
|
.. automethod:: __call__
|
|
122
114
|
"""
|
|
123
115
|
|
|
124
|
-
def __init__(self, session:
|
|
116
|
+
def __init__(self, session: aiohttp.ClientSession = None):
|
|
125
117
|
self._session = session
|
|
126
118
|
self._closed = False
|
|
127
119
|
|
|
@@ -131,7 +123,7 @@ class Request(transport.Request):
|
|
|
131
123
|
method: str = "GET",
|
|
132
124
|
body: Optional[bytes] = None,
|
|
133
125
|
headers: Optional[Mapping[str, str]] = None,
|
|
134
|
-
timeout:
|
|
126
|
+
timeout: float = transport._DEFAULT_TIMEOUT_SECONDS,
|
|
135
127
|
**kwargs,
|
|
136
128
|
) -> transport.Response:
|
|
137
129
|
"""
|
|
@@ -166,10 +158,7 @@ class Request(transport.Request):
|
|
|
166
158
|
if not self._session:
|
|
167
159
|
self._session = aiohttp.ClientSession()
|
|
168
160
|
|
|
169
|
-
|
|
170
|
-
client_timeout = timeout
|
|
171
|
-
else:
|
|
172
|
-
client_timeout = aiohttp.ClientTimeout(total=timeout)
|
|
161
|
+
client_timeout = aiohttp.ClientTimeout(total=timeout)
|
|
173
162
|
_helpers.request_log(_LOGGER, method, url, body, headers)
|
|
174
163
|
response = await self._session.request(
|
|
175
164
|
method,
|
|
@@ -187,12 +176,8 @@ class Request(transport.Request):
|
|
|
187
176
|
raise client_exc from caught_exc
|
|
188
177
|
|
|
189
178
|
except asyncio.TimeoutError as caught_exc:
|
|
190
|
-
if isinstance(timeout, aiohttp.ClientTimeout):
|
|
191
|
-
timeout_seconds = timeout.total
|
|
192
|
-
else:
|
|
193
|
-
timeout_seconds = timeout
|
|
194
179
|
timeout_exc = exceptions.TimeoutError(
|
|
195
|
-
f"Request timed out after {
|
|
180
|
+
f"Request timed out after {timeout} seconds."
|
|
196
181
|
)
|
|
197
182
|
raise timeout_exc from caught_exc
|
|
198
183
|
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# Copyright 2024 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
import asyncio
|
|
16
|
+
from contextlib import asynccontextmanager
|
|
17
|
+
import functools
|
|
18
|
+
import time
|
|
19
|
+
from typing import Mapping, Optional
|
|
20
|
+
|
|
21
|
+
from google.auth import _exponential_backoff, exceptions
|
|
22
|
+
from google.auth.aio import transport
|
|
23
|
+
from google.auth.aio.credentials import Credentials
|
|
24
|
+
from google.auth.exceptions import TimeoutError
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
from google.auth.aio.transport.aiohttp import Request as AiohttpRequest
|
|
28
|
+
|
|
29
|
+
AIOHTTP_INSTALLED = True
|
|
30
|
+
except ImportError: # pragma: NO COVER
|
|
31
|
+
AIOHTTP_INSTALLED = False
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@asynccontextmanager
|
|
35
|
+
async def timeout_guard(timeout):
|
|
36
|
+
"""
|
|
37
|
+
timeout_guard is an asynchronous context manager to apply a timeout to an asynchronous block of code.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
timeout (float): The time in seconds before the context manager times out.
|
|
41
|
+
|
|
42
|
+
Raises:
|
|
43
|
+
google.auth.exceptions.TimeoutError: If the code within the context exceeds the provided timeout.
|
|
44
|
+
|
|
45
|
+
Usage:
|
|
46
|
+
async with timeout_guard(10) as with_timeout:
|
|
47
|
+
await with_timeout(async_function())
|
|
48
|
+
"""
|
|
49
|
+
start = time.monotonic()
|
|
50
|
+
total_timeout = timeout
|
|
51
|
+
|
|
52
|
+
def _remaining_time():
|
|
53
|
+
elapsed = time.monotonic() - start
|
|
54
|
+
remaining = total_timeout - elapsed
|
|
55
|
+
if remaining <= 0:
|
|
56
|
+
raise TimeoutError(
|
|
57
|
+
f"Context manager exceeded the configured timeout of {total_timeout}s."
|
|
58
|
+
)
|
|
59
|
+
return remaining
|
|
60
|
+
|
|
61
|
+
async def with_timeout(coro):
|
|
62
|
+
try:
|
|
63
|
+
remaining = _remaining_time()
|
|
64
|
+
response = await asyncio.wait_for(coro, remaining)
|
|
65
|
+
return response
|
|
66
|
+
except (asyncio.TimeoutError, TimeoutError) as e:
|
|
67
|
+
raise TimeoutError(
|
|
68
|
+
f"The operation {coro} exceeded the configured timeout of {total_timeout}s."
|
|
69
|
+
) from e
|
|
70
|
+
|
|
71
|
+
try:
|
|
72
|
+
yield with_timeout
|
|
73
|
+
|
|
74
|
+
finally:
|
|
75
|
+
_remaining_time()
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class AsyncAuthorizedSession:
|
|
79
|
+
"""This is an asynchronous implementation of :class:`google.auth.requests.AuthorizedSession` class.
|
|
80
|
+
We utilize an instance of a class that implements :class:`google.auth.aio.transport.Request` configured
|
|
81
|
+
by the caller or otherwise default to `google.auth.aio.transport.aiohttp.Request` if the external aiohttp
|
|
82
|
+
package is installed.
|
|
83
|
+
|
|
84
|
+
A Requests Session class with credentials.
|
|
85
|
+
|
|
86
|
+
This class is used to perform asynchronous requests to API endpoints that require
|
|
87
|
+
authorization::
|
|
88
|
+
|
|
89
|
+
import aiohttp
|
|
90
|
+
from google.auth.aio.transport import sessions
|
|
91
|
+
|
|
92
|
+
async with sessions.AsyncAuthorizedSession(credentials) as authed_session:
|
|
93
|
+
response = await authed_session.request(
|
|
94
|
+
'GET', 'https://www.googleapis.com/storage/v1/b')
|
|
95
|
+
|
|
96
|
+
The underlying :meth:`request` implementation handles adding the
|
|
97
|
+
credentials' headers to the request and refreshing credentials as needed.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
credentials (google.auth.aio.credentials.Credentials):
|
|
101
|
+
The credentials to add to the request.
|
|
102
|
+
auth_request (Optional[google.auth.aio.transport.Request]):
|
|
103
|
+
An instance of a class that implements
|
|
104
|
+
:class:`~google.auth.aio.transport.Request` used to make requests
|
|
105
|
+
and refresh credentials. If not passed,
|
|
106
|
+
an instance of :class:`~google.auth.aio.transport.aiohttp.Request`
|
|
107
|
+
is created.
|
|
108
|
+
|
|
109
|
+
Raises:
|
|
110
|
+
- google.auth.exceptions.TransportError: If `auth_request` is `None`
|
|
111
|
+
and the external package `aiohttp` is not installed.
|
|
112
|
+
- google.auth.exceptions.InvalidType: If the provided credentials are
|
|
113
|
+
not of type `google.auth.aio.credentials.Credentials`.
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
def __init__(
|
|
117
|
+
self, credentials: Credentials, auth_request: Optional[transport.Request] = None
|
|
118
|
+
):
|
|
119
|
+
if not isinstance(credentials, Credentials):
|
|
120
|
+
raise exceptions.InvalidType(
|
|
121
|
+
f"The configured credentials of type {type(credentials)} are invalid and must be of type `google.auth.aio.credentials.Credentials`"
|
|
122
|
+
)
|
|
123
|
+
self._credentials = credentials
|
|
124
|
+
_auth_request = auth_request
|
|
125
|
+
if not _auth_request and AIOHTTP_INSTALLED:
|
|
126
|
+
_auth_request = AiohttpRequest()
|
|
127
|
+
if _auth_request is None:
|
|
128
|
+
raise exceptions.TransportError(
|
|
129
|
+
"`auth_request` must either be configured or the external package `aiohttp` must be installed to use the default value."
|
|
130
|
+
)
|
|
131
|
+
self._auth_request = _auth_request
|
|
132
|
+
|
|
133
|
+
async def request(
|
|
134
|
+
self,
|
|
135
|
+
method: str,
|
|
136
|
+
url: str,
|
|
137
|
+
data: Optional[bytes] = None,
|
|
138
|
+
headers: Optional[Mapping[str, str]] = None,
|
|
139
|
+
max_allowed_time: float = transport._DEFAULT_TIMEOUT_SECONDS,
|
|
140
|
+
timeout: float = transport._DEFAULT_TIMEOUT_SECONDS,
|
|
141
|
+
**kwargs,
|
|
142
|
+
) -> transport.Response:
|
|
143
|
+
"""
|
|
144
|
+
Args:
|
|
145
|
+
method (str): The http method used to make the request.
|
|
146
|
+
url (str): The URI to be requested.
|
|
147
|
+
data (Optional[bytes]): The payload or body in HTTP request.
|
|
148
|
+
headers (Optional[Mapping[str, str]]): Request headers.
|
|
149
|
+
timeout (float):
|
|
150
|
+
The amount of time in seconds to wait for the server response
|
|
151
|
+
with each individual request.
|
|
152
|
+
max_allowed_time (float):
|
|
153
|
+
If the method runs longer than this, a ``Timeout`` exception is
|
|
154
|
+
automatically raised. Unlike the ``timeout`` parameter, this
|
|
155
|
+
value applies to the total method execution time, even if
|
|
156
|
+
multiple requests are made under the hood.
|
|
157
|
+
|
|
158
|
+
Mind that it is not guaranteed that the timeout error is raised
|
|
159
|
+
at ``max_allowed_time``. It might take longer, for example, if
|
|
160
|
+
an underlying request takes a lot of time, but the request
|
|
161
|
+
itself does not timeout, e.g. if a large file is being
|
|
162
|
+
transmitted. The timeout error will be raised after such
|
|
163
|
+
request completes.
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
google.auth.aio.transport.Response: The HTTP response.
|
|
167
|
+
|
|
168
|
+
Raises:
|
|
169
|
+
google.auth.exceptions.TimeoutError: If the method does not complete within
|
|
170
|
+
the configured `max_allowed_time` or the request exceeds the configured
|
|
171
|
+
`timeout`.
|
|
172
|
+
"""
|
|
173
|
+
|
|
174
|
+
retries = _exponential_backoff.AsyncExponentialBackoff(
|
|
175
|
+
total_attempts=transport.DEFAULT_MAX_RETRY_ATTEMPTS
|
|
176
|
+
)
|
|
177
|
+
async with timeout_guard(max_allowed_time) as with_timeout:
|
|
178
|
+
await with_timeout(
|
|
179
|
+
# Note: before_request will attempt to refresh credentials if expired.
|
|
180
|
+
self._credentials.before_request(
|
|
181
|
+
self._auth_request, method, url, headers
|
|
182
|
+
)
|
|
183
|
+
)
|
|
184
|
+
# Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch`
|
|
185
|
+
# See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372
|
|
186
|
+
async for _ in retries: # pragma: no branch
|
|
187
|
+
response = await with_timeout(
|
|
188
|
+
self._auth_request(url, method, data, headers, timeout, **kwargs)
|
|
189
|
+
)
|
|
190
|
+
if response.status_code not in transport.DEFAULT_RETRYABLE_STATUS_CODES:
|
|
191
|
+
break
|
|
192
|
+
return response
|
|
193
|
+
|
|
194
|
+
@functools.wraps(request)
|
|
195
|
+
async def get(
|
|
196
|
+
self,
|
|
197
|
+
url: str,
|
|
198
|
+
data: Optional[bytes] = None,
|
|
199
|
+
headers: Optional[Mapping[str, str]] = None,
|
|
200
|
+
max_allowed_time: float = transport._DEFAULT_TIMEOUT_SECONDS,
|
|
201
|
+
timeout: float = transport._DEFAULT_TIMEOUT_SECONDS,
|
|
202
|
+
**kwargs,
|
|
203
|
+
) -> transport.Response:
|
|
204
|
+
return await self.request(
|
|
205
|
+
"GET", url, data, headers, max_allowed_time, timeout, **kwargs
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
@functools.wraps(request)
|
|
209
|
+
async def post(
|
|
210
|
+
self,
|
|
211
|
+
url: str,
|
|
212
|
+
data: Optional[bytes] = None,
|
|
213
|
+
headers: Optional[Mapping[str, str]] = None,
|
|
214
|
+
max_allowed_time: float = transport._DEFAULT_TIMEOUT_SECONDS,
|
|
215
|
+
timeout: float = transport._DEFAULT_TIMEOUT_SECONDS,
|
|
216
|
+
**kwargs,
|
|
217
|
+
) -> transport.Response:
|
|
218
|
+
return await self.request(
|
|
219
|
+
"POST", url, data, headers, max_allowed_time, timeout, **kwargs
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
@functools.wraps(request)
|
|
223
|
+
async def put(
|
|
224
|
+
self,
|
|
225
|
+
url: str,
|
|
226
|
+
data: Optional[bytes] = None,
|
|
227
|
+
headers: Optional[Mapping[str, str]] = None,
|
|
228
|
+
max_allowed_time: float = transport._DEFAULT_TIMEOUT_SECONDS,
|
|
229
|
+
timeout: float = transport._DEFAULT_TIMEOUT_SECONDS,
|
|
230
|
+
**kwargs,
|
|
231
|
+
) -> transport.Response:
|
|
232
|
+
return await self.request(
|
|
233
|
+
"PUT", url, data, headers, max_allowed_time, timeout, **kwargs
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
@functools.wraps(request)
|
|
237
|
+
async def patch(
|
|
238
|
+
self,
|
|
239
|
+
url: str,
|
|
240
|
+
data: Optional[bytes] = None,
|
|
241
|
+
headers: Optional[Mapping[str, str]] = None,
|
|
242
|
+
max_allowed_time: float = transport._DEFAULT_TIMEOUT_SECONDS,
|
|
243
|
+
timeout: float = transport._DEFAULT_TIMEOUT_SECONDS,
|
|
244
|
+
**kwargs,
|
|
245
|
+
) -> transport.Response:
|
|
246
|
+
return await self.request(
|
|
247
|
+
"PATCH", url, data, headers, max_allowed_time, timeout, **kwargs
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
@functools.wraps(request)
|
|
251
|
+
async def delete(
|
|
252
|
+
self,
|
|
253
|
+
url: str,
|
|
254
|
+
data: Optional[bytes] = None,
|
|
255
|
+
headers: Optional[Mapping[str, str]] = None,
|
|
256
|
+
max_allowed_time: float = transport._DEFAULT_TIMEOUT_SECONDS,
|
|
257
|
+
timeout: float = transport._DEFAULT_TIMEOUT_SECONDS,
|
|
258
|
+
**kwargs,
|
|
259
|
+
) -> transport.Response:
|
|
260
|
+
return await self.request(
|
|
261
|
+
"DELETE", url, data, headers, max_allowed_time, timeout, **kwargs
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
async def close(self) -> None:
|
|
265
|
+
"""
|
|
266
|
+
Close the underlying auth request session.
|
|
267
|
+
"""
|
|
268
|
+
await self._auth_request.close()
|
|
@@ -24,7 +24,6 @@ from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey
|
|
|
24
24
|
|
|
25
25
|
from google.auth import _helpers
|
|
26
26
|
from google.auth.crypt import _cryptography_rsa
|
|
27
|
-
from google.auth.crypt import _python_rsa
|
|
28
27
|
from google.auth.crypt import base
|
|
29
28
|
|
|
30
29
|
RSA_KEY_MODULE_PREFIX = "rsa.key"
|
|
@@ -37,6 +36,7 @@ class RSAVerifier(base.Verifier):
|
|
|
37
36
|
public_key (Union["rsa.key.PublicKey", cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey]):
|
|
38
37
|
The public key used to verify signatures.
|
|
39
38
|
Raises:
|
|
39
|
+
ImportError: if called with an rsa.key.PublicKey, when the rsa library is not installed
|
|
40
40
|
ValueError: if an unrecognized public key is provided
|
|
41
41
|
"""
|
|
42
42
|
|
|
@@ -45,6 +45,8 @@ class RSAVerifier(base.Verifier):
|
|
|
45
45
|
if isinstance(public_key, RSAPublicKey):
|
|
46
46
|
impl_lib = _cryptography_rsa
|
|
47
47
|
elif module_str.startswith(RSA_KEY_MODULE_PREFIX):
|
|
48
|
+
from google.auth.crypt import _python_rsa
|
|
49
|
+
|
|
48
50
|
impl_lib = _python_rsa
|
|
49
51
|
else:
|
|
50
52
|
raise ValueError(f"unrecognized public key type: {type(public_key)}")
|
|
@@ -85,6 +87,7 @@ class RSASigner(base.Signer, base.FromServiceAccountMixin):
|
|
|
85
87
|
public key or certificate.
|
|
86
88
|
|
|
87
89
|
Raises:
|
|
90
|
+
ImportError: if called with an rsa.key.PrivateKey, when the rsa library is not installed
|
|
88
91
|
ValueError: if an unrecognized public key is provided
|
|
89
92
|
"""
|
|
90
93
|
|
|
@@ -93,6 +96,8 @@ class RSASigner(base.Signer, base.FromServiceAccountMixin):
|
|
|
93
96
|
if isinstance(private_key, RSAPrivateKey):
|
|
94
97
|
impl_lib = _cryptography_rsa
|
|
95
98
|
elif module_str.startswith(RSA_KEY_MODULE_PREFIX):
|
|
99
|
+
from google.auth.crypt import _python_rsa
|
|
100
|
+
|
|
96
101
|
impl_lib = _python_rsa
|
|
97
102
|
else:
|
|
98
103
|
raise ValueError(f"unrecognized private key type: {type(private_key)}")
|
|
@@ -113,18 +113,6 @@ GOOGLE_API_CERTIFICATE_CONFIG = "GOOGLE_API_CERTIFICATE_CONFIG"
|
|
|
113
113
|
"""Environment variable defining the location of Google API certificate config
|
|
114
114
|
file."""
|
|
115
115
|
|
|
116
|
-
CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE = (
|
|
117
|
-
"CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE"
|
|
118
|
-
)
|
|
119
|
-
"""Environment variable controlling whether to use client certificate or not.
|
|
120
|
-
This variable is the fallback of GOOGLE_API_USE_CLIENT_CERTIFICATE."""
|
|
121
|
-
|
|
122
|
-
CLOUDSDK_CONTEXT_AWARE_CERTIFICATE_CONFIG_FILE_PATH = (
|
|
123
|
-
"CLOUDSDK_CONTEXT_AWARE_CERTIFICATE_CONFIG_FILE_PATH"
|
|
124
|
-
)
|
|
125
|
-
"""Environment variable defining the location of Google API certificate config
|
|
126
|
-
file. This variable is the fallback of GOOGLE_API_CERTIFICATE_CONFIG."""
|
|
127
|
-
|
|
128
116
|
GOOGLE_API_PREVENT_AGENT_TOKEN_SHARING_FOR_GCP_SERVICES = (
|
|
129
117
|
"GOOGLE_API_PREVENT_AGENT_TOKEN_SHARING_FOR_GCP_SERVICES"
|
|
130
118
|
)
|
|
@@ -22,13 +22,14 @@ API`_'s auth-related functionality.
|
|
|
22
22
|
import base64
|
|
23
23
|
import http.client as http_client
|
|
24
24
|
import json
|
|
25
|
+
import os
|
|
25
26
|
|
|
26
27
|
from google.auth import _exponential_backoff
|
|
27
28
|
from google.auth import _helpers
|
|
28
29
|
from google.auth import credentials
|
|
29
30
|
from google.auth import crypt
|
|
30
31
|
from google.auth import exceptions
|
|
31
|
-
from google.auth.transport import
|
|
32
|
+
from google.auth.transport import mtls
|
|
32
33
|
|
|
33
34
|
IAM_RETRY_CODES = {
|
|
34
35
|
http_client.INTERNAL_SERVER_ERROR,
|
|
@@ -39,12 +40,20 @@ IAM_RETRY_CODES = {
|
|
|
39
40
|
|
|
40
41
|
_IAM_SCOPE = ["https://www.googleapis.com/auth/iam"]
|
|
41
42
|
|
|
42
|
-
# Determine if we should use mTLS.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
#
|
|
43
|
+
# 1. Determine if we should use mTLS.
|
|
44
|
+
# Note: We only support automatic mTLS on the default googleapis.com universe.
|
|
45
|
+
if hasattr(mtls, "should_use_client_cert"):
|
|
46
|
+
use_client_cert = mtls.should_use_client_cert()
|
|
47
|
+
else: # pragma: NO COVER
|
|
48
|
+
# if unsupported, fallback to reading from env var
|
|
49
|
+
use_client_cert = (
|
|
50
|
+
os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false").lower() == "true"
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
# 2. Construct the template domain using the library's DEFAULT_UNIVERSE_DOMAIN constant.
|
|
54
|
+
# This ensures that the .replace() calls in the classes will work correctly.
|
|
55
|
+
if use_client_cert:
|
|
56
|
+
# We use the .mtls. prefix only for the default universe template
|
|
48
57
|
_IAM_DOMAIN = f"iamcredentials.mtls.{credentials.DEFAULT_UNIVERSE_DOMAIN}"
|
|
49
58
|
else:
|
|
50
59
|
_IAM_DOMAIN = f"iamcredentials.{credentials.DEFAULT_UNIVERSE_DOMAIN}"
|
|
@@ -25,8 +25,6 @@ from google.auth import environment_vars
|
|
|
25
25
|
from google.auth import exceptions
|
|
26
26
|
|
|
27
27
|
CONTEXT_AWARE_METADATA_PATH = "~/.secureConnect/context_aware_metadata.json"
|
|
28
|
-
|
|
29
|
-
# Default gcloud config path, to be used with path.expanduser for cross-platform compatibility.
|
|
30
28
|
CERTIFICATE_CONFIGURATION_DEFAULT_PATH = "~/.config/gcloud/certificate_config.json"
|
|
31
29
|
_CERT_PROVIDER_COMMAND = "cert_provider_command"
|
|
32
30
|
_CERT_REGEX = re.compile(
|
|
@@ -105,9 +103,7 @@ def _load_json_file(path):
|
|
|
105
103
|
return json_data
|
|
106
104
|
|
|
107
105
|
|
|
108
|
-
def _get_workload_cert_and_key(
|
|
109
|
-
certificate_config_path=None, include_context_aware=True
|
|
110
|
-
):
|
|
106
|
+
def _get_workload_cert_and_key(certificate_config_path=None):
|
|
111
107
|
"""Read the workload identity cert and key files specified in the certificate config provided.
|
|
112
108
|
If no config path is provided, check the environment variable: "GOOGLE_API_CERTIFICATE_CONFIG"
|
|
113
109
|
first, then the well known gcloud location: "~/.config/gcloud/certificate_config.json".
|
|
@@ -115,8 +111,6 @@ def _get_workload_cert_and_key(
|
|
|
115
111
|
Args:
|
|
116
112
|
certificate_config_path (string): The certificate config path. If no path is provided,
|
|
117
113
|
the environment variable will be checked first, then the well known gcloud location.
|
|
118
|
-
include_context_aware (bool): If context aware metadata path should be checked for the
|
|
119
|
-
SecureConnect mTLS configuration.
|
|
120
114
|
|
|
121
115
|
Returns:
|
|
122
116
|
Tuple[Optional[bytes], Optional[bytes]]: client certificate bytes in PEM format and key
|
|
@@ -127,9 +121,7 @@ def _get_workload_cert_and_key(
|
|
|
127
121
|
the certificate or key information.
|
|
128
122
|
"""
|
|
129
123
|
|
|
130
|
-
cert_path, key_path = _get_workload_cert_and_key_paths(
|
|
131
|
-
certificate_config_path, include_context_aware
|
|
132
|
-
)
|
|
124
|
+
cert_path, key_path = _get_workload_cert_and_key_paths(certificate_config_path)
|
|
133
125
|
|
|
134
126
|
if cert_path is None and key_path is None:
|
|
135
127
|
return None, None
|
|
@@ -137,7 +129,7 @@ def _get_workload_cert_and_key(
|
|
|
137
129
|
return _read_cert_and_key_files(cert_path, key_path)
|
|
138
130
|
|
|
139
131
|
|
|
140
|
-
def _get_cert_config_path(certificate_config_path=None
|
|
132
|
+
def _get_cert_config_path(certificate_config_path=None):
|
|
141
133
|
"""Get the certificate configuration path based on the following order:
|
|
142
134
|
|
|
143
135
|
1: Explicit override, if set
|
|
@@ -149,8 +141,6 @@ def _get_cert_config_path(certificate_config_path=None, include_context_aware=Tr
|
|
|
149
141
|
Args:
|
|
150
142
|
certificate_config_path (string): The certificate config path. If provided, the well known
|
|
151
143
|
location and environment variable will be ignored.
|
|
152
|
-
include_context_aware (bool): If context aware metadata path should be checked for the
|
|
153
|
-
SecureConnect mTLS configuration.
|
|
154
144
|
|
|
155
145
|
Returns:
|
|
156
146
|
The absolute path of the certificate config file, and None if the file does not exist.
|
|
@@ -161,14 +151,7 @@ def _get_cert_config_path(certificate_config_path=None, include_context_aware=Tr
|
|
|
161
151
|
if env_path is not None and env_path != "":
|
|
162
152
|
certificate_config_path = env_path
|
|
163
153
|
else:
|
|
164
|
-
|
|
165
|
-
environment_vars.CLOUDSDK_CONTEXT_AWARE_CERTIFICATE_CONFIG_FILE_PATH,
|
|
166
|
-
None,
|
|
167
|
-
)
|
|
168
|
-
if include_context_aware and env_path is not None and env_path != "":
|
|
169
|
-
certificate_config_path = env_path
|
|
170
|
-
else:
|
|
171
|
-
certificate_config_path = CERTIFICATE_CONFIGURATION_DEFAULT_PATH
|
|
154
|
+
certificate_config_path = CERTIFICATE_CONFIGURATION_DEFAULT_PATH
|
|
172
155
|
|
|
173
156
|
certificate_config_path = path.expanduser(certificate_config_path)
|
|
174
157
|
if not path.exists(certificate_config_path):
|
|
@@ -176,8 +159,8 @@ def _get_cert_config_path(certificate_config_path=None, include_context_aware=Tr
|
|
|
176
159
|
return certificate_config_path
|
|
177
160
|
|
|
178
161
|
|
|
179
|
-
def _get_workload_cert_and_key_paths(config_path
|
|
180
|
-
absolute_path = _get_cert_config_path(config_path
|
|
162
|
+
def _get_workload_cert_and_key_paths(config_path):
|
|
163
|
+
absolute_path = _get_cert_config_path(config_path)
|
|
181
164
|
if absolute_path is None:
|
|
182
165
|
return None, None
|
|
183
166
|
|
|
@@ -191,21 +174,28 @@ def _get_workload_cert_and_key_paths(config_path, include_context_aware=True):
|
|
|
191
174
|
)
|
|
192
175
|
cert_configs = data["cert_configs"]
|
|
193
176
|
|
|
194
|
-
# We return None, None if the expected workload fields are not present.
|
|
195
|
-
# The certificate config might be present for other types of connections (e.g. gECC),
|
|
196
|
-
# and we want to gracefully fallback to testing other mTLS configurations
|
|
197
|
-
# like SecureConnect instead of throwing an exception.
|
|
198
|
-
|
|
199
177
|
if "workload" not in cert_configs:
|
|
200
|
-
|
|
178
|
+
raise exceptions.ClientCertError(
|
|
179
|
+
'Certificate config file {} is in an invalid format, a "workload" cert config is expected'.format(
|
|
180
|
+
absolute_path
|
|
181
|
+
)
|
|
182
|
+
)
|
|
201
183
|
workload = cert_configs["workload"]
|
|
202
184
|
|
|
203
185
|
if "cert_path" not in workload:
|
|
204
|
-
|
|
186
|
+
raise exceptions.ClientCertError(
|
|
187
|
+
'Certificate config file {} is in an invalid format, a "cert_path" is expected in the workload cert config'.format(
|
|
188
|
+
absolute_path
|
|
189
|
+
)
|
|
190
|
+
)
|
|
205
191
|
cert_path = workload["cert_path"]
|
|
206
192
|
|
|
207
193
|
if "key_path" not in workload:
|
|
208
|
-
|
|
194
|
+
raise exceptions.ClientCertError(
|
|
195
|
+
'Certificate config file {} is in an invalid format, a "key_path" is expected in the workload cert config'.format(
|
|
196
|
+
absolute_path
|
|
197
|
+
)
|
|
198
|
+
)
|
|
209
199
|
key_path = workload["key_path"]
|
|
210
200
|
|
|
211
201
|
# == BEGIN Temporary Cloud Run PATCH ==
|
|
@@ -462,23 +452,13 @@ def check_use_client_cert():
|
|
|
462
452
|
Returns:
|
|
463
453
|
bool: Whether the client certificate should be used for mTLS connection.
|
|
464
454
|
"""
|
|
465
|
-
use_client_cert = getenv(
|
|
466
|
-
if use_client_cert is None or use_client_cert == "":
|
|
467
|
-
use_client_cert = getenv(
|
|
468
|
-
environment_vars.CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE
|
|
469
|
-
)
|
|
470
|
-
|
|
455
|
+
use_client_cert = getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE")
|
|
471
456
|
# Check if the value of GOOGLE_API_USE_CLIENT_CERTIFICATE is set.
|
|
472
457
|
if use_client_cert:
|
|
473
458
|
return use_client_cert.lower() == "true"
|
|
474
459
|
else:
|
|
475
460
|
# Check if the value of GOOGLE_API_CERTIFICATE_CONFIG is set.
|
|
476
|
-
cert_path = getenv(
|
|
477
|
-
if cert_path is None:
|
|
478
|
-
cert_path = getenv(
|
|
479
|
-
environment_vars.CLOUDSDK_CONTEXT_AWARE_CERTIFICATE_CONFIG_FILE_PATH
|
|
480
|
-
)
|
|
481
|
-
|
|
461
|
+
cert_path = getenv("GOOGLE_API_CERTIFICATE_CONFIG")
|
|
482
462
|
if cert_path:
|
|
483
463
|
try:
|
|
484
464
|
with open(cert_path, "r") as f:
|
|
@@ -20,19 +20,14 @@ from google.auth import exceptions
|
|
|
20
20
|
from google.auth.transport import _mtls_helper
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
def has_default_client_cert_source(
|
|
23
|
+
def has_default_client_cert_source():
|
|
24
24
|
"""Check if default client SSL credentials exists on the device.
|
|
25
25
|
|
|
26
|
-
Args:
|
|
27
|
-
include_context_aware (bool): include_context_aware indicates if context_aware
|
|
28
|
-
path location will be checked or should it be skipped.
|
|
29
|
-
|
|
30
26
|
Returns:
|
|
31
27
|
bool: indicating if the default client cert source exists.
|
|
32
28
|
"""
|
|
33
29
|
if (
|
|
34
|
-
|
|
35
|
-
and _mtls_helper._check_config_path(_mtls_helper.CONTEXT_AWARE_METADATA_PATH)
|
|
30
|
+
_mtls_helper._check_config_path(_mtls_helper.CONTEXT_AWARE_METADATA_PATH)
|
|
36
31
|
is not None
|
|
37
32
|
):
|
|
38
33
|
return True
|
|
@@ -63,7 +58,7 @@ def default_client_cert_source():
|
|
|
63
58
|
google.auth.exceptions.DefaultClientCertSourceError: If the default
|
|
64
59
|
client SSL credentials don't exist or are malformed.
|
|
65
60
|
"""
|
|
66
|
-
if not has_default_client_cert_source(
|
|
61
|
+
if not has_default_client_cert_source():
|
|
67
62
|
raise exceptions.MutualTLSChannelError(
|
|
68
63
|
"Default client cert source doesn't exist"
|
|
69
64
|
)
|
|
@@ -99,7 +94,7 @@ def default_client_encrypted_cert_source(cert_path, key_path):
|
|
|
99
94
|
google.auth.exceptions.DefaultClientCertSourceError: If any problem
|
|
100
95
|
occurs when loading or saving the client certificate and key.
|
|
101
96
|
"""
|
|
102
|
-
if not has_default_client_cert_source(
|
|
97
|
+
if not has_default_client_cert_source():
|
|
103
98
|
raise exceptions.MutualTLSChannelError(
|
|
104
99
|
"Default client encrypted cert source doesn't exist"
|
|
105
100
|
)
|