From da1a9050d3d7a8c35cd82ed05bdebb105f36a9d9 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Thu, 26 Feb 2026 13:14:13 -0500 Subject: [PATCH] samples: deletes samples/cloud-client/snippets --- .../authenticate_explicit_with_adc.py | 55 ----- .../authenticate_implicit_with_adc.py | 46 ----- .../snippets/custom_aws_supplier.py | 117 ----------- .../snippets/custom_okta_supplier.py | 190 ------------------ .../idtoken_from_impersonated_credentials.py | 75 ------- .../snippets/idtoken_from_metadata_server.py | 50 ----- .../snippets/idtoken_from_service_account.py | 50 ----- samples/cloud-client/snippets/noxfile.py | 85 -------- .../cloud-client/snippets/noxfile_config.py | 38 ---- .../cloud-client/snippets/requirements.txt | 8 - .../cloud-client/snippets/snippets_test.py | 77 ------- .../snippets/verify_google_idtoken.py | 62 ------ 12 files changed, 853 deletions(-) delete mode 100644 samples/cloud-client/snippets/authenticate_explicit_with_adc.py delete mode 100644 samples/cloud-client/snippets/authenticate_implicit_with_adc.py delete mode 100644 samples/cloud-client/snippets/custom_aws_supplier.py delete mode 100644 samples/cloud-client/snippets/custom_okta_supplier.py delete mode 100644 samples/cloud-client/snippets/idtoken_from_impersonated_credentials.py delete mode 100644 samples/cloud-client/snippets/idtoken_from_metadata_server.py delete mode 100644 samples/cloud-client/snippets/idtoken_from_service_account.py delete mode 100644 samples/cloud-client/snippets/noxfile.py delete mode 100644 samples/cloud-client/snippets/noxfile_config.py delete mode 100644 samples/cloud-client/snippets/requirements.txt delete mode 100644 samples/cloud-client/snippets/snippets_test.py delete mode 100644 samples/cloud-client/snippets/verify_google_idtoken.py diff --git a/samples/cloud-client/snippets/authenticate_explicit_with_adc.py b/samples/cloud-client/snippets/authenticate_explicit_with_adc.py deleted file mode 100644 index 8483bd7ea..000000000 --- a/samples/cloud-client/snippets/authenticate_explicit_with_adc.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright 2022 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# [START auth_cloud_explicit_adc] - -from google.cloud import storage - -import google.oauth2.credentials -import google.auth - - -def authenticate_explicit_with_adc(): - """ - List storage buckets by authenticating with ADC. - - // TODO(Developer): - // 1. Before running this sample, - // set up ADC as described in https://cloud.google.com/docs/authentication/external/set-up-adc - // 2. Replace the project variable. - // 3. Make sure you have the necessary permission to list storage buckets: "storage.buckets.list" - """ - - # Construct the Google credentials object which obtains the default configuration from your - # working environment. - # google.auth.default() will give you ComputeEngineCredentials - # if you are on a GCE (or other metadata server supported environments). - credentials, project_id = google.auth.default() - # If you are authenticating to a Cloud API, you can let the library include the default scope, - # https://www.googleapis.com/auth/cloud-platform, because IAM is used to provide fine-grained - # permissions for Cloud. - # If you need to provide a scope, specify it as follows: - # credentials = google.auth.default(scopes=scope) - # For more information on scopes to use, - # see: https://developers.google.com/identity/protocols/oauth2/scopes - - # Construct the Storage client. - storage_client = storage.Client(credentials=credentials, project=project_id) - buckets = storage_client.list_buckets() - print("Buckets:") - for bucket in buckets: - print(bucket.name) - print("Listed all storage buckets.") - -# [END auth_cloud_explicit_adc] diff --git a/samples/cloud-client/snippets/authenticate_implicit_with_adc.py b/samples/cloud-client/snippets/authenticate_implicit_with_adc.py deleted file mode 100644 index 2c1a0414d..000000000 --- a/samples/cloud-client/snippets/authenticate_implicit_with_adc.py +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright 2022 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# [START auth_cloud_implicit_adc] - -from google.cloud import storage - - -def authenticate_implicit_with_adc(project_id="your-google-cloud-project-id"): - """ - When interacting with Google Cloud Client libraries, the library can auto-detect the - credentials to use. - - // TODO(Developer): - // 1. Before running this sample, - // set up ADC as described in https://cloud.google.com/docs/authentication/external/set-up-adc - // 2. Replace the project variable. - // 3. Make sure that the user account or service account that you are using - // has the required permissions. For this sample, you must have "storage.buckets.list". - Args: - project_id: The project id of your Google Cloud project. - """ - - # This snippet demonstrates how to list buckets. - # *NOTE*: Replace the client created below with the client required for your application. - # Note that the credentials are not specified when constructing the client. - # Hence, the client library will look for credentials using ADC. - storage_client = storage.Client(project=project_id) - buckets = storage_client.list_buckets() - print("Buckets:") - for bucket in buckets: - print(bucket.name) - print("Listed all storage buckets.") - -# [END auth_cloud_implicit_adc] diff --git a/samples/cloud-client/snippets/custom_aws_supplier.py b/samples/cloud-client/snippets/custom_aws_supplier.py deleted file mode 100644 index ec5bf8a10..000000000 --- a/samples/cloud-client/snippets/custom_aws_supplier.py +++ /dev/null @@ -1,117 +0,0 @@ -# Copyright 2025 Google LLC -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import json -import os -import sys - -import boto3 -from dotenv import load_dotenv -from google.auth.aws import Credentials as AwsCredentials -from google.auth.aws import AwsSecurityCredentials, AwsSecurityCredentialsSupplier -from google.auth.exceptions import GoogleAuthError -from google.auth.transport.requests import AuthorizedSession - -load_dotenv() - - -class CustomAwsSupplier(AwsSecurityCredentialsSupplier): - """Custom AWS Security Credentials Supplier.""" - - def __init__(self): - """Initializes the Boto3 session, prioritizing environment variables for region.""" - # Explicitly read the region from the environment first. This ensures that - # a value from a .env file is picked up reliably for local testing. - region = os.getenv("AWS_REGION") or os.getenv("AWS_DEFAULT_REGION") - - # If region is None, Boto3's discovery chain will be used when needed. - self.session = boto3.Session(region_name=region) - self._cached_region = None - print(f"[INFO] CustomAwsSupplier initialized. Region from env: {region}") - - def get_aws_region(self, context, request) -> str: - """Returns the AWS region using Boto3's default provider chain.""" - if self._cached_region: - return self._cached_region - - # Accessing region_name will use the value from the constructor if provided, - # otherwise it triggers Boto3's lazy-loading discovery (e.g., metadata service). - self._cached_region = self.session.region_name - - if not self._cached_region: - print("[ERROR] Boto3 was unable to resolve an AWS region.", file=sys.stderr) - raise GoogleAuthError("Boto3 was unable to resolve an AWS region.") - - print(f"[INFO] Boto3 resolved AWS Region: {self._cached_region}") - return self._cached_region - - def get_aws_security_credentials(self, context, request=None) -> AwsSecurityCredentials: - """Retrieves AWS security credentials using Boto3's default provider chain.""" - aws_credentials = self.session.get_credentials() - if not aws_credentials: - print("[ERROR] Unable to resolve AWS credentials.", file=sys.stderr) - raise GoogleAuthError("Unable to resolve AWS credentials from the provider chain.") - - print(f"[INFO] Resolved AWS Access Key ID: {aws_credentials.access_key}") - - return AwsSecurityCredentials( - access_key_id=aws_credentials.access_key, - secret_access_key=aws_credentials.secret_key, - session_token=aws_credentials.token, - ) - - -def main(): - """Main function to demonstrate the custom AWS supplier.""" - print("--- Starting Script ---") - - gcp_audience = os.getenv("GCP_WORKLOAD_AUDIENCE") - sa_impersonation_url = os.getenv("GCP_SERVICE_ACCOUNT_IMPERSONATION_URL") - gcs_bucket_name = os.getenv("GCS_BUCKET_NAME") - - print(f"GCP_WORKLOAD_AUDIENCE: {gcp_audience}") - print(f"GCS_BUCKET_NAME: {gcs_bucket_name}") - - if not all([gcp_audience, sa_impersonation_url, gcs_bucket_name]): - print("[ERROR] Missing required environment variables.", file=sys.stderr) - raise GoogleAuthError("Missing required environment variables.") - - custom_supplier = CustomAwsSupplier() - - credentials = AwsCredentials( - audience=gcp_audience, - subject_token_type="urn:ietf:params:aws:token-type:aws4_request", - service_account_impersonation_url=sa_impersonation_url, - aws_security_credentials_supplier=custom_supplier, - scopes=['https://www.googleapis.com/auth/devstorage.read_write'], - ) - - bucket_url = f"https://storage.googleapis.com/storage/v1/b/{gcs_bucket_name}" - print(f"Request URL: {bucket_url}") - - authed_session = AuthorizedSession(credentials) - try: - print("Attempting to make authenticated request to Google Cloud Storage...") - res = authed_session.get(bucket_url) - res.raise_for_status() - print("\n--- SUCCESS! ---") - print("Successfully authenticated and retrieved bucket data:") - print(json.dumps(res.json(), indent=2)) - except Exception as e: - print("--- FAILED --- ", file=sys.stderr) - print(e, file=sys.stderr) - exit(1) - - -if __name__ == "__main__": - main() diff --git a/samples/cloud-client/snippets/custom_okta_supplier.py b/samples/cloud-client/snippets/custom_okta_supplier.py deleted file mode 100644 index 12f83dcfa..000000000 --- a/samples/cloud-client/snippets/custom_okta_supplier.py +++ /dev/null @@ -1,190 +0,0 @@ -# Copyright 2025 Google LLC -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import json -import urllib.parse -import os -import time - -import requests -from dotenv import load_dotenv -from google.auth.exceptions import GoogleAuthError -from google.auth.identity_pool import Credentials as IdentityPoolClient -from google.auth.transport.requests import AuthorizedSession - -load_dotenv() - -# Workload Identity Pool Configuration -GCP_WORKLOAD_AUDIENCE = os.getenv("GCP_WORKLOAD_AUDIENCE") -SERVICE_ACCOUNT_IMPERSONATION_URL = os.getenv("GCP_SERVICE_ACCOUNT_IMPERSONATION_URL") -GCS_BUCKET_NAME = os.getenv("GCS_BUCKET_NAME") - -# Okta Configuration -OKTA_DOMAIN = os.getenv("OKTA_DOMAIN") -OKTA_CLIENT_ID = os.getenv("OKTA_CLIENT_ID") -OKTA_CLIENT_SECRET = os.getenv("OKTA_CLIENT_SECRET") - -# Constants -TOKEN_URL = "https://sts.googleapis.com/v1/token" -SUBJECT_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:jwt" - - -class OktaClientCredentialsSupplier: - """A custom SubjectTokenSupplier that authenticates with Okta. - - This supplier uses the Client Credentials grant flow for machine-to-machine - (M2M) authentication with Okta. - """ - - def __init__(self, domain, client_id, client_secret): - self.okta_token_url = f"{domain}/oauth2/default/v1/token" - self.client_id = client_id - self.client_secret = client_secret - self.access_token = None - self.expiry_time = 0 - print("OktaClientCredentialsSupplier initialized.") - - def get_subject_token(self, context, request=None) -> str: - """Fetches a new token if the current one is expired or missing. - - Args: - context: The context object, not used in this implementation. - - Returns: - The Okta Access token. - """ - # Check if the current token is still valid (with a 60-second buffer). - is_token_valid = self.access_token and time.time() < self.expiry_time - 60 - - if is_token_valid: - print("[Supplier] Returning cached Okta Access token.") - return self.access_token - - print( - "[Supplier] Token is missing or expired. Fetching new Okta Access token..." - ) - self._fetch_okta_access_token() - return self.access_token - - def _fetch_okta_access_token(self): - """Performs the Client Credentials grant flow with Okta.""" - headers = { - "Content-Type": "application/x-www-form-urlencoded", - "Accept": "application/json", - } - data = { - "grant_type": "client_credentials", - "scope": "gcp.test.read", - } - encoded_data = urllib.parse.urlencode(data) - - try: - response = requests.post( - self.okta_token_url, - headers=headers, - data=encoded_data, - auth=(self.client_id, self.client_secret), - ) - response.raise_for_status() - token_data = response.json() - - if "access_token" in token_data and "expires_in" in token_data: - self.access_token = token_data["access_token"] - self.expiry_time = time.time() + token_data["expires_in"] - print( - f"[Supplier] Successfully received Access Token from Okta. " - f"Expires in {token_data['expires_in']} seconds." - ) - else: - raise GoogleAuthError( - "Access token or expires_in not found in Okta response." - ) - except requests.exceptions.RequestException as e: - print(f"[Supplier] Error fetching token from Okta: {e}") - if e.response: - print(f"[Supplier] Okta response: {e.response.text}") - raise GoogleAuthError( - "Failed to authenticate with Okta using Client Credentials grant." - ) from e - - -def main(): - """Main function to demonstrate the custom Okta supplier. - - TODO(Developer): - 1. Before running this sample, set up your environment variables. You can do - this by creating a .env file in the same directory as this script and - populating it with the following variables: - - GCP_WORKLOAD_AUDIENCE: The audience for the GCP workload identity pool. - - GCP_SERVICE_ACCOUNT_IMPERSONATION_URL: The URL for service account impersonation (optional). - - GCS_BUCKET_NAME: The name of the GCS bucket to access. - - OKTA_DOMAIN: Your Okta domain (e.g., https://dev-12345.okta.com). - - OKTA_CLIENT_ID: The Client ID of your Okta M2M application. - - OKTA_CLIENT_SECRET: The Client Secret of your Okta M2M application. - """ - if not all( - [ - GCP_WORKLOAD_AUDIENCE, - GCS_BUCKET_NAME, - OKTA_DOMAIN, - OKTA_CLIENT_ID, - OKTA_CLIENT_SECRET, - ] - ): - raise GoogleAuthError( - "Missing required environment variables. Please check your .env file." - ) - - # 1. Instantiate the custom supplier with Okta credentials. - okta_supplier = OktaClientCredentialsSupplier( - OKTA_DOMAIN, OKTA_CLIENT_ID, OKTA_CLIENT_SECRET - ) - - # 2. Instantiate an IdentityPoolClient. - client = IdentityPoolClient( - audience=GCP_WORKLOAD_AUDIENCE, - subject_token_type=SUBJECT_TOKEN_TYPE, - token_url=TOKEN_URL, - subject_token_supplier=okta_supplier, - # If you choose to provide explicit scopes: use the `scopes` parameter. - default_scopes=['https://www.googleapis.com/auth/cloud-platform'], - service_account_impersonation_url=SERVICE_ACCOUNT_IMPERSONATION_URL, - ) - - # 3. Construct the URL for the Cloud Storage JSON API. - bucket_url = f"https://storage.googleapis.com/storage/v1/b/{GCS_BUCKET_NAME}" - print(f"[Test] Getting metadata for bucket: {GCS_BUCKET_NAME}...") - print(f"[Test] Request URL: {bucket_url}") - - # 4. Use the client to make an authenticated request. - authed_session = AuthorizedSession(client) - try: - res = authed_session.get(bucket_url) - res.raise_for_status() - print("\n--- SUCCESS! ---") - print("Successfully authenticated and retrieved bucket data:") - print(json.dumps(res.json(), indent=2)) - except requests.exceptions.RequestException as e: - print("\n--- FAILED ---") - print(f"Request failed: {e}") - if e.response: - print(f"Response: {e.response.text}") - exit(1) - except GoogleAuthError as e: - print("\n--- FAILED ---") - print(f"Authentication or request failed: {e}") - exit(1) - - -if __name__ == "__main__": - main() diff --git a/samples/cloud-client/snippets/idtoken_from_impersonated_credentials.py b/samples/cloud-client/snippets/idtoken_from_impersonated_credentials.py deleted file mode 100644 index a27e6cffd..000000000 --- a/samples/cloud-client/snippets/idtoken_from_impersonated_credentials.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright 2022 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# [auth_cloud_idtoken_impersonated_credentials] - -import google -from google.auth import impersonated_credentials -import google.auth.transport.requests - - -def idtoken_from_impersonated_credentials( - impersonated_service_account: str, scope: str, target_audience: str): - """ - Use a service account (SA1) to impersonate as another service account (SA2) and obtain id token - for the impersonated account. - To obtain token for SA2, SA1 should have the "roles/iam.serviceAccountTokenCreator" permission - on SA2. - - Args: - impersonated_service_account: The name of the privilege-bearing service account for whom the credential is created. - Examples: name@project.service.gserviceaccount.com - - scope: Provide the scopes that you might need to request to access Google APIs, - depending on the level of access you need. - For this example, we use the cloud-wide scope and use IAM to narrow the permissions. - https://cloud.google.com/docs/authentication#authorization_for_services - For more information, see: https://developers.google.com/identity/protocols/oauth2/scopes - - target_audience: The service name for which the id token is requested. Service name refers to the - logical identifier of an API service, such as "iap.googleapis.com". - Examples: iap.googleapis.com - """ - - # Construct the GoogleCredentials object which obtains the default configuration from your - # working environment. - credentials, project_id = google.auth.default() - - # Create the impersonated credential. - target_credentials = impersonated_credentials.Credentials( - source_credentials=credentials, - target_principal=impersonated_service_account, - # delegates: The chained list of delegates required to grant the final accessToken. - # For more information, see: - # https://cloud.google.com/iam/docs/create-short-lived-credentials-direct#sa-credentials-permissions - # Delegate is NOT USED here. - delegates=[], - target_scopes=[scope], - lifetime=300) - - # Set the impersonated credential, target audience and token options. - id_creds = impersonated_credentials.IDTokenCredentials( - target_credentials, - target_audience=target_audience, - include_email=True) - - # Get the ID token. - # Once you've obtained the ID token, use it to make an authenticated call - # to the target audience. - request = google.auth.transport.requests.Request() - id_creds.refresh(request) - # token = id_creds.token - print("Generated ID token.") - -# [auth_cloud_idtoken_impersonated_credentials] diff --git a/samples/cloud-client/snippets/idtoken_from_metadata_server.py b/samples/cloud-client/snippets/idtoken_from_metadata_server.py deleted file mode 100644 index b59a05544..000000000 --- a/samples/cloud-client/snippets/idtoken_from_metadata_server.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2022 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# [START auth_cloud_idtoken_metadata_server] - -import google -import google.oauth2.credentials -from google.auth import compute_engine -import google.auth.transport.requests - - -def idtoken_from_metadata_server(url: str): - """ - Use the Google Cloud metadata server in the Cloud Run (or AppEngine or Kubernetes etc.,) - environment to create an identity token and add it to the HTTP request as part of an - Authorization header. - - Args: - url: The url or target audience to obtain the ID token for. - Examples: http://www.example.com - """ - - request = google.auth.transport.requests.Request() - # Set the target audience. - # Setting "use_metadata_identity_endpoint" to "True" will make the request use the default application - # credentials. Optionally, you can also specify a specific service account to use by mentioning - # the service_account_email. - credentials = compute_engine.IDTokenCredentials( - request=request, target_audience=url, use_metadata_identity_endpoint=True - ) - - # Get the ID token. - # Once you've obtained the ID token, use it to make an authenticated call - # to the target audience. - credentials.refresh(request) - # print(credentials.token) - print("Generated ID token.") - -# [END auth_cloud_idtoken_metadata_server] diff --git a/samples/cloud-client/snippets/idtoken_from_service_account.py b/samples/cloud-client/snippets/idtoken_from_service_account.py deleted file mode 100644 index 912035b0b..000000000 --- a/samples/cloud-client/snippets/idtoken_from_service_account.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2022 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# [START auth_cloud_idtoken_service_account] - -import google.auth -import google.auth.transport.requests - -from google.oauth2 import service_account - - -def get_idToken_from_serviceaccount(json_credential_path: str, target_audience: str): - """ - TODO(Developer): Replace the below variables before running the code. - - *NOTE*: - Using service account keys introduces risk; they are long-lived, and can be used by anyone - that obtains the key. Proper rotation and storage reduce this risk but do not eliminate it. - For these reasons, you should consider an alternative approach that - does not use a service account key. Several alternatives to service account keys - are described here: - https://cloud.google.com/docs/authentication/external/set-up-adc - - Args: - json_credential_path: Path to the service account json credential file. - target_audience: The url or target audience to obtain the ID token for. - Examples: http://www.abc.com - """ - - # Obtain the id token by providing the json file path and target audience. - credentials = service_account.IDTokenCredentials.from_service_account_file( - filename=json_credential_path, - target_audience=target_audience) - - request = google.auth.transport.requests.Request() - credentials.refresh(request) - print("Generated ID token.") - -# [END auth_cloud_idtoken_service_account] diff --git a/samples/cloud-client/snippets/noxfile.py b/samples/cloud-client/snippets/noxfile.py deleted file mode 100644 index 3cdf3cf3b..000000000 --- a/samples/cloud-client/snippets/noxfile.py +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright 2019 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import pathlib - -import nox - -CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() - -# https://github.com/psf/black/issues/2964, pin click version to 8.0.4 to -# avoid incompatiblity with black. -CLICK_VERSION = "click==8.0.4" -BLACK_VERSION = "black==19.3b0" -BLACK_PATHS = [ - "google", - "tests", - "tests_async", - "noxfile.py", - "setup.py", - "docs/conf.py", -] - - -# Error if a python version is missing -nox.options.error_on_missing_interpreters = True - -# -# Style Checks -# - - -# Linting with flake8. -# -# We ignore the following rules: -# E203: whitespace before ‘:’ -# E266: too many leading ‘#’ for block comment -# E501: line too long -# I202: Additional newline in a section of imports -# -# We also need to specify the rules which are ignored by default: -# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] -FLAKE8_COMMON_ARGS = [ - "--show-source", - "--builtin=gettext", - "--max-complexity=20", - "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", - "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", - "--max-line-length=88", -] - - -@nox.session(python=["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]) -def unit(session): - # constraints_path = str( - # CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" - # ) - session.install("-r", "requirements.txt") - # session.install("-e", ".") - session.run( - "pytest", - f"--junitxml=unit_{session.python}_sponge_log.xml", - "snippets_test.py", - # "tests_async", - ) - - -@nox.session -def lint(session: nox.sessions.Session) -> None: - session.install("flake8") - - args = FLAKE8_COMMON_ARGS + [ - ".", - ] - session.run("flake8", *args) diff --git a/samples/cloud-client/snippets/noxfile_config.py b/samples/cloud-client/snippets/noxfile_config.py deleted file mode 100644 index e892b338f..000000000 --- a/samples/cloud-client/snippets/noxfile_config.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2022 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Default TEST_CONFIG_OVERRIDE for python repos. - -# You can copy this file into your directory, then it will be inported from -# the noxfile.py. - -# The source of truth: -# https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/noxfile_config.py - -TEST_CONFIG_OVERRIDE = { - # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7"], - # Old samples are opted out of enforcing Python type hints - # All new samples should feature them - "enforce_type_hints": True, - # An envvar key for determining the project id to use. Change it - # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a - # build specific Cloud project. You can also use your own string - # to use your own Cloud project. - # "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", - "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", - # A dictionary you want to inject into your test. Don't put any - # secrets here. These values will override predefined values. - "envs": {}, -} diff --git a/samples/cloud-client/snippets/requirements.txt b/samples/cloud-client/snippets/requirements.txt deleted file mode 100644 index 0729ffd9e..000000000 --- a/samples/cloud-client/snippets/requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -google-cloud-compute==1.43.0 -google-cloud-storage==3.9.0 -google-auth==2.48.0 -pytest===8.4.2; python_version == '3.9' -pytest==9.0.2; python_version > '3.9' -boto3>=1.26.0 -requests==2.32.5 -python-dotenv==1.2.1 diff --git a/samples/cloud-client/snippets/snippets_test.py b/samples/cloud-client/snippets/snippets_test.py deleted file mode 100644 index 180882843..000000000 --- a/samples/cloud-client/snippets/snippets_test.py +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright 2022 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -import re - -from _pytest.capture import CaptureFixture - -import authenticate_explicit_with_adc -import authenticate_implicit_with_adc -import idtoken_from_metadata_server -import idtoken_from_service_account -# from system_tests.noxfile import SERVICE_ACCOUNT_FILE -import verify_google_idtoken - -import google -from google.oauth2 import service_account -import google.auth.transport.requests -import os - -CREDENTIALS, PROJECT = google.auth.default() -SERVICE_ACCOUNT_FILE = os.getenv("GOOGLE_APPLICATION_CREDENTIALS") - - -def test_authenticate_explicit_with_adc(capsys: CaptureFixture): - authenticate_explicit_with_adc.authenticate_explicit_with_adc() - out, err = capsys.readouterr() - assert re.search("Listed all storage buckets.", out) - - -def test_authenticate_implicit_with_adc(capsys: CaptureFixture): - authenticate_implicit_with_adc.authenticate_implicit_with_adc(PROJECT) - out, err = capsys.readouterr() - assert re.search("Listed all storage buckets.", out) - - -def test_idtoken_from_metadata_server(capsys: CaptureFixture): - idtoken_from_metadata_server.idtoken_from_metadata_server("https://www.google.com") - out, err = capsys.readouterr() - assert re.search("Generated ID token.", out) - - -def test_idtoken_from_service_account(capsys: CaptureFixture): - idtoken_from_service_account.get_idToken_from_serviceaccount( - SERVICE_ACCOUNT_FILE, - "iap.googleapis.com") - out, err = capsys.readouterr() - assert re.search("Generated ID token.", out) - - -def test_verify_google_idtoken(): - idtoken = get_idtoken_from_service_account(SERVICE_ACCOUNT_FILE, "iap.googleapis.com") - - verify_google_idtoken.verify_google_idtoken( - idtoken, - "iap.googleapis.com", - "https://www.googleapis.com/oauth2/v3/certs" - ) - - -def get_idtoken_from_service_account(json_credential_path: str, target_audience: str): - credentials = service_account.IDTokenCredentials.from_service_account_file( - filename=json_credential_path, - target_audience=target_audience) - - request = google.auth.transport.requests.Request() - credentials.refresh(request) - return credentials.token diff --git a/samples/cloud-client/snippets/verify_google_idtoken.py b/samples/cloud-client/snippets/verify_google_idtoken.py deleted file mode 100644 index 35b88c99e..000000000 --- a/samples/cloud-client/snippets/verify_google_idtoken.py +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright 2022 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# [START auth_cloud_verify_google_idtoken] - -import google -import google.auth.transport.requests -from google.oauth2 import id_token - - -def verify_google_idtoken(idtoken: str, audience="iap.googleapis.com", - jwk_url="https://www.googleapis.com/oauth2/v3/certs"): - """ - Verifies the obtained Google id token. This is done at the receiving end of the OIDC endpoint. - The most common use case for verifying the ID token is when you are protecting - your own APIs with IAP. Google services already verify credentials as a platform, - so verifying ID tokens before making Google API calls is usually unnecessary. - - Args: - idtoken: The Google ID token to verify. - - audience: The service name for which the id token is requested. Service name refers to the - logical identifier of an API service, such as "iap.googleapis.com". - - jwk_url: To verify id tokens, get the Json Web Key endpoint (jwk). - OpenID Connect allows the use of a "Discovery document," a JSON document found at a - well-known location containing key-value pairs which provide details about the - OpenID Connect provider's configuration. - For more information on validating the jwt, see: - https://developers.google.com/identity/protocols/oauth2/openid-connect#validatinganidtoken - - Here, we validate Google's token using Google's OpenID Connect service (jwkUrl). - For more information on jwk,see: - https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-key-sets - """ - - request = google.auth.transport.requests.Request() - # Set the parameters and verify the token. - # Setting "certs_url" is optional. When verifying a Google ID token, this is set by default. - result = id_token.verify_token(idtoken, request, audience, clock_skew_in_seconds=10) - - # Verify that the token contains subject and email claims. - # Get the User id. - if not result["sub"] is None: - print(f"User id: {result['sub']}") - # Optionally, if "INCLUDE_EMAIL" was set in the token options, check if the - # email was verified. - if result['email_verified'] == "True": - print(f"Email verified {result['email']}") - -# [END auth_cloud_verify_google_idtoken]