├── .coveragerc
├── .flake8
├── .github
├── .OwlBot.lock.yaml
├── .OwlBot.yaml
├── CODEOWNERS
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── feature_request.md
│ └── support_request.md
├── release-please.yml
├── release-trigger.yml
└── sync-repo-settings.yaml
├── .gitignore
├── .kokoro
├── build-systests.sh
├── build.sh
├── common.cfg
├── continuous
│ ├── common.cfg
│ ├── continuous.cfg
│ └── prerelease-deps.cfg
├── populate-secrets.sh
├── presubmit
│ ├── common.cfg
│ ├── prerelease-deps.cfg
│ ├── presubmit.cfg
│ └── system-3.7.cfg
├── samples-test-setup.sh
├── samples
│ ├── lint
│ │ ├── common.cfg
│ │ ├── continuous.cfg
│ │ ├── periodic.cfg
│ │ └── presubmit.cfg
│ ├── python3.10
│ │ ├── common.cfg
│ │ ├── continuous.cfg
│ │ ├── periodic-head.cfg
│ │ ├── periodic.cfg
│ │ └── presubmit.cfg
│ ├── python3.11
│ │ ├── common.cfg
│ │ ├── continuous.cfg
│ │ ├── periodic-head.cfg
│ │ ├── periodic.cfg
│ │ └── presubmit.cfg
│ ├── python3.12
│ │ ├── common.cfg
│ │ ├── continuous.cfg
│ │ ├── periodic-head.cfg
│ │ ├── periodic.cfg
│ │ └── presubmit.cfg
│ ├── python3.13
│ │ ├── common.cfg
│ │ ├── continuous.cfg
│ │ ├── periodic-head.cfg
│ │ ├── periodic.cfg
│ │ └── presubmit.cfg
│ ├── python3.7
│ │ ├── common.cfg
│ │ ├── continuous.cfg
│ │ ├── periodic-head.cfg
│ │ ├── periodic.cfg
│ │ └── presubmit.cfg
│ ├── python3.8
│ │ ├── common.cfg
│ │ ├── continuous.cfg
│ │ ├── periodic-head.cfg
│ │ ├── periodic.cfg
│ │ └── presubmit.cfg
│ └── python3.9
│ │ ├── common.cfg
│ │ ├── continuous.cfg
│ │ ├── periodic-head.cfg
│ │ ├── periodic.cfg
│ │ └── presubmit.cfg
├── test-samples-against-head.sh
├── test-samples-impl.sh
├── test-samples.sh
├── trampoline.sh
└── trampoline_v2.sh
├── .readthedocs.yaml
├── .repo-metadata.json
├── .trampolinerc
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.rst
├── CONTRIBUTORS.md
├── LICENSE
├── MANIFEST.in
├── README.rst
├── SECURITY.md
├── docs
├── _static
│ └── custom.css
├── conf.py
├── index.rst
├── oauth2client-deprecation.rst
├── reference
│ ├── google.auth._credentials_async.rst
│ ├── google.auth._jwt_async.rst
│ ├── google.auth.app_engine.rst
│ ├── google.auth.aws.rst
│ ├── google.auth.compute_engine.credentials.rst
│ ├── google.auth.compute_engine.rst
│ ├── google.auth.credentials.rst
│ ├── google.auth.crypt.base.rst
│ ├── google.auth.crypt.es256.rst
│ ├── google.auth.crypt.rsa.rst
│ ├── google.auth.crypt.rst
│ ├── google.auth.downscoped.rst
│ ├── google.auth.environment_vars.rst
│ ├── google.auth.exceptions.rst
│ ├── google.auth.external_account.rst
│ ├── google.auth.iam.rst
│ ├── google.auth.identity_pool.rst
│ ├── google.auth.impersonated_credentials.rst
│ ├── google.auth.jwt.rst
│ ├── google.auth.rst
│ ├── google.auth.transport._aiohttp_requests.rst
│ ├── google.auth.transport.grpc.rst
│ ├── google.auth.transport.mtls.rst
│ ├── google.auth.transport.requests.rst
│ ├── google.auth.transport.rst
│ ├── google.auth.transport.urllib3.rst
│ ├── google.oauth2._credentials_async.rst
│ ├── google.oauth2._service_account_async.rst
│ ├── google.oauth2.credentials.rst
│ ├── google.oauth2.id_token.rst
│ ├── google.oauth2.rst
│ ├── google.oauth2.service_account.rst
│ ├── google.oauth2.sts.rst
│ ├── google.oauth2.utils.rst
│ ├── google.rst
│ └── modules.rst
├── requirements-docs.txt
└── user-guide.rst
├── google
├── auth
│ ├── __init__.py
│ ├── _cloud_sdk.py
│ ├── _credentials_async.py
│ ├── _credentials_base.py
│ ├── _default.py
│ ├── _default_async.py
│ ├── _exponential_backoff.py
│ ├── _helpers.py
│ ├── _jwt_async.py
│ ├── _oauth2client.py
│ ├── _refresh_worker.py
│ ├── _service_account_info.py
│ ├── aio
│ │ ├── __init__.py
│ │ ├── _helpers.py
│ │ ├── credentials.py
│ │ └── transport
│ │ │ ├── __init__.py
│ │ │ ├── aiohttp.py
│ │ │ └── sessions.py
│ ├── api_key.py
│ ├── app_engine.py
│ ├── aws.py
│ ├── compute_engine
│ │ ├── __init__.py
│ │ ├── _metadata.py
│ │ └── credentials.py
│ ├── credentials.py
│ ├── crypt
│ │ ├── __init__.py
│ │ ├── _cryptography_rsa.py
│ │ ├── _helpers.py
│ │ ├── _python_rsa.py
│ │ ├── base.py
│ │ ├── es256.py
│ │ └── rsa.py
│ ├── downscoped.py
│ ├── environment_vars.py
│ ├── exceptions.py
│ ├── external_account.py
│ ├── external_account_authorized_user.py
│ ├── iam.py
│ ├── identity_pool.py
│ ├── impersonated_credentials.py
│ ├── jwt.py
│ ├── metrics.py
│ ├── pluggable.py
│ ├── py.typed
│ ├── transport
│ │ ├── __init__.py
│ │ ├── _aiohttp_requests.py
│ │ ├── _custom_tls_signer.py
│ │ ├── _http_client.py
│ │ ├── _mtls_helper.py
│ │ ├── _requests_base.py
│ │ ├── grpc.py
│ │ ├── mtls.py
│ │ ├── requests.py
│ │ └── urllib3.py
│ └── version.py
└── oauth2
│ ├── __init__.py
│ ├── _client.py
│ ├── _client_async.py
│ ├── _credentials_async.py
│ ├── _id_token_async.py
│ ├── _reauth_async.py
│ ├── _service_account_async.py
│ ├── challenges.py
│ ├── credentials.py
│ ├── gdch_credentials.py
│ ├── id_token.py
│ ├── py.typed
│ ├── reauth.py
│ ├── service_account.py
│ ├── sts.py
│ ├── utils.py
│ ├── webauthn_handler.py
│ ├── webauthn_handler_factory.py
│ └── webauthn_types.py
├── mypy.ini
├── noxfile.py
├── owlbot.py
├── renovate.json
├── samples
└── cloud-client
│ └── snippets
│ ├── authenticate_explicit_with_adc.py
│ ├── authenticate_implicit_with_adc.py
│ ├── idtoken_from_impersonated_credentials.py
│ ├── idtoken_from_metadata_server.py
│ ├── idtoken_from_service_account.py
│ ├── noxfile.py
│ ├── noxfile_config.py
│ ├── requirements.txt
│ ├── snippets_test.py
│ └── verify_google_idtoken.py
├── scripts
├── decrypt-secrets.sh
├── encrypt-secrets.sh
├── setup_external_accounts.sh
└── travis.sh
├── setup.cfg
├── setup.py
├── system_tests
├── __init__.py
├── noxfile.py
├── secrets.tar.enc
├── system_tests_async
│ ├── __init__.py
│ ├── conftest.py
│ ├── test_default.py
│ ├── test_id_token.py
│ └── test_service_account.py
└── system_tests_sync
│ ├── .gitignore
│ ├── __init__.py
│ ├── conftest.py
│ ├── secrets.tar.enc
│ ├── test_compute_engine.py
│ ├── test_default.py
│ ├── test_downscoping.py
│ ├── test_external_accounts.py
│ ├── test_grpc.py
│ ├── test_id_token.py
│ ├── test_impersonated_credentials.py
│ ├── test_mtls_http.py
│ ├── test_oauth2_credentials.py
│ ├── test_requests.py
│ ├── test_service_account.py
│ └── test_urllib3.py
├── testing
├── constraints-3.10.txt
├── constraints-3.11.txt
├── constraints-3.12.txt
├── constraints-3.13.txt
├── constraints-3.7.txt
├── constraints-3.8.txt
└── constraints-3.9.txt
├── tests
├── __init__.py
├── aio
│ └── test__helpers.py
├── compute_engine
│ ├── __init__.py
│ ├── data
│ │ ├── smbios_product_name
│ │ └── smbios_product_name_non_google
│ ├── test__metadata.py
│ └── test_credentials.py
├── conftest.py
├── crypt
│ ├── __init__.py
│ ├── test__cryptography_rsa.py
│ ├── test__python_rsa.py
│ ├── test_crypt.py
│ └── test_es256.py
├── data
│ ├── authorized_user.json
│ ├── authorized_user_cloud_sdk.json
│ ├── authorized_user_cloud_sdk_with_quota_project_id.json
│ ├── authorized_user_with_rapt_token.json
│ ├── client_secrets.json
│ ├── context_aware_metadata.json
│ ├── enterprise_cert_invalid.json
│ ├── enterprise_cert_valid.json
│ ├── enterprise_cert_valid_provider.json
│ ├── es256_privatekey.pem
│ ├── es256_public_cert.pem
│ ├── es256_publickey.pem
│ ├── es256_service_account.json
│ ├── external_account_authorized_user.json
│ ├── external_account_authorized_user_non_gdu.json
│ ├── external_subject_token.json
│ ├── external_subject_token.txt
│ ├── gdch_service_account.json
│ ├── impersonated_service_account_authorized_user_source.json
│ ├── impersonated_service_account_external_account_authorized_user_source.json
│ ├── impersonated_service_account_service_account_source.json
│ ├── impersonated_service_account_with_quota_project.json
│ ├── old_oauth_credentials_py3.pickle
│ ├── other_cert.pem
│ ├── pem_from_pkcs12.pem
│ ├── privatekey.p12
│ ├── privatekey.pem
│ ├── privatekey.pub
│ ├── public_cert.pem
│ ├── service_account.json
│ ├── service_account_non_gdu.json
│ ├── trust_chain_with_leaf.pem
│ ├── trust_chain_without_leaf.pem
│ └── trust_chain_wrong_order.pem
├── oauth2
│ ├── __init__.py
│ ├── test__client.py
│ ├── test_challenges.py
│ ├── test_credentials.py
│ ├── test_gdch_credentials.py
│ ├── test_id_token.py
│ ├── test_reauth.py
│ ├── test_service_account.py
│ ├── test_sts.py
│ ├── test_utils.py
│ ├── test_webauthn_handler.py
│ ├── test_webauthn_handler_factory.py
│ └── test_webauthn_types.py
├── test__cloud_sdk.py
├── test__default.py
├── test__exponential_backoff.py
├── test__helpers.py
├── test__oauth2client.py
├── test__refresh_worker.py
├── test__service_account_info.py
├── test_api_key.py
├── test_app_engine.py
├── test_aws.py
├── test_credentials.py
├── test_credentials_async.py
├── test_downscoped.py
├── test_exceptions.py
├── test_external_account.py
├── test_external_account_authorized_user.py
├── test_iam.py
├── test_identity_pool.py
├── test_impersonated_credentials.py
├── test_jwt.py
├── test_metrics.py
├── test_packaging.py
├── test_pluggable.py
└── transport
│ ├── __init__.py
│ ├── aio
│ ├── test_aiohttp.py
│ └── test_sessions.py
│ ├── compliance.py
│ ├── test__custom_tls_signer.py
│ ├── test__http_client.py
│ ├── test__mtls_helper.py
│ ├── test_grpc.py
│ ├── test_mtls.py
│ ├── test_requests.py
│ └── test_urllib3.py
└── tests_async
├── __init__.py
├── conftest.py
├── oauth2
├── test__client_async.py
├── test_credentials_async.py
├── test_id_token.py
├── test_reauth_async.py
└── test_service_account_async.py
├── test__default_async.py
├── test_credentials_async.py
├── test_jwt_async.py
└── transport
├── __init__.py
├── async_compliance.py
└── test_aiohttp_requests.py
/.coveragerc:
--------------------------------------------------------------------------------
1 | [run]
2 | branch = True
3 |
4 | [report]
5 | omit =
6 | */samples/*
7 | */conftest.py
8 | */google-cloud-sdk/lib/*
9 | # NOTE: Temporarily disabling coverage for `_requests_base.py`.
10 | */_requests_base.py
11 | exclude_lines =
12 | # Re-enable the standard pragma
13 | pragma: NO COVER
14 | # Ignore debug-only repr
15 | def __repr__
16 | # Don't complain if tests don't hit defensive assertion code:
17 | raise NotImplementedError
18 |
--------------------------------------------------------------------------------
/.flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | ignore = E203, E266, E501, W503
3 | exclude =
4 | # Standard linting exemptions.
5 | __pycache__,
6 | .git,
7 | *.pyc,
8 | conf.py
9 |
--------------------------------------------------------------------------------
/.github/.OwlBot.lock.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2025 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 | docker:
15 | image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest
16 | digest: sha256:023a21377a2a00008057f99f0118edadc30a19d1636a3fee47189ebec2f3921c
17 | # created: 2025-03-31T16:51:40.130756953Z
18 |
--------------------------------------------------------------------------------
/.github/.OwlBot.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2021 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 | docker:
16 | image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest
17 |
18 | begin-after-commit-hash: ee56c3493ec6aeb237ff515ecea949710944a20f
19 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Code owners file.
2 | # This file controls who is tagged for review for any given pull request.
3 | #
4 | # For syntax help see:
5 | # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax
6 |
7 | # The @googleapis/googleapis-auth and @googleapis/yoshi-python is the default owner for changes in this repo
8 | * @googleapis/googleapis-auth @googleapis/yoshi-python
9 | google/auth/_default.py @googleapis/googleapis-auth @googleapis/aion-sdk
10 | google/auth/aws.py @googleapis/googleapis-auth @googleapis/aion-sdk
11 | google/auth/credentials.py @googleapis/googleapis-auth @googleapis/aion-sdk
12 | google/auth/downscoped.py @googleapis/googleapis-auth @googleapis/aion-sdk
13 | google/auth/external_account.py @googleapis/googleapis-auth @googleapis/aion-sdk
14 | google/auth/external_account_authorized_user.py @googleapis/googleapis-auth @googleapis/aion-sdk
15 | google/auth/identity_pool.py @googleapis/googleapis-auth @googleapis/aion-sdk
16 | google/auth/pluggable.py @googleapis/googleapis-auth @googleapis/aion-sdk
17 | google/auth/sts.py @googleapis/googleapis-auth @googleapis/aion-sdk
18 | google/auth/impersonated_credentials.py @googleapis/googleapis-auth @googleapis/aion-sdk
19 | tests/test__default.py @googleapis/googleapis-auth @googleapis/aion-sdk
20 | tests/test_aws.py @googleapis/googleapis-auth @googleapis/aion-sdk
21 | tests/test_credentials.py @googleapis/googleapis-auth @googleapis/aion-sdk
22 | tests/test_downscoped.py @googleapis/googleapis-auth @googleapis/aion-sdk
23 | tests/test_external_account.py @googleapis/googleapis-auth @googleapis/aion-sdk
24 | tests/test_external_account_authorized_user.py @googleapis/googleapis-auth @googleapis/aion-sdk
25 | tests/test_identity_pool.py @googleapis/googleapis-auth @googleapis/aion-sdk
26 | tests/test_pluggable.py @googleapis/googleapis-auth @googleapis/aion-sdk
27 | tests/test_sts.py @googleapis/googleapis-auth @googleapis/aion-sdk
28 | tests/test_impersonated_credentials.py @googleapis/googleapis-auth @googleapis/aion-sdk
29 | /samples/ @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/python-samples-owners
30 | system_tests/secrets.tar.enc # Remove noise from test creds.
31 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to Contribute
2 |
3 | We'd love to accept your patches and contributions to this project. There are
4 | just a few small guidelines you need to follow.
5 |
6 | ## Contributor License Agreement
7 |
8 | Contributions to this project must be accompanied by a Contributor License
9 | Agreement. You (or your employer) retain the copyright to your contribution;
10 | this simply gives us permission to use and redistribute your contributions as
11 | part of the project. Head over to to see
12 | your current agreements on file or to sign a new one.
13 |
14 | You generally only need to submit a CLA once, so if you've already submitted one
15 | (even if it was for a different project), you probably don't need to do it
16 | again.
17 |
18 | ## Code reviews
19 |
20 | All submissions, including submissions by project members, require review. We
21 | use GitHub pull requests for this purpose. Consult
22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
23 | information on using pull requests.
24 |
25 | ## Community Guidelines
26 |
27 | This project follows [Google's Open Source Community
28 | Guidelines](https://opensource.google.com/conduct/).
29 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 |
5 | ---
6 |
7 | Thanks for stopping by to let us know something could be better!
8 |
9 | **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response.
10 |
11 | Please run down the following list and make sure you've tried the usual "quick fixes":
12 |
13 | - Search the issues already opened: https://github.com/googleapis/google-auth-library-python/issues
14 |
15 | If you are still having issues, please be sure to include as much information as possible:
16 |
17 | #### Environment details
18 |
19 | - OS:
20 | - Python version:
21 | - pip version:
22 | - `google-auth` version:
23 |
24 | #### Steps to reproduce
25 |
26 | 1. ?
27 | 2. ?
28 |
29 | Making sure to follow these steps will guarantee the quickest resolution possible.
30 |
31 | Thanks!
32 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this library
4 |
5 | ---
6 |
7 | Thanks for stopping by to let us know something could be better!
8 |
9 | **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response.
10 |
11 | **Is your feature request related to a problem? Please describe.**
12 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 | **Describe alternatives you've considered**
16 | A clear and concise description of any alternative solutions or features you've considered.
17 | **Additional context**
18 | Add any other context or screenshots about the feature request here.
19 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/support_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Support request
3 | about: If you have a support contract with Google, please create an issue in the Google Cloud Support console.
4 |
5 | ---
6 |
7 | **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response.
8 |
--------------------------------------------------------------------------------
/.github/release-please.yml:
--------------------------------------------------------------------------------
1 | releaseType: python
2 | handleGHRelease: true
3 |
--------------------------------------------------------------------------------
/.github/release-trigger.yml:
--------------------------------------------------------------------------------
1 | enabled: true
2 |
--------------------------------------------------------------------------------
/.github/sync-repo-settings.yaml:
--------------------------------------------------------------------------------
1 | # https://github.com/googleapis/repo-automation-bots/tree/main/packages/sync-repo-settings
2 | # Rules for main branch protection
3 | branchProtectionRules:
4 | # Identifies the protection rule pattern. Name of the branch to be protected.
5 | # Defaults to `main`
6 | - pattern: main
7 | requiresCodeOwnerReviews: true
8 | requiresStrictStatusChecks: true
9 | requiredStatusCheckContexts:
10 | - 'cla/google'
11 | - 'OwlBot Post Processor'
12 | - 'Kokoro system-3.7'
13 | - 'Kokoro'
14 | - 'Samples - Python 3.7'
15 | - 'Samples - Python 3.8'
16 | - 'Samples - Python 3.9'
17 | - 'Samples - Python 3.10'
18 | - 'Samples - Python 3.11'
19 | - 'Samples - Python 3.12'
20 | permissionRules:
21 | - team: actools-python
22 | permission: admin
23 | - team: actools
24 | permission: admin
25 | - team: yoshi-python
26 | permission: push
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build artifacts
2 | *.py[cod]
3 | __pycache__
4 | *.egg-info/
5 | build/
6 | dist/
7 |
8 | # Documentation-related
9 | docs/_build
10 |
11 | # Test files
12 | .nox/
13 | .tox/
14 | .cache/
15 | .pytest_cache/
16 | cert_path
17 | key_path
18 |
19 | # Django test database
20 | db.sqlite3
21 |
22 | # Coverage files
23 | .coverage
24 | coverage.xml
25 | *sponge_log.xml
26 | nosetests.xml
27 | htmlcov/
28 |
29 | # Files with private / local data
30 | scripts/local_test_setup
31 | tests/data/key.json
32 | tests/data/key.p12
33 | tests/data/user-key.json
34 | system_tests/data/
35 |
36 | # PyCharm configuration:
37 | .idea
38 | venv/
39 |
40 | # Generated files
41 | pylintrc
42 | pylintrc.test
43 | pytype_output/
44 |
45 | .python-version
46 | .DS_Store
47 | cert_path
48 | key_path
49 | env/
50 | .vscode/
--------------------------------------------------------------------------------
/.kokoro/build-systests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2018 Google LLC
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # https://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | set -eo pipefail
17 |
18 | if [[ -z "${PROJECT_ROOT:-}" ]]; then
19 | PROJECT_ROOT="github/google-auth-library-python"
20 | fi
21 |
22 | cd "${PROJECT_ROOT}"
23 |
24 | # Disable buffering, so that the logs stream through.
25 | export PYTHONUNBUFFERED=1
26 |
27 | # Remove old nox
28 | python3 -m pip uninstall --yes --quiet nox-automation
29 |
30 | # Install nox
31 | python3 -m pip install nox==2024.10.9
32 | python3 -m nox --version
33 |
34 | # Setup service account credentials.
35 | export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/service-account.json
36 |
37 | # Setup project id.
38 | export PROJECT_ID=$(cat "${KOKORO_GFILE_DIR}/project-id.txt")
39 |
40 | # Activate gcloud with service account credentials
41 | gcloud auth activate-service-account --key-file=$GOOGLE_APPLICATION_CREDENTIALS
42 | gcloud config set project ${PROJECT_ID}
43 |
44 | # Decrypt system test secrets
45 | ./scripts/decrypt-secrets.sh
46 |
47 | # Run system tests which use a different noxfile
48 | python3 -m nox -f system_tests/noxfile.py
49 |
--------------------------------------------------------------------------------
/.kokoro/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2018 Google LLC
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # https://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | set -eo pipefail
17 |
18 | if [[ -z "${PROJECT_ROOT:-}" ]]; then
19 | PROJECT_ROOT="github/google-auth-library-python"
20 | fi
21 |
22 | cd "${PROJECT_ROOT}"
23 |
24 | # Disable buffering, so that the logs stream through.
25 | export PYTHONUNBUFFERED=1
26 |
27 | # Remove old nox
28 | python3 -m pip uninstall --yes --quiet nox-automation
29 |
30 | # Install nox
31 | python3 -m pip install --upgrade --quiet nox
32 | python3 -m nox --version
33 |
34 | # If NOX_SESSION is set, it only runs the specified session,
35 | # otherwise run all the sessions.
36 | if [[ -n "${NOX_SESSION:-}" ]]; then
37 | python3 -m nox -s ${NOX_SESSION:-}
38 | else
39 | python3 -m nox
40 | fi
41 |
--------------------------------------------------------------------------------
/.kokoro/common.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | # Download trampoline resources. These will be in ${KOKORO_GFILE_DIR}
4 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
5 |
6 | # Download resources for tests
7 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-auth-library-python"
8 |
9 | # All builds use the trampoline script to run in docker.
10 | build_file: "google-auth-library-python/.kokoro/trampoline.sh"
11 |
12 | # Use the Python worker docker iamge.
13 | env_vars: {
14 | key: "TRAMPOLINE_IMAGE"
15 | value: "gcr.io/cloud-devrel-public-resources/python-multi"
16 | }
17 |
--------------------------------------------------------------------------------
/.kokoro/continuous/common.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | # Build logs will be here
4 | action {
5 | define_artifacts {
6 | regex: "**/*sponge_log.xml"
7 | }
8 | }
9 |
10 | # Download trampoline resources.
11 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
12 |
13 | # Download resources for system tests (service account key, etc.)
14 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-auth-library-python"
15 |
16 | # Use the trampoline script to run in docker.
17 | build_file: "google-auth-library-python/.kokoro/trampoline.sh"
18 |
19 | # Configure the docker image for kokoro-trampoline.
20 | env_vars: {
21 | key: "TRAMPOLINE_IMAGE"
22 | value: "gcr.io/cloud-devrel-kokoro-resources/python-multi"
23 | }
24 | env_vars: {
25 | key: "TRAMPOLINE_BUILD_FILE"
26 | value: "github/google-auth-library-python/.kokoro/build.sh"
27 | }
28 |
--------------------------------------------------------------------------------
/.kokoro/continuous/continuous.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
--------------------------------------------------------------------------------
/.kokoro/continuous/prerelease-deps.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | # Only run this nox session.
4 | env_vars: {
5 | key: "NOX_SESSION"
6 | value: "prerelease_deps"
7 | }
8 |
--------------------------------------------------------------------------------
/.kokoro/populate-secrets.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2024 Google LLC.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | set -eo pipefail
17 |
18 | function now { date +"%Y-%m-%d %H:%M:%S" | tr -d '\n' ;}
19 | function msg { println "$*" >&2 ;}
20 | function println { printf '%s\n' "$(now) $*" ;}
21 |
22 |
23 | # Populates requested secrets set in SECRET_MANAGER_KEYS from service account:
24 | # kokoro-trampoline@cloud-devrel-kokoro-resources.iam.gserviceaccount.com
25 | SECRET_LOCATION="${KOKORO_GFILE_DIR}/secret_manager"
26 | msg "Creating folder on disk for secrets: ${SECRET_LOCATION}"
27 | mkdir -p ${SECRET_LOCATION}
28 | for key in $(echo ${SECRET_MANAGER_KEYS} | sed "s/,/ /g")
29 | do
30 | msg "Retrieving secret ${key}"
31 | docker run --entrypoint=gcloud \
32 | --volume=${KOKORO_GFILE_DIR}:${KOKORO_GFILE_DIR} \
33 | gcr.io/google.com/cloudsdktool/cloud-sdk \
34 | secrets versions access latest \
35 | --project cloud-devrel-kokoro-resources \
36 | --secret ${key} > \
37 | "${SECRET_LOCATION}/${key}"
38 | if [[ $? == 0 ]]; then
39 | msg "Secret written to ${SECRET_LOCATION}/${key}"
40 | else
41 | msg "Error retrieving secret ${key}"
42 | fi
43 | done
44 |
--------------------------------------------------------------------------------
/.kokoro/presubmit/common.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | # Build logs will be here
4 | action {
5 | define_artifacts {
6 | regex: "**/*sponge_log.xml"
7 | }
8 | }
9 |
10 | # Download trampoline resources.
11 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
12 |
13 | # Download resources for system tests (service account key, etc.)
14 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-auth-library-python"
15 |
16 | # Use the trampoline script to run in docker.
17 | build_file: "google-auth-library-python/.kokoro/trampoline.sh"
18 |
19 | # Configure the docker image for kokoro-trampoline.
20 | env_vars: {
21 | key: "TRAMPOLINE_IMAGE"
22 | value: "gcr.io/cloud-devrel-kokoro-resources/python-multi"
23 | }
24 | env_vars: {
25 | key: "TRAMPOLINE_BUILD_FILE"
26 | value: "github/google-auth-library-python/.kokoro/build.sh"
27 | }
28 |
--------------------------------------------------------------------------------
/.kokoro/presubmit/prerelease-deps.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | # Only run this nox session.
4 | env_vars: {
5 | key: "NOX_SESSION"
6 | value: "prerelease_deps"
7 | }
8 |
--------------------------------------------------------------------------------
/.kokoro/presubmit/presubmit.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
--------------------------------------------------------------------------------
/.kokoro/presubmit/system-3.7.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 | env_vars: {
3 | key: "TRAMPOLINE_BUILD_FILE"
4 | value: "github/google-auth-library-python/.kokoro/build-systests.sh"
5 | }
6 |
--------------------------------------------------------------------------------
/.kokoro/samples-test-setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2018 Google LLC
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # https://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | set -eo pipefail
17 |
18 | if [[ -z "${PROJECT_ROOT:-}" ]]; then
19 | PROJECT_ROOT="github/google-auth-library-python"
20 | fi
21 |
22 | cd "${PROJECT_ROOT}"
23 |
24 | # Disable buffering, so that the logs stream through.
25 | export PYTHONUNBUFFERED=1
26 |
27 | # Remove old nox
28 | python3 -m pip uninstall --yes --quiet nox-automation
29 |
30 | # Install nox
31 | python3 -m pip install --upgrade --quiet nox
32 | python3 -m nox --version
33 |
34 | # Setup service account credentials.
35 | export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/service-account.json
36 |
37 | # Setup project id.
38 | export PROJECT_ID=$(cat "${KOKORO_GFILE_DIR}/project-id.txt")
39 |
40 | # Activate gcloud with service account credentials
41 | gcloud auth activate-service-account --key-file=$GOOGLE_APPLICATION_CREDENTIALS
42 | gcloud config set project ${PROJECT_ID}
43 |
44 | # Decrypt system test secrets
45 | ./scripts/decrypt-secrets.sh
46 |
47 | # Run samples tests which use a different noxfile
48 | python3 -m nox -f samples/cloud-client/snippets/noxfile.py -s "$RUN_TESTS_SESSION"
49 |
--------------------------------------------------------------------------------
/.kokoro/samples/lint/common.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | # Build logs will be here
4 | action {
5 | define_artifacts {
6 | regex: "**/*sponge_log.xml"
7 | }
8 | }
9 |
10 | # Specify which tests to run
11 | env_vars: {
12 | key: "RUN_TESTS_SESSION"
13 | value: "lint"
14 | }
15 |
16 |
17 | # Download trampoline resources.
18 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
19 |
20 | # Download resources for system tests (service account key, etc.)
21 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-auth-library-python"
22 |
23 | # Use the trampoline script to run in docker.
24 | build_file: "google-auth-library-python/.kokoro/trampoline.sh"
25 |
26 | # Configure the docker image for kokoro-trampoline.
27 | env_vars: {
28 | key: "TRAMPOLINE_IMAGE"
29 | value: "gcr.io/cloud-devrel-kokoro-resources/python-multi"
30 | }
31 | env_vars: {
32 | key: "TRAMPOLINE_BUILD_FILE"
33 | value: "github/google-auth-library-python/.kokoro/build.sh"
34 | }
35 | env_vars: {
36 | key: "TRAMPOLINE_BUILD_FILE"
37 | value: "github/google-auth-library-python/.kokoro/samples-test-setup.sh"
38 | }
--------------------------------------------------------------------------------
/.kokoro/samples/lint/continuous.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
--------------------------------------------------------------------------------
/.kokoro/samples/lint/periodic.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "False"
6 | }
--------------------------------------------------------------------------------
/.kokoro/samples/lint/presubmit.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.10/common.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | # Build logs will be here
4 | action {
5 | define_artifacts {
6 | regex: "**/*sponge_log.xml"
7 | }
8 | }
9 |
10 | # Specify which tests to run
11 | env_vars: {
12 | key: "RUN_TESTS_SESSION"
13 | value: "unit-3.10"
14 | }
15 |
16 | # Download trampoline resources.
17 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
18 |
19 | # Download resources for system tests (service account key, etc.)
20 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-auth-library-python"
21 |
22 | # Use the trampoline script to run in docker.
23 | build_file: "google-auth-library-python/.kokoro/trampoline.sh"
24 |
25 | # Configure the docker image for kokoro-trampoline.
26 | env_vars: {
27 | key: "TRAMPOLINE_IMAGE"
28 | value: "gcr.io/cloud-devrel-kokoro-resources/python-multi"
29 | }
30 | env_vars: {
31 | key: "TRAMPOLINE_BUILD_FILE"
32 | value: "github/google-auth-library-python/.kokoro/build.sh"
33 | }
34 | env_vars: {
35 | key: "TRAMPOLINE_BUILD_FILE"
36 | value: "github/google-auth-library-python/.kokoro/samples-test-setup.sh"
37 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.10/continuous.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.10/periodic-head.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
7 |
8 | env_vars: {
9 | key: "TRAMPOLINE_BUILD_FILE"
10 | value: "github/google-auth-library-python/.kokoro/test-samples-against-head.sh"
11 | }
12 |
--------------------------------------------------------------------------------
/.kokoro/samples/python3.10/periodic.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "False"
6 | }
7 |
--------------------------------------------------------------------------------
/.kokoro/samples/python3.10/presubmit.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.11/common.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | # Build logs will be here
4 | action {
5 | define_artifacts {
6 | regex: "**/*sponge_log.xml"
7 | }
8 | }
9 |
10 | # Specify which tests to run
11 | env_vars: {
12 | key: "RUN_TESTS_SESSION"
13 | value: "unit-3.11"
14 | }
15 |
16 | # Download trampoline resources.
17 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
18 |
19 | # Download resources for system tests (service account key, etc.)
20 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-auth-library-python"
21 |
22 | # Use the trampoline script to run in docker.
23 | build_file: "google-auth-library-python/.kokoro/trampoline.sh"
24 |
25 | # Configure the docker image for kokoro-trampoline.
26 | env_vars: {
27 | key: "TRAMPOLINE_IMAGE"
28 | value: "gcr.io/cloud-devrel-kokoro-resources/python-multi"
29 | }
30 | env_vars: {
31 | key: "TRAMPOLINE_BUILD_FILE"
32 | value: "github/google-auth-library-python/.kokoro/build.sh"
33 | }
34 | env_vars: {
35 | key: "TRAMPOLINE_BUILD_FILE"
36 | value: "github/google-auth-library-python/.kokoro/samples-test-setup.sh"
37 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.11/continuous.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.11/periodic-head.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
7 |
8 | env_vars: {
9 | key: "TRAMPOLINE_BUILD_FILE"
10 | value: "github/google-auth-library-python/.kokoro/test-samples-against-head.sh"
11 | }
12 |
--------------------------------------------------------------------------------
/.kokoro/samples/python3.11/periodic.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "False"
6 | }
7 |
--------------------------------------------------------------------------------
/.kokoro/samples/python3.11/presubmit.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.12/common.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | # Build logs will be here
4 | action {
5 | define_artifacts {
6 | regex: "**/*sponge_log.xml"
7 | }
8 | }
9 |
10 | # Specify which tests to run
11 | env_vars: {
12 | key: "RUN_TESTS_SESSION"
13 | value: "unit-3.12"
14 | }
15 |
16 | # Download trampoline resources.
17 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
18 |
19 | # Download resources for system tests (service account key, etc.)
20 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-auth-library-python"
21 |
22 | # Use the trampoline script to run in docker.
23 | build_file: "google-auth-library-python/.kokoro/trampoline.sh"
24 |
25 | # Configure the docker image for kokoro-trampoline.
26 | env_vars: {
27 | key: "TRAMPOLINE_IMAGE"
28 | value: "gcr.io/cloud-devrel-kokoro-resources/python-multi"
29 | }
30 | env_vars: {
31 | key: "TRAMPOLINE_BUILD_FILE"
32 | value: "github/google-auth-library-python/.kokoro/build.sh"
33 | }
34 | env_vars: {
35 | key: "TRAMPOLINE_BUILD_FILE"
36 | value: "github/google-auth-library-python/.kokoro/samples-test-setup.sh"
37 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.12/continuous.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.12/periodic-head.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
7 |
8 | env_vars: {
9 | key: "TRAMPOLINE_BUILD_FILE"
10 | value: "github/google-auth-library-python/.kokoro/test-samples-against-head.sh"
11 | }
12 |
--------------------------------------------------------------------------------
/.kokoro/samples/python3.12/periodic.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "False"
6 | }
7 |
--------------------------------------------------------------------------------
/.kokoro/samples/python3.12/presubmit.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.13/common.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | # Build logs will be here
4 | action {
5 | define_artifacts {
6 | regex: "**/*sponge_log.xml"
7 | }
8 | }
9 |
10 | # Specify which tests to run
11 | env_vars: {
12 | key: "RUN_TESTS_SESSION"
13 | value: "unit-3.13"
14 | }
15 |
16 | # Download trampoline resources.
17 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
18 |
19 | # Download resources for system tests (service account key, etc.)
20 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-auth-library-python"
21 |
22 | # Use the trampoline script to run in docker.
23 | build_file: "google-auth-library-python/.kokoro/trampoline.sh"
24 |
25 | # Configure the docker image for kokoro-trampoline.
26 | env_vars: {
27 | key: "TRAMPOLINE_IMAGE"
28 | value: "gcr.io/cloud-devrel-kokoro-resources/python-multi"
29 | }
30 | env_vars: {
31 | key: "TRAMPOLINE_BUILD_FILE"
32 | value: "github/google-auth-library-python/.kokoro/build.sh"
33 | }
34 | env_vars: {
35 | key: "TRAMPOLINE_BUILD_FILE"
36 | value: "github/google-auth-library-python/.kokoro/samples-test-setup.sh"
37 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.13/continuous.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.13/periodic-head.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
7 |
8 | env_vars: {
9 | key: "TRAMPOLINE_BUILD_FILE"
10 | value: "github/google-auth-library-python/.kokoro/test-samples-against-head.sh"
11 | }
12 |
--------------------------------------------------------------------------------
/.kokoro/samples/python3.13/periodic.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "False"
6 | }
7 |
--------------------------------------------------------------------------------
/.kokoro/samples/python3.13/presubmit.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.7/common.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | # Build logs will be here
4 | action {
5 | define_artifacts {
6 | regex: "**/*sponge_log.xml"
7 | }
8 | }
9 |
10 |
11 | # Specify which tests to run
12 | env_vars: {
13 | key: "RUN_TESTS_SESSION"
14 | value: "unit-3.7"
15 | }
16 |
17 | # Download trampoline resources.
18 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
19 |
20 | # Download resources for system tests (service account key, etc.)
21 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-auth-library-python"
22 |
23 | # Use the trampoline script to run in docker.
24 | build_file: "google-auth-library-python/.kokoro/trampoline.sh"
25 |
26 | # Configure the docker image for kokoro-trampoline.
27 | env_vars: {
28 | key: "TRAMPOLINE_IMAGE"
29 | value: "gcr.io/cloud-devrel-kokoro-resources/python-multi"
30 | }
31 | env_vars: {
32 | key: "TRAMPOLINE_BUILD_FILE"
33 | value: "github/google-auth-library-python/.kokoro/build.sh"
34 | }
35 | env_vars: {
36 | key: "TRAMPOLINE_BUILD_FILE"
37 | value: "github/google-auth-library-python/.kokoro/samples-test-setup.sh"
38 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.7/continuous.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.7/periodic-head.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
7 |
8 | env_vars: {
9 | key: "TRAMPOLINE_BUILD_FILE"
10 | value: "github/google-auth-library-python/.kokoro/test-samples-against-head.sh"
11 | }
12 |
--------------------------------------------------------------------------------
/.kokoro/samples/python3.7/periodic.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "False"
6 | }
7 |
--------------------------------------------------------------------------------
/.kokoro/samples/python3.7/presubmit.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.8/common.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | # Build logs will be here
4 | action {
5 | define_artifacts {
6 | regex: "**/*sponge_log.xml"
7 | }
8 | }
9 |
10 | # Specify which tests to run
11 | env_vars: {
12 | key: "RUN_TESTS_SESSION"
13 | value: "unit-3.8"
14 | }
15 |
16 | # Download trampoline resources.
17 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
18 |
19 | # Download resources for system tests (service account key, etc.)
20 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-auth-library-python"
21 |
22 | # Use the trampoline script to run in docker.
23 | build_file: "google-auth-library-python/.kokoro/trampoline.sh"
24 |
25 | # Configure the docker image for kokoro-trampoline.
26 | env_vars: {
27 | key: "TRAMPOLINE_IMAGE"
28 | value: "gcr.io/cloud-devrel-kokoro-resources/python-multi"
29 | }
30 | env_vars: {
31 | key: "TRAMPOLINE_BUILD_FILE"
32 | value: "github/google-auth-library-python/.kokoro/build.sh"
33 | }
34 | env_vars: {
35 | key: "TRAMPOLINE_BUILD_FILE"
36 | value: "github/google-auth-library-python/.kokoro/samples-test-setup.sh"
37 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.8/continuous.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.8/periodic-head.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
7 |
8 | env_vars: {
9 | key: "TRAMPOLINE_BUILD_FILE"
10 | value: "github/google-auth-library-python/.kokoro/test-samples-against-head.sh"
11 | }
12 |
--------------------------------------------------------------------------------
/.kokoro/samples/python3.8/periodic.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "False"
6 | }
7 |
--------------------------------------------------------------------------------
/.kokoro/samples/python3.8/presubmit.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.9/common.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | # Build logs will be here
4 | action {
5 | define_artifacts {
6 | regex: "**/*sponge_log.xml"
7 | }
8 | }
9 |
10 | # Specify which tests to run
11 | env_vars: {
12 | key: "RUN_TESTS_SESSION"
13 | value: "unit-3.9"
14 | }
15 |
16 | # Download trampoline resources.
17 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
18 |
19 | # Download resources for system tests (service account key, etc.)
20 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-auth-library-python"
21 |
22 | # Use the trampoline script to run in docker.
23 | build_file: "google-auth-library-python/.kokoro/trampoline.sh"
24 |
25 | # Configure the docker image for kokoro-trampoline.
26 | env_vars: {
27 | key: "TRAMPOLINE_IMAGE"
28 | value: "gcr.io/cloud-devrel-kokoro-resources/python-multi"
29 | }
30 | env_vars: {
31 | key: "TRAMPOLINE_BUILD_FILE"
32 | value: "github/google-auth-library-python/.kokoro/build.sh"
33 | }
34 | env_vars: {
35 | key: "TRAMPOLINE_BUILD_FILE"
36 | value: "github/google-auth-library-python/.kokoro/samples-test-setup.sh"
37 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.9/continuous.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
--------------------------------------------------------------------------------
/.kokoro/samples/python3.9/periodic-head.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
7 |
8 | env_vars: {
9 | key: "TRAMPOLINE_BUILD_FILE"
10 | value: "github/google-auth-library-python/.kokoro/test-samples-against-head.sh"
11 | }
12 |
--------------------------------------------------------------------------------
/.kokoro/samples/python3.9/periodic.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "False"
6 | }
7 |
--------------------------------------------------------------------------------
/.kokoro/samples/python3.9/presubmit.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "INSTALL_LIBRARY_FROM_SOURCE"
5 | value: "True"
6 | }
--------------------------------------------------------------------------------
/.kokoro/test-samples-against-head.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2024 Google LLC
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # https://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | # A customized test runner for samples.
17 | #
18 | # For periodic builds, you can specify this file for testing against head.
19 |
20 | # `-e` enables the script to automatically fail when a command fails
21 | # `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero
22 | set -eo pipefail
23 | # Enables `**` to include files nested inside sub-folders
24 | shopt -s globstar
25 |
26 | exec .kokoro/test-samples-impl.sh
27 |
--------------------------------------------------------------------------------
/.kokoro/test-samples.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2024 Google LLC
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # https://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | # The default test runner for samples.
17 | #
18 | # For periodic builds, we rewinds the repo to the latest release, and
19 | # run test-samples-impl.sh.
20 |
21 | # `-e` enables the script to automatically fail when a command fails
22 | # `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero
23 | set -eo pipefail
24 | # Enables `**` to include files nested inside sub-folders
25 | shopt -s globstar
26 |
27 | # Run periodic samples tests at latest release
28 | if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then
29 | # preserving the test runner implementation.
30 | cp .kokoro/test-samples-impl.sh "${TMPDIR}/test-samples-impl.sh"
31 | echo "--- IMPORTANT IMPORTANT IMPORTANT ---"
32 | echo "Now we rewind the repo back to the latest release..."
33 | LATEST_RELEASE=$(git describe --abbrev=0 --tags)
34 | git checkout $LATEST_RELEASE
35 | echo "The current head is: "
36 | echo $(git rev-parse --verify HEAD)
37 | echo "--- IMPORTANT IMPORTANT IMPORTANT ---"
38 | # move back the test runner implementation if there's no file.
39 | if [ ! -f .kokoro/test-samples-impl.sh ]; then
40 | cp "${TMPDIR}/test-samples-impl.sh" .kokoro/test-samples-impl.sh
41 | fi
42 | fi
43 |
44 | exec .kokoro/test-samples-impl.sh
45 |
--------------------------------------------------------------------------------
/.kokoro/trampoline.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2024 Google LLC
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | set -eo pipefail
17 |
18 | # Always run the cleanup script, regardless of the success of bouncing into
19 | # the container.
20 | function cleanup() {
21 | chmod +x ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh
22 | ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh
23 | echo "cleanup";
24 | }
25 | trap cleanup EXIT
26 |
27 | $(dirname $0)/populate-secrets.sh # Secret Manager secrets.
28 | python3 "${KOKORO_GFILE_DIR}/trampoline_v1.py"
--------------------------------------------------------------------------------
/.readthedocs.yaml:
--------------------------------------------------------------------------------
1 | # Read the Docs configuration file
2 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
3 |
4 | # Required
5 | version: 2
6 |
7 | # Set the OS, Python version, and other tools you might need
8 | build:
9 | os: ubuntu-24.04
10 | tools:
11 | python: "3.10"
12 |
13 | # Build documentation in the "docs/" directory with Sphinx
14 | sphinx:
15 | configuration: docs/conf.py
16 |
17 | python:
18 | install:
19 | - requirements: docs/requirements-docs.txt
20 | # Install our python package before building the docs
21 | - method: pip
22 | path: .
23 |
--------------------------------------------------------------------------------
/.repo-metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "google-auth",
3 | "name_pretty": "Google Auth Python Library",
4 | "client_documentation": "https://googleapis.dev/python/google-auth/latest",
5 | "issue_tracker": "https://github.com/googleapis/google-auth-library-python/issues",
6 | "release_level": "stable",
7 | "language": "python",
8 | "library_type": "AUTH",
9 | "repo": "googleapis/google-auth-library-python",
10 | "distribution_name": "google-auth"
11 | }
12 |
--------------------------------------------------------------------------------
/.trampolinerc:
--------------------------------------------------------------------------------
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 | # Add required env vars here.
16 | required_envvars+=(
17 | )
18 |
19 | # Add env vars which are passed down into the container here.
20 | pass_down_envvars+=(
21 | "NOX_SESSION"
22 | ###############
23 | # Docs builds
24 | ###############
25 | "STAGING_BUCKET"
26 | "V2_STAGING_BUCKET"
27 | ##################
28 | # Samples builds
29 | ##################
30 | "INSTALL_LIBRARY_FROM_SOURCE"
31 | "RUN_TESTS_SESSION"
32 | "BUILD_SPECIFIC_GCLOUD_PROJECT"
33 | # Target directories.
34 | "RUN_TESTS_DIRS"
35 | # The nox session to run.
36 | "RUN_TESTS_SESSION"
37 | )
38 |
39 | # Prevent unintentional override on the default image.
40 | if [[ "${TRAMPOLINE_IMAGE_UPLOAD:-false}" == "true" ]] && \
41 | [[ -z "${TRAMPOLINE_IMAGE:-}" ]]; then
42 | echo "Please set TRAMPOLINE_IMAGE if you want to upload the Docker image."
43 | exit 1
44 | fi
45 |
46 | # Define the default value if it makes sense.
47 | if [[ -z "${TRAMPOLINE_IMAGE_UPLOAD:-}" ]]; then
48 | TRAMPOLINE_IMAGE_UPLOAD=""
49 | fi
50 |
51 | if [[ -z "${TRAMPOLINE_IMAGE:-}" ]]; then
52 | TRAMPOLINE_IMAGE=""
53 | fi
54 |
55 | if [[ -z "${TRAMPOLINE_DOCKERFILE:-}" ]]; then
56 | TRAMPOLINE_DOCKERFILE=""
57 | fi
58 |
59 | if [[ -z "${TRAMPOLINE_BUILD_FILE:-}" ]]; then
60 | TRAMPOLINE_BUILD_FILE=""
61 | fi
62 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Code of Conduct
2 |
3 | As contributors and maintainers of this project,
4 | and in the interest of fostering an open and welcoming community,
5 | we pledge to respect all people who contribute through reporting issues,
6 | posting feature requests, updating documentation,
7 | submitting pull requests or patches, and other activities.
8 |
9 | We are committed to making participation in this project
10 | a harassment-free experience for everyone,
11 | regardless of level of experience, gender, gender identity and expression,
12 | sexual orientation, disability, personal appearance,
13 | body size, race, ethnicity, age, religion, or nationality.
14 |
15 | Examples of unacceptable behavior by participants include:
16 |
17 | * The use of sexualized language or imagery
18 | * Personal attacks
19 | * Trolling or insulting/derogatory comments
20 | * Public or private harassment
21 | * Publishing other's private information,
22 | such as physical or electronic
23 | addresses, without explicit permission
24 | * Other unethical or unprofessional conduct.
25 |
26 | Project maintainers have the right and responsibility to remove, edit, or reject
27 | comments, commits, code, wiki edits, issues, and other contributions
28 | that are not aligned to this Code of Conduct.
29 | By adopting this Code of Conduct,
30 | project maintainers commit themselves to fairly and consistently
31 | applying these principles to every aspect of managing this project.
32 | Project maintainers who do not follow or enforce the Code of Conduct
33 | may be permanently removed from the project team.
34 |
35 | This code of conduct applies both within project spaces and in public spaces
36 | when an individual is representing the project or its community.
37 |
38 | Instances of abusive, harassing, or otherwise unacceptable behavior
39 | may be reported by opening an issue
40 | or contacting one or more of the project maintainers.
41 |
42 | This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0,
43 | available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
44 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include README.rst LICENSE CHANGELOG.rst
2 | recursive-include tests *
3 | global-exclude *.pyc __pycache__
4 | global-include *.typed
5 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | Google Auth Python Library
2 | ==========================
3 |
4 | |pypi|
5 |
6 | This library simplifies using Google's various server-to-server authentication
7 | mechanisms to access Google APIs.
8 |
9 | .. |pypi| image:: https://img.shields.io/pypi/v/google-auth.svg
10 | :target: https://pypi.python.org/pypi/google-auth
11 |
12 | Installing
13 | ----------
14 |
15 | You can install using `pip`_::
16 |
17 | $ pip install google-auth
18 |
19 | .. _pip: https://pip.pypa.io/en/stable/
20 |
21 | For more information on setting up your Python development environment, please refer to `Python Development Environment Setup Guide`_ for Google Cloud Platform.
22 |
23 | .. _`Python Development Environment Setup Guide`: https://cloud.google.com/python/docs/setup
24 |
25 | Extras
26 | ------
27 |
28 | google-auth has few extras that you can install. For example::
29 |
30 | $ pip install google-auth[pyopenssl]
31 |
32 | Note that the extras pyopenssl and enterprise_cert should not be used together because they use conflicting versions of `cryptography`_.
33 |
34 | .. _`cryptography`: https://cryptography.io/en/latest/
35 |
36 | Supported Python Versions
37 | ^^^^^^^^^^^^^^^^^^^^^^^^^
38 | Python >= 3.7
39 |
40 | **NOTE**:
41 | Python 3.7 was marked as `unsupported`_ by the python community in June 2023.
42 | We recommend that all developers upgrade to Python 3.8 and newer as soon as
43 | they can. Support for Python 3.7 will be removed from this library after
44 | January 1 2024. Previous releases that support Python 3.7 will continue to be available
45 | for download, but releases after January 1 2024 will only target Python 3.8 and
46 | newer.
47 |
48 | .. _unsupported: https://devguide.python.org/versions/#unsupported-versions
49 |
50 | Unsupported Python Versions
51 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
52 | - Python == 2.7: The last version of this library with support for Python 2.7
53 | was `google.auth == 1.34.0`.
54 |
55 | - Python 3.5: The last version of this library with support for Python 3.5
56 | was `google.auth == 1.23.0`.
57 |
58 | - Python 3.6: The last version of this library with support for Python 3.6
59 | was `google.auth == 2.22.0`.
60 |
61 | Documentation
62 | -------------
63 |
64 | Google Auth Python Library has usage and reference documentation at https://googleapis.dev/python/google-auth/latest/index.html.
65 |
66 | Current Maintainers
67 | -------------------
68 | - googleapis-auth@google.com
69 |
70 | Authors
71 | -------
72 |
73 | - `@theacodes `_ (Thea Flowers)
74 | - `@dhermes `_ (Danny Hermes)
75 | - `@lukesneeringer `_ (Luke Sneeringer)
76 | - `@busunkim96 `_ (Bu Sun Kim)
77 |
78 | Contributing
79 | ------------
80 |
81 | Contributions to this library are always welcome and highly encouraged.
82 |
83 | See `CONTRIBUTING.rst`_ for more information on how to get started.
84 |
85 | .. _CONTRIBUTING.rst: https://github.com/googleapis/google-auth-library-python/blob/main/CONTRIBUTING.rst
86 |
87 | License
88 | -------
89 |
90 | Apache 2.0 - See `the LICENSE`_ for more information.
91 |
92 | .. _the LICENSE: https://github.com/googleapis/google-auth-library-python/blob/main/LICENSE
93 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | To report a security issue, please use [g.co/vulnz](https://g.co/vulnz).
4 |
5 | The Google Security Team will respond within 5 working days of your report on g.co/vulnz.
6 |
7 | We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue.
8 |
--------------------------------------------------------------------------------
/docs/_static/custom.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css?family=Roboto|Roboto+Mono');
2 |
3 | @media screen and (min-width: 1080px) {
4 | div.document {
5 | width: 1040px;
6 | }
7 | }
8 |
9 | code.descname {
10 | color: #4885ed;
11 | }
12 |
13 | th.field-name {
14 | min-width: 100px;
15 | color: #3cba54;
16 | }
17 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | google-auth
2 | ===========
3 |
4 | .. toctree::
5 | :hidden:
6 | :maxdepth: 2
7 |
8 | user-guide
9 | Reference
10 |
11 | google-auth is the Google authentication library for Python. This library
12 | provides the ability to authenticate to Google APIs using various methods. It
13 | also provides integration with several HTTP libraries.
14 |
15 | - Support for Google :func:`Application Default Credentials `.
16 | - Support for signing and verifying :mod:`JWTs `.
17 | - Support for creating `Google ID Tokens `__.
18 | - Support for verifying and decoding :mod:`ID Tokens `.
19 | - Support for Google :mod:`Service Account credentials `.
20 | - Support for Google :mod:`Impersonated Credentials `.
21 | - Support for :mod:`Google Compute Engine credentials `.
22 | - Support for :mod:`Google App Engine standard credentials `.
23 | - Support for :mod:`Identity Pool credentials `.
24 | - Support for :mod:`AWS credentials `.
25 | - Support for :mod:`Downscoping with Credential Access Boundaries credentials `.
26 | - Support for various transports, including
27 | :mod:`Requests `,
28 | :mod:`urllib3 `, and
29 | :mod:`gRPC `.
30 |
31 | .. note:: ``oauth2client`` was recently deprecated in favor of this library. For more details on the deprecation, see :doc:`oauth2client-deprecation`.
32 |
33 | Installing
34 | ----------
35 |
36 | google-auth can be installed with `pip`_::
37 |
38 | $ pip install --upgrade google-auth
39 |
40 | google-auth is open-source, so you can alternatively grab the source code from
41 | `GitHub`_ and install from source.
42 |
43 |
44 | For more information on setting up your Python development environment, please refer to `Python Development Environment Setup Guide`_ for Google Cloud Platform.
45 |
46 | .. _`Python Development Environment Setup Guide`: https://cloud.google.com/python/setup
47 | .. _pip: https://pip.pypa.io
48 | .. _GitHub: https://github.com/GoogleCloudPlatform/google-auth-library-python
49 |
50 | Usage
51 | -----
52 |
53 | The :doc:`user-guide` is the place to go to learn how to use the library and
54 | accomplish common tasks.
55 |
56 | The :doc:`Module Reference ` documentation provides API-level documentation.
57 |
58 | License
59 | -------
60 |
61 | google-auth is made available under the Apache License, Version 2.0. For more
62 | details, see `LICENSE`_
63 |
64 | .. _LICENSE:
65 | https://github.com/GoogleCloudPlatform/google-auth-library-python/blob/main/LICENSE
66 |
67 | Contributing
68 | ------------
69 |
70 | We happily welcome contributions, please see our `contributing`_ documentation
71 | for details.
72 |
73 | .. _contributing:
74 | https://github.com/GoogleCloudPlatform/google-auth-library-python/blob/main/CONTRIBUTING.rst
75 |
--------------------------------------------------------------------------------
/docs/reference/google.auth._credentials_async.rst:
--------------------------------------------------------------------------------
1 | google.auth.credentials\_async module
2 | =====================================
3 |
4 | .. automodule:: google.auth._credentials_async
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth._jwt_async.rst:
--------------------------------------------------------------------------------
1 | google.auth.jwt\_async module
2 | =============================
3 |
4 | .. automodule:: google.auth._jwt_async
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.app_engine.rst:
--------------------------------------------------------------------------------
1 | google.auth.app\_engine module
2 | ==============================
3 |
4 | .. automodule:: google.auth.app_engine
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.aws.rst:
--------------------------------------------------------------------------------
1 | google.auth.aws module
2 | ======================
3 |
4 | .. automodule:: google.auth.aws
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.compute_engine.credentials.rst:
--------------------------------------------------------------------------------
1 | google.auth.compute\_engine.credentials module
2 | ==============================================
3 |
4 | .. automodule:: google.auth.compute_engine.credentials
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.compute_engine.rst:
--------------------------------------------------------------------------------
1 | google.auth.compute\_engine package
2 | ===================================
3 |
4 | .. automodule:: google.auth.compute_engine
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
9 | Submodules
10 | ----------
11 |
12 | .. toctree::
13 | :maxdepth: 4
14 |
15 | google.auth.compute_engine.credentials
16 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.credentials.rst:
--------------------------------------------------------------------------------
1 | google.auth.credentials module
2 | ==============================
3 |
4 | .. automodule:: google.auth.credentials
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.crypt.base.rst:
--------------------------------------------------------------------------------
1 | google.auth.crypt.base module
2 | =============================
3 |
4 | .. automodule:: google.auth.crypt.base
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.crypt.es256.rst:
--------------------------------------------------------------------------------
1 | google.auth.crypt.es256 module
2 | ==============================
3 |
4 | .. automodule:: google.auth.crypt.es256
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.crypt.rsa.rst:
--------------------------------------------------------------------------------
1 | google.auth.crypt.rsa module
2 | ============================
3 |
4 | .. automodule:: google.auth.crypt.rsa
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.crypt.rst:
--------------------------------------------------------------------------------
1 | google.auth.crypt package
2 | =========================
3 |
4 | .. automodule:: google.auth.crypt
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
9 | Submodules
10 | ----------
11 |
12 | .. toctree::
13 | :maxdepth: 4
14 |
15 | google.auth.crypt.base
16 | google.auth.crypt.es256
17 | google.auth.crypt.rsa
18 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.downscoped.rst:
--------------------------------------------------------------------------------
1 | google.auth.downscoped module
2 | =============================
3 |
4 | .. automodule:: google.auth.downscoped
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.environment_vars.rst:
--------------------------------------------------------------------------------
1 | google.auth.environment\_vars module
2 | ====================================
3 |
4 | .. automodule:: google.auth.environment_vars
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.exceptions.rst:
--------------------------------------------------------------------------------
1 | google.auth.exceptions module
2 | =============================
3 |
4 | .. automodule:: google.auth.exceptions
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.external_account.rst:
--------------------------------------------------------------------------------
1 | google.auth.external\_account module
2 | ====================================
3 |
4 | .. automodule:: google.auth.external_account
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.iam.rst:
--------------------------------------------------------------------------------
1 | google.auth.iam module
2 | ======================
3 |
4 | .. automodule:: google.auth.iam
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.identity_pool.rst:
--------------------------------------------------------------------------------
1 | google.auth.identity\_pool module
2 | =================================
3 |
4 | .. automodule:: google.auth.identity_pool
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.impersonated_credentials.rst:
--------------------------------------------------------------------------------
1 | google.auth.impersonated\_credentials module
2 | ============================================
3 |
4 | .. automodule:: google.auth.impersonated_credentials
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.jwt.rst:
--------------------------------------------------------------------------------
1 | google.auth.jwt module
2 | ======================
3 |
4 | .. automodule:: google.auth.jwt
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.rst:
--------------------------------------------------------------------------------
1 | google.auth package
2 | ===================
3 |
4 | .. automodule:: google.auth
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
9 | Subpackages
10 | -----------
11 |
12 | .. toctree::
13 | :maxdepth: 4
14 |
15 | google.auth.compute_engine
16 | google.auth.crypt
17 | google.auth.transport
18 |
19 | Submodules
20 | ----------
21 |
22 | .. toctree::
23 | :maxdepth: 4
24 |
25 | google.auth.app_engine
26 | google.auth.aws
27 | google.auth.credentials
28 | google.auth._credentials_async
29 | google.auth.downscoped
30 | google.auth.environment_vars
31 | google.auth.exceptions
32 | google.auth.external_account
33 | google.auth.iam
34 | google.auth.identity_pool
35 | google.auth.impersonated_credentials
36 | google.auth.jwt
37 | google.auth._jwt_async
38 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.transport._aiohttp_requests.rst:
--------------------------------------------------------------------------------
1 | google.auth.transport.aiohttp\_requests module
2 | ==============================================
3 |
4 | .. automodule:: google.auth.transport._aiohttp_requests
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.transport.grpc.rst:
--------------------------------------------------------------------------------
1 | google.auth.transport.grpc module
2 | =================================
3 |
4 | .. automodule:: google.auth.transport.grpc
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.transport.mtls.rst:
--------------------------------------------------------------------------------
1 | google.auth.transport.mtls module
2 | =================================
3 |
4 | .. automodule:: google.auth.transport.mtls
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.transport.requests.rst:
--------------------------------------------------------------------------------
1 | google.auth.transport.requests module
2 | =====================================
3 |
4 | .. automodule:: google.auth.transport.requests
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.transport.rst:
--------------------------------------------------------------------------------
1 | google.auth.transport package
2 | =============================
3 |
4 | .. automodule:: google.auth.transport
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
9 | Submodules
10 | ----------
11 |
12 | .. toctree::
13 | :maxdepth: 4
14 |
15 | google.auth.transport._aiohttp_requests
16 | google.auth.transport.grpc
17 | google.auth.transport.mtls
18 | google.auth.transport.requests
19 | google.auth.transport.urllib3
20 |
--------------------------------------------------------------------------------
/docs/reference/google.auth.transport.urllib3.rst:
--------------------------------------------------------------------------------
1 | google.auth.transport.urllib3 module
2 | ====================================
3 |
4 | .. automodule:: google.auth.transport.urllib3
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.oauth2._credentials_async.rst:
--------------------------------------------------------------------------------
1 | google.oauth2.credentials\_async module
2 | =======================================
3 |
4 | .. automodule:: google.oauth2._credentials_async
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.oauth2._service_account_async.rst:
--------------------------------------------------------------------------------
1 | google.oauth2.service\_account\_async module
2 | ============================================
3 |
4 | .. automodule:: google.oauth2._service_account_async
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.oauth2.credentials.rst:
--------------------------------------------------------------------------------
1 | google.oauth2.credentials module
2 | ================================
3 |
4 | .. automodule:: google.oauth2.credentials
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.oauth2.id_token.rst:
--------------------------------------------------------------------------------
1 | google.oauth2.id\_token module
2 | ==============================
3 |
4 | .. automodule:: google.oauth2.id_token
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.oauth2.rst:
--------------------------------------------------------------------------------
1 | google.oauth2 package
2 | =====================
3 |
4 | .. automodule:: google.oauth2
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
9 | Submodules
10 | ----------
11 |
12 | .. toctree::
13 | :maxdepth: 4
14 |
15 | google.oauth2.credentials
16 | google.oauth2._credentials_async
17 | google.oauth2.id_token
18 | google.oauth2.service_account
19 | google.oauth2._service_account_async
20 | google.oauth2.sts
21 | google.oauth2.utils
22 |
--------------------------------------------------------------------------------
/docs/reference/google.oauth2.service_account.rst:
--------------------------------------------------------------------------------
1 | google.oauth2.service\_account module
2 | =====================================
3 |
4 | .. automodule:: google.oauth2.service_account
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.oauth2.sts.rst:
--------------------------------------------------------------------------------
1 | google.oauth2.sts module
2 | ========================
3 |
4 | .. automodule:: google.oauth2.sts
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.oauth2.utils.rst:
--------------------------------------------------------------------------------
1 | google.oauth2.utils module
2 | ==========================
3 |
4 | .. automodule:: google.oauth2.utils
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/reference/google.rst:
--------------------------------------------------------------------------------
1 | google package
2 | ==============
3 |
4 | .. automodule:: google
5 | :members:
6 | :inherited-members:
7 | :show-inheritance:
8 |
9 | Subpackages
10 | -----------
11 |
12 | .. toctree::
13 | :maxdepth: 4
14 |
15 | google.auth
16 | google.oauth2
17 |
--------------------------------------------------------------------------------
/docs/reference/modules.rst:
--------------------------------------------------------------------------------
1 | google
2 | ======
3 |
4 | .. toctree::
5 | :maxdepth: 4
6 |
7 | google
8 |
--------------------------------------------------------------------------------
/docs/requirements-docs.txt:
--------------------------------------------------------------------------------
1 | cryptography
2 | sphinx-docstring-typing
3 | urllib3
4 | requests
5 | requests-oauthlib
6 | # We need to pin to specific versions of the `sphinxcontrib-*` packages
7 | # which still support sphinx 4.x.
8 | # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344
9 | # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345.
10 | sphinxcontrib-applehelp==1.0.4
11 | sphinxcontrib-devhelp==1.0.2
12 | sphinxcontrib-htmlhelp==2.0.1
13 | sphinxcontrib-qthelp==1.0.3
14 | sphinxcontrib-serializinghtml==1.1.5
15 | sphinx==4.5.0
16 | alabaster
17 | recommonmark
18 |
--------------------------------------------------------------------------------
/google/auth/__init__.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 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 | """Google Auth Library for Python."""
16 |
17 | import logging
18 | import sys
19 | import warnings
20 |
21 | from google.auth import version as google_auth_version
22 | from google.auth._default import (
23 | default,
24 | load_credentials_from_dict,
25 | load_credentials_from_file,
26 | )
27 |
28 |
29 | __version__ = google_auth_version.__version__
30 |
31 |
32 | __all__ = ["default", "load_credentials_from_file", "load_credentials_from_dict"]
33 |
34 |
35 | class Python37DeprecationWarning(DeprecationWarning): # pragma: NO COVER
36 | """
37 | Deprecation warning raised when Python 3.7 runtime is detected.
38 | Python 3.7 support will be dropped after January 1, 2024.
39 | """
40 |
41 | pass
42 |
43 |
44 | # Checks if the current runtime is Python 3.7.
45 | if sys.version_info.major == 3 and sys.version_info.minor == 7: # pragma: NO COVER
46 | message = (
47 | "After January 1, 2024, new releases of this library will drop support "
48 | "for Python 3.7."
49 | )
50 | warnings.warn(message, Python37DeprecationWarning)
51 |
52 | # Set default logging handler to avoid "No handler found" warnings.
53 | logging.getLogger(__name__).addHandler(logging.NullHandler())
54 |
--------------------------------------------------------------------------------
/google/auth/_credentials_base.py:
--------------------------------------------------------------------------------
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 |
16 | """Interface for base credentials."""
17 |
18 | import abc
19 |
20 | from google.auth import _helpers
21 |
22 |
23 | class _BaseCredentials(metaclass=abc.ABCMeta):
24 | """Base class for all credentials.
25 |
26 | All credentials have a :attr:`token` that is used for authentication and
27 | may also optionally set an :attr:`expiry` to indicate when the token will
28 | no longer be valid.
29 |
30 | Most credentials will be :attr:`invalid` until :meth:`refresh` is called.
31 | Credentials can do this automatically before the first HTTP request in
32 | :meth:`before_request`.
33 |
34 | Although the token and expiration will change as the credentials are
35 | :meth:`refreshed ` and used, credentials should be considered
36 | immutable. Various credentials will accept configuration such as private
37 | keys, scopes, and other options. These options are not changeable after
38 | construction. Some classes will provide mechanisms to copy the credentials
39 | with modifications such as :meth:`ScopedCredentials.with_scopes`.
40 |
41 | Attributes:
42 | token (Optional[str]): The bearer token that can be used in HTTP headers to make
43 | authenticated requests.
44 | """
45 |
46 | def __init__(self):
47 | self.token = None
48 |
49 | @abc.abstractmethod
50 | def refresh(self, request):
51 | """Refreshes the access token.
52 |
53 | Args:
54 | request (google.auth.transport.Request): The object used to make
55 | HTTP requests.
56 |
57 | Raises:
58 | google.auth.exceptions.RefreshError: If the credentials could
59 | not be refreshed.
60 | """
61 | # pylint: disable=missing-raises-doc
62 | # (pylint doesn't recognize that this is abstract)
63 | raise NotImplementedError("Refresh must be implemented")
64 |
65 | def _apply(self, headers, token=None):
66 | """Apply the token to the authentication header.
67 |
68 | Args:
69 | headers (Mapping): The HTTP request headers.
70 | token (Optional[str]): If specified, overrides the current access
71 | token.
72 | """
73 | headers["authorization"] = "Bearer {}".format(
74 | _helpers.from_bytes(token or self.token)
75 | )
76 |
--------------------------------------------------------------------------------
/google/auth/_service_account_info.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 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 | """Helper functions for loading data from a Google service account file."""
16 |
17 | import io
18 | import json
19 |
20 | from google.auth import crypt
21 | from google.auth import exceptions
22 |
23 |
24 | def from_dict(data, require=None, use_rsa_signer=True):
25 | """Validates a dictionary containing Google service account data.
26 |
27 | Creates and returns a :class:`google.auth.crypt.Signer` instance from the
28 | private key specified in the data.
29 |
30 | Args:
31 | data (Mapping[str, str]): The service account data
32 | require (Sequence[str]): List of keys required to be present in the
33 | info.
34 | use_rsa_signer (Optional[bool]): Whether to use RSA signer or EC signer.
35 | We use RSA signer by default.
36 |
37 | Returns:
38 | google.auth.crypt.Signer: A signer created from the private key in the
39 | service account file.
40 |
41 | Raises:
42 | MalformedError: if the data was in the wrong format, or if one of the
43 | required keys is missing.
44 | """
45 | keys_needed = set(require if require is not None else [])
46 |
47 | missing = keys_needed.difference(data.keys())
48 |
49 | if missing:
50 | raise exceptions.MalformedError(
51 | "Service account info was not in the expected format, missing "
52 | "fields {}.".format(", ".join(missing))
53 | )
54 |
55 | # Create a signer.
56 | if use_rsa_signer:
57 | signer = crypt.RSASigner.from_service_account_info(data)
58 | else:
59 | signer = crypt.ES256Signer.from_service_account_info(data)
60 |
61 | return signer
62 |
63 |
64 | def from_filename(filename, require=None, use_rsa_signer=True):
65 | """Reads a Google service account JSON file and returns its parsed info.
66 |
67 | Args:
68 | filename (str): The path to the service account .json file.
69 | require (Sequence[str]): List of keys required to be present in the
70 | info.
71 | use_rsa_signer (Optional[bool]): Whether to use RSA signer or EC signer.
72 | We use RSA signer by default.
73 |
74 | Returns:
75 | Tuple[ Mapping[str, str], google.auth.crypt.Signer ]: The verified
76 | info and a signer instance.
77 | """
78 | with io.open(filename, "r", encoding="utf-8") as json_file:
79 | data = json.load(json_file)
80 | return data, from_dict(data, require=require, use_rsa_signer=use_rsa_signer)
81 |
--------------------------------------------------------------------------------
/google/auth/aio/__init__.py:
--------------------------------------------------------------------------------
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 | """Google Auth AIO Library for Python."""
16 |
17 | import logging
18 |
19 | from google.auth import version as google_auth_version
20 |
21 |
22 | __version__ = google_auth_version.__version__
23 |
24 | # Set default logging handler to avoid "No handler found" warnings.
25 | logging.getLogger(__name__).addHandler(logging.NullHandler())
26 |
--------------------------------------------------------------------------------
/google/auth/aio/_helpers.py:
--------------------------------------------------------------------------------
1 | # Copyright 2025 Google Inc.
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 | """Helper functions for commonly used utilities."""
16 |
17 |
18 | import logging
19 | from typing import Any
20 |
21 | from google.auth import _helpers
22 |
23 |
24 | async def _parse_response_async(response: Any) -> Any:
25 | """
26 | Parses an async response, attempting to decode JSON.
27 |
28 | Args:
29 | response: The response object to parse. This can be any type, but
30 | it is expected to have a `json()` method if it contains JSON.
31 |
32 | Returns:
33 | The parsed response. If the response contains valid JSON, the
34 | decoded JSON object (e.g., a dictionary) is returned.
35 | If the response does not have a `json()` method or if the JSON
36 | decoding fails, None is returned.
37 | """
38 | try:
39 | json_response = await response.json()
40 | return json_response
41 | except Exception:
42 | # TODO(https://github.com/googleapis/google-auth-library-python/issues/1745):
43 | # Parse and return response payload as json based on different content types.
44 | return None
45 |
46 |
47 | async def response_log_async(logger: logging.Logger, response: Any) -> None:
48 | """
49 | Logs an Async HTTP response at the DEBUG level if logging is enabled.
50 |
51 | Args:
52 | logger: The logging.Logger instance to use.
53 | response: The HTTP response object to log.
54 | """
55 | if _helpers.is_logging_enabled(logger):
56 | # TODO(https://github.com/googleapis/google-auth-library-python/issues/1755):
57 | # Parsing the response for async streaming logging results in
58 | # the stream to be empty downstream. For now, we will not be logging
59 | # the response for async responses until we investigate further.
60 | # json_response = await _parse_response_async(response)
61 | json_response = None
62 | _helpers._response_log_base(logger, json_response)
63 |
--------------------------------------------------------------------------------
/google/auth/api_key.py:
--------------------------------------------------------------------------------
1 | # Copyright 2022 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 | """Google API key support.
16 | This module provides authentication using the `API key`_.
17 | .. _API key:
18 | https://cloud.google.com/docs/authentication/api-keys/
19 | """
20 |
21 | from google.auth import _helpers
22 | from google.auth import credentials
23 | from google.auth import exceptions
24 |
25 |
26 | class Credentials(credentials.Credentials):
27 | """API key credentials.
28 | These credentials use API key to provide authorization to applications.
29 | """
30 |
31 | def __init__(self, token):
32 | """
33 | Args:
34 | token (str): API key string
35 | Raises:
36 | ValueError: If the provided API key is not a non-empty string.
37 | """
38 | super(Credentials, self).__init__()
39 | if not token:
40 | raise exceptions.InvalidValue("Token must be a non-empty API key string")
41 | self.token = token
42 |
43 | @property
44 | def expired(self):
45 | return False
46 |
47 | @property
48 | def valid(self):
49 | return True
50 |
51 | @_helpers.copy_docstring(credentials.Credentials)
52 | def refresh(self, request):
53 | return
54 |
55 | def apply(self, headers, token=None):
56 | """Apply the API key token to the x-goog-api-key header.
57 | Args:
58 | headers (Mapping): The HTTP request headers.
59 | token (Optional[str]): If specified, overrides the current access
60 | token.
61 | """
62 | headers["x-goog-api-key"] = token or self.token
63 |
64 | def before_request(self, request, method, url, headers):
65 | """Performs credential-specific before request logic.
66 | Refreshes the credentials if necessary, then calls :meth:`apply` to
67 | apply the token to the x-goog-api-key header.
68 | Args:
69 | request (google.auth.transport.Request): The object used to make
70 | HTTP requests.
71 | method (str): The request's HTTP method or the RPC method being
72 | invoked.
73 | url (str): The request's URI or the RPC service's URI.
74 | headers (Mapping): The request's headers.
75 | """
76 | self.apply(headers)
77 |
--------------------------------------------------------------------------------
/google/auth/compute_engine/__init__.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 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 | """Google Compute Engine authentication."""
16 |
17 | from google.auth.compute_engine._metadata import detect_gce_residency_linux
18 | from google.auth.compute_engine.credentials import Credentials
19 | from google.auth.compute_engine.credentials import IDTokenCredentials
20 |
21 |
22 | __all__ = ["Credentials", "IDTokenCredentials", "detect_gce_residency_linux"]
23 |
--------------------------------------------------------------------------------
/google/auth/crypt/__init__.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 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 | """Cryptography helpers for verifying and signing messages.
16 |
17 | The simplest way to verify signatures is using :func:`verify_signature`::
18 |
19 | cert = open('certs.pem').read()
20 | valid = crypt.verify_signature(message, signature, cert)
21 |
22 | If you're going to verify many messages with the same certificate, you can use
23 | :class:`RSAVerifier`::
24 |
25 | cert = open('certs.pem').read()
26 | verifier = crypt.RSAVerifier.from_string(cert)
27 | valid = verifier.verify(message, signature)
28 |
29 | To sign messages use :class:`RSASigner` with a private key::
30 |
31 | private_key = open('private_key.pem').read()
32 | signer = crypt.RSASigner.from_string(private_key)
33 | signature = signer.sign(message)
34 |
35 | The code above also works for :class:`ES256Signer` and :class:`ES256Verifier`.
36 | Note that these two classes are only available if your `cryptography` dependency
37 | version is at least 1.4.0.
38 | """
39 |
40 | from google.auth.crypt import base
41 | from google.auth.crypt import rsa
42 |
43 | try:
44 | from google.auth.crypt import es256
45 | except ImportError: # pragma: NO COVER
46 | es256 = None # type: ignore
47 |
48 | if es256 is not None: # pragma: NO COVER
49 | __all__ = [
50 | "ES256Signer",
51 | "ES256Verifier",
52 | "RSASigner",
53 | "RSAVerifier",
54 | "Signer",
55 | "Verifier",
56 | ]
57 | else: # pragma: NO COVER
58 | __all__ = ["RSASigner", "RSAVerifier", "Signer", "Verifier"]
59 |
60 |
61 | # Aliases to maintain the v1.0.0 interface, as the crypt module was split
62 | # into submodules.
63 | Signer = base.Signer
64 | Verifier = base.Verifier
65 | RSASigner = rsa.RSASigner
66 | RSAVerifier = rsa.RSAVerifier
67 |
68 | if es256 is not None: # pragma: NO COVER
69 | ES256Signer = es256.ES256Signer
70 | ES256Verifier = es256.ES256Verifier
71 |
72 |
73 | def verify_signature(message, signature, certs, verifier_cls=rsa.RSAVerifier):
74 | """Verify an RSA or ECDSA cryptographic signature.
75 |
76 | Checks that the provided ``signature`` was generated from ``bytes`` using
77 | the private key associated with the ``cert``.
78 |
79 | Args:
80 | message (Union[str, bytes]): The plaintext message.
81 | signature (Union[str, bytes]): The cryptographic signature to check.
82 | certs (Union[Sequence, str, bytes]): The certificate or certificates
83 | to use to check the signature.
84 | verifier_cls (Optional[~google.auth.crypt.base.Signer]): Which verifier
85 | class to use for verification. This can be used to select different
86 | algorithms, such as RSA or ECDSA. Default value is :class:`RSAVerifier`.
87 |
88 | Returns:
89 | bool: True if the signature is valid, otherwise False.
90 | """
91 | if isinstance(certs, (str, bytes)):
92 | certs = [certs]
93 |
94 | for cert in certs:
95 | verifier = verifier_cls.from_string(cert)
96 | if verifier.verify(message, signature):
97 | return True
98 | return False
99 |
--------------------------------------------------------------------------------
/google/auth/crypt/_helpers.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googleapis/google-auth-library-python/ca94ead4035beea4741dc5384449032f8e6f75d8/google/auth/crypt/_helpers.py
--------------------------------------------------------------------------------
/google/auth/crypt/rsa.py:
--------------------------------------------------------------------------------
1 | # Copyright 2017 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 | """RSA cryptography signer and verifier."""
16 |
17 |
18 | try:
19 | # Prefer cryptograph-based RSA implementation.
20 | from google.auth.crypt import _cryptography_rsa
21 |
22 | RSASigner = _cryptography_rsa.RSASigner
23 | RSAVerifier = _cryptography_rsa.RSAVerifier
24 | except ImportError: # pragma: NO COVER
25 | # Fallback to pure-python RSA implementation if cryptography is
26 | # unavailable.
27 | from google.auth.crypt import _python_rsa
28 |
29 | RSASigner = _python_rsa.RSASigner # type: ignore
30 | RSAVerifier = _python_rsa.RSAVerifier # type: ignore
31 |
--------------------------------------------------------------------------------
/google/auth/environment_vars.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 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 | """Environment variables used by :mod:`google.auth`."""
16 |
17 |
18 | PROJECT = "GOOGLE_CLOUD_PROJECT"
19 | """Environment variable defining default project.
20 |
21 | This used by :func:`google.auth.default` to explicitly set a project ID. This
22 | environment variable is also used by the Google Cloud Python Library.
23 | """
24 |
25 | LEGACY_PROJECT = "GCLOUD_PROJECT"
26 | """Previously used environment variable defining the default project.
27 |
28 | This environment variable is used instead of the current one in some
29 | situations (such as Google App Engine).
30 | """
31 |
32 | GOOGLE_CLOUD_QUOTA_PROJECT = "GOOGLE_CLOUD_QUOTA_PROJECT"
33 | """Environment variable defining the project to be used for
34 | quota and billing."""
35 |
36 | CREDENTIALS = "GOOGLE_APPLICATION_CREDENTIALS"
37 | """Environment variable defining the location of Google application default
38 | credentials."""
39 |
40 | # The environment variable name which can replace ~/.config if set.
41 | CLOUD_SDK_CONFIG_DIR = "CLOUDSDK_CONFIG"
42 | """Environment variable defines the location of Google Cloud SDK's config
43 | files."""
44 |
45 | # These two variables allow for customization of the addresses used when
46 | # contacting the GCE metadata service.
47 | GCE_METADATA_HOST = "GCE_METADATA_HOST"
48 | """Environment variable providing an alternate hostname or host:port to be
49 | used for GCE metadata requests.
50 |
51 | This environment variable was originally named GCE_METADATA_ROOT. The system will
52 | check this environemnt variable first; should there be no value present,
53 | the system will fall back to the old variable.
54 | """
55 |
56 | GCE_METADATA_ROOT = "GCE_METADATA_ROOT"
57 | """Old environment variable for GCE_METADATA_HOST."""
58 |
59 | GCE_METADATA_IP = "GCE_METADATA_IP"
60 | """Environment variable providing an alternate ip:port to be used for ip-only
61 | GCE metadata requests."""
62 |
63 | GOOGLE_API_USE_CLIENT_CERTIFICATE = "GOOGLE_API_USE_CLIENT_CERTIFICATE"
64 | """Environment variable controlling whether to use client certificate or not.
65 |
66 | The default value is false. Users have to explicitly set this value to true
67 | in order to use client certificate to establish a mutual TLS channel."""
68 |
69 | LEGACY_APPENGINE_RUNTIME = "APPENGINE_RUNTIME"
70 | """Gen1 environment variable defining the App Engine Runtime.
71 |
72 | Used to distinguish between GAE gen1 and GAE gen2+.
73 | """
74 |
75 | # AWS environment variables used with AWS workload identity pools to retrieve
76 | # AWS security credentials and the AWS region needed to create a serialized
77 | # signed requests to the AWS STS GetCalledIdentity API that can be exchanged
78 | # for a Google access tokens via the GCP STS endpoint.
79 | # When not available the AWS metadata server is used to retrieve these values.
80 | AWS_ACCESS_KEY_ID = "AWS_ACCESS_KEY_ID"
81 | AWS_SECRET_ACCESS_KEY = "AWS_SECRET_ACCESS_KEY"
82 | AWS_SESSION_TOKEN = "AWS_SESSION_TOKEN"
83 | AWS_REGION = "AWS_REGION"
84 | AWS_DEFAULT_REGION = "AWS_DEFAULT_REGION"
85 |
--------------------------------------------------------------------------------
/google/auth/exceptions.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 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 | """Exceptions used in the google.auth package."""
16 |
17 |
18 | class GoogleAuthError(Exception):
19 | """Base class for all google.auth errors."""
20 |
21 | def __init__(self, *args, **kwargs):
22 | super(GoogleAuthError, self).__init__(*args)
23 | retryable = kwargs.get("retryable", False)
24 | self._retryable = retryable
25 |
26 | @property
27 | def retryable(self):
28 | return self._retryable
29 |
30 |
31 | class TransportError(GoogleAuthError):
32 | """Used to indicate an error occurred during an HTTP request."""
33 |
34 |
35 | class RefreshError(GoogleAuthError):
36 | """Used to indicate that an refreshing the credentials' access token
37 | failed."""
38 |
39 |
40 | class UserAccessTokenError(GoogleAuthError):
41 | """Used to indicate ``gcloud auth print-access-token`` command failed."""
42 |
43 |
44 | class DefaultCredentialsError(GoogleAuthError):
45 | """Used to indicate that acquiring default credentials failed."""
46 |
47 |
48 | class MutualTLSChannelError(GoogleAuthError):
49 | """Used to indicate that mutual TLS channel creation is failed, or mutual
50 | TLS channel credentials is missing or invalid."""
51 |
52 |
53 | class ClientCertError(GoogleAuthError):
54 | """Used to indicate that client certificate is missing or invalid."""
55 |
56 | @property
57 | def retryable(self):
58 | return False
59 |
60 |
61 | class OAuthError(GoogleAuthError):
62 | """Used to indicate an error occurred during an OAuth related HTTP
63 | request."""
64 |
65 |
66 | class ReauthFailError(RefreshError):
67 | """An exception for when reauth failed."""
68 |
69 | def __init__(self, message=None, **kwargs):
70 | super(ReauthFailError, self).__init__(
71 | "Reauthentication failed. {0}".format(message), **kwargs
72 | )
73 |
74 |
75 | class ReauthSamlChallengeFailError(ReauthFailError):
76 | """An exception for SAML reauth challenge failures."""
77 |
78 |
79 | class MalformedError(DefaultCredentialsError, ValueError):
80 | """An exception for malformed data."""
81 |
82 |
83 | class InvalidResource(DefaultCredentialsError, ValueError):
84 | """An exception for URL error."""
85 |
86 |
87 | class InvalidOperation(DefaultCredentialsError, ValueError):
88 | """An exception for invalid operation."""
89 |
90 |
91 | class InvalidValue(DefaultCredentialsError, ValueError):
92 | """Used to wrap general ValueError of python."""
93 |
94 |
95 | class InvalidType(DefaultCredentialsError, TypeError):
96 | """Used to wrap general TypeError of python."""
97 |
98 |
99 | class OSError(DefaultCredentialsError, EnvironmentError):
100 | """Used to wrap EnvironmentError(OSError after python3.3)."""
101 |
102 |
103 | class TimeoutError(GoogleAuthError):
104 | """Used to indicate a timeout error occurred during an HTTP request."""
105 |
106 |
107 | class ResponseError(GoogleAuthError):
108 | """Used to indicate an error occurred when reading an HTTP response."""
109 |
--------------------------------------------------------------------------------
/google/auth/py.typed:
--------------------------------------------------------------------------------
1 | # Marker file for PEP 561.
2 | # The google-auth package uses inline types.
3 |
--------------------------------------------------------------------------------
/google/auth/transport/_requests_base.py:
--------------------------------------------------------------------------------
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 | """Transport adapter for Base Requests."""
16 | # NOTE: The coverage for this file is temporarily disabled in `.coveragerc`
17 | # since it is currently unused.
18 |
19 | import abc
20 |
21 |
22 | _DEFAULT_TIMEOUT = 120 # in second
23 |
24 |
25 | class _BaseAuthorizedSession(metaclass=abc.ABCMeta):
26 | """Base class for a Request Session with credentials. This class is intended to capture
27 | the common logic between synchronous and asynchronous request sessions and is not intended to
28 | be instantiated directly.
29 |
30 | Args:
31 | credentials (google.auth._credentials_base.BaseCredentials): The credentials to
32 | add to the request.
33 | """
34 |
35 | def __init__(self, credentials):
36 | self.credentials = credentials
37 |
38 | @abc.abstractmethod
39 | def request(
40 | self,
41 | method,
42 | url,
43 | data=None,
44 | headers=None,
45 | max_allowed_time=None,
46 | timeout=_DEFAULT_TIMEOUT,
47 | **kwargs
48 | ):
49 | raise NotImplementedError("Request must be implemented")
50 |
51 | @abc.abstractmethod
52 | def close(self):
53 | raise NotImplementedError("Close must be implemented")
54 |
--------------------------------------------------------------------------------
/google/auth/version.py:
--------------------------------------------------------------------------------
1 | # Copyright 2021 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 | __version__ = "2.40.3"
16 |
--------------------------------------------------------------------------------
/google/oauth2/__init__.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 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 | """Google OAuth 2.0 Library for Python."""
16 |
17 | import sys
18 | import warnings
19 |
20 |
21 | class Python37DeprecationWarning(DeprecationWarning): # pragma: NO COVER
22 | """
23 | Deprecation warning raised when Python 3.7 runtime is detected.
24 | Python 3.7 support will be dropped after January 1, 2024.
25 | """
26 |
27 | pass
28 |
29 |
30 | # Checks if the current runtime is Python 3.7.
31 | if sys.version_info.major == 3 and sys.version_info.minor == 7: # pragma: NO COVER
32 | message = (
33 | "After January 1, 2024, new releases of this library will drop support "
34 | "for Python 3.7."
35 | )
36 | warnings.warn(message, Python37DeprecationWarning)
37 |
--------------------------------------------------------------------------------
/google/oauth2/py.typed:
--------------------------------------------------------------------------------
1 | # Marker file for PEP 561.
2 | # The google-oauth2 package uses inline types.
3 |
--------------------------------------------------------------------------------
/google/oauth2/webauthn_handler.py:
--------------------------------------------------------------------------------
1 | import abc
2 | import os
3 | import struct
4 | import subprocess
5 |
6 | from google.auth import exceptions
7 | from google.oauth2.webauthn_types import GetRequest, GetResponse
8 |
9 |
10 | class WebAuthnHandler(abc.ABC):
11 | @abc.abstractmethod
12 | def is_available(self) -> bool:
13 | """Check whether this WebAuthn handler is available"""
14 | raise NotImplementedError("is_available method must be implemented")
15 |
16 | @abc.abstractmethod
17 | def get(self, get_request: GetRequest) -> GetResponse:
18 | """WebAuthn get (assertion)"""
19 | raise NotImplementedError("get method must be implemented")
20 |
21 |
22 | class PluginHandler(WebAuthnHandler):
23 | """Offloads WebAuthn get reqeust to a pluggable command-line tool.
24 |
25 | Offloads WebAuthn get to a plugin which takes the form of a
26 | command-line tool. The command-line tool is configurable via the
27 | PluginHandler._ENV_VAR environment variable.
28 |
29 | The WebAuthn plugin should implement the following interface:
30 |
31 | Communication occurs over stdin/stdout, and messages are both sent and
32 | received in the form:
33 |
34 | [4 bytes - payload size (little-endian)][variable bytes - json payload]
35 | """
36 |
37 | _ENV_VAR = "GOOGLE_AUTH_WEBAUTHN_PLUGIN"
38 |
39 | def is_available(self) -> bool:
40 | try:
41 | self._find_plugin()
42 | except Exception:
43 | return False
44 | else:
45 | return True
46 |
47 | def get(self, get_request: GetRequest) -> GetResponse:
48 | request_json = get_request.to_json()
49 | cmd = self._find_plugin()
50 | response_json = self._call_plugin(cmd, request_json)
51 | return GetResponse.from_json(response_json)
52 |
53 | def _call_plugin(self, cmd: str, input_json: str) -> str:
54 | # Calculate length of input
55 | input_length = len(input_json)
56 | length_bytes_le = struct.pack(" str:
77 | plugin_cmd = os.environ.get(PluginHandler._ENV_VAR)
78 | if plugin_cmd is None:
79 | raise exceptions.InvalidResource(
80 | "{} env var is not set".format(PluginHandler._ENV_VAR)
81 | )
82 | return plugin_cmd
83 |
--------------------------------------------------------------------------------
/google/oauth2/webauthn_handler_factory.py:
--------------------------------------------------------------------------------
1 | from typing import List, Optional
2 |
3 | from google.oauth2.webauthn_handler import PluginHandler, WebAuthnHandler
4 |
5 |
6 | class WebauthnHandlerFactory:
7 | handlers: List[WebAuthnHandler]
8 |
9 | def __init__(self):
10 | self.handlers = [PluginHandler()]
11 |
12 | def get_handler(self) -> Optional[WebAuthnHandler]:
13 | for handler in self.handlers:
14 | if handler.is_available():
15 | return handler
16 | return None
17 |
--------------------------------------------------------------------------------
/mypy.ini:
--------------------------------------------------------------------------------
1 | [mypy]
2 | python_version = 3.7
3 | namespace_packages = True
4 |
--------------------------------------------------------------------------------
/owlbot.py:
--------------------------------------------------------------------------------
1 | import synthtool as s
2 | from synthtool import gcp
3 |
4 | common = gcp.CommonTemplates()
5 |
6 | # ----------------------------------------------------------------------------
7 | # Add templated files
8 | # ----------------------------------------------------------------------------
9 | templated_files = common.py_library(unit_cov_level=100, cov_level=100)
10 |
11 |
12 | s.move(
13 | templated_files / ".kokoro",
14 | excludes=[
15 | "continuous/common.cfg",
16 | "presubmit/common.cfg",
17 | "build.sh",
18 | "samples/*",
19 | ],
20 | ) # just move kokoro configs
21 | s.move(
22 | # needed by samples kokoro jobs
23 | templated_files / ".trampolinerc"
24 | )
25 | s.move(
26 | templated_files / "renovate.json",
27 | )
28 |
29 | s.shell.run(["nox", "-s", "blacken"], hide_output=False)
30 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "config:base",
4 | "group:all",
5 | ":preserveSemverRanges",
6 | ":disableDependencyDashboard"
7 | ],
8 | "ignorePaths": [".pre-commit-config.yaml", ".kokoro/requirements.txt", "setup.py", ".github/workflows/unittest.yml"],
9 | "pip_requirements": {
10 | "fileMatch": ["requirements-test.txt", "samples/[\\S/]*constraints.txt", "samples/[\\S/]*constraints-test.txt"]
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/samples/cloud-client/snippets/authenticate_explicit_with_adc.py:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Google Inc.
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 | # [START auth_cloud_explicit_adc]
16 |
17 | from google.cloud import storage
18 |
19 | import google.oauth2.credentials
20 | import google.auth
21 |
22 |
23 | def authenticate_explicit_with_adc():
24 | """
25 | List storage buckets by authenticating with ADC.
26 |
27 | // TODO(Developer):
28 | // 1. Before running this sample,
29 | // set up ADC as described in https://cloud.google.com/docs/authentication/external/set-up-adc
30 | // 2. Replace the project variable.
31 | // 3. Make sure you have the necessary permission to list storage buckets: "storage.buckets.list"
32 | """
33 |
34 | # Construct the Google credentials object which obtains the default configuration from your
35 | # working environment.
36 | # google.auth.default() will give you ComputeEngineCredentials
37 | # if you are on a GCE (or other metadata server supported environments).
38 | credentials, project_id = google.auth.default()
39 | # If you are authenticating to a Cloud API, you can let the library include the default scope,
40 | # https://www.googleapis.com/auth/cloud-platform, because IAM is used to provide fine-grained
41 | # permissions for Cloud.
42 | # If you need to provide a scope, specify it as follows:
43 | # credentials = google.auth.default(scopes=scope)
44 | # For more information on scopes to use,
45 | # see: https://developers.google.com/identity/protocols/oauth2/scopes
46 |
47 | # Construct the Storage client.
48 | storage_client = storage.Client(credentials=credentials, project=project_id)
49 | buckets = storage_client.list_buckets()
50 | print("Buckets:")
51 | for bucket in buckets:
52 | print(bucket.name)
53 | print("Listed all storage buckets.")
54 |
55 | # [END auth_cloud_explicit_adc]
56 |
--------------------------------------------------------------------------------
/samples/cloud-client/snippets/authenticate_implicit_with_adc.py:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Google Inc.
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 | # [START auth_cloud_implicit_adc]
16 |
17 | from google.cloud import storage
18 |
19 |
20 | def authenticate_implicit_with_adc(project_id="your-google-cloud-project-id"):
21 | """
22 | When interacting with Google Cloud Client libraries, the library can auto-detect the
23 | credentials to use.
24 |
25 | // TODO(Developer):
26 | // 1. Before running this sample,
27 | // set up ADC as described in https://cloud.google.com/docs/authentication/external/set-up-adc
28 | // 2. Replace the project variable.
29 | // 3. Make sure that the user account or service account that you are using
30 | // has the required permissions. For this sample, you must have "storage.buckets.list".
31 | Args:
32 | project_id: The project id of your Google Cloud project.
33 | """
34 |
35 | # This snippet demonstrates how to list buckets.
36 | # *NOTE*: Replace the client created below with the client required for your application.
37 | # Note that the credentials are not specified when constructing the client.
38 | # Hence, the client library will look for credentials using ADC.
39 | storage_client = storage.Client(project=project_id)
40 | buckets = storage_client.list_buckets()
41 | print("Buckets:")
42 | for bucket in buckets:
43 | print(bucket.name)
44 | print("Listed all storage buckets.")
45 |
46 | # [END auth_cloud_implicit_adc]
47 |
--------------------------------------------------------------------------------
/samples/cloud-client/snippets/idtoken_from_impersonated_credentials.py:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Google Inc.
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 | # [auth_cloud_idtoken_impersonated_credentials]
16 |
17 | import google
18 | from google.auth import impersonated_credentials
19 | import google.auth.transport.requests
20 |
21 |
22 | def idtoken_from_impersonated_credentials(
23 | impersonated_service_account: str, scope: str, target_audience: str):
24 | """
25 | Use a service account (SA1) to impersonate as another service account (SA2) and obtain id token
26 | for the impersonated account.
27 | To obtain token for SA2, SA1 should have the "roles/iam.serviceAccountTokenCreator" permission
28 | on SA2.
29 |
30 | Args:
31 | impersonated_service_account: The name of the privilege-bearing service account for whom the credential is created.
32 | Examples: name@project.service.gserviceaccount.com
33 |
34 | scope: Provide the scopes that you might need to request to access Google APIs,
35 | depending on the level of access you need.
36 | For this example, we use the cloud-wide scope and use IAM to narrow the permissions.
37 | https://cloud.google.com/docs/authentication#authorization_for_services
38 | For more information, see: https://developers.google.com/identity/protocols/oauth2/scopes
39 |
40 | target_audience: The service name for which the id token is requested. Service name refers to the
41 | logical identifier of an API service, such as "iap.googleapis.com".
42 | Examples: iap.googleapis.com
43 | """
44 |
45 | # Construct the GoogleCredentials object which obtains the default configuration from your
46 | # working environment.
47 | credentials, project_id = google.auth.default()
48 |
49 | # Create the impersonated credential.
50 | target_credentials = impersonated_credentials.Credentials(
51 | source_credentials=credentials,
52 | target_principal=impersonated_service_account,
53 | # delegates: The chained list of delegates required to grant the final accessToken.
54 | # For more information, see:
55 | # https://cloud.google.com/iam/docs/create-short-lived-credentials-direct#sa-credentials-permissions
56 | # Delegate is NOT USED here.
57 | delegates=[],
58 | target_scopes=[scope],
59 | lifetime=300)
60 |
61 | # Set the impersonated credential, target audience and token options.
62 | id_creds = impersonated_credentials.IDTokenCredentials(
63 | target_credentials,
64 | target_audience=target_audience,
65 | include_email=True)
66 |
67 | # Get the ID token.
68 | # Once you've obtained the ID token, use it to make an authenticated call
69 | # to the target audience.
70 | request = google.auth.transport.requests.Request()
71 | id_creds.refresh(request)
72 | # token = id_creds.token
73 | print("Generated ID token.")
74 |
75 | # [auth_cloud_idtoken_impersonated_credentials]
76 |
--------------------------------------------------------------------------------
/samples/cloud-client/snippets/idtoken_from_metadata_server.py:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Google Inc.
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 | # [START auth_cloud_idtoken_metadata_server]
16 |
17 | import google
18 | import google.oauth2.credentials
19 | from google.auth import compute_engine
20 | import google.auth.transport.requests
21 |
22 |
23 | def idtoken_from_metadata_server(url: str):
24 | """
25 | Use the Google Cloud metadata server in the Cloud Run (or AppEngine or Kubernetes etc.,)
26 | environment to create an identity token and add it to the HTTP request as part of an
27 | Authorization header.
28 |
29 | Args:
30 | url: The url or target audience to obtain the ID token for.
31 | Examples: http://www.example.com
32 | """
33 |
34 | request = google.auth.transport.requests.Request()
35 | # Set the target audience.
36 | # Setting "use_metadata_identity_endpoint" to "True" will make the request use the default application
37 | # credentials. Optionally, you can also specify a specific service account to use by mentioning
38 | # the service_account_email.
39 | credentials = compute_engine.IDTokenCredentials(
40 | request=request, target_audience=url, use_metadata_identity_endpoint=True
41 | )
42 |
43 | # Get the ID token.
44 | # Once you've obtained the ID token, use it to make an authenticated call
45 | # to the target audience.
46 | credentials.refresh(request)
47 | # print(credentials.token)
48 | print("Generated ID token.")
49 |
50 | # [END auth_cloud_idtoken_metadata_server]
51 |
--------------------------------------------------------------------------------
/samples/cloud-client/snippets/idtoken_from_service_account.py:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Google Inc.
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 | # [START auth_cloud_idtoken_service_account]
16 |
17 | import google.auth
18 | import google.auth.transport.requests
19 |
20 | from google.oauth2 import service_account
21 |
22 |
23 | def get_idToken_from_serviceaccount(json_credential_path: str, target_audience: str):
24 | """
25 | TODO(Developer): Replace the below variables before running the code.
26 |
27 | *NOTE*:
28 | Using service account keys introduces risk; they are long-lived, and can be used by anyone
29 | that obtains the key. Proper rotation and storage reduce this risk but do not eliminate it.
30 | For these reasons, you should consider an alternative approach that
31 | does not use a service account key. Several alternatives to service account keys
32 | are described here:
33 | https://cloud.google.com/docs/authentication/external/set-up-adc
34 |
35 | Args:
36 | json_credential_path: Path to the service account json credential file.
37 | target_audience: The url or target audience to obtain the ID token for.
38 | Examples: http://www.abc.com
39 | """
40 |
41 | # Obtain the id token by providing the json file path and target audience.
42 | credentials = service_account.IDTokenCredentials.from_service_account_file(
43 | filename=json_credential_path,
44 | target_audience=target_audience)
45 |
46 | request = google.auth.transport.requests.Request()
47 | credentials.refresh(request)
48 | print("Generated ID token.")
49 |
50 | # [END auth_cloud_idtoken_service_account]
51 |
--------------------------------------------------------------------------------
/samples/cloud-client/snippets/noxfile.py:
--------------------------------------------------------------------------------
1 | # Copyright 2019 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 pathlib
16 |
17 | import nox
18 |
19 | CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute()
20 |
21 | # https://github.com/psf/black/issues/2964, pin click version to 8.0.4 to
22 | # avoid incompatiblity with black.
23 | CLICK_VERSION = "click==8.0.4"
24 | BLACK_VERSION = "black==19.3b0"
25 | BLACK_PATHS = [
26 | "google",
27 | "tests",
28 | "tests_async",
29 | "noxfile.py",
30 | "setup.py",
31 | "docs/conf.py",
32 | ]
33 |
34 |
35 | # Error if a python version is missing
36 | nox.options.error_on_missing_interpreters = True
37 |
38 | #
39 | # Style Checks
40 | #
41 |
42 |
43 | # Linting with flake8.
44 | #
45 | # We ignore the following rules:
46 | # E203: whitespace before ‘:’
47 | # E266: too many leading ‘#’ for block comment
48 | # E501: line too long
49 | # I202: Additional newline in a section of imports
50 | #
51 | # We also need to specify the rules which are ignored by default:
52 | # ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121']
53 | FLAKE8_COMMON_ARGS = [
54 | "--show-source",
55 | "--builtin=gettext",
56 | "--max-complexity=20",
57 | "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py",
58 | "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202",
59 | "--max-line-length=88",
60 | ]
61 |
62 |
63 | @nox.session(python=["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"])
64 | def unit(session):
65 | # constraints_path = str(
66 | # CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt"
67 | # )
68 | session.install("-r", "requirements.txt")
69 | # session.install("-e", ".")
70 | session.run(
71 | "pytest",
72 | f"--junitxml=unit_{session.python}_sponge_log.xml",
73 | "snippets_test.py",
74 | # "tests_async",
75 | )
76 |
77 |
78 | @nox.session
79 | def lint(session: nox.sessions.Session) -> None:
80 | session.install("flake8")
81 |
82 | args = FLAKE8_COMMON_ARGS + [
83 | ".",
84 | ]
85 | session.run("flake8", *args)
86 |
--------------------------------------------------------------------------------
/samples/cloud-client/snippets/noxfile_config.py:
--------------------------------------------------------------------------------
1 | # Copyright 2022 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 | # Default TEST_CONFIG_OVERRIDE for python repos.
16 |
17 | # You can copy this file into your directory, then it will be inported from
18 | # the noxfile.py.
19 |
20 | # The source of truth:
21 | # https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/noxfile_config.py
22 |
23 | TEST_CONFIG_OVERRIDE = {
24 | # You can opt out from the test for specific Python versions.
25 | "ignored_versions": ["2.7"],
26 | # Old samples are opted out of enforcing Python type hints
27 | # All new samples should feature them
28 | "enforce_type_hints": True,
29 | # An envvar key for determining the project id to use. Change it
30 | # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a
31 | # build specific Cloud project. You can also use your own string
32 | # to use your own Cloud project.
33 | # "gcloud_project_env": "GOOGLE_CLOUD_PROJECT",
34 | "gcloud_project_env": "GOOGLE_CLOUD_PROJECT",
35 | # A dictionary you want to inject into your test. Don't put any
36 | # secrets here. These values will override predefined values.
37 | "envs": {},
38 | }
39 |
--------------------------------------------------------------------------------
/samples/cloud-client/snippets/requirements.txt:
--------------------------------------------------------------------------------
1 | google-cloud-compute==1.5.1
2 | google-cloud-storage==3.1.0
3 | google-auth==2.38.0
4 | pytest==7.1.2
5 |
--------------------------------------------------------------------------------
/samples/cloud-client/snippets/snippets_test.py:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Google Inc.
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 | import re
15 |
16 | from _pytest.capture import CaptureFixture
17 |
18 | import authenticate_explicit_with_adc
19 | import authenticate_implicit_with_adc
20 | import idtoken_from_metadata_server
21 | import idtoken_from_service_account
22 | # from system_tests.noxfile import SERVICE_ACCOUNT_FILE
23 | import verify_google_idtoken
24 |
25 | import google
26 | from google.oauth2 import service_account
27 | import google.auth.transport.requests
28 | import os
29 |
30 | CREDENTIALS, PROJECT = google.auth.default()
31 | SERVICE_ACCOUNT_FILE = os.getenv("GOOGLE_APPLICATION_CREDENTIALS")
32 |
33 |
34 | def test_authenticate_explicit_with_adc(capsys: CaptureFixture):
35 | authenticate_explicit_with_adc.authenticate_explicit_with_adc()
36 | out, err = capsys.readouterr()
37 | assert re.search("Listed all storage buckets.", out)
38 |
39 |
40 | def test_authenticate_implicit_with_adc(capsys: CaptureFixture):
41 | authenticate_implicit_with_adc.authenticate_implicit_with_adc(PROJECT)
42 | out, err = capsys.readouterr()
43 | assert re.search("Listed all storage buckets.", out)
44 |
45 |
46 | def test_idtoken_from_metadata_server(capsys: CaptureFixture):
47 | idtoken_from_metadata_server.idtoken_from_metadata_server("https://www.google.com")
48 | out, err = capsys.readouterr()
49 | assert re.search("Generated ID token.", out)
50 |
51 |
52 | def test_idtoken_from_service_account(capsys: CaptureFixture):
53 | idtoken_from_service_account.get_idToken_from_serviceaccount(
54 | SERVICE_ACCOUNT_FILE,
55 | "iap.googleapis.com")
56 | out, err = capsys.readouterr()
57 | assert re.search("Generated ID token.", out)
58 |
59 |
60 | def test_verify_google_idtoken():
61 | idtoken = get_idtoken_from_service_account(SERVICE_ACCOUNT_FILE, "iap.googleapis.com")
62 |
63 | verify_google_idtoken.verify_google_idtoken(
64 | idtoken,
65 | "iap.googleapis.com",
66 | "https://www.googleapis.com/oauth2/v3/certs"
67 | )
68 |
69 |
70 | def get_idtoken_from_service_account(json_credential_path: str, target_audience: str):
71 | credentials = service_account.IDTokenCredentials.from_service_account_file(
72 | filename=json_credential_path,
73 | target_audience=target_audience)
74 |
75 | request = google.auth.transport.requests.Request()
76 | credentials.refresh(request)
77 | return credentials.token
78 |
--------------------------------------------------------------------------------
/samples/cloud-client/snippets/verify_google_idtoken.py:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Google Inc.
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 | # [START auth_cloud_verify_google_idtoken]
16 |
17 | import google
18 | import google.auth.transport.requests
19 | from google.oauth2 import id_token
20 |
21 |
22 | def verify_google_idtoken(idtoken: str, audience="iap.googleapis.com",
23 | jwk_url="https://www.googleapis.com/oauth2/v3/certs"):
24 | """
25 | Verifies the obtained Google id token. This is done at the receiving end of the OIDC endpoint.
26 | The most common use case for verifying the ID token is when you are protecting
27 | your own APIs with IAP. Google services already verify credentials as a platform,
28 | so verifying ID tokens before making Google API calls is usually unnecessary.
29 |
30 | Args:
31 | idtoken: The Google ID token to verify.
32 |
33 | audience: The service name for which the id token is requested. Service name refers to the
34 | logical identifier of an API service, such as "iap.googleapis.com".
35 |
36 | jwk_url: To verify id tokens, get the Json Web Key endpoint (jwk).
37 | OpenID Connect allows the use of a "Discovery document," a JSON document found at a
38 | well-known location containing key-value pairs which provide details about the
39 | OpenID Connect provider's configuration.
40 | For more information on validating the jwt, see:
41 | https://developers.google.com/identity/protocols/oauth2/openid-connect#validatinganidtoken
42 |
43 | Here, we validate Google's token using Google's OpenID Connect service (jwkUrl).
44 | For more information on jwk,see:
45 | https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-key-sets
46 | """
47 |
48 | request = google.auth.transport.requests.Request()
49 | # Set the parameters and verify the token.
50 | # Setting "certs_url" is optional. When verifying a Google ID token, this is set by default.
51 | result = id_token.verify_token(idtoken, request, audience, clock_skew_in_seconds=10)
52 |
53 | # Verify that the token contains subject and email claims.
54 | # Get the User id.
55 | if not result["sub"] is None:
56 | print(f"User id: {result['sub']}")
57 | # Optionally, if "INCLUDE_EMAIL" was set in the token options, check if the
58 | # email was verified.
59 | if result['email_verified'] == "True":
60 | print(f"Email verified {result['email']}")
61 |
62 | # [END auth_cloud_verify_google_idtoken]
63 |
--------------------------------------------------------------------------------
/scripts/decrypt-secrets.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Copyright 2015 Google Inc. All rights reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
18 | ROOT=$( dirname "$DIR" )
19 |
20 | # Work from the project root.
21 | cd $ROOT
22 |
23 | gcloud kms decrypt \
24 | --location=global \
25 | --keyring=ci \
26 | --key=kokoro-secrets \
27 | --ciphertext-file=system_tests/secrets.tar.enc \
28 | --plaintext-file=system_tests/secrets.tar
29 | tar xvf system_tests/secrets.tar
30 | rm system_tests/secrets.tar
31 |
--------------------------------------------------------------------------------
/scripts/encrypt-secrets.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Copyright 2015 Google Inc. All rights reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
18 | ROOT=$( dirname "$DIR" )
19 |
20 | # Work from the project root.
21 | cd $ROOT
22 |
23 | tar cvf system_tests/secrets.tar system_tests/data
24 |
25 | gcloud kms encrypt \
26 | --location=global \
27 | --keyring=ci \
28 | --key=kokoro-secrets \
29 | --plaintext-file=system_tests/secrets.tar \
30 | --ciphertext-file=system_tests/secrets.tar.enc
31 |
32 | rm system_tests/secrets.tar
--------------------------------------------------------------------------------
/scripts/travis.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Copyright 2015 Google Inc. All rights reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -eo pipefail
18 |
19 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
20 | ROOT=$( dirname "$DIR" )
21 |
22 | # Work from the project root.
23 | cd $ROOT
24 |
25 | # Decrypt secrets and run system tests if not on an external PR.
26 | if [[ -n $SYSTEM_TEST ]]; then
27 | if [[ $TRAVIS_SECURE_ENV_VARS == "true" ]]; then
28 | echo 'Extracting secrets.'
29 | scripts/decrypt-secrets.sh "$SECRETS_PASSWORD"
30 | # Prevent build failures from leaking our password.
31 | # looking at you, Tox.
32 | export SECRETS_PASSWORD=""
33 | else
34 | # This is an external PR, so just mark system tests as green.
35 | echo 'In system test but secrets are not available, skipping.'
36 | exit 0
37 | fi
38 | fi
39 |
40 | # Run nox.
41 | echo "Running nox..."
42 | nox
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [bdist_wheel]
2 | universal = 1
--------------------------------------------------------------------------------
/system_tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googleapis/google-auth-library-python/ca94ead4035beea4741dc5384449032f8e6f75d8/system_tests/__init__.py
--------------------------------------------------------------------------------
/system_tests/secrets.tar.enc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googleapis/google-auth-library-python/ca94ead4035beea4741dc5384449032f8e6f75d8/system_tests/secrets.tar.enc
--------------------------------------------------------------------------------
/system_tests/system_tests_async/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googleapis/google-auth-library-python/ca94ead4035beea4741dc5384449032f8e6f75d8/system_tests/system_tests_async/__init__.py
--------------------------------------------------------------------------------
/system_tests/system_tests_async/test_default.py:
--------------------------------------------------------------------------------
1 | # Copyright 2020 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 os
16 | import pytest
17 |
18 | from google.auth import _default_async
19 |
20 | EXPECT_PROJECT_ID = os.environ.get("EXPECT_PROJECT_ID")
21 |
22 | @pytest.mark.asyncio
23 | async def test_application_default_credentials(verify_refresh):
24 | credentials, project_id = _default_async.default_async()
25 |
26 | if EXPECT_PROJECT_ID is not None:
27 | assert project_id is not None
28 |
29 | await verify_refresh(credentials)
30 |
--------------------------------------------------------------------------------
/system_tests/system_tests_async/test_id_token.py:
--------------------------------------------------------------------------------
1 | # Copyright 2020 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 | import pytest
15 |
16 | from google.auth import jwt
17 | import google.oauth2._id_token_async
18 |
19 | @pytest.mark.asyncio
20 | async def test_fetch_id_token(http_request):
21 | audience = "https://pubsub.googleapis.com"
22 | token = await google.oauth2._id_token_async.fetch_id_token(http_request, audience)
23 |
24 | _, payload, _, _ = jwt._unverified_decode(token)
25 | assert payload["aud"] == audience
26 |
--------------------------------------------------------------------------------
/system_tests/system_tests_async/test_service_account.py:
--------------------------------------------------------------------------------
1 | # Copyright 2020 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 pytest
16 |
17 | from google.auth import _helpers
18 | from google.auth import exceptions
19 | from google.auth import iam
20 | from google.oauth2 import _service_account_async
21 |
22 |
23 | @pytest.fixture
24 | def credentials(service_account_file):
25 | yield _service_account_async.Credentials.from_service_account_file(service_account_file)
26 |
27 |
28 | @pytest.mark.asyncio
29 | async def test_refresh_no_scopes(http_request, credentials):
30 | """
31 | We expect the http request to refresh credentials
32 | without scopes provided to throw an error.
33 | """
34 | with pytest.raises(exceptions.RefreshError):
35 | await credentials.refresh(http_request)
36 |
37 | @pytest.mark.asyncio
38 | async def test_refresh_success(http_request, credentials, token_info):
39 | credentials = credentials.with_scopes(["email", "profile"])
40 | await credentials.refresh(http_request)
41 |
42 | assert credentials.token
43 |
44 | info = await token_info(credentials.token)
45 |
46 | assert info["email"] == credentials.service_account_email
47 | info_scopes = _helpers.string_to_scopes(info["scope"])
48 | assert set(info_scopes) == set(
49 | [
50 | "https://www.googleapis.com/auth/userinfo.email",
51 | "https://www.googleapis.com/auth/userinfo.profile",
52 | ]
53 | )
54 |
--------------------------------------------------------------------------------
/system_tests/system_tests_sync/.gitignore:
--------------------------------------------------------------------------------
1 | data
2 | secrets.tar
--------------------------------------------------------------------------------
/system_tests/system_tests_sync/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googleapis/google-auth-library-python/ca94ead4035beea4741dc5384449032f8e6f75d8/system_tests/system_tests_sync/__init__.py
--------------------------------------------------------------------------------
/system_tests/system_tests_sync/secrets.tar.enc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googleapis/google-auth-library-python/ca94ead4035beea4741dc5384449032f8e6f75d8/system_tests/system_tests_sync/secrets.tar.enc
--------------------------------------------------------------------------------
/system_tests/system_tests_sync/test_compute_engine.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 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 | from datetime import datetime
16 |
17 | import pytest
18 |
19 | import google.auth
20 | from google.auth import compute_engine
21 | from google.auth import _helpers
22 | from google.auth import exceptions
23 | from google.auth import jwt
24 | from google.auth.compute_engine import _metadata
25 | import google.oauth2.id_token
26 |
27 | AUDIENCE = "https://pubsub.googleapis.com"
28 |
29 |
30 | @pytest.fixture(autouse=True)
31 | def check_gce_environment(http_request):
32 | try:
33 | _metadata.get_service_account_info(http_request)
34 | except exceptions.TransportError:
35 | pytest.skip("Compute Engine metadata service is not available.")
36 |
37 |
38 | def test_refresh(http_request, token_info):
39 | credentials = compute_engine.Credentials()
40 |
41 | credentials.refresh(http_request)
42 |
43 | assert credentials.token is not None
44 | assert credentials.service_account_email is not None
45 |
46 | info = token_info(credentials.token)
47 | info_scopes = _helpers.string_to_scopes(info["scope"])
48 | assert set(info_scopes) == set(credentials.scopes)
49 |
50 |
51 | def test_default(verify_refresh):
52 | credentials, project_id = google.auth.default()
53 |
54 | assert project_id is not None
55 | assert isinstance(credentials, compute_engine.Credentials)
56 | verify_refresh(credentials)
57 |
58 |
59 | def test_id_token_from_metadata(http_request):
60 | credentials = compute_engine.IDTokenCredentials(
61 | http_request, AUDIENCE, use_metadata_identity_endpoint=True
62 | )
63 | credentials.refresh(http_request)
64 |
65 | _, payload, _, _ = jwt._unverified_decode(credentials.token)
66 | assert credentials.valid
67 | assert payload["aud"] == AUDIENCE
68 | assert datetime.fromtimestamp(payload["exp"]) == credentials.expiry
69 |
70 |
71 | def test_fetch_id_token(http_request):
72 | token = google.oauth2.id_token.fetch_id_token(http_request, AUDIENCE)
73 |
74 | _, payload, _, _ = jwt._unverified_decode(token)
75 | assert payload["aud"] == AUDIENCE
76 |
--------------------------------------------------------------------------------
/system_tests/system_tests_sync/test_default.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 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 os
16 |
17 | import google.auth
18 |
19 | EXPECT_PROJECT_ID = os.environ.get("EXPECT_PROJECT_ID")
20 |
21 |
22 | def test_application_default_credentials(verify_refresh):
23 | credentials, project_id = google.auth.default()
24 |
25 | if EXPECT_PROJECT_ID is not None:
26 | assert project_id is not None
27 |
28 | verify_refresh(credentials)
29 |
--------------------------------------------------------------------------------
/system_tests/system_tests_sync/test_grpc.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 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 google.auth
16 | import google.auth.credentials
17 | import google.auth.jwt
18 | import google.auth.transport.grpc
19 | from google.oauth2 import service_account
20 |
21 | from google.cloud import pubsub_v1
22 |
23 |
24 | def test_grpc_request_with_regular_credentials(http_request):
25 | credentials, project_id = google.auth.default()
26 | credentials = google.auth.credentials.with_scopes_if_required(
27 | credentials, scopes=["https://www.googleapis.com/auth/pubsub"]
28 | )
29 |
30 |
31 | # Create a pub/sub client.
32 | client = pubsub_v1.PublisherClient(credentials=credentials)
33 |
34 | # list the topics and drain the iterator to test that an authorized API
35 | # call works.
36 | list_topics_iter = client.list_topics(project="projects/{}".format(project_id))
37 | list(list_topics_iter)
38 |
39 |
40 | def test_grpc_request_with_regular_credentials_and_self_signed_jwt(http_request):
41 | credentials, project_id = google.auth.default()
42 |
43 | # At the time this test is being written, there are no GAPIC libraries
44 | # that will trigger the self-signed JWT flow. Manually create the self-signed
45 | # jwt on the service account credential to check that the request
46 | # succeeds.
47 | credentials = credentials.with_scopes(
48 | scopes=[], default_scopes=["https://www.googleapis.com/auth/pubsub"]
49 | )
50 | credentials._create_self_signed_jwt(audience="https://pubsub.googleapis.com/")
51 |
52 | # Create a pub/sub client.
53 | client = pubsub_v1.PublisherClient(credentials=credentials)
54 |
55 | # list the topics and drain the iterator to test that an authorized API
56 | # call works.
57 | list_topics_iter = client.list_topics(project="projects/{}".format(project_id))
58 | list(list_topics_iter)
59 |
60 | # Check that self-signed JWT was created and is being used
61 | assert credentials._jwt_credentials is not None
62 | assert credentials._jwt_credentials.token == credentials.token
63 |
64 |
65 | def test_grpc_request_with_jwt_credentials():
66 | credentials, project_id = google.auth.default()
67 | audience = "https://pubsub.googleapis.com/google.pubsub.v1.Publisher"
68 | credentials = google.auth.jwt.Credentials.from_signing_credentials(
69 | credentials, audience=audience
70 | )
71 |
72 | # Create a pub/sub client.
73 | client = pubsub_v1.PublisherClient(credentials=credentials)
74 |
75 | # list the topics and drain the iterator to test that an authorized API
76 | # call works.
77 | list_topics_iter = client.list_topics(project="projects/{}".format(project_id))
78 | list(list_topics_iter)
79 |
80 |
81 | def test_grpc_request_with_on_demand_jwt_credentials():
82 | credentials, project_id = google.auth.default()
83 | credentials = google.auth.jwt.OnDemandCredentials.from_signing_credentials(
84 | credentials
85 | )
86 |
87 | # Create a pub/sub client.
88 | client = pubsub_v1.PublisherClient(credentials=credentials)
89 |
90 | # list the topics and drain the iterator to test that an authorized API
91 | # call works.
92 | list_topics_iter = client.list_topics(project="projects/{}".format(project_id))
93 | list(list_topics_iter)
94 |
--------------------------------------------------------------------------------
/system_tests/system_tests_sync/test_id_token.py:
--------------------------------------------------------------------------------
1 | # Copyright 2020 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 | import pytest
15 |
16 | from google.auth import jwt
17 | import google.oauth2.id_token
18 |
19 |
20 | def test_fetch_id_token(http_request):
21 | audience = "https://pubsub.googleapis.com"
22 | token = google.oauth2.id_token.fetch_id_token(http_request, audience)
23 |
24 | _, payload, _, _ = jwt._unverified_decode(token)
25 | assert payload["aud"] == audience
26 |
--------------------------------------------------------------------------------
/system_tests/system_tests_sync/test_oauth2_credentials.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 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 json
16 |
17 | from google.auth import _helpers
18 | import google.oauth2.credentials
19 |
20 | GOOGLE_OAUTH2_TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token"
21 |
22 |
23 | def test_refresh(authorized_user_file, http_request, token_info):
24 | with open(authorized_user_file, "r") as fh:
25 | info = json.load(fh)
26 |
27 | credentials = google.oauth2.credentials.Credentials(
28 | None, # No access token, must be refreshed.
29 | refresh_token=info["refresh_token"],
30 | token_uri=GOOGLE_OAUTH2_TOKEN_ENDPOINT,
31 | client_id=info["client_id"],
32 | client_secret=info["client_secret"],
33 | )
34 |
35 | credentials.refresh(http_request)
36 |
37 | assert credentials.token
38 |
39 | info = token_info(credentials.token)
40 |
41 | info_scopes = _helpers.string_to_scopes(info["scope"])
42 |
43 | # Canonical list of scopes at https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login
44 | # or do `gcloud auth application-defaut login --help`
45 | canonical_scopes = set(
46 | [
47 | "https://www.googleapis.com/auth/userinfo.email",
48 | "https://www.googleapis.com/auth/cloud-platform",
49 | "openid",
50 | ]
51 | )
52 | # When running the test locally, we always have an additional "accounts.reauth" scope.
53 | canonical_scopes_with_reauth = canonical_scopes.copy()
54 | canonical_scopes_with_reauth.add("https://www.googleapis.com/auth/accounts.reauth")
55 | assert set(info_scopes) == canonical_scopes or set(info_scopes) == canonical_scopes_with_reauth
56 |
--------------------------------------------------------------------------------
/system_tests/system_tests_sync/test_requests.py:
--------------------------------------------------------------------------------
1 | # Copyright 2021 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 google.auth
16 | import google.auth.credentials
17 | import google.auth.transport.requests
18 | from google.oauth2 import service_account
19 |
20 |
21 | def test_authorized_session_with_service_account_and_self_signed_jwt():
22 | credentials, project_id = google.auth.default()
23 |
24 | credentials = credentials.with_scopes(
25 | scopes=[],
26 | default_scopes=["https://www.googleapis.com/auth/pubsub"],
27 | )
28 |
29 | session = google.auth.transport.requests.AuthorizedSession(
30 | credentials=credentials, default_host="pubsub.googleapis.com"
31 | )
32 |
33 | # List Pub/Sub Topics through the REST API
34 | # https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.topics/list
35 | url = "https://pubsub.googleapis.com/v1/projects/{}/topics".format(project_id)
36 | with session:
37 | response = session.get(url)
38 | response.raise_for_status()
39 |
40 | # Check that self-signed JWT was created and is being used
41 | assert credentials._jwt_credentials is not None
42 | assert credentials._jwt_credentials.token.decode() == credentials.token
43 |
--------------------------------------------------------------------------------
/system_tests/system_tests_sync/test_service_account.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 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 pytest
16 |
17 | from google.auth import _helpers
18 | from google.auth import exceptions
19 | from google.auth import iam
20 | from google.oauth2 import service_account
21 |
22 |
23 | @pytest.fixture
24 | def credentials(service_account_file):
25 | yield service_account.Credentials.from_service_account_file(service_account_file)
26 |
27 |
28 | def test_refresh_no_scopes(http_request, credentials):
29 | with pytest.raises(exceptions.RefreshError):
30 | credentials.refresh(http_request)
31 |
32 |
33 | def test_refresh_success(http_request, credentials, token_info):
34 | credentials = credentials.with_scopes(["email", "profile"])
35 |
36 | credentials.refresh(http_request)
37 |
38 | assert credentials.token
39 |
40 | info = token_info(credentials.token)
41 |
42 | assert info["email"] == credentials.service_account_email
43 | info_scopes = _helpers.string_to_scopes(info["scope"])
44 | assert set(info_scopes) == set(
45 | [
46 | "https://www.googleapis.com/auth/userinfo.email",
47 | "https://www.googleapis.com/auth/userinfo.profile",
48 | ]
49 | )
50 |
51 | def test_iam_signer(http_request, credentials):
52 | credentials = credentials.with_scopes(
53 | ["https://www.googleapis.com/auth/iam"]
54 | )
55 |
56 | # Verify iamcredentials signer.
57 | signer = iam.Signer(
58 | http_request,
59 | credentials,
60 | credentials.service_account_email
61 | )
62 |
63 | signed_blob = signer.sign("message")
64 |
65 | assert isinstance(signed_blob, bytes)
66 |
--------------------------------------------------------------------------------
/system_tests/system_tests_sync/test_urllib3.py:
--------------------------------------------------------------------------------
1 | # Copyright 2021 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 google.auth
16 | import google.auth.credentials
17 | import google.auth.transport.requests
18 | from google.oauth2 import service_account
19 |
20 |
21 | def test_authorized_session_with_service_account_and_self_signed_jwt():
22 | credentials, project_id = google.auth.default()
23 |
24 | credentials = credentials.with_scopes(
25 | scopes=[],
26 | default_scopes=["https://www.googleapis.com/auth/pubsub"],
27 | )
28 |
29 | http = google.auth.transport.urllib3.AuthorizedHttp(
30 | credentials=credentials, default_host="pubsub.googleapis.com"
31 | )
32 |
33 | # List Pub/Sub Topics through the REST API
34 | # https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.topics/list
35 | response = http.urlopen(
36 | method="GET",
37 | url="https://pubsub.googleapis.com/v1/projects/{}/topics".format(project_id)
38 | )
39 |
40 | assert response.status == 200
41 |
42 | # Check that self-signed JWT was created and is being used
43 | assert credentials._jwt_credentials is not None
44 | assert credentials._jwt_credentials.token.decode() == credentials.token
45 |
--------------------------------------------------------------------------------
/testing/constraints-3.10.txt:
--------------------------------------------------------------------------------
1 | urllib3<2.0.0
--------------------------------------------------------------------------------
/testing/constraints-3.11.txt:
--------------------------------------------------------------------------------
1 | urllib3>2.0.0
--------------------------------------------------------------------------------
/testing/constraints-3.12.txt:
--------------------------------------------------------------------------------
1 | urllib3>2.0.0
--------------------------------------------------------------------------------
/testing/constraints-3.13.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googleapis/google-auth-library-python/ca94ead4035beea4741dc5384449032f8e6f75d8/testing/constraints-3.13.txt
--------------------------------------------------------------------------------
/testing/constraints-3.7.txt:
--------------------------------------------------------------------------------
1 | # This constraints file is used to check that lower bounds
2 | # are correct in setup.py
3 | # List *all* library dependencies and extras in this file.
4 | # Pin the version to the lower bound.
5 | #
6 | # e.g., if setup.py has "foo >= 1.14.0, < 2.0.0dev",
7 | # Then this file should have foo==1.14.0
8 | cachetools==2.0.0
9 | pyasn1-modules==0.2.1
10 | setuptools==40.3.0
11 | rsa==3.1.4
12 | aiohttp==3.6.2
13 | requests==2.20.0
14 | pyjwt==2.0
--------------------------------------------------------------------------------
/testing/constraints-3.8.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googleapis/google-auth-library-python/ca94ead4035beea4741dc5384449032f8e6f75d8/testing/constraints-3.8.txt
--------------------------------------------------------------------------------
/testing/constraints-3.9.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googleapis/google-auth-library-python/ca94ead4035beea4741dc5384449032f8e6f75d8/testing/constraints-3.9.txt
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googleapis/google-auth-library-python/ca94ead4035beea4741dc5384449032f8e6f75d8/tests/__init__.py
--------------------------------------------------------------------------------
/tests/compute_engine/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googleapis/google-auth-library-python/ca94ead4035beea4741dc5384449032f8e6f75d8/tests/compute_engine/__init__.py
--------------------------------------------------------------------------------
/tests/compute_engine/data/smbios_product_name:
--------------------------------------------------------------------------------
1 | Google Compute Engine
2 |
--------------------------------------------------------------------------------
/tests/compute_engine/data/smbios_product_name_non_google:
--------------------------------------------------------------------------------
1 | ABC Compute Engine
2 |
--------------------------------------------------------------------------------
/tests/conftest.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 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 os
16 | import sys
17 |
18 | import mock
19 | import pytest # type: ignore
20 |
21 |
22 | def pytest_configure():
23 | """Load public certificate and private key."""
24 | pytest.data_dir = os.path.join(os.path.dirname(__file__), "data")
25 |
26 | with open(os.path.join(pytest.data_dir, "privatekey.pem"), "rb") as fh:
27 | pytest.private_key_bytes = fh.read()
28 |
29 | with open(os.path.join(pytest.data_dir, "public_cert.pem"), "rb") as fh:
30 | pytest.public_cert_bytes = fh.read()
31 |
32 |
33 | @pytest.fixture
34 | def mock_non_existent_module(monkeypatch):
35 | """Mocks a non-existing module in sys.modules.
36 |
37 | Additionally mocks any non-existing modules specified in the dotted path.
38 | """
39 |
40 | def _mock_non_existent_module(path):
41 | parts = path.split(".")
42 | partial = []
43 | for part in parts:
44 | partial.append(part)
45 | current_module = ".".join(partial)
46 | if current_module not in sys.modules:
47 | monkeypatch.setitem(sys.modules, current_module, mock.MagicMock())
48 |
49 | return _mock_non_existent_module
50 |
--------------------------------------------------------------------------------
/tests/crypt/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googleapis/google-auth-library-python/ca94ead4035beea4741dc5384449032f8e6f75d8/tests/crypt/__init__.py
--------------------------------------------------------------------------------
/tests/crypt/test_crypt.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 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 os
16 |
17 | from google.auth import crypt
18 |
19 |
20 | DATA_DIR = os.path.join(os.path.dirname(__file__), "..", "data")
21 |
22 | # To generate privatekey.pem, privatekey.pub, and public_cert.pem:
23 | # $ openssl req -new -newkey rsa:1024 -x509 -nodes -out public_cert.pem \
24 | # > -keyout privatekey.pem
25 | # $ openssl rsa -in privatekey.pem -pubout -out privatekey.pub
26 |
27 | with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh:
28 | PRIVATE_KEY_BYTES = fh.read()
29 |
30 | with open(os.path.join(DATA_DIR, "public_cert.pem"), "rb") as fh:
31 | PUBLIC_CERT_BYTES = fh.read()
32 |
33 | # To generate other_cert.pem:
34 | # $ openssl req -new -newkey rsa:1024 -x509 -nodes -out other_cert.pem
35 |
36 | with open(os.path.join(DATA_DIR, "other_cert.pem"), "rb") as fh:
37 | OTHER_CERT_BYTES = fh.read()
38 |
39 |
40 | def test_verify_signature():
41 | to_sign = b"foo"
42 | signer = crypt.RSASigner.from_string(PRIVATE_KEY_BYTES)
43 | signature = signer.sign(to_sign)
44 |
45 | assert crypt.verify_signature(to_sign, signature, PUBLIC_CERT_BYTES)
46 |
47 | # List of certs
48 | assert crypt.verify_signature(
49 | to_sign, signature, [OTHER_CERT_BYTES, PUBLIC_CERT_BYTES]
50 | )
51 |
52 |
53 | def test_verify_signature_failure():
54 | to_sign = b"foo"
55 | signer = crypt.RSASigner.from_string(PRIVATE_KEY_BYTES)
56 | signature = signer.sign(to_sign)
57 |
58 | assert not crypt.verify_signature(to_sign, signature, OTHER_CERT_BYTES)
59 |
--------------------------------------------------------------------------------
/tests/data/authorized_user.json:
--------------------------------------------------------------------------------
1 | {
2 | "client_id": "123",
3 | "client_secret": "secret",
4 | "refresh_token": "alabalaportocala",
5 | "type": "authorized_user"
6 | }
7 |
--------------------------------------------------------------------------------
/tests/data/authorized_user_cloud_sdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "client_id": "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com",
3 | "client_secret": "secret",
4 | "refresh_token": "alabalaportocala",
5 | "type": "authorized_user"
6 | }
7 |
--------------------------------------------------------------------------------
/tests/data/authorized_user_cloud_sdk_with_quota_project_id.json:
--------------------------------------------------------------------------------
1 | {
2 | "client_id": "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com",
3 | "client_secret": "secret",
4 | "refresh_token": "alabalaportocala",
5 | "type": "authorized_user",
6 | "quota_project_id": "quota_project_id"
7 | }
8 |
--------------------------------------------------------------------------------
/tests/data/authorized_user_with_rapt_token.json:
--------------------------------------------------------------------------------
1 | {
2 | "client_id": "123",
3 | "client_secret": "secret",
4 | "refresh_token": "alabalaportocala",
5 | "type": "authorized_user",
6 | "rapt_token": "rapt"
7 | }
8 |
--------------------------------------------------------------------------------
/tests/data/client_secrets.json:
--------------------------------------------------------------------------------
1 | {
2 | "web": {
3 | "client_id": "example.apps.googleusercontent.com",
4 | "project_id": "example",
5 | "auth_uri": "https://accounts.google.com/o/oauth2/auth",
6 | "token_uri": "https://accounts.google.com/o/oauth2/token",
7 | "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
8 | "client_secret": "itsasecrettoeveryone",
9 | "redirect_uris": [
10 | "urn:ietf:wg:oauth:2.0:oob",
11 | "http://localhost"
12 | ]
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tests/data/context_aware_metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "cert_provider_command":[
3 | "/opt/google/endpoint-verification/bin/SecureConnectHelper",
4 | "--print_certificate"],
5 | "device_resource_ids":["11111111-1111-1111"]
6 | }
7 |
--------------------------------------------------------------------------------
/tests/data/enterprise_cert_invalid.json:
--------------------------------------------------------------------------------
1 | {
2 | "libs": {}
3 | }
--------------------------------------------------------------------------------
/tests/data/enterprise_cert_valid.json:
--------------------------------------------------------------------------------
1 | {
2 | "libs": {
3 | "ecp_client": "/path/to/signer/lib",
4 | "tls_offload": "/path/to/offload/lib"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/tests/data/enterprise_cert_valid_provider.json:
--------------------------------------------------------------------------------
1 | {
2 | "libs": {
3 | "ecp_client": "/path/to/signer/lib",
4 | "ecp_provider": "/path/to/provider/lib"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/tests/data/es256_privatekey.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN EC PRIVATE KEY-----
2 | MHcCAQEEIAIC57aTx5ev4T2HBMQk4fXV09AzLDQ3Ju1uNoEB0LngoAoGCCqGSM49
3 | AwEHoUQDQgAEsACsrmP6Bp216OCFm73C8W/VRHZWcO8yU/bMwx96f05BkTII3KeJ
4 | z2O0IRAnXfso8K6YsjMuUDGCfj+b1IDIoA==
5 | -----END EC PRIVATE KEY-----
6 |
--------------------------------------------------------------------------------
/tests/data/es256_public_cert.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIBGDCBwAIJAPUA0H4EQWsdMAoGCCqGSM49BAMCMBUxEzARBgNVBAMMCnVuaXQt
3 | dGVzdHMwHhcNMTkwNTA5MDI1MDExWhcNMTkwNjA4MDI1MDExWjAVMRMwEQYDVQQD
4 | DAp1bml0LXRlc3RzMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEsACsrmP6Bp21
5 | 6OCFm73C8W/VRHZWcO8yU/bMwx96f05BkTII3KeJz2O0IRAnXfso8K6YsjMuUDGC
6 | fj+b1IDIoDAKBggqhkjOPQQDAgNHADBEAh8PcDTMyWk8SHqV/v8FLuMbDxdtAsq2
7 | dwCpuHQwqCcmAiEAnwtkiyieN+8zozaf1P4QKp2mAqNGqua50y3ua5uVotc=
8 | -----END CERTIFICATE-----
9 |
--------------------------------------------------------------------------------
/tests/data/es256_publickey.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEsACsrmP6Bp216OCFm73C8W/VRHZW
3 | cO8yU/bMwx96f05BkTII3KeJz2O0IRAnXfso8K6YsjMuUDGCfj+b1IDIoA==
4 | -----END PUBLIC KEY-----
5 |
--------------------------------------------------------------------------------
/tests/data/es256_service_account.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "service_account",
3 | "project_id": "example-project",
4 | "private_key_id": "1",
5 | "private_key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIAIC57aTx5ev4T2HBMQk4fXV09AzLDQ3Ju1uNoEB0LngoAoGCCqGSM49\nAwEHoUQDQgAEsACsrmP6Bp216OCFm73C8W/VRHZWcO8yU/bMwx96f05BkTII3KeJ\nz2O0IRAnXfso8K6YsjMuUDGCfj+b1IDIoA==\n-----END EC PRIVATE KEY-----",
6 | "client_email": "service-account@example.com",
7 | "client_id": "1234",
8 | "auth_uri": "https://accounts.google.com/o/oauth2/auth",
9 | "token_uri": "https://accounts.google.com/o/oauth2/token"
10 | }
11 |
--------------------------------------------------------------------------------
/tests/data/external_account_authorized_user.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "external_account_authorized_user",
3 | "audience": "//iam.googleapis.com/locations/global/workforcePools/$WORKFORCE_POOL_ID/providers/$PROVIDER_ID",
4 | "refresh_token": "refreshToken",
5 | "token_url": "https://sts.googleapis.com/v1/oauth/token",
6 | "token_info_url": "https://sts.googleapis.com/v1/instrospect",
7 | "client_id": "clientId",
8 | "client_secret": "clientSecret"
9 | }
10 |
--------------------------------------------------------------------------------
/tests/data/external_account_authorized_user_non_gdu.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "external_account_authorized_user",
3 | "audience": "//iam.fake_universe_domain/locations/global/workforcePools/$WORKFORCE_POOL_ID/providers/$PROVIDER_ID",
4 | "refresh_token": "refreshToken",
5 | "token_url": "https://sts.fake_universe_domain/v1/oauth/token",
6 | "token_info_url": "https://sts.fake_universe_domain/v1/instrospect",
7 | "client_id": "clientId",
8 | "client_secret": "clientSecret",
9 | "universe_domain": "fake_universe_domain"
10 | }
11 |
--------------------------------------------------------------------------------
/tests/data/external_subject_token.json:
--------------------------------------------------------------------------------
1 | {
2 | "access_token": "HEADER.SIMULATED_JWT_PAYLOAD.SIGNATURE"
3 | }
--------------------------------------------------------------------------------
/tests/data/external_subject_token.txt:
--------------------------------------------------------------------------------
1 | HEADER.SIMULATED_JWT_PAYLOAD.SIGNATURE
--------------------------------------------------------------------------------
/tests/data/gdch_service_account.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "gdch_service_account",
3 | "format_version": "1",
4 | "project": "project_foo",
5 | "private_key_id": "key_foo",
6 | "private_key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIIGb2np7v54Hs6++NiLE7CQtQg7rzm4znstHvrOUlcMMoAoGCCqGSM49\nAwEHoUQDQgAECvv0VyZS9nYOa8tdwKCbkNxlWgrAZVClhJXqrvOZHlH4N3d8Rplk\n2DEJvzp04eMxlHw1jm6JCs3iJR6KAokG+w==\n-----END EC PRIVATE KEY-----\n",
7 | "name": "service_identity_name",
8 | "ca_cert_path": "/path/to/ca/cert",
9 | "token_uri": "https://service-identity./authenticate"
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/tests/data/impersonated_service_account_authorized_user_source.json:
--------------------------------------------------------------------------------
1 | {
2 | "delegates": [
3 | "service-account-delegate@example.com"
4 | ],
5 | "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/service-account-target@example.com:generateAccessToken",
6 | "source_credentials": {
7 | "client_id": "123",
8 | "client_secret": "secret",
9 | "refresh_token": "alabalaportocala",
10 | "type": "authorized_user"
11 | },
12 | "type": "impersonated_service_account"
13 | }
--------------------------------------------------------------------------------
/tests/data/impersonated_service_account_external_account_authorized_user_source.json:
--------------------------------------------------------------------------------
1 | {
2 | "delegates": [
3 | "service-account-delegate@example.com"
4 | ],
5 | "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/service-account-target@example.com:generateAccessToken",
6 | "source_credentials": {
7 | "type": "external_account_authorized_user",
8 | "audience": "//iam.googleapis.com/locations/global/workforcePools/$WORKFORCE_POOL_ID/providers/$PROVIDER_ID",
9 | "refresh_token": "refreshToken",
10 | "token_url": "https://sts.googleapis.com/v1/oauth/token",
11 | "token_info_url": "https://sts.googleapis.com/v1/instrospect",
12 | "client_id": "clientId",
13 | "client_secret": "clientSecret"
14 | },
15 | "type": "impersonated_service_account"
16 | }
--------------------------------------------------------------------------------
/tests/data/impersonated_service_account_service_account_source.json:
--------------------------------------------------------------------------------
1 | {
2 | "delegates": [
3 | "service-account-delegate@example.com"
4 | ],
5 | "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/service-account-target@example.com:generateAccessToken",
6 | "source_credentials": {
7 | "type": "service_account",
8 | "project_id": "example-project",
9 | "private_key_id": "1",
10 | "private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA4ej0p7bQ7L/r4rVGUz9RN4VQWoej1Bg1mYWIDYslvKrk1gpj\n7wZgkdmM7oVK2OfgrSj/FCTkInKPqaCR0gD7K80q+mLBrN3PUkDrJQZpvRZIff3/\nxmVU1WeruQLFJjnFb2dqu0s/FY/2kWiJtBCakXvXEOb7zfbINuayL+MSsCGSdVYs\nSliS5qQpgyDap+8b5fpXZVJkq92hrcNtbkg7hCYUJczt8n9hcCTJCfUpApvaFQ18\npe+zpyl4+WzkP66I28hniMQyUlA1hBiskT7qiouq0m8IOodhv2fagSZKjOTTU2xk\nSBc//fy3ZpsL7WqgsZS7Q+0VRK8gKfqkxg5OYQIDAQABAoIBAQDGGHzQxGKX+ANk\nnQi53v/c6632dJKYXVJC+PDAz4+bzU800Y+n/bOYsWf/kCp94XcG4Lgsdd0Gx+Zq\nHD9CI1IcqqBRR2AFscsmmX6YzPLTuEKBGMW8twaYy3utlFxElMwoUEsrSWRcCA1y\nnHSDzTt871c7nxCXHxuZ6Nm/XCL7Bg8uidRTSC1sQrQyKgTPhtQdYrPQ4WZ1A4J9\nIisyDYmZodSNZe5P+LTJ6M1SCgH8KH9ZGIxv3diMwzNNpk3kxJc9yCnja4mjiGE2\nYCNusSycU5IhZwVeCTlhQGcNeV/skfg64xkiJE34c2y2ttFbdwBTPixStGaF09nU\nZ422D40BAoGBAPvVyRRsC3BF+qZdaSMFwI1yiXY7vQw5+JZh01tD28NuYdRFzjcJ\nvzT2n8LFpj5ZfZFvSMLMVEFVMgQvWnN0O6xdXvGov6qlRUSGaH9u+TCPNnIldjMP\nB8+xTwFMqI7uQr54wBB+Poq7dVRP+0oHb0NYAwUBXoEuvYo3c/nDoRcZAoGBAOWl\naLHjMv4CJbArzT8sPfic/8waSiLV9Ixs3Re5YREUTtnLq7LoymqB57UXJB3BNz/2\neCueuW71avlWlRtE/wXASj5jx6y5mIrlV4nZbVuyYff0QlcG+fgb6pcJQuO9DxMI\naqFGrWP3zye+LK87a6iR76dS9vRU+bHZpSVvGMKJAoGAFGt3TIKeQtJJyqeUWNSk\nklORNdcOMymYMIlqG+JatXQD1rR6ThgqOt8sgRyJqFCVT++YFMOAqXOBBLnaObZZ\nCFbh1fJ66BlSjoXff0W+SuOx5HuJJAa5+WtFHrPajwxeuRcNa8jwxUsB7n41wADu\nUqWWSRedVBg4Ijbw3nWwYDECgYB0pLew4z4bVuvdt+HgnJA9n0EuYowVdadpTEJg\nsoBjNHV4msLzdNqbjrAqgz6M/n8Ztg8D2PNHMNDNJPVHjJwcR7duSTA6w2p/4k28\nbvvk/45Ta3XmzlxZcZSOct3O31Cw0i2XDVc018IY5be8qendDYM08icNo7vQYkRH\n504kQQKBgQDjx60zpz8ozvm1XAj0wVhi7GwXe+5lTxiLi9Fxq721WDxPMiHDW2XL\nYXfFVy/9/GIMvEiGYdmarK1NW+VhWl1DC5xhDg0kvMfxplt4tynoq1uTsQTY31Mx\nBeF5CT/JuNYk3bEBF0H/Q3VGO1/ggVS+YezdFbLWIRoMnLj6XCFEGg==\n-----END RSA PRIVATE KEY-----\n",
11 | "client_email": "service-account@example.com",
12 | "client_id": "1234",
13 | "auth_uri": "https://accounts.google.com/o/oauth2/auth",
14 | "token_uri": "https://accounts.google.com/o/oauth2/token"
15 | },
16 | "type": "impersonated_service_account"
17 | }
--------------------------------------------------------------------------------
/tests/data/impersonated_service_account_with_quota_project.json:
--------------------------------------------------------------------------------
1 | {
2 | "delegates": [
3 | "service-account-delegate@example.com"
4 | ],
5 | "quota_project_id": "quota_project",
6 | "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/service-account-target@example.com:generateAccessToken",
7 | "source_credentials": {
8 | "client_id": "123",
9 | "client_secret": "secret",
10 | "refresh_token": "alabalaportocala",
11 | "type": "authorized_user"
12 | },
13 | "type": "impersonated_service_account"
14 | }
--------------------------------------------------------------------------------
/tests/data/old_oauth_credentials_py3.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googleapis/google-auth-library-python/ca94ead4035beea4741dc5384449032f8e6f75d8/tests/data/old_oauth_credentials_py3.pickle
--------------------------------------------------------------------------------
/tests/data/other_cert.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIFtTCCA52gAwIBAgIJAPBsLZmNGfKtMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
3 | BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
4 | aWRnaXRzIFB0eSBMdGQwHhcNMTYwOTIxMDI0NTEyWhcNMTYxMDIxMDI0NTEyWjBF
5 | MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
6 | ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
7 | CgKCAgEAsiMC7mTsmUXwZoYlT4aHY1FLw8bxIXC+z3IqA+TY1WqfbeiZRo8MA5Zx
8 | lTTxYMKPCZUE1XBc7jvD8GJhWIj6pToPYHn73B01IBkLBxq4kF1yV2Z7DVmkvc6H
9 | EcxXXq8zkCx0j6XOfiI4+qkXnuQn8cvrk8xfhtnMMZM7iVm6VSN93iRP/8ey6xuL
10 | XTHrDX7ukoRce1hpT8O+15GXNrY0irhhYQz5xKibNCJF3EjV28WMry8y7I8uYUFU
11 | RWDiQawwK9ec1zhZ94v92+GZDlPevmcFmSERKYQ0NsKcT0Y3lGuGnaExs8GyOpnC
12 | oksu4YJGXQjg7lkv4MxzsNbRqmCkUwxw1Mg6FP0tsCNsw9qTrkvWCRA9zp/aU+sZ
13 | IBGh1t4UGCub8joeQFvHxvr/3F7mH/dyvCjA34u0Lo1VPx+jYUIi9i0odltMspDW
14 | xOpjqdGARZYmlJP5Au9q5cQjPMcwS/EBIb8cwNl32mUE6WnFlep+38mNR/FghIjO
15 | ViAkXuKQmcHe6xppZAoHFsO/t3l4Tjek5vNW7erI1rgrFku/fvkIW/G8V1yIm/+Q
16 | F+CE4maQzCJfhftpkhM/sPC/FuLNBmNE8BHVX8y58xG4is/cQxL4Z9TsFIw0C5+3
17 | uTrFW9D0agysahMVzPGtCqhDQqJdIJrBQqlS6bztpzBA8zEI0skCAwEAAaOBpzCB
18 | pDAdBgNVHQ4EFgQUz/8FmW6TfqXyNJZr7rhc+Tn5sKQwdQYDVR0jBG4wbIAUz/8F
19 | mW6TfqXyNJZr7rhc+Tn5sKShSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpT
20 | b21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDw
21 | bC2ZjRnyrTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4ICAQCQmrcfhurX
22 | riR3Q0Y+nq040/3dJIAJXjyI9CEtxaU0nzCNTng7PwgZ0CKmCelQfInuwWFwBSHS
23 | 6kBfC1rgJeFnjnTt8a3RCgRlIgUr9NCdPSEccB7TurobwPJ2h6cJjjR8urcb0CXh
24 | CEMvPneyPj0xUFY8vVKXMGWahz/kyfwIiVqcX/OtMZ29fUu1onbWl71g2gVLtUZl
25 | sECdZ+AC/6HDCVpYIVETMl1T7N/XyqXZQiDLDNRDeZhnapz8w9fsW1KVujAZLNQR
26 | pVnw2qa2UK1dSf2FHX+lQU5mFSYM4vtwaMlX/LgfdLZ9I796hFh619WwTVz+LO2N
27 | vHnwBMabld3XSPuZRqlbBulDQ07Vbqdjv8DYSLA2aKI4ZkMMKuFLG/oS28V2ZYmv
28 | /KpGEs5UgKY+P9NulYpTDwCU/6SomuQpP795wbG6sm7Hzq82r2RmB61GupNRGeqi
29 | pXKsy69T388zBxYu6zQrosXiDl5YzaViH7tm0J7opye8dCWjjpnahki0vq2znti7
30 | 6cWla2j8Xz1glvLz+JI/NCOMfxUInb82T7ijo80N0VJ2hzf7p2GxRZXAxAV9knLI
31 | nM4F5TLjSd7ZhOOZ7ni/eZFueTMisWfypt2nc41whGjHMX/Zp1kPfhB4H2bLKIX/
32 | lSrwNr3qbGTEJX8JqpDBNVAd96XkMvDNyA==
33 | -----END CERTIFICATE-----
34 |
--------------------------------------------------------------------------------
/tests/data/pem_from_pkcs12.pem:
--------------------------------------------------------------------------------
1 | Bag Attributes
2 | friendlyName: key
3 | localKeyID: 22 7E 04 FC 64 48 20 83 1E C1 BD E3 F5 2F 44 7D EA 99 A5 BC
4 | Key Attributes:
5 | -----BEGIN PRIVATE KEY-----
6 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDh6PSnttDsv+vi
7 | tUZTP1E3hVBah6PUGDWZhYgNiyW8quTWCmPvBmCR2YzuhUrY5+CtKP8UJOQico+p
8 | oJHSAPsrzSr6YsGs3c9SQOslBmm9Fkh9/f/GZVTVZ6u5AsUmOcVvZ2q7Sz8Vj/aR
9 | aIm0EJqRe9cQ5vvN9sg25rIv4xKwIZJ1VixKWJLmpCmDINqn7xvl+ldlUmSr3aGt
10 | w21uSDuEJhQlzO3yf2FwJMkJ9SkCm9oVDXyl77OnKXj5bOQ/rojbyGeIxDJSUDWE
11 | GKyRPuqKi6rSbwg6h2G/Z9qBJkqM5NNTbGRIFz/9/LdmmwvtaqCxlLtD7RVEryAp
12 | +qTGDk5hAgMBAAECggEBAMYYfNDEYpf4A2SdCLne/9zrrfZ0kphdUkL48MDPj5vN
13 | TzTRj6f9s5ixZ/+QKn3hdwbguCx13QbH5mocP0IjUhyqoFFHYAWxyyaZfpjM8tO4
14 | QoEYxby3BpjLe62UXESUzChQSytJZFwIDXKcdIPNO3zvVzufEJcfG5no2b9cIvsG
15 | Dy6J1FNILWxCtDIqBM+G1B1is9DhZnUDgn0iKzINiZmh1I1l7k/4tMnozVIKAfwo
16 | f1kYjG/d2IzDM02mTeTElz3IKeNriaOIYTZgI26xLJxTkiFnBV4JOWFAZw15X+yR
17 | +DrjGSIkTfhzbLa20Vt3AFM+LFK0ZoXT2dRnjbYPjQECgYEA+9XJFGwLcEX6pl1p
18 | IwXAjXKJdju9DDn4lmHTW0Pbw25h1EXONwm/NPafwsWmPll9kW9IwsxUQVUyBC9a
19 | c3Q7rF1e8ai/qqVFRIZof275MI82ciV2Mw8Hz7FPAUyoju5CvnjAEH4+irt1VE/7
20 | SgdvQ1gDBQFegS69ijdz+cOhFxkCgYEA5aVoseMy/gIlsCvNPyw9+Jz/zBpKItX0
21 | jGzdF7lhERRO2cursujKaoHntRckHcE3P/Z4K565bvVq+VaVG0T/BcBKPmPHrLmY
22 | iuVXidltW7Jh9/RCVwb5+BvqlwlC470PEwhqoUatY/fPJ74srztrqJHvp1L29FT5
23 | sdmlJW8YwokCgYAUa3dMgp5C0knKp5RY1KSSU5E11w4zKZgwiWob4lq1dAPWtHpO
24 | GCo63yyBHImoUJVP75gUw4Cpc4EEudo5tlkIVuHV8nroGVKOhd9/Rb5K47Hke4kk
25 | Brn5a0Ues9qPDF65Fw1ryPDFSwHufjXAAO5SpZZJF51UGDgiNvDedbBgMQKBgHSk
26 | t7DjPhtW69234eCckD2fQS5ijBV1p2lMQmCygGM0dXiawvN02puOsCqDPoz+fxm2
27 | DwPY80cw0M0k9UeMnBxHt25JMDrDan/iTbxu++T/jlNrdebOXFlxlI5y3c7fULDS
28 | LZcNVzTXwhjlt7yp6d0NgzTyJw2ju9BiREfnTiRBAoGBAOPHrTOnPyjO+bVcCPTB
29 | WGLsbBd77mVPGIuL0XGrvbVYPE8yIcNbZcthd8VXL/38Ygy8SIZh2ZqsrU1b5WFa
30 | XUMLnGEODSS8x/GmW3i3KeirW5OxBNjfUzEF4XkJP8m41iTdsQEXQf9DdUY7X+CB
31 | VL5h7N0VstYhGgycuPpcIUQa
32 | -----END PRIVATE KEY-----
33 |
--------------------------------------------------------------------------------
/tests/data/privatekey.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googleapis/google-auth-library-python/ca94ead4035beea4741dc5384449032f8e6f75d8/tests/data/privatekey.p12
--------------------------------------------------------------------------------
/tests/data/privatekey.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIIEpAIBAAKCAQEA4ej0p7bQ7L/r4rVGUz9RN4VQWoej1Bg1mYWIDYslvKrk1gpj
3 | 7wZgkdmM7oVK2OfgrSj/FCTkInKPqaCR0gD7K80q+mLBrN3PUkDrJQZpvRZIff3/
4 | xmVU1WeruQLFJjnFb2dqu0s/FY/2kWiJtBCakXvXEOb7zfbINuayL+MSsCGSdVYs
5 | SliS5qQpgyDap+8b5fpXZVJkq92hrcNtbkg7hCYUJczt8n9hcCTJCfUpApvaFQ18
6 | pe+zpyl4+WzkP66I28hniMQyUlA1hBiskT7qiouq0m8IOodhv2fagSZKjOTTU2xk
7 | SBc//fy3ZpsL7WqgsZS7Q+0VRK8gKfqkxg5OYQIDAQABAoIBAQDGGHzQxGKX+ANk
8 | nQi53v/c6632dJKYXVJC+PDAz4+bzU800Y+n/bOYsWf/kCp94XcG4Lgsdd0Gx+Zq
9 | HD9CI1IcqqBRR2AFscsmmX6YzPLTuEKBGMW8twaYy3utlFxElMwoUEsrSWRcCA1y
10 | nHSDzTt871c7nxCXHxuZ6Nm/XCL7Bg8uidRTSC1sQrQyKgTPhtQdYrPQ4WZ1A4J9
11 | IisyDYmZodSNZe5P+LTJ6M1SCgH8KH9ZGIxv3diMwzNNpk3kxJc9yCnja4mjiGE2
12 | YCNusSycU5IhZwVeCTlhQGcNeV/skfg64xkiJE34c2y2ttFbdwBTPixStGaF09nU
13 | Z422D40BAoGBAPvVyRRsC3BF+qZdaSMFwI1yiXY7vQw5+JZh01tD28NuYdRFzjcJ
14 | vzT2n8LFpj5ZfZFvSMLMVEFVMgQvWnN0O6xdXvGov6qlRUSGaH9u+TCPNnIldjMP
15 | B8+xTwFMqI7uQr54wBB+Poq7dVRP+0oHb0NYAwUBXoEuvYo3c/nDoRcZAoGBAOWl
16 | aLHjMv4CJbArzT8sPfic/8waSiLV9Ixs3Re5YREUTtnLq7LoymqB57UXJB3BNz/2
17 | eCueuW71avlWlRtE/wXASj5jx6y5mIrlV4nZbVuyYff0QlcG+fgb6pcJQuO9DxMI
18 | aqFGrWP3zye+LK87a6iR76dS9vRU+bHZpSVvGMKJAoGAFGt3TIKeQtJJyqeUWNSk
19 | klORNdcOMymYMIlqG+JatXQD1rR6ThgqOt8sgRyJqFCVT++YFMOAqXOBBLnaObZZ
20 | CFbh1fJ66BlSjoXff0W+SuOx5HuJJAa5+WtFHrPajwxeuRcNa8jwxUsB7n41wADu
21 | UqWWSRedVBg4Ijbw3nWwYDECgYB0pLew4z4bVuvdt+HgnJA9n0EuYowVdadpTEJg
22 | soBjNHV4msLzdNqbjrAqgz6M/n8Ztg8D2PNHMNDNJPVHjJwcR7duSTA6w2p/4k28
23 | bvvk/45Ta3XmzlxZcZSOct3O31Cw0i2XDVc018IY5be8qendDYM08icNo7vQYkRH
24 | 504kQQKBgQDjx60zpz8ozvm1XAj0wVhi7GwXe+5lTxiLi9Fxq721WDxPMiHDW2XL
25 | YXfFVy/9/GIMvEiGYdmarK1NW+VhWl1DC5xhDg0kvMfxplt4tynoq1uTsQTY31Mx
26 | BeF5CT/JuNYk3bEBF0H/Q3VGO1/ggVS+YezdFbLWIRoMnLj6XCFEGg==
27 | -----END RSA PRIVATE KEY-----
28 |
--------------------------------------------------------------------------------
/tests/data/privatekey.pub:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PUBLIC KEY-----
2 | MIIBCgKCAQEA4ej0p7bQ7L/r4rVGUz9RN4VQWoej1Bg1mYWIDYslvKrk1gpj7wZg
3 | kdmM7oVK2OfgrSj/FCTkInKPqaCR0gD7K80q+mLBrN3PUkDrJQZpvRZIff3/xmVU
4 | 1WeruQLFJjnFb2dqu0s/FY/2kWiJtBCakXvXEOb7zfbINuayL+MSsCGSdVYsSliS
5 | 5qQpgyDap+8b5fpXZVJkq92hrcNtbkg7hCYUJczt8n9hcCTJCfUpApvaFQ18pe+z
6 | pyl4+WzkP66I28hniMQyUlA1hBiskT7qiouq0m8IOodhv2fagSZKjOTTU2xkSBc/
7 | /fy3ZpsL7WqgsZS7Q+0VRK8gKfqkxg5OYQIDAQAB
8 | -----END RSA PUBLIC KEY-----
9 |
--------------------------------------------------------------------------------
/tests/data/public_cert.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIDIzCCAgugAwIBAgIJAMfISuBQ5m+5MA0GCSqGSIb3DQEBBQUAMBUxEzARBgNV
3 | BAMTCnVuaXQtdGVzdHMwHhcNMTExMjA2MTYyNjAyWhcNMjExMjAzMTYyNjAyWjAV
4 | MRMwEQYDVQQDEwp1bml0LXRlc3RzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
5 | CgKCAQEA4ej0p7bQ7L/r4rVGUz9RN4VQWoej1Bg1mYWIDYslvKrk1gpj7wZgkdmM
6 | 7oVK2OfgrSj/FCTkInKPqaCR0gD7K80q+mLBrN3PUkDrJQZpvRZIff3/xmVU1Wer
7 | uQLFJjnFb2dqu0s/FY/2kWiJtBCakXvXEOb7zfbINuayL+MSsCGSdVYsSliS5qQp
8 | gyDap+8b5fpXZVJkq92hrcNtbkg7hCYUJczt8n9hcCTJCfUpApvaFQ18pe+zpyl4
9 | +WzkP66I28hniMQyUlA1hBiskT7qiouq0m8IOodhv2fagSZKjOTTU2xkSBc//fy3
10 | ZpsL7WqgsZS7Q+0VRK8gKfqkxg5OYQIDAQABo3YwdDAdBgNVHQ4EFgQU2RQ8yO+O
11 | gN8oVW2SW7RLrfYd9jEwRQYDVR0jBD4wPIAU2RQ8yO+OgN8oVW2SW7RLrfYd9jGh
12 | GaQXMBUxEzARBgNVBAMTCnVuaXQtdGVzdHOCCQDHyErgUOZvuTAMBgNVHRMEBTAD
13 | AQH/MA0GCSqGSIb3DQEBBQUAA4IBAQBRv+M/6+FiVu7KXNjFI5pSN17OcW5QUtPr
14 | odJMlWrJBtynn/TA1oJlYu3yV5clc/71Vr/AxuX5xGP+IXL32YDF9lTUJXG/uUGk
15 | +JETpKmQviPbRsvzYhz4pf6ZIOZMc3/GIcNq92ECbseGO+yAgyWUVKMmZM0HqXC9
16 | ovNslqe0M8C1sLm1zAR5z/h/litE7/8O2ietija3Q/qtl2TOXJdCA6sgjJX2WUql
17 | ybrC55ct18NKf3qhpcEkGQvFU40rVYApJpi98DiZPYFdx1oBDp/f4uZ3ojpxRVFT
18 | cDwcJLfNRCPUhormsY7fDS9xSyThiHsW9mjJYdcaKQkwYZ0F11yB
19 | -----END CERTIFICATE-----
20 |
--------------------------------------------------------------------------------
/tests/data/service_account.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "service_account",
3 | "project_id": "example-project",
4 | "private_key_id": "1",
5 | "private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA4ej0p7bQ7L/r4rVGUz9RN4VQWoej1Bg1mYWIDYslvKrk1gpj\n7wZgkdmM7oVK2OfgrSj/FCTkInKPqaCR0gD7K80q+mLBrN3PUkDrJQZpvRZIff3/\nxmVU1WeruQLFJjnFb2dqu0s/FY/2kWiJtBCakXvXEOb7zfbINuayL+MSsCGSdVYs\nSliS5qQpgyDap+8b5fpXZVJkq92hrcNtbkg7hCYUJczt8n9hcCTJCfUpApvaFQ18\npe+zpyl4+WzkP66I28hniMQyUlA1hBiskT7qiouq0m8IOodhv2fagSZKjOTTU2xk\nSBc//fy3ZpsL7WqgsZS7Q+0VRK8gKfqkxg5OYQIDAQABAoIBAQDGGHzQxGKX+ANk\nnQi53v/c6632dJKYXVJC+PDAz4+bzU800Y+n/bOYsWf/kCp94XcG4Lgsdd0Gx+Zq\nHD9CI1IcqqBRR2AFscsmmX6YzPLTuEKBGMW8twaYy3utlFxElMwoUEsrSWRcCA1y\nnHSDzTt871c7nxCXHxuZ6Nm/XCL7Bg8uidRTSC1sQrQyKgTPhtQdYrPQ4WZ1A4J9\nIisyDYmZodSNZe5P+LTJ6M1SCgH8KH9ZGIxv3diMwzNNpk3kxJc9yCnja4mjiGE2\nYCNusSycU5IhZwVeCTlhQGcNeV/skfg64xkiJE34c2y2ttFbdwBTPixStGaF09nU\nZ422D40BAoGBAPvVyRRsC3BF+qZdaSMFwI1yiXY7vQw5+JZh01tD28NuYdRFzjcJ\nvzT2n8LFpj5ZfZFvSMLMVEFVMgQvWnN0O6xdXvGov6qlRUSGaH9u+TCPNnIldjMP\nB8+xTwFMqI7uQr54wBB+Poq7dVRP+0oHb0NYAwUBXoEuvYo3c/nDoRcZAoGBAOWl\naLHjMv4CJbArzT8sPfic/8waSiLV9Ixs3Re5YREUTtnLq7LoymqB57UXJB3BNz/2\neCueuW71avlWlRtE/wXASj5jx6y5mIrlV4nZbVuyYff0QlcG+fgb6pcJQuO9DxMI\naqFGrWP3zye+LK87a6iR76dS9vRU+bHZpSVvGMKJAoGAFGt3TIKeQtJJyqeUWNSk\nklORNdcOMymYMIlqG+JatXQD1rR6ThgqOt8sgRyJqFCVT++YFMOAqXOBBLnaObZZ\nCFbh1fJ66BlSjoXff0W+SuOx5HuJJAa5+WtFHrPajwxeuRcNa8jwxUsB7n41wADu\nUqWWSRedVBg4Ijbw3nWwYDECgYB0pLew4z4bVuvdt+HgnJA9n0EuYowVdadpTEJg\nsoBjNHV4msLzdNqbjrAqgz6M/n8Ztg8D2PNHMNDNJPVHjJwcR7duSTA6w2p/4k28\nbvvk/45Ta3XmzlxZcZSOct3O31Cw0i2XDVc018IY5be8qendDYM08icNo7vQYkRH\n504kQQKBgQDjx60zpz8ozvm1XAj0wVhi7GwXe+5lTxiLi9Fxq721WDxPMiHDW2XL\nYXfFVy/9/GIMvEiGYdmarK1NW+VhWl1DC5xhDg0kvMfxplt4tynoq1uTsQTY31Mx\nBeF5CT/JuNYk3bEBF0H/Q3VGO1/ggVS+YezdFbLWIRoMnLj6XCFEGg==\n-----END RSA PRIVATE KEY-----\n",
6 | "client_email": "service-account@example.com",
7 | "client_id": "1234",
8 | "auth_uri": "https://accounts.google.com/o/oauth2/auth",
9 | "token_uri": "https://accounts.google.com/o/oauth2/token"
10 | }
11 |
--------------------------------------------------------------------------------
/tests/data/service_account_non_gdu.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "service_account",
3 | "universe_domain": "universe.foo",
4 | "project_id": "example_project",
5 | "private_key_id": "1",
6 | "private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA4ej0p7bQ7L/r4rVGUz9RN4VQWoej1Bg1mYWIDYslvKrk1gpj\n7wZgkdmM7oVK2OfgrSj/FCTkInKPqaCR0gD7K80q+mLBrN3PUkDrJQZpvRZIff3/\nxmVU1WeruQLFJjnFb2dqu0s/FY/2kWiJtBCakXvXEOb7zfbINuayL+MSsCGSdVYs\nSliS5qQpgyDap+8b5fpXZVJkq92hrcNtbkg7hCYUJczt8n9hcCTJCfUpApvaFQ18\npe+zpyl4+WzkP66I28hniMQyUlA1hBiskT7qiouq0m8IOodhv2fagSZKjOTTU2xk\nSBc//fy3ZpsL7WqgsZS7Q+0VRK8gKfqkxg5OYQIDAQABAoIBAQDGGHzQxGKX+ANk\nnQi53v/c6632dJKYXVJC+PDAz4+bzU800Y+n/bOYsWf/kCp94XcG4Lgsdd0Gx+Zq\nHD9CI1IcqqBRR2AFscsmmX6YzPLTuEKBGMW8twaYy3utlFxElMwoUEsrSWRcCA1y\nnHSDzTt871c7nxCXHxuZ6Nm/XCL7Bg8uidRTSC1sQrQyKgTPhtQdYrPQ4WZ1A4J9\nIisyDYmZodSNZe5P+LTJ6M1SCgH8KH9ZGIxv3diMwzNNpk3kxJc9yCnja4mjiGE2\nYCNusSycU5IhZwVeCTlhQGcNeV/skfg64xkiJE34c2y2ttFbdwBTPixStGaF09nU\nZ422D40BAoGBAPvVyRRsC3BF+qZdaSMFwI1yiXY7vQw5+JZh01tD28NuYdRFzjcJ\nvzT2n8LFpj5ZfZFvSMLMVEFVMgQvWnN0O6xdXvGov6qlRUSGaH9u+TCPNnIldjMP\nB8+xTwFMqI7uQr54wBB+Poq7dVRP+0oHb0NYAwUBXoEuvYo3c/nDoRcZAoGBAOWl\naLHjMv4CJbArzT8sPfic/8waSiLV9Ixs3Re5YREUTtnLq7LoymqB57UXJB3BNz/2\neCueuW71avlWlRtE/wXASj5jx6y5mIrlV4nZbVuyYff0QlcG+fgb6pcJQuO9DxMI\naqFGrWP3zye+LK87a6iR76dS9vRU+bHZpSVvGMKJAoGAFGt3TIKeQtJJyqeUWNSk\nklORNdcOMymYMIlqG+JatXQD1rR6ThgqOt8sgRyJqFCVT++YFMOAqXOBBLnaObZZ\nCFbh1fJ66BlSjoXff0W+SuOx5HuJJAa5+WtFHrPajwxeuRcNa8jwxUsB7n41wADu\nUqWWSRedVBg4Ijbw3nWwYDECgYB0pLew4z4bVuvdt+HgnJA9n0EuYowVdadpTEJg\nsoBjNHV4msLzdNqbjrAqgz6M/n8Ztg8D2PNHMNDNJPVHjJwcR7duSTA6w2p/4k28\nbvvk/45Ta3XmzlxZcZSOct3O31Cw0i2XDVc018IY5be8qendDYM08icNo7vQYkRH\n504kQQKBgQDjx60zpz8ozvm1XAj0wVhi7GwXe+5lTxiLi9Fxq721WDxPMiHDW2XL\nYXfFVy/9/GIMvEiGYdmarK1NW+VhWl1DC5xhDg0kvMfxplt4tynoq1uTsQTY31Mx\nBeF5CT/JuNYk3bEBF0H/Q3VGO1/ggVS+YezdFbLWIRoMnLj6XCFEGg==\n-----END RSA PRIVATE KEY-----\n",
7 | "client_email": "testsa@foo.iam.gserviceaccount.com",
8 | "client_id": "1234",
9 | "auth_uri": "https://accounts.google.com/o/oauth2/auth",
10 | "token_uri": "https://oauth2.universe.foo/token",
11 | "auth_provider_x509_cert_url": "https://www.universe.foo/oauth2/v1/certs",
12 | "client_x509_cert_url": "https://www.universe.foo/robot/v1/metadata/x509/foo.iam.gserviceaccount.com"
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/tests/data/trust_chain_with_leaf.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIDIzCCAgugAwIBAgIJAMfISuBQ5m+5MA0GCSqGSIb3DQEBBQUAMBUxEzARBgNV
3 | BAMTCnVuaXQtdGVzdHMwHhcNMTExMjA2MTYyNjAyWhcNMjExMjAzMTYyNjAyWjAV
4 | MRMwEQYDVQQDEwp1bml0LXRlc3RzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
5 | CgKCAQEA4ej0p7bQ7L/r4rVGUz9RN4VQWoej1Bg1mYWIDYslvKrk1gpj7wZgkdmM
6 | 7oVK2OfgrSj/FCTkInKPqaCR0gD7K80q+mLBrN3PUkDrJQZpvRZIff3/xmVU1Wer
7 | uQLFJjnFb2dqu0s/FY/2kWiJtBCakXvXEOb7zfbINuayL+MSsCGSdVYsSliS5qQp
8 | gyDap+8b5fpXZVJkq92hrcNtbkg7hCYUJczt8n9hcCTJCfUpApvaFQ18pe+zpyl4
9 | +WzkP66I28hniMQyUlA1hBiskT7qiouq0m8IOodhv2fagSZKjOTTU2xkSBc//fy3
10 | ZpsL7WqgsZS7Q+0VRK8gKfqkxg5OYQIDAQABo3YwdDAdBgNVHQ4EFgQU2RQ8yO+O
11 | gN8oVW2SW7RLrfYd9jEwRQYDVR0jBD4wPIAU2RQ8yO+OgN8oVW2SW7RLrfYd9jGh
12 | GaQXMBUxEzARBgNVBAMTCnVuaXQtdGVzdHOCCQDHyErgUOZvuTAMBgNVHRMEBTAD
13 | AQH/MA0GCSqGSIb3DQEBBQUAA4IBAQBRv+M/6+FiVu7KXNjFI5pSN17OcW5QUtPr
14 | odJMlWrJBtynn/TA1oJlYu3yV5clc/71Vr/AxuX5xGP+IXL32YDF9lTUJXG/uUGk
15 | +JETpKmQviPbRsvzYhz4pf6ZIOZMc3/GIcNq92ECbseGO+yAgyWUVKMmZM0HqXC9
16 | ovNslqe0M8C1sLm1zAR5z/h/litE7/8O2ietija3Q/qtl2TOXJdCA6sgjJX2WUql
17 | ybrC55ct18NKf3qhpcEkGQvFU40rVYApJpi98DiZPYFdx1oBDp/f4uZ3ojpxRVFT
18 | cDwcJLfNRCPUhormsY7fDS9xSyThiHsW9mjJYdcaKQkwYZ0F11yB
19 | -----END CERTIFICATE-----
20 | -----BEGIN CERTIFICATE-----
21 | MIIFtTCCA52gAwIBAgIJAPBsLZmNGfKtMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
22 | BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
23 | aWRnaXRzIFB0eSBMdGQwHhcNMTYwOTIxMDI0NTEyWhcNMTYxMDIxMDI0NTEyWjBF
24 | MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
25 | ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
26 | CgKCAgEAsiMC7mTsmUXwZoYlT4aHY1FLw8bxIXC+z3IqA+TY1WqfbeiZRo8MA5Zx
27 | lTTxYMKPCZUE1XBc7jvD8GJhWIj6pToPYHn73B01IBkLBxq4kF1yV2Z7DVmkvc6H
28 | EcxXXq8zkCx0j6XOfiI4+qkXnuQn8cvrk8xfhtnMMZM7iVm6VSN93iRP/8ey6xuL
29 | XTHrDX7ukoRce1hpT8O+15GXNrY0irhhYQz5xKibNCJF3EjV28WMry8y7I8uYUFU
30 | RWDiQawwK9ec1zhZ94v92+GZDlPevmcFmSERKYQ0NsKcT0Y3lGuGnaExs8GyOpnC
31 | oksu4YJGXQjg7lkv4MxzsNbRqmCkUwxw1Mg6FP0tsCNsw9qTrkvWCRA9zp/aU+sZ
32 | IBGh1t4UGCub8joeQFvHxvr/3F7mH/dyvCjA34u0Lo1VPx+jYUIi9i0odltMspDW
33 | xOpjqdGARZYmlJP5Au9q5cQjPMcwS/EBIb8cwNl32mUE6WnFlep+38mNR/FghIjO
34 | ViAkXuKQmcHe6xppZAoHFsO/t3l4Tjek5vNW7erI1rgrFku/fvkIW/G8V1yIm/+Q
35 | F+CE4maQzCJfhftpkhM/sPC/FuLNBmNE8BHVX8y58xG4is/cQxL4Z9TsFIw0C5+3
36 | uTrFW9D0agysahMVzPGtCqhDQqJdIJrBQqlS6bztpzBA8zEI0skCAwEAAaOBpzCB
37 | pDAdBgNVHQ4EFgQUz/8FmW6TfqXyNJZr7rhc+Tn5sKQwdQYDVR0jBG4wbIAUz/8F
38 | mW6TfqXyNJZr7rhc+Tn5sKShSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpT
39 | b21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDw
40 | bC2ZjRnyrTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4ICAQCQmrcfhurX
41 | riR3Q0Y+nq040/3dJIAJXjyI9CEtxaU0nzCNTng7PwgZ0CKmCelQfInuwWFwBSHS
42 | 6kBfC1rgJeFnjnTt8a3RCgRlIgUr9NCdPSEccB7TurobwPJ2h6cJjjR8urcb0CXh
43 | CEMvPneyPj0xUFY8vVKXMGWahz/kyfwIiVqcX/OtMZ29fUu1onbWl71g2gVLtUZl
44 | sECdZ+AC/6HDCVpYIVETMl1T7N/XyqXZQiDLDNRDeZhnapz8w9fsW1KVujAZLNQR
45 | pVnw2qa2UK1dSf2FHX+lQU5mFSYM4vtwaMlX/LgfdLZ9I796hFh619WwTVz+LO2N
46 | vHnwBMabld3XSPuZRqlbBulDQ07Vbqdjv8DYSLA2aKI4ZkMMKuFLG/oS28V2ZYmv
47 | /KpGEs5UgKY+P9NulYpTDwCU/6SomuQpP795wbG6sm7Hzq82r2RmB61GupNRGeqi
48 | pXKsy69T388zBxYu6zQrosXiDl5YzaViH7tm0J7opye8dCWjjpnahki0vq2znti7
49 | 6cWla2j8Xz1glvLz+JI/NCOMfxUInb82T7ijo80N0VJ2hzf7p2GxRZXAxAV9knLI
50 | nM4F5TLjSd7ZhOOZ7ni/eZFueTMisWfypt2nc41whGjHMX/Zp1kPfhB4H2bLKIX/
51 | lSrwNr3qbGTEJX8JqpDBNVAd96XkMvDNyA==
52 | -----END CERTIFICATE-----
--------------------------------------------------------------------------------
/tests/data/trust_chain_without_leaf.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIFtTCCA52gAwIBAgIJAPBsLZmNGfKtMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
3 | BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
4 | aWRnaXRzIFB0eSBMdGQwHhcNMTYwOTIxMDI0NTEyWhcNMTYxMDIxMDI0NTEyWjBF
5 | MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
6 | ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
7 | CgKCAgEAsiMC7mTsmUXwZoYlT4aHY1FLw8bxIXC+z3IqA+TY1WqfbeiZRo8MA5Zx
8 | lTTxYMKPCZUE1XBc7jvD8GJhWIj6pToPYHn73B01IBkLBxq4kF1yV2Z7DVmkvc6H
9 | EcxXXq8zkCx0j6XOfiI4+qkXnuQn8cvrk8xfhtnMMZM7iVm6VSN93iRP/8ey6xuL
10 | XTHrDX7ukoRce1hpT8O+15GXNrY0irhhYQz5xKibNCJF3EjV28WMry8y7I8uYUFU
11 | RWDiQawwK9ec1zhZ94v92+GZDlPevmcFmSERKYQ0NsKcT0Y3lGuGnaExs8GyOpnC
12 | oksu4YJGXQjg7lkv4MxzsNbRqmCkUwxw1Mg6FP0tsCNsw9qTrkvWCRA9zp/aU+sZ
13 | IBGh1t4UGCub8joeQFvHxvr/3F7mH/dyvCjA34u0Lo1VPx+jYUIi9i0odltMspDW
14 | xOpjqdGARZYmlJP5Au9q5cQjPMcwS/EBIb8cwNl32mUE6WnFlep+38mNR/FghIjO
15 | ViAkXuKQmcHe6xppZAoHFsO/t3l4Tjek5vNW7erI1rgrFku/fvkIW/G8V1yIm/+Q
16 | F+CE4maQzCJfhftpkhM/sPC/FuLNBmNE8BHVX8y58xG4is/cQxL4Z9TsFIw0C5+3
17 | uTrFW9D0agysahMVzPGtCqhDQqJdIJrBQqlS6bztpzBA8zEI0skCAwEAAaOBpzCB
18 | pDAdBgNVHQ4EFgQUz/8FmW6TfqXyNJZr7rhc+Tn5sKQwdQYDVR0jBG4wbIAUz/8F
19 | mW6TfqXyNJZr7rhc+Tn5sKShSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpT
20 | b21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDw
21 | bC2ZjRnyrTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4ICAQCQmrcfhurX
22 | riR3Q0Y+nq040/3dJIAJXjyI9CEtxaU0nzCNTng7PwgZ0CKmCelQfInuwWFwBSHS
23 | 6kBfC1rgJeFnjnTt8a3RCgRlIgUr9NCdPSEccB7TurobwPJ2h6cJjjR8urcb0CXh
24 | CEMvPneyPj0xUFY8vVKXMGWahz/kyfwIiVqcX/OtMZ29fUu1onbWl71g2gVLtUZl
25 | sECdZ+AC/6HDCVpYIVETMl1T7N/XyqXZQiDLDNRDeZhnapz8w9fsW1KVujAZLNQR
26 | pVnw2qa2UK1dSf2FHX+lQU5mFSYM4vtwaMlX/LgfdLZ9I796hFh619WwTVz+LO2N
27 | vHnwBMabld3XSPuZRqlbBulDQ07Vbqdjv8DYSLA2aKI4ZkMMKuFLG/oS28V2ZYmv
28 | /KpGEs5UgKY+P9NulYpTDwCU/6SomuQpP795wbG6sm7Hzq82r2RmB61GupNRGeqi
29 | pXKsy69T388zBxYu6zQrosXiDl5YzaViH7tm0J7opye8dCWjjpnahki0vq2znti7
30 | 6cWla2j8Xz1glvLz+JI/NCOMfxUInb82T7ijo80N0VJ2hzf7p2GxRZXAxAV9knLI
31 | nM4F5TLjSd7ZhOOZ7ni/eZFueTMisWfypt2nc41whGjHMX/Zp1kPfhB4H2bLKIX/
32 | lSrwNr3qbGTEJX8JqpDBNVAd96XkMvDNyA==
33 | -----END CERTIFICATE-----
--------------------------------------------------------------------------------
/tests/data/trust_chain_wrong_order.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIFtTCCA52gAwIBAgIJAPBsLZmNGfKtMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
3 | BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
4 | aWRnaXRzIFB0eSBMdGQwHhcNMTYwOTIxMDI0NTEyWhcNMTYxMDIxMDI0NTEyWjBF
5 | MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
6 | ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
7 | CgKCAgEAsiMC7mTsmUXwZoYlT4aHY1FLw8bxIXC+z3IqA+TY1WqfbeiZRo8MA5Zx
8 | lTTxYMKPCZUE1XBc7jvD8GJhWIj6pToPYHn73B01IBkLBxq4kF1yV2Z7DVmkvc6H
9 | EcxXXq8zkCx0j6XOfiI4+qkXnuQn8cvrk8xfhtnMMZM7iVm6VSN93iRP/8ey6xuL
10 | XTHrDX7ukoRce1hpT8O+15GXNrY0irhhYQz5xKibNCJF3EjV28WMry8y7I8uYUFU
11 | RWDiQawwK9ec1zhZ94v92+GZDlPevmcFmSERKYQ0NsKcT0Y3lGuGnaExs8GyOpnC
12 | oksu4YJGXQjg7lkv4MxzsNbRqmCkUwxw1Mg6FP0tsCNsw9qTrkvWCRA9zp/aU+sZ
13 | IBGh1t4UGCub8joeQFvHxvr/3F7mH/dyvCjA34u0Lo1VPx+jYUIi9i0odltMspDW
14 | xOpjqdGARZYmlJP5Au9q5cQjPMcwS/EBIb8cwNl32mUE6WnFlep+38mNR/FghIjO
15 | ViAkXuKQmcHe6xppZAoHFsO/t3l4Tjek5vNW7erI1rgrFku/fvkIW/G8V1yIm/+Q
16 | F+CE4maQzCJfhftpkhM/sPC/FuLNBmNE8BHVX8y58xG4is/cQxL4Z9TsFIw0C5+3
17 | uTrFW9D0agysahMVzPGtCqhDQqJdIJrBQqlS6bztpzBA8zEI0skCAwEAAaOBpzCB
18 | pDAdBgNVHQ4EFgQUz/8FmW6TfqXyNJZr7rhc+Tn5sKQwdQYDVR0jBG4wbIAUz/8F
19 | mW6TfqXyNJZr7rhc+Tn5sKShSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpT
20 | b21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDw
21 | bC2ZjRnyrTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4ICAQCQmrcfhurX
22 | riR3Q0Y+nq040/3dJIAJXjyI9CEtxaU0nzCNTng7PwgZ0CKmCelQfInuwWFwBSHS
23 | 6kBfC1rgJeFnjnTt8a3RCgRlIgUr9NCdPSEccB7TurobwPJ2h6cJjjR8urcb0CXh
24 | CEMvPneyPj0xUFY8vVKXMGWahz/kyfwIiVqcX/OtMZ29fUu1onbWl71g2gVLtUZl
25 | sECdZ+AC/6HDCVpYIVETMl1T7N/XyqXZQiDLDNRDeZhnapz8w9fsW1KVujAZLNQR
26 | pVnw2qa2UK1dSf2FHX+lQU5mFSYM4vtwaMlX/LgfdLZ9I796hFh619WwTVz+LO2N
27 | vHnwBMabld3XSPuZRqlbBulDQ07Vbqdjv8DYSLA2aKI4ZkMMKuFLG/oS28V2ZYmv
28 | /KpGEs5UgKY+P9NulYpTDwCU/6SomuQpP795wbG6sm7Hzq82r2RmB61GupNRGeqi
29 | pXKsy69T388zBxYu6zQrosXiDl5YzaViH7tm0J7opye8dCWjjpnahki0vq2znti7
30 | 6cWla2j8Xz1glvLz+JI/NCOMfxUInb82T7ijo80N0VJ2hzf7p2GxRZXAxAV9knLI
31 | nM4F5TLjSd7ZhOOZ7ni/eZFueTMisWfypt2nc41whGjHMX/Zp1kPfhB4H2bLKIX/
32 | lSrwNr3qbGTEJX8JqpDBNVAd96XkMvDNyA==
33 | -----END CERTIFICATE-----
34 | -----BEGIN CERTIFICATE-----
35 | MIIDIzCCAgugAwIBAgIJAMfISuBQ5m+5MA0GCSqGSIb3DQEBBQUAMBUxEzARBgNV
36 | BAMTCnVuaXQtdGVzdHMwHhcNMTExMjA2MTYyNjAyWhcNMjExMjAzMTYyNjAyWjAV
37 | MRMwEQYDVQQDEwp1bml0LXRlc3RzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
38 | CgKCAQEA4ej0p7bQ7L/r4rVGUz9RN4VQWoej1Bg1mYWIDYslvKrk1gpj7wZgkdmM
39 | 7oVK2OfgrSj/FCTkInKPqaCR0gD7K80q+mLBrN3PUkDrJQZpvRZIff3/xmVU1Wer
40 | uQLFJjnFb2dqu0s/FY/2kWiJtBCakXvXEOb7zfbINuayL+MSsCGSdVYsSliS5qQp
41 | gyDap+8b5fpXZVJkq92hrcNtbkg7hCYUJczt8n9hcCTJCfUpApvaFQ18pe+zpyl4
42 | +WzkP66I28hniMQyUlA1hBiskT7qiouq0m8IOodhv2fagSZKjOTTU2xkSBc//fy3
43 | ZpsL7WqgsZS7Q+0VRK8gKfqkxg5OYQIDAQABo3YwdDAdBgNVHQ4EFgQU2RQ8yO+O
44 | gN8oVW2SW7RLrfYd9jEwRQYDVR0jBD4wPIAU2RQ8yO+OgN8oVW2SW7RLrfYd9jGh
45 | GaQXMBUxEzARBgNVBAMTCnVuaXQtdGVzdHOCCQDHyErgUOZvuTAMBgNVHRMEBTAD
46 | AQH/MA0GCSqGSIb3DQEBBQUAA4IBAQBRv+M/6+FiVu7KXNjFI5pSN17OcW5QUtPr
47 | odJMlWrJBtynn/TA1oJlYu3yV5clc/71Vr/AxuX5xGP+IXL32YDF9lTUJXG/uUGk
48 | +JETpKmQviPbRsvzYhz4pf6ZIOZMc3/GIcNq92ECbseGO+yAgyWUVKMmZM0HqXC9
49 | ovNslqe0M8C1sLm1zAR5z/h/litE7/8O2ietija3Q/qtl2TOXJdCA6sgjJX2WUql
50 | ybrC55ct18NKf3qhpcEkGQvFU40rVYApJpi98DiZPYFdx1oBDp/f4uZ3ojpxRVFT
51 | cDwcJLfNRCPUhormsY7fDS9xSyThiHsW9mjJYdcaKQkwYZ0F11yB
52 | -----END CERTIFICATE-----
--------------------------------------------------------------------------------
/tests/oauth2/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googleapis/google-auth-library-python/ca94ead4035beea4741dc5384449032f8e6f75d8/tests/oauth2/__init__.py
--------------------------------------------------------------------------------
/tests/oauth2/test_webauthn_handler_factory.py:
--------------------------------------------------------------------------------
1 | import mock
2 | import pytest # type: ignore
3 |
4 | from google.oauth2 import webauthn_handler
5 | from google.oauth2 import webauthn_handler_factory
6 |
7 |
8 | @pytest.fixture
9 | def os_get_stub():
10 | with mock.patch.object(
11 | webauthn_handler.os.environ,
12 | "get",
13 | return_value="gcloud_webauthn_plugin",
14 | name="fake os.environ.get",
15 | ) as mock_os_environ_get:
16 | yield mock_os_environ_get
17 |
18 |
19 | # Check that get_handler returns a value when env is set,
20 | # that type is PluginHandler, and that no value is returned
21 | # if env not set.
22 | def test_WebauthHandlerFactory_get(os_get_stub):
23 | factory = webauthn_handler_factory.WebauthnHandlerFactory()
24 | assert factory.get_handler() is not None
25 |
26 | assert isinstance(factory.get_handler(), webauthn_handler.PluginHandler)
27 |
28 | os_get_stub.return_value = None
29 | assert factory.get_handler() is None
30 |
--------------------------------------------------------------------------------
/tests/test__service_account_info.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 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 json
16 | import os
17 |
18 | import pytest # type: ignore
19 |
20 | from google.auth import _service_account_info
21 | from google.auth import crypt
22 |
23 |
24 | DATA_DIR = os.path.join(os.path.dirname(__file__), "data")
25 | SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, "service_account.json")
26 | GDCH_SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, "gdch_service_account.json")
27 |
28 | with open(SERVICE_ACCOUNT_JSON_FILE, "r") as fh:
29 | SERVICE_ACCOUNT_INFO = json.load(fh)
30 |
31 | with open(GDCH_SERVICE_ACCOUNT_JSON_FILE, "r") as fh:
32 | GDCH_SERVICE_ACCOUNT_INFO = json.load(fh)
33 |
34 |
35 | def test_from_dict():
36 | signer = _service_account_info.from_dict(SERVICE_ACCOUNT_INFO)
37 | assert isinstance(signer, crypt.RSASigner)
38 | assert signer.key_id == SERVICE_ACCOUNT_INFO["private_key_id"]
39 |
40 |
41 | def test_from_dict_es256_signer():
42 | signer = _service_account_info.from_dict(
43 | GDCH_SERVICE_ACCOUNT_INFO, use_rsa_signer=False
44 | )
45 | assert isinstance(signer, crypt.ES256Signer)
46 | assert signer.key_id == GDCH_SERVICE_ACCOUNT_INFO["private_key_id"]
47 |
48 |
49 | def test_from_dict_bad_private_key():
50 | info = SERVICE_ACCOUNT_INFO.copy()
51 | info["private_key"] = "garbage"
52 |
53 | with pytest.raises(ValueError) as excinfo:
54 | _service_account_info.from_dict(info)
55 |
56 | assert excinfo.match(r"(?i)(key|PEM)")
57 |
58 |
59 | def test_from_dict_bad_format():
60 | with pytest.raises(ValueError) as excinfo:
61 | _service_account_info.from_dict({}, require=("meep",))
62 |
63 | assert excinfo.match(r"missing fields")
64 |
65 |
66 | def test_from_filename():
67 | info, signer = _service_account_info.from_filename(SERVICE_ACCOUNT_JSON_FILE)
68 |
69 | for key, value in SERVICE_ACCOUNT_INFO.items():
70 | assert info[key] == value
71 |
72 | assert isinstance(signer, crypt.RSASigner)
73 | assert signer.key_id == SERVICE_ACCOUNT_INFO["private_key_id"]
74 |
75 |
76 | def test_from_filename_es256_signer():
77 | _, signer = _service_account_info.from_filename(
78 | GDCH_SERVICE_ACCOUNT_JSON_FILE, use_rsa_signer=False
79 | )
80 |
81 | assert isinstance(signer, crypt.ES256Signer)
82 | assert signer.key_id == GDCH_SERVICE_ACCOUNT_INFO["private_key_id"]
83 |
--------------------------------------------------------------------------------
/tests/test_api_key.py:
--------------------------------------------------------------------------------
1 | # Copyright 2022 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 pytest # type: ignore
16 |
17 | from google.auth import api_key
18 |
19 |
20 | def test_credentials_constructor():
21 | with pytest.raises(ValueError) as excinfo:
22 | api_key.Credentials("")
23 |
24 | assert excinfo.match(r"Token must be a non-empty API key string")
25 |
26 |
27 | def test_expired_and_valid():
28 | credentials = api_key.Credentials("api-key")
29 |
30 | assert credentials.valid
31 | assert credentials.token == "api-key"
32 | assert not credentials.expired
33 |
34 | credentials.refresh(None)
35 | assert credentials.valid
36 | assert credentials.token == "api-key"
37 | assert not credentials.expired
38 |
39 |
40 | def test_before_request():
41 | credentials = api_key.Credentials("api-key")
42 | headers = {}
43 |
44 | credentials.before_request(None, "http://example.com", "GET", headers)
45 | assert headers["x-goog-api-key"] == "api-key"
46 |
--------------------------------------------------------------------------------
/tests/test_exceptions.py:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Google Inc.
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 pytest # type: ignore
16 |
17 | from google.auth import exceptions # type:ignore
18 |
19 |
20 | @pytest.fixture(
21 | params=[
22 | exceptions.GoogleAuthError,
23 | exceptions.TransportError,
24 | exceptions.RefreshError,
25 | exceptions.UserAccessTokenError,
26 | exceptions.DefaultCredentialsError,
27 | exceptions.MutualTLSChannelError,
28 | exceptions.OAuthError,
29 | exceptions.ReauthFailError,
30 | exceptions.ReauthSamlChallengeFailError,
31 | ]
32 | )
33 | def retryable_exception(request):
34 | return request.param
35 |
36 |
37 | @pytest.fixture(params=[exceptions.ClientCertError])
38 | def non_retryable_exception(request):
39 | return request.param
40 |
41 |
42 | def test_default_retryable_exceptions(retryable_exception):
43 | assert not retryable_exception().retryable
44 |
45 |
46 | @pytest.mark.parametrize("retryable", [True, False])
47 | def test_retryable_exceptions(retryable_exception, retryable):
48 | retryable_exception = retryable_exception(retryable=retryable)
49 | assert retryable_exception.retryable == retryable
50 |
51 |
52 | @pytest.mark.parametrize("retryable", [True, False])
53 | def test_non_retryable_exceptions(non_retryable_exception, retryable):
54 | non_retryable_exception = non_retryable_exception(retryable=retryable)
55 | assert not non_retryable_exception.retryable
56 |
--------------------------------------------------------------------------------
/tests/test_metrics.py:
--------------------------------------------------------------------------------
1 | # Copyright 2014 Google Inc.
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 platform
16 |
17 | import mock
18 |
19 | from google.auth import metrics
20 | from google.auth import version
21 |
22 |
23 | def test_add_metric_header():
24 | headers = {}
25 | metrics.add_metric_header(headers, None)
26 | assert headers == {}
27 |
28 | headers = {"x-goog-api-client": "foo"}
29 | metrics.add_metric_header(headers, "bar")
30 | assert headers == {"x-goog-api-client": "foo bar"}
31 |
32 | headers = {}
33 | metrics.add_metric_header(headers, "bar")
34 | assert headers == {"x-goog-api-client": "bar"}
35 |
36 |
37 | @mock.patch.object(platform, "python_version", return_value="3.7")
38 | def test_versions(mock_python_version):
39 | version_save = version.__version__
40 | version.__version__ = "1.1"
41 | assert metrics.python_and_auth_lib_version() == "gl-python/3.7 auth/1.1"
42 | version.__version__ = version_save
43 |
44 |
45 | @mock.patch(
46 | "google.auth.metrics.python_and_auth_lib_version",
47 | return_value="gl-python/3.7 auth/1.1",
48 | )
49 | def test_metric_values(mock_python_and_auth_lib_version):
50 | assert (
51 | metrics.token_request_access_token_mds()
52 | == "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/mds"
53 | )
54 | assert (
55 | metrics.token_request_id_token_mds()
56 | == "gl-python/3.7 auth/1.1 auth-request-type/it cred-type/mds"
57 | )
58 | assert (
59 | metrics.token_request_access_token_impersonate()
60 | == "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/imp"
61 | )
62 | assert (
63 | metrics.token_request_id_token_impersonate()
64 | == "gl-python/3.7 auth/1.1 auth-request-type/it cred-type/imp"
65 | )
66 | assert (
67 | metrics.token_request_access_token_sa_assertion()
68 | == "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/sa"
69 | )
70 | assert (
71 | metrics.token_request_id_token_sa_assertion()
72 | == "gl-python/3.7 auth/1.1 auth-request-type/it cred-type/sa"
73 | )
74 | assert metrics.token_request_user() == "gl-python/3.7 auth/1.1 cred-type/u"
75 | assert metrics.mds_ping() == "gl-python/3.7 auth/1.1 auth-request-type/mds"
76 | assert metrics.reauth_start() == "gl-python/3.7 auth/1.1 auth-request-type/re-start"
77 | assert (
78 | metrics.reauth_continue() == "gl-python/3.7 auth/1.1 auth-request-type/re-cont"
79 | )
80 |
81 |
82 | @mock.patch(
83 | "google.auth.metrics.python_and_auth_lib_version",
84 | return_value="gl-python/3.7 auth/1.1",
85 | )
86 | def test_byoid_metric_header(mock_python_and_auth_lib_version):
87 | metrics_options = {}
88 | assert (
89 | metrics.byoid_metrics_header(metrics_options)
90 | == "gl-python/3.7 auth/1.1 google-byoid-sdk"
91 | )
92 | metrics_options["testKey"] = "testValue"
93 | assert (
94 | metrics.byoid_metrics_header(metrics_options)
95 | == "gl-python/3.7 auth/1.1 google-byoid-sdk testKey/testValue"
96 | )
97 |
--------------------------------------------------------------------------------
/tests/test_packaging.py:
--------------------------------------------------------------------------------
1 | # Copyright 2022 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 os
16 | import subprocess
17 | import sys
18 |
19 |
20 | def test_namespace_package_compat(tmp_path):
21 | """
22 | The ``google`` namespace package should not be masked
23 | by the presence of ``google-auth``.
24 | """
25 | google = tmp_path / "google"
26 | google.mkdir()
27 | google.joinpath("othermod.py").write_text("")
28 | env = dict(os.environ, PYTHONPATH=str(tmp_path))
29 | cmd = [sys.executable, "-m", "google.othermod"]
30 | subprocess.check_call(cmd, env=env)
31 |
--------------------------------------------------------------------------------
/tests/transport/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googleapis/google-auth-library-python/ca94ead4035beea4741dc5384449032f8e6f75d8/tests/transport/__init__.py
--------------------------------------------------------------------------------
/tests/transport/test__http_client.py:
--------------------------------------------------------------------------------
1 | # Copyright 2016 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 pytest # type: ignore
16 |
17 | from google.auth import exceptions
18 | import google.auth.transport._http_client
19 | from tests.transport import compliance
20 |
21 |
22 | class TestRequestResponse(compliance.RequestResponseTests):
23 | def make_request(self):
24 | return google.auth.transport._http_client.Request()
25 |
26 | def test_non_http(self):
27 | request = self.make_request()
28 | with pytest.raises(exceptions.TransportError) as excinfo:
29 | request(url="https://{}".format(compliance.NXDOMAIN), method="GET")
30 |
31 | assert excinfo.match("https")
32 |
--------------------------------------------------------------------------------
/tests_async/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googleapis/google-auth-library-python/ca94ead4035beea4741dc5384449032f8e6f75d8/tests_async/__init__.py
--------------------------------------------------------------------------------
/tests_async/conftest.py:
--------------------------------------------------------------------------------
1 | # Copyright 2020 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 os
16 | import sys
17 |
18 | import mock
19 | import pytest # type: ignore
20 |
21 |
22 | def pytest_configure():
23 | """Load public certificate and private key."""
24 | pytest.data_dir = os.path.join(
25 | os.path.abspath(os.path.join(__file__, "../..")), "tests/data"
26 | )
27 |
28 | with open(os.path.join(pytest.data_dir, "privatekey.pem"), "rb") as fh:
29 | pytest.private_key_bytes = fh.read()
30 |
31 | with open(os.path.join(pytest.data_dir, "public_cert.pem"), "rb") as fh:
32 | pytest.public_cert_bytes = fh.read()
33 |
34 |
35 | @pytest.fixture
36 | def mock_non_existent_module(monkeypatch):
37 | """Mocks a non-existing module in sys.modules.
38 |
39 | Additionally mocks any non-existing modules specified in the dotted path.
40 | """
41 |
42 | def _mock_non_existent_module(path):
43 | parts = path.split(".")
44 | partial = []
45 | for part in parts:
46 | partial.append(part)
47 | current_module = ".".join(partial)
48 | if current_module not in sys.modules:
49 | monkeypatch.setitem(sys.modules, current_module, mock.MagicMock())
50 |
51 | return _mock_non_existent_module
52 |
--------------------------------------------------------------------------------
/tests_async/transport/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/googleapis/google-auth-library-python/ca94ead4035beea4741dc5384449032f8e6f75d8/tests_async/transport/__init__.py
--------------------------------------------------------------------------------