diff --git a/auth/cloud-client-temp/noxfile.py b/auth/cloud-client-temp/noxfile.py deleted file mode 100644 index 3cdf3cf3bdb..00000000000 --- a/auth/cloud-client-temp/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/auth/cloud-client-temp/requirements.txt b/auth/cloud-client-temp/requirements.txt deleted file mode 100644 index 8dafe853ea0..00000000000 --- a/auth/cloud-client-temp/requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -google-cloud-compute==1.42.0 -google-cloud-storage==3.8.0 -google-auth==2.47.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/auth/cloud-client-temp/snippets_test.py b/auth/cloud-client-temp/snippets_test.py deleted file mode 100644 index 940f27e553c..00000000000 --- a/auth/cloud-client-temp/snippets_test.py +++ /dev/null @@ -1,76 +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. -import os -import re - -from _pytest.capture import CaptureFixture -import google -import google.auth.transport.requests -from google.oauth2 import service_account - -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 - -CREDENTIALS, PROJECT = google.auth.default() -SERVICE_ACCOUNT_FILE = os.getenv("GOOGLE_APPLICATION_CREDENTIALS") - - -def test_authenticate_explicit_with_adc(capsys: CaptureFixture) -> None: - 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) -> None: - 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) -> None: - 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) -> None: - 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() -> None: - 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) -> 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/auth/cloud-client-temp/authenticate_explicit_with_adc.py b/auth/cloud-client/authenticate_explicit_with_adc.py similarity index 100% rename from auth/cloud-client-temp/authenticate_explicit_with_adc.py rename to auth/cloud-client/authenticate_explicit_with_adc.py diff --git a/auth/cloud-client-temp/authenticate_implicit_with_adc.py b/auth/cloud-client/authenticate_implicit_with_adc.py similarity index 100% rename from auth/cloud-client-temp/authenticate_implicit_with_adc.py rename to auth/cloud-client/authenticate_implicit_with_adc.py diff --git a/auth/cloud-client-temp/custom_aws_supplier.py b/auth/cloud-client/custom_aws_supplier.py similarity index 100% rename from auth/cloud-client-temp/custom_aws_supplier.py rename to auth/cloud-client/custom_aws_supplier.py diff --git a/auth/cloud-client-temp/custom_okta_supplier.py b/auth/cloud-client/custom_okta_supplier.py similarity index 100% rename from auth/cloud-client-temp/custom_okta_supplier.py rename to auth/cloud-client/custom_okta_supplier.py diff --git a/auth/cloud-client-temp/idtoken_from_impersonated_credentials.py b/auth/cloud-client/idtoken_from_impersonated_credentials.py similarity index 100% rename from auth/cloud-client-temp/idtoken_from_impersonated_credentials.py rename to auth/cloud-client/idtoken_from_impersonated_credentials.py diff --git a/auth/cloud-client-temp/idtoken_from_metadata_server.py b/auth/cloud-client/idtoken_from_metadata_server.py similarity index 100% rename from auth/cloud-client-temp/idtoken_from_metadata_server.py rename to auth/cloud-client/idtoken_from_metadata_server.py diff --git a/auth/cloud-client-temp/idtoken_from_service_account.py b/auth/cloud-client/idtoken_from_service_account.py similarity index 100% rename from auth/cloud-client-temp/idtoken_from_service_account.py rename to auth/cloud-client/idtoken_from_service_account.py diff --git a/auth/cloud-client-temp/noxfile_config.py b/auth/cloud-client/noxfile_config.py similarity index 100% rename from auth/cloud-client-temp/noxfile_config.py rename to auth/cloud-client/noxfile_config.py diff --git a/auth/cloud-client/requirements-test.txt b/auth/cloud-client/requirements-test.txt deleted file mode 100644 index 15d066af319..00000000000 --- a/auth/cloud-client/requirements-test.txt +++ /dev/null @@ -1 +0,0 @@ -pytest==8.2.0 diff --git a/auth/cloud-client/requirements.txt b/auth/cloud-client/requirements.txt index 3f1d3521dc4..8dafe853ea0 100644 --- a/auth/cloud-client/requirements.txt +++ b/auth/cloud-client/requirements.txt @@ -1,2 +1,8 @@ -google-cloud-storage==2.9.0; python_version < '3.7' -google-cloud-storage==2.9.0; python_version > '3.6' +google-cloud-compute==1.42.0 +google-cloud-storage==3.8.0 +google-auth==2.47.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/auth/cloud-client/snippets.py b/auth/cloud-client/snippets.py deleted file mode 100644 index 274d3047e04..00000000000 --- a/auth/cloud-client/snippets.py +++ /dev/null @@ -1,156 +0,0 @@ -# Copyright 2016 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. - -"""Demonstrates how to authenticate to Google Cloud Platform APIs using -the Google Cloud Client Libraries.""" - -import argparse - - -# [START auth_cloud_implicit] -def implicit(): - from google.cloud import storage - - # If you don't specify credentials when constructing the client, the - # client library will look for credentials in the environment. - storage_client = storage.Client() - - # Make an authenticated API request - buckets = list(storage_client.list_buckets()) - print(buckets) - - -# [END auth_cloud_implicit] - - -# [START auth_cloud_explicit] -def explicit(): - from google.cloud import storage - - # Explicitly use service account credentials by specifying the private key - # file. - storage_client = storage.Client.from_service_account_json("service_account.json") - - # Make an authenticated API request - buckets = list(storage_client.list_buckets()) - print(buckets) - - -# [END auth_cloud_explicit] - - -# [START auth_cloud_explicit_compute_engine] -def explicit_compute_engine(project): - from google.auth import compute_engine - from google.cloud import storage - - # Explicitly use Compute Engine credentials. These credentials are - # available on Compute Engine, App Engine Flexible, and Kubernetes Engine. - credentials = compute_engine.Credentials() - - # Create the client using the credentials and specifying a project ID. - storage_client = storage.Client(credentials=credentials, project=project) - - # Make an authenticated API request - buckets = list(storage_client.list_buckets()) - print(buckets) - - -# [END auth_cloud_explicit_compute_engine] - - -# [START auth_cloud_accesstoken_impersonated_credentials] -def accesstoken_from_impersonated_credentials( - impersonated_service_account: str, scope: str -): - from google.auth import impersonated_credentials - import google.auth.transport.requests - - """ - Use a service account (SA1) to impersonate another service account (SA2) - and obtain an ID token for the impersonated account. - To obtain a 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 - """ - - # 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, - ) - - # Get the OAuth2 token. - # Once you've obtained the OAuth2 token, use it to make an authenticated call - # to the target audience. - request = google.auth.transport.requests.Request() - target_credentials.refresh(request) - # The token field is target_credentials.token. - print("Generated OAuth2 token.") - - -# [END auth_cloud_accesstoken_impersonated_credentials] - - -if __name__ == "__main__": - parser = argparse.ArgumentParser( - description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter - ) - - subparsers = parser.add_subparsers(dest="command") - subparsers.add_parser("implicit", help=implicit.__doc__) - subparsers.add_parser("explicit", help=explicit.__doc__) - explicit_gce_parser = subparsers.add_parser( - "explicit_compute_engine", help=explicit_compute_engine.__doc__ - ) - explicit_gce_parser.add_argument("project") - accesstoken_parser = subparsers.add_parser( - "accesstoken_from_impersonated_credentials", - help=accesstoken_from_impersonated_credentials.__doc__, - ) - accesstoken_parser.add_argument("impersonated_service_account") - accesstoken_parser.add_argument("scope") - - args = parser.parse_args() - - if args.command == "implicit": - implicit() - elif args.command == "explicit": - explicit() - elif args.command == "explicit_compute_engine": - explicit_compute_engine(args.project) - elif args.command == "accesstoken_from_impersonated_credentials": - accesstoken_from_impersonated_credentials( - args.impersonated_service_account, args.scope - ) diff --git a/auth/cloud-client/snippets_test.py b/auth/cloud-client/snippets_test.py index fc02b8f3984..940f27e553c 100644 --- a/auth/cloud-client/snippets_test.py +++ b/auth/cloud-client/snippets_test.py @@ -1,54 +1,76 @@ -# Copyright 2016 Google Inc. +# 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 +# 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 os -from unittest import mock +import re -import google.auth +from _pytest.capture import CaptureFixture +import google +import google.auth.transport.requests +from google.oauth2 import service_account -import snippets +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 +CREDENTIALS, PROJECT = google.auth.default() +SERVICE_ACCOUNT_FILE = os.getenv("GOOGLE_APPLICATION_CREDENTIALS") -def test_implicit(): - snippets.implicit() +def test_authenticate_explicit_with_adc(capsys: CaptureFixture) -> None: + authenticate_explicit_with_adc.authenticate_explicit_with_adc() + out, err = capsys.readouterr() + assert re.search("Listed all storage buckets.", out) -def test_explicit(): - with open(os.environ["GOOGLE_APPLICATION_CREDENTIALS"]) as creds_file: - creds_file_data = creds_file.read() - open_mock = mock.mock_open(read_data=creds_file_data) +def test_authenticate_implicit_with_adc(capsys: CaptureFixture) -> None: + authenticate_implicit_with_adc.authenticate_implicit_with_adc(PROJECT) + out, err = capsys.readouterr() + assert re.search("Listed all storage buckets.", out) - with mock.patch("io.open", open_mock): - snippets.explicit() +def test_idtoken_from_metadata_server(capsys: CaptureFixture) -> None: + 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_explicit_compute_engine(): - adc, project = google.auth.default() - credentials_patch = mock.patch( - "google.auth.compute_engine.Credentials", return_value=adc - ) - with credentials_patch: - snippets.explicit_compute_engine(project) +def test_idtoken_from_service_account(capsys: CaptureFixture) -> None: + 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_accesstoken_from_impersonated_credentials(): - impersonated_service_account = ( - "auth-samples-testing@python-docs-samples-tests.iam.gserviceaccount.com" - ) - scope = "https://www.googleapis.com/auth/cloud-platform" - snippets.accesstoken_from_impersonated_credentials( - impersonated_service_account, scope +def test_verify_google_idtoken() -> None: + 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) -> 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/auth/cloud-client-temp/verify_google_idtoken.py b/auth/cloud-client/verify_google_idtoken.py similarity index 100% rename from auth/cloud-client-temp/verify_google_idtoken.py rename to auth/cloud-client/verify_google_idtoken.py