| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 4598454 commit 89fc6f2
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -113,6 +113,18 @@ | |||
| 113 | 113 | """Environment variable defining the location of Google API certificate config | |
| 114 | 114 | file.""" | |
| 115 | 115 | ||
| 116 | + CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE = ( | ||
| 117 | + "CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE" | ||
| 118 | + ) | ||
| 119 | + """Environment variable controlling whether to use client certificate or not. | ||
| 120 | + This variable is the fallback of GOOGLE_API_USE_CLIENT_CERTIFICATE.""" | ||
| 121 | + | ||
| 122 | + CLOUDSDK_CONTEXT_AWARE_CERTIFICATE_CONFIG_FILE_PATH = ( | ||
| 123 | + "CLOUDSDK_CONTEXT_AWARE_CERTIFICATE_CONFIG_FILE_PATH" | ||
| 124 | + ) | ||
| 125 | + """Environment variable defining the location of Google API certificate config | ||
| 126 | + file. This variable is the fallback of GOOGLE_API_CERTIFICATE_CONFIG.""" | ||
| 127 | + | ||
| 116 | 128 | GOOGLE_API_PREVENT_AGENT_TOKEN_SHARING_FOR_GCP_SERVICES = ( | |
| 117 | 129 | "GOOGLE_API_PREVENT_AGENT_TOKEN_SHARING_FOR_GCP_SERVICES" | |
| 118 | 130 | ) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,14 +22,13 @@ | |||
| 22 | 22 | import base64 | |
| 23 | 23 | import http.client as http_client | |
| 24 | 24 | import json | |
| 25 | - import os | ||
| 26 | 25 | ||
| 27 | 26 | from google.auth import _exponential_backoff | |
| 28 | 27 | from google.auth import _helpers | |
| 29 | 28 | from google.auth import credentials | |
| 30 | 29 | from google.auth import crypt | |
| 31 | 30 | from google.auth import exceptions | |
| 32 | - from google.auth.transport import mtls | ||
| 31 | + from google.auth.transport import _mtls_helper | ||
| 33 | 32 | ||
| 34 | 33 | IAM_RETRY_CODES = { | |
| 35 | 34 | http_client.INTERNAL_SERVER_ERROR, | |
@@ -40,20 +39,12 @@ | |||
| 40 | 39 | ||
| 41 | 40 | _IAM_SCOPE = ["https://www.googleapis.com/auth/iam"] | |
| 42 | 41 | ||
| 43 | - # 1. Determine if we should use mTLS. | ||
| 44 | - # Note: We only support automatic mTLS on the default googleapis.com universe. | ||
| 45 | - if hasattr(mtls, "should_use_client_cert"): | ||
| 46 | - use_client_cert = mtls.should_use_client_cert() | ||
| 47 | - else: # pragma: NO COVER | ||
| 48 | - # if unsupported, fallback to reading from env var | ||
| 49 | - use_client_cert = ( | ||
| 50 | - os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false").lower() == "true" | ||
| 51 | - ) | ||
| 52 | - | ||
| 53 | - # 2. Construct the template domain using the library's DEFAULT_UNIVERSE_DOMAIN constant. | ||
| 54 | - # This ensures that the .replace() calls in the classes will work correctly. | ||
| 55 | - if use_client_cert: | ||
| 56 | - # We use the .mtls. prefix only for the default universe template | ||
| 42 | + # Determine if we should use mTLS. | ||
| 43 | + if ( | ||
| 44 | + hasattr(_mtls_helper, "check_use_client_cert") | ||
| 45 | + and _mtls_helper.check_use_client_cert() | ||
| 46 | + ): | ||
| 47 | + # Construct the template domain using the library's DEFAULT_UNIVERSE_DOMAIN constant. | ||
| 57 | 48 | _IAM_DOMAIN = f"iamcredentials.mtls.{credentials.DEFAULT_UNIVERSE_DOMAIN}" | |
| 58 | 49 | else: | |
| 59 | 50 | _IAM_DOMAIN = f"iamcredentials.{credentials.DEFAULT_UNIVERSE_DOMAIN}" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -151,7 +151,14 @@ def _get_cert_config_path(certificate_config_path=None): | |||
| 151 | 151 | if env_path is not None and env_path != "": | |
| 152 | 152 | certificate_config_path = env_path | |
| 153 | 153 | else: | |
| 154 | - certificate_config_path = CERTIFICATE_CONFIGURATION_DEFAULT_PATH | ||
| 154 | + env_path = environ.get( | ||
| 155 | + environment_vars.CLOUDSDK_CONTEXT_AWARE_CERTIFICATE_CONFIG_FILE_PATH, | ||
| 156 | + None, | ||
| 157 | + ) | ||
| 158 | + if env_path is not None and env_path != "": | ||
| 159 | + certificate_config_path = env_path | ||
| 160 | + else: | ||
| 161 | + certificate_config_path = CERTIFICATE_CONFIGURATION_DEFAULT_PATH | ||
| 155 | 162 | ||
| 156 | 163 | certificate_config_path = path.expanduser(certificate_config_path) | |
| 157 | 164 | if not path.exists(certificate_config_path): | |
@@ -452,13 +459,23 @@ def check_use_client_cert(): | |||
| 452 | 459 | Returns: | |
| 453 | 460 | bool: Whether the client certificate should be used for mTLS connection. | |
| 454 | 461 | """ | |
| 455 | - use_client_cert = getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE") | ||
| 462 | + use_client_cert = getenv(environment_vars.GOOGLE_API_USE_CLIENT_CERTIFICATE) | ||
| 463 | + if use_client_cert is None or use_client_cert == "": | ||
| 464 | + use_client_cert = getenv( | ||
| 465 | + environment_vars.CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE | ||
| 466 | + ) | ||
| 467 | + | ||
| 456 | 468 | # Check if the value of GOOGLE_API_USE_CLIENT_CERTIFICATE is set. | |
| 457 | 469 | if use_client_cert: | |
| 458 | 470 | return use_client_cert.lower() == "true" | |
| 459 | 471 | else: | |
| 460 | 472 | # Check if the value of GOOGLE_API_CERTIFICATE_CONFIG is set. | |
| 461 | - cert_path = getenv("GOOGLE_API_CERTIFICATE_CONFIG") | ||
| 473 | + cert_path = getenv(environment_vars.GOOGLE_API_CERTIFICATE_CONFIG) | ||
| 474 | + if cert_path is None: | ||
| 475 | + cert_path = getenv( | ||
| 476 | + environment_vars.CLOUDSDK_CONTEXT_AWARE_CERTIFICATE_CONFIG_FILE_PATH | ||
| 477 | + ) | ||
| 478 | + | ||
| 462 | 479 | if cert_path: | |
| 463 | 480 | try: | |
| 464 | 481 | with open(cert_path, "r") as f: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,7 +19,7 @@ | |||
| 19 | 19 | from OpenSSL import crypto | |
| 20 | 20 | import pytest # type: ignore | |
| 21 | 21 | ||
| 22 | - from google.auth import exceptions | ||
| 22 | + from google.auth import environment_vars, exceptions | ||
| 23 | 23 | from google.auth.transport import _mtls_helper | |
| 24 | 24 | ||
| 25 | 25 | CERT_MOCK_VAL = b"cert" | |
@@ -681,6 +681,37 @@ def test_env_variable_file_does_not_exist(self, mock_path_exists): | |||
| 681 | 681 | returned_path = _mtls_helper._get_cert_config_path() | |
| 682 | 682 | assert returned_path is None | |
| 683 | 683 | ||
| 684 | + def test_cert_config_path_precedence(self): | ||
| 685 | + # GOOGLE_API_CERTIFICATE_CONFIG takes precedence | ||
| 686 | + google_path = "/path/to/google/config" | ||
| 687 | + cloudsdk_path = "/path/to/cloudsdk/config" | ||
| 688 | + | ||
| 689 | + with mock.patch.dict( | ||
| 690 | + os.environ, | ||
| 691 | + { | ||
| 692 | + environment_vars.GOOGLE_API_CERTIFICATE_CONFIG: google_path, | ||
| 693 | + environment_vars.CLOUDSDK_CONTEXT_AWARE_CERTIFICATE_CONFIG_FILE_PATH: cloudsdk_path, | ||
| 694 | + }, | ||
| 695 | + ): | ||
| 696 | + with mock.patch("os.path.exists", return_value=True): | ||
| 697 | + assert _mtls_helper._get_cert_config_path() == google_path | ||
| 698 | + | ||
| 699 | + def test_cert_config_path_fallback(self): | ||
| 700 | + # Fallback to CLOUDSDK_CONTEXT_AWARE_CERTIFICATE_CONFIG_FILE_PATH if GOOGLE_API_CERTIFICATE_CONFIG is unset | ||
| 701 | + cloudsdk_path = "/path/to/cloudsdk/config" | ||
| 702 | + | ||
| 703 | + with mock.patch.dict( | ||
| 704 | + os.environ, | ||
| 705 | + { | ||
| 706 | + environment_vars.CLOUDSDK_CONTEXT_AWARE_CERTIFICATE_CONFIG_FILE_PATH: cloudsdk_path | ||
| 707 | + }, | ||
| 708 | + ): | ||
| 709 | + if environment_vars.GOOGLE_API_CERTIFICATE_CONFIG in os.environ: | ||
| 710 | + del os.environ[environment_vars.GOOGLE_API_CERTIFICATE_CONFIG] | ||
| 711 | + | ||
| 712 | + with mock.patch("os.path.exists", return_value=True): | ||
| 713 | + assert _mtls_helper._get_cert_config_path() == cloudsdk_path | ||
| 714 | + | ||
| 684 | 715 | @mock.patch.dict( | |
| 685 | 716 | os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": "path/to/config/file"} | |
| 686 | 717 | ) | |
@@ -811,6 +842,74 @@ def test_config_file_not_found(self, mock_file): | |||
| 811 | 842 | def test_no_env_vars_set(self): | |
| 812 | 843 | assert _mtls_helper.check_use_client_cert() is False | |
| 813 | 844 | ||
| 845 | + def test_use_client_cert_precedence(self): | ||
| 846 | + # GOOGLE_API_USE_CLIENT_CERTIFICATE takes precedence | ||
| 847 | + with mock.patch.dict( | ||
| 848 | + os.environ, | ||
| 849 | + { | ||
| 850 | + environment_vars.GOOGLE_API_USE_CLIENT_CERTIFICATE: "true", | ||
| 851 | + environment_vars.CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE: "false", | ||
| 852 | + }, | ||
| 853 | + ): | ||
| 854 | + assert _mtls_helper.check_use_client_cert() is True | ||
| 855 | + | ||
| 856 | + with mock.patch.dict( | ||
| 857 | + os.environ, | ||
| 858 | + { | ||
| 859 | + environment_vars.GOOGLE_API_USE_CLIENT_CERTIFICATE: "false", | ||
| 860 | + environment_vars.CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE: "true", | ||
| 861 | + }, | ||
| 862 | + ): | ||
| 863 | + assert _mtls_helper.check_use_client_cert() is False | ||
| 864 | + | ||
| 865 | + def test_use_client_cert_fallback(self): | ||
| 866 | + # Fallback to CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE if GOOGLE_API_USE_CLIENT_CERTIFICATE is unset | ||
| 867 | + with mock.patch.dict( | ||
| 868 | + os.environ, | ||
| 869 | + {environment_vars.CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE: "true"}, | ||
| 870 | + ): | ||
| 871 | + # Ensure GOOGLE_API_USE_CLIENT_CERTIFICATE is not set | ||
| 872 | + if environment_vars.GOOGLE_API_USE_CLIENT_CERTIFICATE in os.environ: | ||
| 873 | + del os.environ[environment_vars.GOOGLE_API_USE_CLIENT_CERTIFICATE] | ||
| 874 | + assert _mtls_helper.check_use_client_cert() is True | ||
| 875 | + | ||
| 876 | + with mock.patch.dict( | ||
| 877 | + os.environ, | ||
| 878 | + {environment_vars.CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE: "false"}, | ||
| 879 | + ): | ||
| 880 | + if environment_vars.GOOGLE_API_USE_CLIENT_CERTIFICATE in os.environ: | ||
| 881 | + del os.environ[environment_vars.GOOGLE_API_USE_CLIENT_CERTIFICATE] | ||
| 882 | + assert _mtls_helper.check_use_client_cert() is False | ||
| 883 | + | ||
| 884 | + @mock.patch("builtins.open", autospec=True) | ||
| 885 | + def test_check_use_client_cert_config_fallback(self, mock_file): | ||
| 886 | + # Test fallback for config file when determining if client cert should be used | ||
| 887 | + cloudsdk_path = "/path/to/cloudsdk/config" | ||
| 888 | + | ||
| 889 | + mock_file.side_effect = mock.mock_open( | ||
| 890 | + read_data='{"cert_configs": {"workload": "exists"}}' | ||
| 891 | + ) | ||
| 892 | + | ||
| 893 | + with mock.patch.dict( | ||
| 894 | + os.environ, | ||
| 895 | + { | ||
| 896 | + environment_vars.CLOUDSDK_CONTEXT_AWARE_CERTIFICATE_CONFIG_FILE_PATH: cloudsdk_path | ||
| 897 | + }, | ||
| 898 | + ): | ||
| 899 | + if environment_vars.GOOGLE_API_CERTIFICATE_CONFIG in os.environ: | ||
| 900 | + del os.environ[environment_vars.GOOGLE_API_CERTIFICATE_CONFIG] | ||
| 901 | + if environment_vars.GOOGLE_API_USE_CLIENT_CERTIFICATE in os.environ: | ||
| 902 | + del os.environ[environment_vars.GOOGLE_API_USE_CLIENT_CERTIFICATE] | ||
| 903 | + if ( | ||
| 904 | + environment_vars.CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE | ||
| 905 | + in os.environ | ||
| 906 | + ): | ||
| 907 | + del os.environ[ | ||
| 908 | + environment_vars.CLOUDSDK_CONTEXT_AWARE_USE_CLIENT_CERTIFICATE | ||
| 909 | + ] | ||
| 910 | + | ||
| 911 | + assert _mtls_helper.check_use_client_cert() is True | ||
| 912 | + | ||
| 814 | 913 | ||
| 815 | 914 | class TestMtlsHelper: | |
| 816 | 915 | @mock.patch.object(_mtls_helper, "call_client_cert_callback") | |
| Back | FazBrowse Home | New Git URL |
0 commit comments