From dde6876154d6e7ff43dbbf7b75c5205eadd679a5 Mon Sep 17 00:00:00 2001 From: Carl Lundin <108372512+clundin25@users.noreply.github.com> Date: Tue, 14 May 2024 11:24:24 -0700 Subject: [PATCH 01/89] chore: Add auth team as admin. (#1405) --- .github/sync-repo-settings.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index 7b91e263c..e64489953 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -117,6 +117,6 @@ permissionRules: - team: yoshi-admins permission: admin - team: googleapis-auth - permission: push + permission: admin - team: aion-sdk permission: push From 0d9688462e4ed5942d6f24fa7aae9eac765dc642 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Wed, 29 May 2024 21:23:37 +0200 Subject: [PATCH 02/89] chore(deps): update dependency org.sonatype.plugins:nexus-staging-maven-plugin to v1.7.0 (#1410) --- bom/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bom/pom.xml b/bom/pom.xml index 46d81ffb2..0142d451a 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -72,7 +72,7 @@ org.sonatype.plugins nexus-staging-maven-plugin - 1.6.13 + 1.7.0 true ossrh diff --git a/pom.xml b/pom.xml index 199be0190..c33e64c70 100644 --- a/pom.xml +++ b/pom.xml @@ -152,7 +152,7 @@ org.sonatype.plugins nexus-staging-maven-plugin - 1.6.13 + 1.7.0 true ossrh From 45aca7d5e263a7da003aef8c181f4e442ad0a380 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Wed, 29 May 2024 21:30:49 +0200 Subject: [PATCH 03/89] chore(deps): update dependency com.google.cloud:libraries-bom to v26.40.0 (#1404) Co-authored-by: Diego Marquez --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 1eda7c3f3..7fa3862c4 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -30,7 +30,7 @@ com.google.cloud libraries-bom - 26.38.0 + 26.40.0 pom import From 2aa2b855c10ceed9af9d267e48ee50211bfd1855 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Wed, 29 May 2024 21:35:29 +0200 Subject: [PATCH 04/89] chore(deps): update dependency com.google.appengine:appengine-api-1.0-sdk to v2.0.27 (#1403) Co-authored-by: Diego Marquez --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c33e64c70..75d148b79 100644 --- a/pom.xml +++ b/pom.xml @@ -72,7 +72,7 @@ 1.43.3 4.13.2 32.0.0-android - 2.0.26 + 2.0.27 3.0.2 false 2.27.1 From d92b421c8fa9c22dda47b49f5ebec7f6ac2658a9 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Wed, 29 May 2024 15:40:00 -0400 Subject: [PATCH 05/89] feat: [java] allow passing libraries_bom_version from env (#1967) (#1407) * feat: [java] allow passing libraries_bom_version from env * reformat Source-Link: https://github.com/googleapis/synthtool/commit/e36d2f164ca698f0264fb6f79ddc4b0fa024a940 Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-java:latest@sha256:31aa2ef27b071c2e7844b0eb1d5a24254daff06615b1b138b994dd6345c0b0ea Co-authored-by: Owl Bot Co-authored-by: Diego Marquez --- .github/.OwlBot.lock.yaml | 4 +-- .github/workflows/ci.yaml | 30 ++++++++++---------- .github/workflows/renovate_config_check.yaml | 2 +- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index db1099bec..f817c5f44 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -13,5 +13,5 @@ # limitations under the License. docker: image: gcr.io/cloud-devrel-public-resources/owlbot-java:latest - digest: sha256:084ad4c60551b075846bcb2405ec1c14b0d00ec1eb5503d4dd0d2a92cdc2d3e2 -# created: 2024-03-15T14:33:32.257974519Z + digest: sha256:31aa2ef27b071c2e7844b0eb1d5a24254daff06615b1b138b994dd6345c0b0ea +# created: 2024-05-17T15:15:57.6714113Z diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ae66b1973..b91fa381f 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -27,8 +27,8 @@ jobs: matrix: java: [11, 17, 21] steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: distribution: temurin java-version: ${{matrix.java}} @@ -41,8 +41,8 @@ jobs: name: "units (8)" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: java-version: 8 distribution: temurin @@ -51,7 +51,7 @@ jobs: # https://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#jvm run: echo "SUREFIRE_JVM_OPT=-Djvm=${JAVA_HOME}/bin/java" >> $GITHUB_ENV shell: bash - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: java-version: 17 distribution: temurin @@ -63,8 +63,8 @@ jobs: steps: - name: Support longpaths run: git config --system core.longpaths true - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: distribution: temurin java-version: 8 @@ -78,8 +78,8 @@ jobs: matrix: java: [17] steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: distribution: temurin java-version: ${{matrix.java}} @@ -88,8 +88,8 @@ jobs: javadoc: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: distribution: temurin java-version: 17 @@ -100,8 +100,8 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: distribution: temurin java-version: 11 @@ -112,8 +112,8 @@ jobs: clirr: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: distribution: temurin java-version: 8 diff --git a/.github/workflows/renovate_config_check.yaml b/.github/workflows/renovate_config_check.yaml index 87d8eb2be..7c5ec7865 100644 --- a/.github/workflows/renovate_config_check.yaml +++ b/.github/workflows/renovate_config_check.yaml @@ -14,7 +14,7 @@ jobs: uses: actions/checkout@v4 - name: Set up Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: '20' From f284676eaecd3e2df1982184fcc833b014c72b56 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 30 May 2024 17:07:55 +0200 Subject: [PATCH 06/89] chore(deps): update dependency com.google.cloud:google-iam-admin to v3.39.0 (#1401) Co-authored-by: Diego Marquez --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 7fa3862c4..19f9b90a4 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -50,7 +50,7 @@ com.google.cloud google-iam-admin - 3.37.0 + 3.39.0 From 34e0ac2227b6f37da7aa16d4a319d14e4acdb753 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 31 May 2024 20:36:20 +0200 Subject: [PATCH 07/89] chore(deps): update dependency com.google.errorprone:error_prone_annotations to v2.28.0 (#1413) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 75d148b79..58a627c0d 100644 --- a/pom.xml +++ b/pom.xml @@ -75,7 +75,7 @@ 2.0.27 3.0.2 false - 2.27.1 + 2.28.0 From bd6a2fe2c692f8c2fc5078fbf0d7b79d24b3c94d Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 31 May 2024 20:40:01 +0200 Subject: [PATCH 08/89] chore(deps): update dependency com.google.http-client:google-http-client-bom to v1.44.2 (#1379) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 58a627c0d..89aa8d56a 100644 --- a/pom.xml +++ b/pom.xml @@ -69,7 +69,7 @@ UTF-8 - 1.43.3 + 1.44.2 4.13.2 32.0.0-android 2.0.27 From f3c410596e6d43be5d97803f8084b0a09b6b185b Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 31 May 2024 20:47:49 +0200 Subject: [PATCH 09/89] chore(deps): update dependency com.google.guava:guava to v32.1.3-android (#1332) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 89aa8d56a..89f53abba 100644 --- a/pom.xml +++ b/pom.xml @@ -71,7 +71,7 @@ UTF-8 1.44.2 4.13.2 - 32.0.0-android + 32.1.3-android 2.0.27 3.0.2 false From 345ad716777e698b0d3834bf4818ef368dea1402 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 31 May 2024 20:48:41 +0200 Subject: [PATCH 10/89] chore(deps): update dependency com.google.cloud:google-cloud-shared-config to v1.8.0 (#1414) --- .kokoro/presubmit/graalvm-native-a.cfg | 2 +- .kokoro/presubmit/graalvm-native-b.cfg | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.kokoro/presubmit/graalvm-native-a.cfg b/.kokoro/presubmit/graalvm-native-a.cfg index 082c3035b..7124f6f15 100644 --- a/.kokoro/presubmit/graalvm-native-a.cfg +++ b/.kokoro/presubmit/graalvm-native-a.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_a:1.7.7" + value: "gcr.io/cloud-devrel-public-resources/graalvm_a:1.8.0" } env_vars: { diff --git a/.kokoro/presubmit/graalvm-native-b.cfg b/.kokoro/presubmit/graalvm-native-b.cfg index 75a3936cf..d0e6de053 100644 --- a/.kokoro/presubmit/graalvm-native-b.cfg +++ b/.kokoro/presubmit/graalvm-native-b.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_b:1.7.7" + value: "gcr.io/cloud-devrel-public-resources/graalvm_b:1.8.0" } env_vars: { diff --git a/pom.xml b/pom.xml index 89f53abba..fdab14572 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ com.google.cloud google-cloud-shared-config - 1.7.7 + 1.8.0 From f0efe454dc7f1d1dab713ddaeecd5bde08f5fee3 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 31 May 2024 21:09:11 +0200 Subject: [PATCH 11/89] chore(deps): update dependency com.google.guava:guava to v33 (#1398) * chore(deps): update dependency com.google.guava:guava to v33 * exclude j2ocb --------- Co-authored-by: Diego Marquez --- pom.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fdab14572..468a965bb 100644 --- a/pom.xml +++ b/pom.xml @@ -71,7 +71,7 @@ UTF-8 1.44.2 4.13.2 - 32.1.3-android + 33.2.0-android 2.0.27 3.0.2 false @@ -111,6 +111,12 @@ com.google.guava guava ${project.guava.version} + + + com.google.j2objc + j2objc-annotations + + com.google.code.findbugs From ecc754affecbad3287771c5943c3776f055bd64d Mon Sep 17 00:00:00 2001 From: Jin Date: Mon, 10 Jun 2024 10:44:58 -0700 Subject: [PATCH 12/89] chore: fix CI errors on javadoc (#1422) * chore: fix javadoc on doc string checkes * fix lint * address comments * remove unused

tag * fix lint --- oauth2_http/java/com/google/auth/oauth2/AwsCredentials.java | 3 ++- .../google/auth/oauth2/AwsSecurityCredentialsSupplier.java | 2 +- .../auth/oauth2/FileIdentityPoolSubjectTokenSupplier.java | 2 +- .../java/com/google/auth/oauth2/GoogleCredentials.java | 4 ++-- .../auth/oauth2/InternalAwsSecurityCredentialsSupplier.java | 2 +- .../com/google/auth/oauth2/ServiceAccountCredentials.java | 4 ++-- .../auth/oauth2/UrlIdentityPoolSubjectTokenSupplier.java | 2 +- 7 files changed, 10 insertions(+), 9 deletions(-) diff --git a/oauth2_http/java/com/google/auth/oauth2/AwsCredentials.java b/oauth2_http/java/com/google/auth/oauth2/AwsCredentials.java index b8594cb6d..cc270e2e6 100644 --- a/oauth2_http/java/com/google/auth/oauth2/AwsCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/AwsCredentials.java @@ -268,7 +268,8 @@ public Builder setAwsSecurityCredentialsSupplier( * Sets the AWS regional credential verification URL. If set, will override any credential * verification URL provided in the credential source. If not set, the credential verification * URL will default to - * https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15" + * + *

* * @param regionalCredentialVerificationUrlOverride the AWS credential verification url to set. * @return this {@code Builder} object diff --git a/oauth2_http/java/com/google/auth/oauth2/AwsSecurityCredentialsSupplier.java b/oauth2_http/java/com/google/auth/oauth2/AwsSecurityCredentialsSupplier.java index a6e01e26f..f7f219923 100644 --- a/oauth2_http/java/com/google/auth/oauth2/AwsSecurityCredentialsSupplier.java +++ b/oauth2_http/java/com/google/auth/oauth2/AwsSecurityCredentialsSupplier.java @@ -35,7 +35,7 @@ import java.io.Serializable; /** - * Supplier for retrieving AWS Security credentials for {@Link AwsCredentials} to exchange for GCP + * Supplier for retrieving AWS Security credentials for {@link AwsCredentials} to exchange for GCP * access tokens. */ public interface AwsSecurityCredentialsSupplier extends Serializable { diff --git a/oauth2_http/java/com/google/auth/oauth2/FileIdentityPoolSubjectTokenSupplier.java b/oauth2_http/java/com/google/auth/oauth2/FileIdentityPoolSubjectTokenSupplier.java index c527e96b3..392d8e5ee 100644 --- a/oauth2_http/java/com/google/auth/oauth2/FileIdentityPoolSubjectTokenSupplier.java +++ b/oauth2_http/java/com/google/auth/oauth2/FileIdentityPoolSubjectTokenSupplier.java @@ -47,7 +47,7 @@ import java.nio.file.Paths; /** - * Internal provider for retrieving subject tokens for {@Link IdentityPoolCredentials} to exchange + * Internal provider for retrieving subject tokens for {@link IdentityPoolCredentials} to exchange * for GCP access tokens via a local file. */ class FileIdentityPoolSubjectTokenSupplier implements IdentityPoolSubjectTokenSupplier { diff --git a/oauth2_http/java/com/google/auth/oauth2/GoogleCredentials.java b/oauth2_http/java/com/google/auth/oauth2/GoogleCredentials.java index 41388a9e8..c0c8c3035 100644 --- a/oauth2_http/java/com/google/auth/oauth2/GoogleCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/GoogleCredentials.java @@ -329,8 +329,8 @@ public GoogleCredentials(AccessToken accessToken) { } /** - * Constructor that relies on a {@link GoogleCredential.Builder} to provide all the necessary - * field values for initialization. + * Constructor that relies on a {@link Builder} to provide all the necessary field values for + * initialization. * * @param builder an instance of a builder */ diff --git a/oauth2_http/java/com/google/auth/oauth2/InternalAwsSecurityCredentialsSupplier.java b/oauth2_http/java/com/google/auth/oauth2/InternalAwsSecurityCredentialsSupplier.java index 90df85b40..b4140fe8e 100644 --- a/oauth2_http/java/com/google/auth/oauth2/InternalAwsSecurityCredentialsSupplier.java +++ b/oauth2_http/java/com/google/auth/oauth2/InternalAwsSecurityCredentialsSupplier.java @@ -50,7 +50,7 @@ import javax.annotation.Nullable; /** - * Internal provider for retrieving AWS security credentials for {@Link AwsCredentials} to exchange + * Internal provider for retrieving AWS security credentials for {@link AwsCredentials} to exchange * for GCP access tokens. The credentials are retrieved either via environment variables or metadata * endpoints. */ diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java index a133b2e5b..1bd85749f 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java @@ -641,7 +641,7 @@ public ServiceAccountCredentials createWithCustomLifetime(int lifetime) { /** * Clones the service account with a new useJwtAccessWithScope value. This flag will be ignored if - * universeDomain field is different from {@link Credentials.GOOGLE_DEFAULT_UNIVERSE}. + * universeDomain field is different from {@link Credentials#GOOGLE_DEFAULT_UNIVERSE}. * * @param useJwtAccessWithScope whether self-signed JWT with scopes should be used * @return the cloned service account credentials with the given useJwtAccessWithScope @@ -1119,7 +1119,7 @@ public Builder setLifetime(int lifetime) { /** * Sets the useJwtAccessWithScope flag. This flag will be ignored if universeDomain field is - * different from {@link Credentials.GOOGLE_DEFAULT_UNIVERSE}. + * different from {@link Credentials#GOOGLE_DEFAULT_UNIVERSE}. */ @CanIgnoreReturnValue public Builder setUseJwtAccessWithScope(boolean useJwtAccessWithScope) { diff --git a/oauth2_http/java/com/google/auth/oauth2/UrlIdentityPoolSubjectTokenSupplier.java b/oauth2_http/java/com/google/auth/oauth2/UrlIdentityPoolSubjectTokenSupplier.java index b8fc037c7..788911a6c 100644 --- a/oauth2_http/java/com/google/auth/oauth2/UrlIdentityPoolSubjectTokenSupplier.java +++ b/oauth2_http/java/com/google/auth/oauth2/UrlIdentityPoolSubjectTokenSupplier.java @@ -42,7 +42,7 @@ import java.io.IOException; /** - * Provider for retrieving subject tokens for {@Link IdentityPoolCredentials} to exchange for GCP + * Provider for retrieving subject tokens for {@link IdentityPoolCredentials} to exchange for GCP * access tokens. The subject token is retrieved by calling a URL that returns the token. */ class UrlIdentityPoolSubjectTokenSupplier implements IdentityPoolSubjectTokenSupplier { From 80dfde7b9dae24469b9a39454c547282df96bfb4 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 9 Jul 2024 15:57:41 +0200 Subject: [PATCH 13/89] chore(deps): update dependency com.google.cloud:libraries-bom to v26.43.0 (#1425) --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 19f9b90a4..f51182302 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -30,7 +30,7 @@ com.google.cloud libraries-bom - 26.40.0 + 26.43.0 pom import From da2f732ffcc14b89e3f82f35b8e48ec6e3417783 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 9 Jul 2024 16:13:33 +0200 Subject: [PATCH 14/89] chore(deps): update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.7.0 (#1417) Co-authored-by: Min Zhu --- bom/pom.xml | 2 +- pom.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bom/pom.xml b/bom/pom.xml index 0142d451a..d4e9aef5e 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -83,7 +83,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.6.3 + 3.7.0 true diff --git a/pom.xml b/pom.xml index 468a965bb..27754adb3 100644 --- a/pom.xml +++ b/pom.xml @@ -182,7 +182,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.6.3 + 3.7.0 8 false @@ -332,7 +332,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.6.3 + 3.7.0 html @@ -400,7 +400,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.6.3 + 3.7.0 attach-javadocs From 8f1c4a70321fdaf5ae2acfdf0758660ddce3c2dc Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 9 Jul 2024 21:08:19 +0200 Subject: [PATCH 15/89] chore(deps): update dependency org.apache.maven.plugins:maven-checkstyle-plugin to v3.4.0 (#1418) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [org.apache.maven.plugins:maven-checkstyle-plugin](https://maven.apache.org/plugins/) | `3.3.1` -> `3.4.0` | [![age](https://developer.mend.io/api/mc/badges/age/maven/org.apache.maven.plugins:maven-checkstyle-plugin/3.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/org.apache.maven.plugins:maven-checkstyle-plugin/3.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/org.apache.maven.plugins:maven-checkstyle-plugin/3.3.1/3.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/org.apache.maven.plugins:maven-checkstyle-plugin/3.3.1/3.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/googleapis/google-auth-library-java). --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 27754adb3..933ce00b6 100644 --- a/pom.xml +++ b/pom.xml @@ -249,7 +249,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.3.1 + 3.4.0 checkstyle From 008daa18471e70fa2e1fc0c2d8dac86e69369070 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 9 Jul 2024 21:17:26 +0200 Subject: [PATCH 16/89] chore(deps): update dependency com.google.appengine:appengine-api-1.0-sdk to v2.0.29 (#1420) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 933ce00b6..4b1506817 100644 --- a/pom.xml +++ b/pom.xml @@ -72,7 +72,7 @@ 1.44.2 4.13.2 33.2.0-android - 2.0.27 + 2.0.29 3.0.2 false 2.28.0 From ade1d0679d50c59f7b3c48c93693a01f5917506d Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 9 Jul 2024 21:24:18 +0200 Subject: [PATCH 17/89] chore(deps): update dependency com.google.cloud:google-iam-admin to v3.41.0 (#1423) --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index f51182302..7ba334f5e 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -50,7 +50,7 @@ com.google.cloud google-iam-admin - 3.39.0 + 3.41.0 From c2eaacb58ecf2f76404b15d007349bbb06a0b166 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 9 Jul 2024 21:33:06 +0200 Subject: [PATCH 18/89] chore(deps): update dependency org.apache.maven.plugins:maven-dependency-plugin to v3.7.1 (#1424) Co-authored-by: Min Zhu Co-authored-by: Lawrence Qiu --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4b1506817..90191f56d 100644 --- a/pom.xml +++ b/pom.xml @@ -219,7 +219,7 @@ org.apache.maven.plugins maven-dependency-plugin - 3.6.1 + 3.7.1 org.codehaus.mojo From 36d035c0fdfd83bc998f8f425b708981534d5ad7 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 9 Jul 2024 21:40:28 +0200 Subject: [PATCH 19/89] chore(deps): update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.3.0 (#1426) Co-authored-by: Lawrence Qiu --- oauth2_http/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oauth2_http/pom.xml b/oauth2_http/pom.xml index c14201002..b90fdb6ab 100644 --- a/oauth2_http/pom.xml +++ b/oauth2_http/pom.xml @@ -152,7 +152,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.2.5 + 3.3.0 1200 sponge_log From 1c8ccfdec40075f76f77120c83f2c9089ea1b7b2 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 9 Jul 2024 21:50:08 +0200 Subject: [PATCH 20/89] chore(deps): update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.3.0 (#1427) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 90191f56d..806350a0a 100644 --- a/pom.xml +++ b/pom.xml @@ -211,7 +211,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.2.5 + 3.3.0 sponge_log From dc9f604be8672873bf12ae2e349c2c170fdcd270 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 9 Jul 2024 22:03:25 +0200 Subject: [PATCH 21/89] chore(deps): update dependency org.apache.maven.plugins:maven-jar-plugin to v3.4.2 (#1431) Co-authored-by: Min Zhu Co-authored-by: Lawrence Qiu --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 806350a0a..71d9ee2c0 100644 --- a/pom.xml +++ b/pom.xml @@ -199,7 +199,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.4.1 + 3.4.2 From 79592a4cc546efaa7d605c66dcb07bbacf5b07bc Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 9 Jul 2024 22:09:34 +0200 Subject: [PATCH 22/89] chore(deps): update dependency com.google.cloud:google-cloud-shared-config to v1.9.0 (#1434) Co-authored-by: Min Zhu --- .kokoro/presubmit/graalvm-native-a.cfg | 2 +- .kokoro/presubmit/graalvm-native-b.cfg | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.kokoro/presubmit/graalvm-native-a.cfg b/.kokoro/presubmit/graalvm-native-a.cfg index 7124f6f15..be75a7e2a 100644 --- a/.kokoro/presubmit/graalvm-native-a.cfg +++ b/.kokoro/presubmit/graalvm-native-a.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_a:1.8.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_a:1.9.0" } env_vars: { diff --git a/.kokoro/presubmit/graalvm-native-b.cfg b/.kokoro/presubmit/graalvm-native-b.cfg index d0e6de053..4f0dc3a59 100644 --- a/.kokoro/presubmit/graalvm-native-b.cfg +++ b/.kokoro/presubmit/graalvm-native-b.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_b:1.8.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_b:1.9.0" } env_vars: { diff --git a/pom.xml b/pom.xml index 71d9ee2c0..7d257e2ea 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ com.google.cloud google-cloud-shared-config - 1.8.0 + 1.9.0 From 32232e9972771507f239dbb3d90c5811d1f4c50f Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 9 Jul 2024 22:15:09 +0200 Subject: [PATCH 23/89] chore(deps): update dependency com.google.truth:truth to v1.4.3 (#1429) --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 7ba334f5e..7b44d45b0 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -74,7 +74,7 @@ truth com.google.truth test - 1.4.2 + 1.4.3 From 12a40b852556d978e5f92e3b18ad91614340e461 Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Tue, 9 Jul 2024 16:23:52 -0400 Subject: [PATCH 24/89] chore: add dependency dashboard to renovate config (#1430) Co-authored-by: Lawrence Qiu --- renovate.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/renovate.json b/renovate.json index a360a2141..7b57a41af 100644 --- a/renovate.json +++ b/renovate.json @@ -8,7 +8,8 @@ ":automergeDisabled", ":ignoreModulesAndTests", ":maintainLockFilesDisabled", - ":autodetectPinVersions" + ":autodetectPinVersions", + ":dependencyDashboard" ], "ignorePaths": [".kokoro/requirements.txt"], "customManagers": [ From aac53ff0c88cf902831852c3c765b64cb5791616 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 9 Jul 2024 22:29:32 +0200 Subject: [PATCH 25/89] chore(deps): update dependency com.google.guava:guava to v33.2.1-android (#1416) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7d257e2ea..2ab3cf3b1 100644 --- a/pom.xml +++ b/pom.xml @@ -71,7 +71,7 @@ UTF-8 1.44.2 4.13.2 - 33.2.0-android + 33.2.1-android 2.0.29 3.0.2 false From 2cfce1e4fc9d3b0010f5328b2a4ba4f72b4fac1c Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 16:52:31 -0400 Subject: [PATCH 26/89] chore(main): release 1.24.0 (#1367) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Lawrence Qiu --- CHANGELOG.md | 21 +++++++++++++++++++++ appengine/pom.xml | 2 +- bom/pom.xml | 2 +- credentials/pom.xml | 2 +- oauth2_http/pom.xml | 2 +- pom.xml | 2 +- versions.txt | 12 ++++++------ 7 files changed, 32 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a69d4aa4..993c838ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ # Changelog +## [1.24.0](https://github.com/googleapis/google-auth-library-java/compare/v1.23.0...v1.24.0) (2024-07-09) + + +### Features + +* [java] allow passing libraries_bom_version from env ([#1967](https://github.com/googleapis/google-auth-library-java/issues/1967)) ([#1407](https://github.com/googleapis/google-auth-library-java/issues/1407)) ([d92b421](https://github.com/googleapis/google-auth-library-java/commit/d92b421c8fa9c22dda47b49f5ebec7f6ac2658a9)) +* Next release from main branch is 1.21.0 ([#1372](https://github.com/googleapis/google-auth-library-java/issues/1372)) ([23c3cbe](https://github.com/googleapis/google-auth-library-java/commit/23c3cbe70fdce49a3075e15ba965739704a87ace)) + + +### Bug Fixes + +* Makes default token url universe aware ([#1383](https://github.com/googleapis/google-auth-library-java/issues/1383)) ([e3caf05](https://github.com/googleapis/google-auth-library-java/commit/e3caf05831011dc05d3a8b01ebf79305eda70183)) +* Remove Base64 padding in DefaultPKCEProvider ([#1375](https://github.com/googleapis/google-auth-library-java/issues/1375)) ([1405378](https://github.com/googleapis/google-auth-library-java/commit/1405378b05469841a3683bc914f47b92437abcfc)) + + +### Documentation + +* Add supplier sections to table of contents ([#1371](https://github.com/googleapis/google-auth-library-java/issues/1371)) ([9e11763](https://github.com/googleapis/google-auth-library-java/commit/9e11763e79127b3691533488482575adef6f73d2)) +* Adds docs for supplier based external account credentials ([#1362](https://github.com/googleapis/google-auth-library-java/issues/1362)) ([bd898c6](https://github.com/googleapis/google-auth-library-java/commit/bd898c64875a87414f84ca0787ba6c140e05921b)) +* Fix readme documentation for workload custom suppliers. ([#1382](https://github.com/googleapis/google-auth-library-java/issues/1382)) ([75bd749](https://github.com/googleapis/google-auth-library-java/commit/75bd749985e2d507dc48863408067950fcda3ef1)) + ## [1.23.0](https://github.com/googleapis/google-auth-library-java/compare/v1.22.0...v1.23.0) (2024-02-05) diff --git a/appengine/pom.xml b/appengine/pom.xml index 85bef4522..586c9fe4d 100644 --- a/appengine/pom.xml +++ b/appengine/pom.xml @@ -5,7 +5,7 @@ com.google.auth google-auth-library-parent - 1.23.1-SNAPSHOT + 1.24.0 ../pom.xml diff --git a/bom/pom.xml b/bom/pom.xml index d4e9aef5e..5ad6de365 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.auth google-auth-library-bom - 1.23.1-SNAPSHOT + 1.24.0 pom Google Auth Library for Java BOM diff --git a/credentials/pom.xml b/credentials/pom.xml index 42bb369b0..13b427066 100644 --- a/credentials/pom.xml +++ b/credentials/pom.xml @@ -4,7 +4,7 @@ com.google.auth google-auth-library-parent - 1.23.1-SNAPSHOT + 1.24.0 ../pom.xml diff --git a/oauth2_http/pom.xml b/oauth2_http/pom.xml index b90fdb6ab..1aef5b498 100644 --- a/oauth2_http/pom.xml +++ b/oauth2_http/pom.xml @@ -7,7 +7,7 @@ com.google.auth google-auth-library-parent - 1.23.1-SNAPSHOT + 1.24.0 ../pom.xml diff --git a/pom.xml b/pom.xml index 2ab3cf3b1..bb9290ba7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.google.auth google-auth-library-parent - 1.23.1-SNAPSHOT + 1.24.0 pom Google Auth Library for Java Client libraries providing authentication and diff --git a/versions.txt b/versions.txt index e1a417028..25d1efe03 100644 --- a/versions.txt +++ b/versions.txt @@ -1,9 +1,9 @@ # Format: # module:released-version:current-version -google-auth-library:1.23.0:1.23.1-SNAPSHOT -google-auth-library-bom:1.23.0:1.23.1-SNAPSHOT -google-auth-library-parent:1.23.0:1.23.1-SNAPSHOT -google-auth-library-appengine:1.23.0:1.23.1-SNAPSHOT -google-auth-library-credentials:1.23.0:1.23.1-SNAPSHOT -google-auth-library-oauth2-http:1.23.0:1.23.1-SNAPSHOT +google-auth-library:1.24.0:1.24.0 +google-auth-library-bom:1.24.0:1.24.0 +google-auth-library-parent:1.24.0:1.24.0 +google-auth-library-appengine:1.24.0:1.24.0 +google-auth-library-credentials:1.24.0:1.24.0 +google-auth-library-oauth2-http:1.24.0:1.24.0 From 4789d9106dd44481ec9553e4ed10fd60dfd31a8f Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 20:54:22 +0000 Subject: [PATCH 27/89] chore(main): release 1.24.1-SNAPSHOT (#1436) :robot: I have created a release *beep* *boop* --- ### Updating meta-information for bleeding-edge SNAPSHOT release. --- This PR was generated with [Release Please](https://togithub.com/googleapis/release-please). See [documentation](https://togithub.com/googleapis/release-please#release-please). --- appengine/pom.xml | 2 +- bom/pom.xml | 2 +- credentials/pom.xml | 2 +- oauth2_http/pom.xml | 2 +- pom.xml | 2 +- versions.txt | 12 ++++++------ 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/appengine/pom.xml b/appengine/pom.xml index 586c9fe4d..d3267c2d5 100644 --- a/appengine/pom.xml +++ b/appengine/pom.xml @@ -5,7 +5,7 @@ com.google.auth google-auth-library-parent - 1.24.0 + 1.24.1-SNAPSHOT ../pom.xml diff --git a/bom/pom.xml b/bom/pom.xml index 5ad6de365..01f3c91fe 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.auth google-auth-library-bom - 1.24.0 + 1.24.1-SNAPSHOT pom Google Auth Library for Java BOM diff --git a/credentials/pom.xml b/credentials/pom.xml index 13b427066..b684d064a 100644 --- a/credentials/pom.xml +++ b/credentials/pom.xml @@ -4,7 +4,7 @@ com.google.auth google-auth-library-parent - 1.24.0 + 1.24.1-SNAPSHOT ../pom.xml diff --git a/oauth2_http/pom.xml b/oauth2_http/pom.xml index 1aef5b498..fddc7a02c 100644 --- a/oauth2_http/pom.xml +++ b/oauth2_http/pom.xml @@ -7,7 +7,7 @@ com.google.auth google-auth-library-parent - 1.24.0 + 1.24.1-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index bb9290ba7..1f8b2bf43 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.google.auth google-auth-library-parent - 1.24.0 + 1.24.1-SNAPSHOT pom Google Auth Library for Java Client libraries providing authentication and diff --git a/versions.txt b/versions.txt index 25d1efe03..44822b655 100644 --- a/versions.txt +++ b/versions.txt @@ -1,9 +1,9 @@ # Format: # module:released-version:current-version -google-auth-library:1.24.0:1.24.0 -google-auth-library-bom:1.24.0:1.24.0 -google-auth-library-parent:1.24.0:1.24.0 -google-auth-library-appengine:1.24.0:1.24.0 -google-auth-library-credentials:1.24.0:1.24.0 -google-auth-library-oauth2-http:1.24.0:1.24.0 +google-auth-library:1.24.0:1.24.1-SNAPSHOT +google-auth-library-bom:1.24.0:1.24.1-SNAPSHOT +google-auth-library-parent:1.24.0:1.24.1-SNAPSHOT +google-auth-library-appengine:1.24.0:1.24.1-SNAPSHOT +google-auth-library-credentials:1.24.0:1.24.1-SNAPSHOT +google-auth-library-oauth2-http:1.24.0:1.24.1-SNAPSHOT From 338115e7e2c227bdddc2fb2e9042f676d1ac3ce8 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 9 Jul 2024 23:28:56 +0200 Subject: [PATCH 28/89] chore(deps): update actions/checkout action to v4 (#1437) --- .github/workflows/sonar.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sonar.yaml b/.github/workflows/sonar.yaml index 5b0dd8c11..6456ccd2d 100644 --- a/.github/workflows/sonar.yaml +++ b/.github/workflows/sonar.yaml @@ -10,7 +10,7 @@ jobs: name: Build runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: Set up JDK 17 From b4cb81777a6af062e962cc6bc152ea523b0a5a3e Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 17:45:04 -0400 Subject: [PATCH 29/89] ci: [java] automatic kokoro label in and /gcbrun comment (#1965) (#1419) Source-Link: https://github.com/googleapis/synthtool/commit/bd2bae89f70bad380da47fab9ec25985dfb87d67 Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-java:latest@sha256:72f0d373307d128b2cb720c5cb4d90b31f0e86529dd138c632710ae0c69efae3 Co-authored-by: Owl Bot Co-authored-by: Lawrence Qiu --- .github/.OwlBot.lock.yaml | 4 ++-- .github/trusted-contribution.yml | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index f817c5f44..359fe71c1 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -13,5 +13,5 @@ # limitations under the License. docker: image: gcr.io/cloud-devrel-public-resources/owlbot-java:latest - digest: sha256:31aa2ef27b071c2e7844b0eb1d5a24254daff06615b1b138b994dd6345c0b0ea -# created: 2024-05-17T15:15:57.6714113Z + digest: sha256:72f0d373307d128b2cb720c5cb4d90b31f0e86529dd138c632710ae0c69efae3 +# created: 2024-06-05T18:32:21.724930324Z diff --git a/.github/trusted-contribution.yml b/.github/trusted-contribution.yml index a0ba1f7d9..88d3ac9bf 100644 --- a/.github/trusted-contribution.yml +++ b/.github/trusted-contribution.yml @@ -1,3 +1,9 @@ trustedContributors: - renovate-bot - gcf-owl-bot[bot] + +annotations: +- type: comment + text: "/gcbrun" +- type: label + text: "kokoro:force-run" From c5ec2949bde5ce1c735edf82abcad5449a562a54 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Wed, 10 Jul 2024 16:11:43 +0200 Subject: [PATCH 30/89] chore(deps): update dependency com.google.auth:google-auth-library-oauth2-http to v1.24.0 (#1438) --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 7b44d45b0..e64f166c6 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -43,7 +43,7 @@ com.google.auth google-auth-library-oauth2-http - 1.23.0 + 1.24.0 From 13b3a9069c55272584d993dc6d61cb9d0098e974 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Wed, 10 Jul 2024 23:10:57 +0200 Subject: [PATCH 31/89] chore(deps): update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.3.1 (#1439) --- oauth2_http/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oauth2_http/pom.xml b/oauth2_http/pom.xml index fddc7a02c..3c3bd2283 100644 --- a/oauth2_http/pom.xml +++ b/oauth2_http/pom.xml @@ -152,7 +152,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.3.0 + 3.3.1 1200 sponge_log From 9013f275ffb856761ef6e809d2fe388ea99fc614 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 11 Jul 2024 18:18:09 +0200 Subject: [PATCH 32/89] chore(deps): update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.3.1 (#1440) Co-authored-by: Lawrence Qiu --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1f8b2bf43..f0db06ef2 100644 --- a/pom.xml +++ b/pom.xml @@ -211,7 +211,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.3.0 + 3.3.1 sponge_log From cc957e3738dc2f73e86bbef0668f611eb46fe99f Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 15 Jul 2024 17:21:04 +0200 Subject: [PATCH 33/89] chore(deps): update dependency com.google.truth:truth to v1.4.4 (#1441) --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index e64f166c6..4748455d6 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -74,7 +74,7 @@ truth com.google.truth test - 1.4.3 + 1.4.4 From d17473b0839ef699d189b75480aae7e91899c278 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 16 Jul 2024 21:42:38 +0200 Subject: [PATCH 34/89] chore(deps): update dependency com.google.errorprone:error_prone_annotations to v2.29.0 (#1442) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f0db06ef2..1469ec7e8 100644 --- a/pom.xml +++ b/pom.xml @@ -75,7 +75,7 @@ 2.0.29 3.0.2 false - 2.28.0 + 2.29.0 From 7af88b11189860bc6d26ab4c38fea9acfb1fc2d8 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 22 Jul 2024 18:49:57 +0200 Subject: [PATCH 35/89] chore(deps): update dependency com.google.errorprone:error_prone_annotations to v2.29.2 (#1444) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1469ec7e8..272d235e6 100644 --- a/pom.xml +++ b/pom.xml @@ -75,7 +75,7 @@ 2.0.29 3.0.2 false - 2.29.0 + 2.29.2 From 6e442c46c0ab98153cc9f2ccfdcce7acf9e5bff8 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 22 Jul 2024 18:58:45 +0200 Subject: [PATCH 36/89] chore(deps): update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.8.0 (#1445) Co-authored-by: Lawrence Qiu --- bom/pom.xml | 2 +- pom.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bom/pom.xml b/bom/pom.xml index 01f3c91fe..55f01cfa1 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -83,7 +83,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.7.0 + 3.8.0 true diff --git a/pom.xml b/pom.xml index 272d235e6..4f2f05982 100644 --- a/pom.xml +++ b/pom.xml @@ -182,7 +182,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.7.0 + 3.8.0 8 false @@ -332,7 +332,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.7.0 + 3.8.0 html @@ -400,7 +400,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.7.0 + 3.8.0 attach-javadocs From 1e27013048d3f73c082d98dd364053da759c5590 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Wed, 24 Jul 2024 17:01:04 +0200 Subject: [PATCH 37/89] chore(deps): update dependency com.google.cloud:google-cloud-shared-config to v1.9.1 (#1448) --- .kokoro/presubmit/graalvm-native-a.cfg | 2 +- .kokoro/presubmit/graalvm-native-b.cfg | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.kokoro/presubmit/graalvm-native-a.cfg b/.kokoro/presubmit/graalvm-native-a.cfg index be75a7e2a..1a2406a5c 100644 --- a/.kokoro/presubmit/graalvm-native-a.cfg +++ b/.kokoro/presubmit/graalvm-native-a.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_a:1.9.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_a:1.9.1" } env_vars: { diff --git a/.kokoro/presubmit/graalvm-native-b.cfg b/.kokoro/presubmit/graalvm-native-b.cfg index 4f0dc3a59..24c1b2809 100644 --- a/.kokoro/presubmit/graalvm-native-b.cfg +++ b/.kokoro/presubmit/graalvm-native-b.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_b:1.9.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_b:1.9.1" } env_vars: { diff --git a/pom.xml b/pom.xml index 4f2f05982..2213ba60b 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ com.google.cloud google-cloud-shared-config - 1.9.0 + 1.9.1 From c83a71ff3fbf3de2270fc8c909e53caeffca3a04 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 1 Aug 2024 17:38:47 +0200 Subject: [PATCH 38/89] chore(deps): update dependency com.google.cloud:google-iam-admin to v3.42.0 (#1453) --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 4748455d6..67e4d30bd 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -50,7 +50,7 @@ com.google.cloud google-iam-admin - 3.41.0 + 3.42.0 From d42f30acae7c7bd81afbecbfa83ebde5c6db931a Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Tue, 6 Aug 2024 19:35:02 +0000 Subject: [PATCH 39/89] fix: Retry sign blob call with exponential backoff (#1452) * fix: Retry sign blob call with exponential backoff * chore: Add header for IamUtilsTest * chore: Add comments for IamUtilsTest * chore: Move IAM Retry status codes to IamUtils --- .../auth/oauth2/GoogleAuthException.java | 5 +- .../java/com/google/auth/oauth2/IamUtils.java | 48 ++++++-- .../com/google/auth/oauth2/OAuth2Utils.java | 5 + .../oauth2/ServiceAccountCredentials.java | 12 +- .../com/google/auth/oauth2/TokenVerifier.java | 9 +- .../com/google/auth/oauth2/IamUtilsTest.java | 109 ++++++++++++++++++ 6 files changed, 161 insertions(+), 27 deletions(-) create mode 100644 oauth2_http/javatests/com/google/auth/oauth2/IamUtilsTest.java diff --git a/oauth2_http/java/com/google/auth/oauth2/GoogleAuthException.java b/oauth2_http/java/com/google/auth/oauth2/GoogleAuthException.java index 76e9d7c73..bcb15209f 100644 --- a/oauth2_http/java/com/google/auth/oauth2/GoogleAuthException.java +++ b/oauth2_http/java/com/google/auth/oauth2/GoogleAuthException.java @@ -158,11 +158,10 @@ static GoogleAuthException createWithTokenEndpointIOException( if (message == null) { // TODO: temporarily setting retry Count to service account default to remove a direct // dependency, to be reverted after release - return new GoogleAuthException( - true, ServiceAccountCredentials.DEFAULT_NUMBER_OF_RETRIES, ioException); + return new GoogleAuthException(true, OAuth2Utils.DEFAULT_NUMBER_OF_RETRIES, ioException); } else { return new GoogleAuthException( - true, ServiceAccountCredentials.DEFAULT_NUMBER_OF_RETRIES, message, ioException); + true, OAuth2Utils.DEFAULT_NUMBER_OF_RETRIES, message, ioException); } } diff --git a/oauth2_http/java/com/google/auth/oauth2/IamUtils.java b/oauth2_http/java/com/google/auth/oauth2/IamUtils.java index 58ba91f97..3218259fb 100644 --- a/oauth2_http/java/com/google/auth/oauth2/IamUtils.java +++ b/oauth2_http/java/com/google/auth/oauth2/IamUtils.java @@ -32,13 +32,17 @@ package com.google.auth.oauth2; import com.google.api.client.http.GenericUrl; +import com.google.api.client.http.HttpBackOffIOExceptionHandler; +import com.google.api.client.http.HttpBackOffUnsuccessfulResponseHandler; import com.google.api.client.http.HttpRequest; +import com.google.api.client.http.HttpRequestFactory; import com.google.api.client.http.HttpResponse; import com.google.api.client.http.HttpStatusCodes; import com.google.api.client.http.HttpTransport; import com.google.api.client.http.json.JsonHttpContent; import com.google.api.client.json.GenericJson; import com.google.api.client.json.JsonObjectParser; +import com.google.api.client.util.ExponentialBackOff; import com.google.api.client.util.GenericData; import com.google.auth.Credentials; import com.google.auth.ServiceAccountSigner; @@ -46,7 +50,10 @@ import com.google.common.io.BaseEncoding; import java.io.IOException; import java.io.InputStream; +import java.util.Arrays; +import java.util.HashSet; import java.util.Map; +import java.util.Set; /** * This internal class provides shared utilities for interacting with the IAM API for common @@ -60,6 +67,11 @@ class IamUtils { private static final String PARSE_ERROR_MESSAGE = "Error parsing error message response. "; private static final String PARSE_ERROR_SIGNATURE = "Error parsing signature response. "; + // Following guidance for IAM retries: + // https://cloud.google.com/iam/docs/retry-strategy#errors-to-retry + static final Set IAM_RETRYABLE_STATUS_CODES = + new HashSet<>(Arrays.asList(500, 502, 503, 504)); + /** * Returns a signature for the provided bytes. * @@ -78,11 +90,12 @@ static byte[] sign( byte[] toSign, Map additionalFields) { BaseEncoding base64 = BaseEncoding.base64(); + HttpRequestFactory factory = + transport.createRequestFactory(new HttpCredentialsAdapter(credentials)); String signature; try { signature = - getSignature( - serviceAccountEmail, credentials, transport, base64.encode(toSign), additionalFields); + getSignature(serviceAccountEmail, base64.encode(toSign), additionalFields, factory); } catch (IOException ex) { throw new ServiceAccountSigner.SigningException("Failed to sign the provided bytes", ex); } @@ -91,10 +104,9 @@ static byte[] sign( private static String getSignature( String serviceAccountEmail, - Credentials credentials, - HttpTransport transport, String bytes, - Map additionalFields) + Map additionalFields, + HttpRequestFactory factory) throws IOException { String signBlobUrl = String.format(SIGN_BLOB_URL_FORMAT, serviceAccountEmail); GenericUrl genericUrl = new GenericUrl(signBlobUrl); @@ -106,13 +118,27 @@ private static String getSignature( } JsonHttpContent signContent = new JsonHttpContent(OAuth2Utils.JSON_FACTORY, signRequest); - HttpCredentialsAdapter adapter = new HttpCredentialsAdapter(credentials); - HttpRequest request = - transport.createRequestFactory(adapter).buildPostRequest(genericUrl, signContent); + HttpRequest request = factory.buildPostRequest(genericUrl, signContent); JsonObjectParser parser = new JsonObjectParser(OAuth2Utils.JSON_FACTORY); request.setParser(parser); request.setThrowExceptionOnExecuteError(false); + request.setNumberOfRetries(OAuth2Utils.DEFAULT_NUMBER_OF_RETRIES); + + ExponentialBackOff backoff = + new ExponentialBackOff.Builder() + .setInitialIntervalMillis(OAuth2Utils.INITIAL_RETRY_INTERVAL_MILLIS) + .setRandomizationFactor(OAuth2Utils.RETRY_RANDOMIZATION_FACTOR) + .setMultiplier(OAuth2Utils.RETRY_MULTIPLIER) + .build(); + + // Retry on 500, 502, 503, and 503 status codes + request.setUnsuccessfulResponseHandler( + new HttpBackOffUnsuccessfulResponseHandler(backoff) + .setBackOffRequired( + response -> + IamUtils.IAM_RETRYABLE_STATUS_CODES.contains(response.getStatusCode()))); + request.setIOExceptionHandler(new HttpBackOffIOExceptionHandler(backoff)); HttpResponse response = request.execute(); int statusCode = response.getStatusCode(); @@ -125,6 +151,8 @@ private static String getSignature( String.format( "Error code %s trying to sign provided bytes: %s", statusCode, errorMessage)); } + + // Request will have retried a 5xx error 3 times and is still receiving a 5xx error code if (statusCode != HttpStatusCodes.STATUS_CODE_OK) { throw new IOException( String.format( @@ -152,8 +180,8 @@ private static String getSignature( * @param additionalFields additional fields to send in the IAM call * @return IdToken issed to the serviceAccount * @throws IOException if the IdToken cannot be issued. - * @see - * https://cloud.google.com/iam/credentials/reference/rest/v1/projects.serviceAccounts/generateIdToken + * @see ... */ static IdToken getIdToken( String serviceAccountEmail, diff --git a/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java b/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java index d4a29d515..b83a571d3 100644 --- a/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java +++ b/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java @@ -92,6 +92,11 @@ class OAuth2Utils { static final String TOKEN_RESPONSE_SCOPE = "scope"; + static final int INITIAL_RETRY_INTERVAL_MILLIS = 1000; + static final double RETRY_RANDOMIZATION_FACTOR = 0.1; + static final double RETRY_MULTIPLIER = 2; + static final int DEFAULT_NUMBER_OF_RETRIES = 3; + // Includes expected server errors from Google token endpoint // Other 5xx codes are either not used or retries are unlikely to succeed public static final Set TOKEN_ENDPOINT_RETRYABLE_STATUS_CODES = diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java index 1bd85749f..e8264399a 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java @@ -89,10 +89,6 @@ public class ServiceAccountCredentials extends GoogleCredentials private static final String PARSE_ERROR_PREFIX = "Error parsing token refresh response. "; private static final int TWELVE_HOURS_IN_SECONDS = 43200; private static final int DEFAULT_LIFETIME_IN_SECONDS = 3600; - private static final int INITIAL_RETRY_INTERVAL_MILLIS = 1000; - private static final double RETRY_RANDOMIZATION_FACTOR = 0.1; - private static final double RETRY_MULTIPLIER = 2; - static final int DEFAULT_NUMBER_OF_RETRIES = 3; private final String clientId; private final String clientEmail; @@ -505,7 +501,7 @@ public AccessToken refreshAccessToken() throws IOException { HttpRequest request = requestFactory.buildPostRequest(new GenericUrl(tokenServerUri), content); if (this.defaultRetriesEnabled) { - request.setNumberOfRetries(DEFAULT_NUMBER_OF_RETRIES); + request.setNumberOfRetries(OAuth2Utils.DEFAULT_NUMBER_OF_RETRIES); } else { request.setNumberOfRetries(0); } @@ -513,9 +509,9 @@ public AccessToken refreshAccessToken() throws IOException { ExponentialBackOff backoff = new ExponentialBackOff.Builder() - .setInitialIntervalMillis(INITIAL_RETRY_INTERVAL_MILLIS) - .setRandomizationFactor(RETRY_RANDOMIZATION_FACTOR) - .setMultiplier(RETRY_MULTIPLIER) + .setInitialIntervalMillis(OAuth2Utils.INITIAL_RETRY_INTERVAL_MILLIS) + .setRandomizationFactor(OAuth2Utils.RETRY_RANDOMIZATION_FACTOR) + .setMultiplier(OAuth2Utils.RETRY_MULTIPLIER) .build(); request.setUnsuccessfulResponseHandler( diff --git a/oauth2_http/java/com/google/auth/oauth2/TokenVerifier.java b/oauth2_http/java/com/google/auth/oauth2/TokenVerifier.java index af3bfbf05..4617a5de9 100644 --- a/oauth2_http/java/com/google/auth/oauth2/TokenVerifier.java +++ b/oauth2_http/java/com/google/auth/oauth2/TokenVerifier.java @@ -279,9 +279,6 @@ public TokenVerifier build() { /** Custom CacheLoader for mapping certificate urls to the contained public keys. */ static class PublicKeyLoader extends CacheLoader> { private static final int DEFAULT_NUMBER_OF_RETRIES = 2; - private static final int INITIAL_RETRY_INTERVAL_MILLIS = 1000; - private static final double RETRY_RANDOMIZATION_FACTOR = 0.1; - private static final double RETRY_MULTIPLIER = 2; private final HttpTransportFactory httpTransportFactory; /** @@ -330,9 +327,9 @@ public Map load(String certificateUrl) throws Exception { ExponentialBackOff backoff = new ExponentialBackOff.Builder() - .setInitialIntervalMillis(INITIAL_RETRY_INTERVAL_MILLIS) - .setRandomizationFactor(RETRY_RANDOMIZATION_FACTOR) - .setMultiplier(RETRY_MULTIPLIER) + .setInitialIntervalMillis(OAuth2Utils.INITIAL_RETRY_INTERVAL_MILLIS) + .setRandomizationFactor(OAuth2Utils.RETRY_RANDOMIZATION_FACTOR) + .setMultiplier(OAuth2Utils.RETRY_MULTIPLIER) .build(); request.setUnsuccessfulResponseHandler( diff --git a/oauth2_http/javatests/com/google/auth/oauth2/IamUtilsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/IamUtilsTest.java new file mode 100644 index 000000000..22ce80f84 --- /dev/null +++ b/oauth2_http/javatests/com/google/auth/oauth2/IamUtilsTest.java @@ -0,0 +1,109 @@ +/* + * Copyright 2024, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.auth.oauth2; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +import com.google.api.client.http.HttpStatusCodes; +import com.google.auth.ServiceAccountSigner; +import com.google.common.collect.ImmutableMap; +import java.io.IOException; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mockito; + +@RunWith(JUnit4.class) +public class IamUtilsTest { + + private static final String CLIENT_EMAIL = + "36680232662-vrd7ji19qe3nelgchd0ah2csanun6bnr@developer.gserviceaccount.com"; + + @Test + public void sign_noRetry() throws IOException { + byte[] expectedSignature = {0xD, 0xE, 0xA, 0xD}; + + // Mock this call because signing requires an access token. The call is initialized with + // HttpCredentialsAdapter which will make a call to get the access token + ServiceAccountCredentials credentials = Mockito.mock(ServiceAccountCredentials.class); + Mockito.when(credentials.getRequestMetadata(Mockito.any())).thenReturn(ImmutableMap.of()); + + ImpersonatedCredentialsTest.MockIAMCredentialsServiceTransportFactory transportFactory = + new ImpersonatedCredentialsTest.MockIAMCredentialsServiceTransportFactory(); + transportFactory.transport.setSignedBlob(expectedSignature); + transportFactory.transport.setTargetPrincipal(CLIENT_EMAIL); + + byte[] signature = + IamUtils.sign( + CLIENT_EMAIL, + credentials, + transportFactory.transport, + expectedSignature, + ImmutableMap.of()); + assertArrayEquals(expectedSignature, signature); + } + + @Test + public void sign_4xxServerError_exception() throws IOException { + byte[] expectedSignature = {0xD, 0xE, 0xA, 0xD}; + + // Mock this call because signing requires an access token. The call is initialized with + // HttpCredentialsAdapter which will make a call to get the access token + ServiceAccountCredentials credentials = Mockito.mock(ServiceAccountCredentials.class); + Mockito.when(credentials.getRequestMetadata(Mockito.any())).thenReturn(ImmutableMap.of()); + + ImpersonatedCredentialsTest.MockIAMCredentialsServiceTransportFactory transportFactory = + new ImpersonatedCredentialsTest.MockIAMCredentialsServiceTransportFactory(); + transportFactory.transport.setSignedBlob(expectedSignature); + transportFactory.transport.setTargetPrincipal(CLIENT_EMAIL); + transportFactory.transport.setErrorResponseCodeAndMessage( + HttpStatusCodes.STATUS_CODE_UNAUTHORIZED, "Failed to sign the provided bytes"); + + ServiceAccountSigner.SigningException exception = + assertThrows( + ServiceAccountSigner.SigningException.class, + () -> + IamUtils.sign( + CLIENT_EMAIL, + credentials, + transportFactory.transport, + expectedSignature, + ImmutableMap.of())); + assertTrue(exception.getMessage().contains("Failed to sign the provided bytes")); + assertTrue( + exception + .getCause() + .getMessage() + .contains("Error code 401 trying to sign provided bytes:")); + } +} From cb96ca8efc399195be73c7e57be605f243c2cd1f Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 13 Aug 2024 17:06:27 +0200 Subject: [PATCH 40/89] chore(deps): update dependency org.apache.maven.plugins:maven-gpg-plugin to v3.2.4 (#1462) Co-authored-by: Alice <65933803+alicejli@users.noreply.github.com> Co-authored-by: Lawrence Qiu From 2e8d9e9add0aaa289a6e8dac952d7070a40b20ce Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 13 Aug 2024 17:15:05 +0200 Subject: [PATCH 41/89] chore(deps): update dependency com.google.errorprone:error_prone_annotations to v2.30.0 (#1464) Co-authored-by: Lawrence Qiu --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2213ba60b..7cf25d661 100644 --- a/pom.xml +++ b/pom.xml @@ -75,7 +75,7 @@ 2.0.29 3.0.2 false - 2.29.2 + 2.30.0 From 27abe6069b314dcdaaec2e3b2aa8c43a86f9929f Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 13 Aug 2024 17:29:19 +0200 Subject: [PATCH 42/89] chore(deps): update dependency com.google.cloud:libraries-bom to v26.44.0 (#1463) Co-authored-by: Lawrence Qiu --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 67e4d30bd..9c11dd6bd 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -30,7 +30,7 @@ com.google.cloud libraries-bom - 26.43.0 + 26.44.0 pom import From 3e8aebc0bbf099e926b30ad42c75c68f429a9595 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 13 Aug 2024 17:38:31 +0200 Subject: [PATCH 43/89] chore(deps): update dependency org.apache.maven.plugins:maven-gpg-plugin to v3.2.5 (#1465) Co-authored-by: Lawrence Qiu --- bom/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bom/pom.xml b/bom/pom.xml index 55f01cfa1..a2f5aa9af 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -122,7 +122,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.2.4 + 3.2.5 sign-artifacts diff --git a/pom.xml b/pom.xml index 7cf25d661..00a194c8d 100644 --- a/pom.xml +++ b/pom.xml @@ -413,7 +413,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.2.4 + 3.2.5 sign-artifacts From 3e44bb99fc04e63c830c214943520687759d1447 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2024 15:17:16 -0400 Subject: [PATCH 44/89] chore(main): release 1.24.1 (#1458) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Lawrence Qiu --- CHANGELOG.md | 7 +++++++ appengine/pom.xml | 2 +- bom/pom.xml | 2 +- credentials/pom.xml | 2 +- oauth2_http/pom.xml | 2 +- pom.xml | 2 +- versions.txt | 12 ++++++------ 7 files changed, 18 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 993c838ad..3fc7b4f1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.24.1](https://github.com/googleapis/google-auth-library-java/compare/v1.24.0...v1.24.1) (2024-08-13) + + +### Bug Fixes + +* Retry sign blob call with exponential backoff ([#1452](https://github.com/googleapis/google-auth-library-java/issues/1452)) ([d42f30a](https://github.com/googleapis/google-auth-library-java/commit/d42f30acae7c7bd81afbecbfa83ebde5c6db931a)) + ## [1.24.0](https://github.com/googleapis/google-auth-library-java/compare/v1.23.0...v1.24.0) (2024-07-09) diff --git a/appengine/pom.xml b/appengine/pom.xml index d3267c2d5..8b87bc3c9 100644 --- a/appengine/pom.xml +++ b/appengine/pom.xml @@ -5,7 +5,7 @@ com.google.auth google-auth-library-parent - 1.24.1-SNAPSHOT + 1.24.1 ../pom.xml diff --git a/bom/pom.xml b/bom/pom.xml index a2f5aa9af..237e95d06 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.auth google-auth-library-bom - 1.24.1-SNAPSHOT + 1.24.1 pom Google Auth Library for Java BOM diff --git a/credentials/pom.xml b/credentials/pom.xml index b684d064a..6e334f982 100644 --- a/credentials/pom.xml +++ b/credentials/pom.xml @@ -4,7 +4,7 @@ com.google.auth google-auth-library-parent - 1.24.1-SNAPSHOT + 1.24.1 ../pom.xml diff --git a/oauth2_http/pom.xml b/oauth2_http/pom.xml index 3c3bd2283..d46d1e20c 100644 --- a/oauth2_http/pom.xml +++ b/oauth2_http/pom.xml @@ -7,7 +7,7 @@ com.google.auth google-auth-library-parent - 1.24.1-SNAPSHOT + 1.24.1 ../pom.xml diff --git a/pom.xml b/pom.xml index 00a194c8d..54de2b1c1 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.google.auth google-auth-library-parent - 1.24.1-SNAPSHOT + 1.24.1 pom Google Auth Library for Java Client libraries providing authentication and diff --git a/versions.txt b/versions.txt index 44822b655..99f24d2eb 100644 --- a/versions.txt +++ b/versions.txt @@ -1,9 +1,9 @@ # Format: # module:released-version:current-version -google-auth-library:1.24.0:1.24.1-SNAPSHOT -google-auth-library-bom:1.24.0:1.24.1-SNAPSHOT -google-auth-library-parent:1.24.0:1.24.1-SNAPSHOT -google-auth-library-appengine:1.24.0:1.24.1-SNAPSHOT -google-auth-library-credentials:1.24.0:1.24.1-SNAPSHOT -google-auth-library-oauth2-http:1.24.0:1.24.1-SNAPSHOT +google-auth-library:1.24.1:1.24.1 +google-auth-library-bom:1.24.1:1.24.1 +google-auth-library-parent:1.24.1:1.24.1 +google-auth-library-appengine:1.24.1:1.24.1 +google-auth-library-credentials:1.24.1:1.24.1 +google-auth-library-oauth2-http:1.24.1:1.24.1 From d2a5833f9a3b834499adbdddb64a4d501c72bc52 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 11:28:57 -0400 Subject: [PATCH 45/89] chore(main): release 1.24.2-SNAPSHOT (#1466) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- appengine/pom.xml | 2 +- bom/pom.xml | 2 +- credentials/pom.xml | 2 +- oauth2_http/pom.xml | 2 +- pom.xml | 2 +- versions.txt | 12 ++++++------ 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/appengine/pom.xml b/appengine/pom.xml index 8b87bc3c9..67db05102 100644 --- a/appengine/pom.xml +++ b/appengine/pom.xml @@ -5,7 +5,7 @@ com.google.auth google-auth-library-parent - 1.24.1 + 1.24.2-SNAPSHOT ../pom.xml diff --git a/bom/pom.xml b/bom/pom.xml index 237e95d06..0b7e3671e 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.auth google-auth-library-bom - 1.24.1 + 1.24.2-SNAPSHOT pom Google Auth Library for Java BOM diff --git a/credentials/pom.xml b/credentials/pom.xml index 6e334f982..cdcdbabd7 100644 --- a/credentials/pom.xml +++ b/credentials/pom.xml @@ -4,7 +4,7 @@ com.google.auth google-auth-library-parent - 1.24.1 + 1.24.2-SNAPSHOT ../pom.xml diff --git a/oauth2_http/pom.xml b/oauth2_http/pom.xml index d46d1e20c..b9615748b 100644 --- a/oauth2_http/pom.xml +++ b/oauth2_http/pom.xml @@ -7,7 +7,7 @@ com.google.auth google-auth-library-parent - 1.24.1 + 1.24.2-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 54de2b1c1..d6767283b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.google.auth google-auth-library-parent - 1.24.1 + 1.24.2-SNAPSHOT pom Google Auth Library for Java Client libraries providing authentication and diff --git a/versions.txt b/versions.txt index 99f24d2eb..9c9e98ff3 100644 --- a/versions.txt +++ b/versions.txt @@ -1,9 +1,9 @@ # Format: # module:released-version:current-version -google-auth-library:1.24.1:1.24.1 -google-auth-library-bom:1.24.1:1.24.1 -google-auth-library-parent:1.24.1:1.24.1 -google-auth-library-appengine:1.24.1:1.24.1 -google-auth-library-credentials:1.24.1:1.24.1 -google-auth-library-oauth2-http:1.24.1:1.24.1 +google-auth-library:1.24.1:1.24.2-SNAPSHOT +google-auth-library-bom:1.24.1:1.24.2-SNAPSHOT +google-auth-library-parent:1.24.1:1.24.2-SNAPSHOT +google-auth-library-appengine:1.24.1:1.24.2-SNAPSHOT +google-auth-library-credentials:1.24.1:1.24.2-SNAPSHOT +google-auth-library-oauth2-http:1.24.1:1.24.2-SNAPSHOT From c79f7079517c3934ab0c7e4478743b7830411bf7 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 15 Aug 2024 15:48:22 +0000 Subject: [PATCH 46/89] chore: Control each response for calls to the IAM Mock Server (#1455) * fix: Retry sign blob call with exponential backoff * chore: Add header for IamUtilsTest * chore: Add comments for IamUtilsTest * chore: Control each response for calls to the IAM Mock Server * chore: Move IAM Retry status codes to IamUtils * chore: Address PR comments * chore: Address PR comments * chore: Address PR comments --- .../auth/oauth2/GoogleCredentialsTest.java | 3 + .../com/google/auth/oauth2/IamUtilsTest.java | 138 ++++++++++++++++-- .../oauth2/ImpersonatedCredentialsTest.java | 44 +++--- .../MockIAMCredentialsServiceTransport.java | 109 +++++++------- 4 files changed, 210 insertions(+), 84 deletions(-) diff --git a/oauth2_http/javatests/com/google/auth/oauth2/GoogleCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/GoogleCredentialsTest.java index 0de777172..e91ad06d1 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/GoogleCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/GoogleCredentialsTest.java @@ -33,6 +33,7 @@ import static org.junit.Assert.*; +import com.google.api.client.http.HttpStatusCodes; import com.google.api.client.json.GenericJson; import com.google.api.client.util.Clock; import com.google.auth.Credentials; @@ -609,6 +610,7 @@ public void fromStream_Impersonation_providesToken_WithQuotaProject() throws IOE transportFactory.transport.setExpireTime(ImpersonatedCredentialsTest.getDefaultExpireTime()); transportFactory.transport.setAccessTokenEndpoint( ImpersonatedCredentialsTest.IMPERSONATION_URL); + transportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); InputStream impersonationCredentialsStream = ImpersonatedCredentialsTest.writeImpersonationCredentialsStream( @@ -669,6 +671,7 @@ public void fromStream_Impersonation_providesToken_WithoutQuotaProject() throws transportFactory.transport.setExpireTime(ImpersonatedCredentialsTest.getDefaultExpireTime()); transportFactory.transport.setAccessTokenEndpoint( ImpersonatedCredentialsTest.IMPERSONATION_URL); + transportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); InputStream impersonationCredentialsStream = ImpersonatedCredentialsTest.writeImpersonationCredentialsStream( diff --git a/oauth2_http/javatests/com/google/auth/oauth2/IamUtilsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/IamUtilsTest.java index 22ce80f84..ccc8cf37b 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/IamUtilsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/IamUtilsTest.java @@ -31,6 +31,7 @@ package com.google.auth.oauth2; import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; @@ -38,6 +39,7 @@ import com.google.auth.ServiceAccountSigner; import com.google.common.collect.ImmutableMap; import java.io.IOException; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -49,17 +51,53 @@ public class IamUtilsTest { private static final String CLIENT_EMAIL = "36680232662-vrd7ji19qe3nelgchd0ah2csanun6bnr@developer.gserviceaccount.com"; + private ServiceAccountCredentials credentials; + + @Before + public void setup() throws IOException { + // Mock this call for the Credentials because the IAM SignBlob RPC requires an access token. The + // call is initialized with HttpCredentialsAdapter which will make a call to get the access + // token + credentials = Mockito.mock(ServiceAccountCredentials.class); + Mockito.when(credentials.getRequestMetadata(Mockito.any())).thenReturn(ImmutableMap.of()); + } + @Test - public void sign_noRetry() throws IOException { + public void sign_success_noRetry() { byte[] expectedSignature = {0xD, 0xE, 0xA, 0xD}; - // Mock this call because signing requires an access token. The call is initialized with - // HttpCredentialsAdapter which will make a call to get the access token - ServiceAccountCredentials credentials = Mockito.mock(ServiceAccountCredentials.class); - Mockito.when(credentials.getRequestMetadata(Mockito.any())).thenReturn(ImmutableMap.of()); + ImpersonatedCredentialsTest.MockIAMCredentialsServiceTransportFactory transportFactory = + new ImpersonatedCredentialsTest.MockIAMCredentialsServiceTransportFactory(); + transportFactory.transport.setSignedBlob(expectedSignature); + transportFactory.transport.setTargetPrincipal(CLIENT_EMAIL); + transportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); + + byte[] signature = + IamUtils.sign( + CLIENT_EMAIL, + credentials, + transportFactory.transport, + expectedSignature, + ImmutableMap.of()); + assertArrayEquals(expectedSignature, signature); + + assertEquals(1, transportFactory.transport.getNumRequests()); + } + + // The SignBlob RPC will retry up to three times before it gives up. This test will return two + // 5xx status codes before returning a success. This test covers the cases where the number of + // retry attempts is below the configured retry attempt count bounds (3 attempts). + @Test + public void sign_retryTwoTimes_success() { + byte[] expectedSignature = {0xD, 0xE, 0xA, 0xD}; ImpersonatedCredentialsTest.MockIAMCredentialsServiceTransportFactory transportFactory = new ImpersonatedCredentialsTest.MockIAMCredentialsServiceTransportFactory(); + transportFactory.transport.addStatusCodeAndMessage( + HttpStatusCodes.STATUS_CODE_BAD_GATEWAY, "Bad Gateway"); + transportFactory.transport.addStatusCodeAndMessage( + HttpStatusCodes.STATUS_CODE_SERVICE_UNAVAILABLE, "Unavailable"); + transportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); transportFactory.transport.setSignedBlob(expectedSignature); transportFactory.transport.setTargetPrincipal(CLIENT_EMAIL); @@ -71,22 +109,97 @@ public void sign_noRetry() throws IOException { expectedSignature, ImmutableMap.of()); assertArrayEquals(expectedSignature, signature); + + // Expect that three requests are made (2 failures which are retries + 1 final requests which + // resulted in a successful response) + assertEquals(3, transportFactory.transport.getNumRequests()); } + // The rpc will retry up to three times before it gives up. This test will enqueue three failed + // status codes + messages before returning a success. After the third retry attempt, the request + // will try one last time and the result will be reported back to the user. @Test - public void sign_4xxServerError_exception() throws IOException { + public void sign_retryThreeTimes_success() { byte[] expectedSignature = {0xD, 0xE, 0xA, 0xD}; - // Mock this call because signing requires an access token. The call is initialized with - // HttpCredentialsAdapter which will make a call to get the access token - ServiceAccountCredentials credentials = Mockito.mock(ServiceAccountCredentials.class); - Mockito.when(credentials.getRequestMetadata(Mockito.any())).thenReturn(ImmutableMap.of()); + ImpersonatedCredentialsTest.MockIAMCredentialsServiceTransportFactory transportFactory = + new ImpersonatedCredentialsTest.MockIAMCredentialsServiceTransportFactory(); + transportFactory.transport.setSignedBlob(expectedSignature); + transportFactory.transport.setTargetPrincipal(CLIENT_EMAIL); + transportFactory.transport.addStatusCodeAndMessage( + HttpStatusCodes.STATUS_CODE_BAD_GATEWAY, "Bad Gateway"); + transportFactory.transport.addStatusCodeAndMessage( + HttpStatusCodes.STATUS_CODE_SERVICE_UNAVAILABLE, "Unavailable"); + transportFactory.transport.addStatusCodeAndMessage( + HttpStatusCodes.STATUS_CODE_SERVER_ERROR, "Server Error"); + transportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); + + byte[] signature = + IamUtils.sign( + CLIENT_EMAIL, + credentials, + transportFactory.transport, + expectedSignature, + ImmutableMap.of()); + assertArrayEquals(expectedSignature, signature); + + // Expect that three requests are made (3 failures which are retried + 1 final request which + // resulted the final success response) + assertEquals(4, transportFactory.transport.getNumRequests()); + } + + // The rpc will retry up to three times before it gives up. This test will enqueue four failed + // status codes + messages before returning a success. After the third retry attempt, the request + // will try one last time and the result will be reported back to the user. + @Test + public void sign_retryThreeTimes_exception() { + byte[] expectedSignature = {0xD, 0xE, 0xA, 0xD}; ImpersonatedCredentialsTest.MockIAMCredentialsServiceTransportFactory transportFactory = new ImpersonatedCredentialsTest.MockIAMCredentialsServiceTransportFactory(); transportFactory.transport.setSignedBlob(expectedSignature); transportFactory.transport.setTargetPrincipal(CLIENT_EMAIL); - transportFactory.transport.setErrorResponseCodeAndMessage( + transportFactory.transport.addStatusCodeAndMessage( + HttpStatusCodes.STATUS_CODE_BAD_GATEWAY, "Bad Gateway"); + transportFactory.transport.addStatusCodeAndMessage( + HttpStatusCodes.STATUS_CODE_SERVICE_UNAVAILABLE, "Unavailable"); + transportFactory.transport.addStatusCodeAndMessage( + HttpStatusCodes.STATUS_CODE_SERVER_ERROR, "Server Error"); + transportFactory.transport.addStatusCodeAndMessage( + HttpStatusCodes.STATUS_CODE_BAD_GATEWAY, "Bad Gateway"); + transportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); + + ServiceAccountSigner.SigningException exception = + assertThrows( + ServiceAccountSigner.SigningException.class, + () -> + IamUtils.sign( + CLIENT_EMAIL, + credentials, + transportFactory.transport, + expectedSignature, + ImmutableMap.of())); + assertTrue(exception.getMessage().contains("Failed to sign the provided bytes")); + assertTrue( + exception + .getCause() + .getMessage() + .contains("Unexpected Error code 502 trying to sign provided bytes")); + + // Expect that three requests are made (3 failures which are retried + 1 final request which + // resulted in another failed response) + assertEquals(4, transportFactory.transport.getNumRequests()); + } + + @Test + public void sign_4xxError_noRetry_exception() { + byte[] expectedSignature = {0xD, 0xE, 0xA, 0xD}; + + ImpersonatedCredentialsTest.MockIAMCredentialsServiceTransportFactory transportFactory = + new ImpersonatedCredentialsTest.MockIAMCredentialsServiceTransportFactory(); + transportFactory.transport.setSignedBlob(expectedSignature); + transportFactory.transport.setTargetPrincipal(CLIENT_EMAIL); + transportFactory.transport.addStatusCodeAndMessage( HttpStatusCodes.STATUS_CODE_UNAUTHORIZED, "Failed to sign the provided bytes"); ServiceAccountSigner.SigningException exception = @@ -105,5 +218,8 @@ public void sign_4xxServerError_exception() throws IOException { .getCause() .getMessage() .contains("Error code 401 trying to sign provided bytes:")); + + // Only one request will have been made for a 4xx error (no retries) + assertEquals(1, transportFactory.transport.getNumRequests()); } } diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ImpersonatedCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ImpersonatedCredentialsTest.java index aa3df6ec4..1e000e2b6 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ImpersonatedCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ImpersonatedCredentialsTest.java @@ -363,14 +363,13 @@ public void createScopedWithIamEndpointOverride() { @Test public void refreshAccessToken_unauthorized() throws IOException { - String expectedMessage = "The caller does not have permission"; mockTransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); - mockTransportFactory.transport.setTokenResponseErrorCode( - HttpStatusCodes.STATUS_CODE_UNAUTHORIZED); - mockTransportFactory.transport.setTokenResponseErrorContent( + mockTransportFactory.transport.addStatusCodeAndMessage( + HttpStatusCodes.STATUS_CODE_UNAUTHORIZED, generateErrorJson( - HttpStatusCodes.STATUS_CODE_UNAUTHORIZED, expectedMessage, "global", "forbidden")); + HttpStatusCodes.STATUS_CODE_UNAUTHORIZED, expectedMessage, "global", "forbidden"), + true); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create( sourceCredentials, @@ -395,9 +394,8 @@ public void refreshAccessToken_malformedTarget() throws IOException { String invalidTargetEmail = "foo"; String expectedMessage = "Request contains an invalid argument"; mockTransportFactory.transport.setTargetPrincipal(invalidTargetEmail); - mockTransportFactory.transport.setTokenResponseErrorCode( - HttpStatusCodes.STATUS_CODE_BAD_REQUEST); - mockTransportFactory.transport.setTokenResponseErrorContent( + mockTransportFactory.transport.addStatusCodeAndMessage( + HttpStatusCodes.STATUS_CODE_BAD_REQUEST, generateErrorJson( HttpStatusCodes.STATUS_CODE_BAD_REQUEST, expectedMessage, "global", "badRequest")); ImpersonatedCredentials targetCredentials = @@ -465,10 +463,10 @@ public void credential_with_invalid_scope() throws IOException, IllegalStateExce @Test() public void refreshAccessToken_success() throws IOException, IllegalStateException { - mockTransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mockTransportFactory.transport.setAccessToken(ACCESS_TOKEN); mockTransportFactory.transport.setExpireTime(getDefaultExpireTime()); + mockTransportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create( sourceCredentials, @@ -488,6 +486,7 @@ public void refreshAccessToken_endpointOverride() throws IOException, IllegalSta mockTransportFactory.transport.setAccessToken(ACCESS_TOKEN); mockTransportFactory.transport.setExpireTime(getDefaultExpireTime()); mockTransportFactory.transport.setAccessTokenEndpoint(IMPERSONATION_URL); + mockTransportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create( @@ -506,10 +505,10 @@ public void refreshAccessToken_endpointOverride() throws IOException, IllegalSta @Test() public void getRequestMetadata_withQuotaProjectId() throws IOException, IllegalStateException { - mockTransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mockTransportFactory.transport.setAccessToken(ACCESS_TOKEN); mockTransportFactory.transport.setExpireTime(getDefaultExpireTime()); + mockTransportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create( sourceCredentials, @@ -529,10 +528,10 @@ public void getRequestMetadata_withQuotaProjectId() throws IOException, IllegalS @Test() public void getRequestMetadata_withoutQuotaProjectId() throws IOException, IllegalStateException { - mockTransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mockTransportFactory.transport.setAccessToken(ACCESS_TOKEN); mockTransportFactory.transport.setExpireTime(getDefaultExpireTime()); + mockTransportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create( sourceCredentials, @@ -548,10 +547,10 @@ public void getRequestMetadata_withoutQuotaProjectId() throws IOException, Illeg @Test() public void refreshAccessToken_delegates_success() throws IOException, IllegalStateException { - mockTransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mockTransportFactory.transport.setAccessToken(ACCESS_TOKEN); mockTransportFactory.transport.setExpireTime(getDefaultExpireTime()); + mockTransportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); List delegates = Arrays.asList("delegate-account@iam.gserviceaccount.com"); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create( @@ -574,6 +573,7 @@ public void refreshAccessToken_GMT_dateParsedCorrectly() mockTransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mockTransportFactory.transport.setAccessToken(ACCESS_TOKEN); mockTransportFactory.transport.setExpireTime(getFormattedTime(c.getTime())); + mockTransportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create( sourceCredentials, @@ -600,6 +600,7 @@ public void refreshAccessToken_nonGMT_dateParsedCorrectly() mockTransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mockTransportFactory.transport.setAccessToken(ACCESS_TOKEN); mockTransportFactory.transport.setExpireTime(getFormattedTime(c.getTime())); + mockTransportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create( sourceCredentials, @@ -619,11 +620,11 @@ public void refreshAccessToken_nonGMT_dateParsedCorrectly() @Test public void refreshAccessToken_invalidDate() throws IllegalStateException { - String expectedMessage = "Unparseable date"; mockTransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mockTransportFactory.transport.setAccessToken("foo"); mockTransportFactory.transport.setExpireTime("1973-09-29T15:01:23"); + mockTransportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create( sourceCredentials, @@ -663,6 +664,7 @@ public void sign_sameAs() { mockTransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mockTransportFactory.transport.setAccessToken(ACCESS_TOKEN); mockTransportFactory.transport.setExpireTime(getDefaultExpireTime()); + mockTransportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create( sourceCredentials, @@ -685,6 +687,7 @@ public void sign_requestIncludesDelegates() throws IOException { mockTransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mockTransportFactory.transport.setAccessToken(ACCESS_TOKEN); mockTransportFactory.transport.setExpireTime(getDefaultExpireTime()); + mockTransportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create( sourceCredentials, @@ -724,6 +727,7 @@ public void sign_usesSourceCredentials() { mockTransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mockTransportFactory.transport.setAccessToken(ACCESS_TOKEN); mockTransportFactory.transport.setExpireTime(getDefaultExpireTime()); + mockTransportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create( sourceCredentials, @@ -762,7 +766,7 @@ public void sign_accessDenied_throws() { mockTransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mockTransportFactory.transport.setSignedBlob(expectedSignature); - mockTransportFactory.transport.setErrorResponseCodeAndMessage( + mockTransportFactory.transport.addStatusCodeAndMessage( HttpStatusCodes.STATUS_CODE_FORBIDDEN, "Sign Error"); try { @@ -794,8 +798,8 @@ public void sign_serverError_throws() { mockTransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mockTransportFactory.transport.setSignedBlob(expectedSignature); - mockTransportFactory.transport.setErrorResponseCodeAndMessage( - HttpStatusCodes.STATUS_CODE_SERVER_ERROR, "Sign Error"); + mockTransportFactory.transport.addStatusCodeAndMessage( + HttpStatusCodes.STATUS_CODE_NOT_FOUND, "Sign Error"); try { byte[] bytes = {0xD, 0xE, 0xA, 0xD}; @@ -804,7 +808,7 @@ public void sign_serverError_throws() { } catch (SigningException e) { assertEquals("Failed to sign the provided bytes", e.getMessage()); assertNotNull(e.getCause()); - assertTrue(e.getCause().getMessage().contains("500")); + assertTrue(e.getCause().getMessage().contains("404")); } } @@ -813,6 +817,7 @@ public void idTokenWithAudience_sameAs() throws IOException { mockTransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mockTransportFactory.transport.setAccessToken(ACCESS_TOKEN); mockTransportFactory.transport.setExpireTime(getDefaultExpireTime()); + mockTransportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create( @@ -844,6 +849,7 @@ public void idTokenWithAudience_withEmail() throws IOException { mockTransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mockTransportFactory.transport.setAccessToken(ACCESS_TOKEN); mockTransportFactory.transport.setExpireTime(getDefaultExpireTime()); + mockTransportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create( @@ -885,7 +891,7 @@ public void idToken_withServerError() { mockTransportFactory); mockTransportFactory.transport.setIdToken(STANDARD_ID_TOKEN); - mockTransportFactory.transport.setErrorResponseCodeAndMessage( + mockTransportFactory.transport.addStatusCodeAndMessage( HttpStatusCodes.STATUS_CODE_SERVER_ERROR, "Internal Server Error"); String targetAudience = "https://foo.bar"; @@ -918,7 +924,7 @@ public void idToken_withOtherError() { mockTransportFactory); mockTransportFactory.transport.setIdToken(STANDARD_ID_TOKEN); - mockTransportFactory.transport.setErrorResponseCodeAndMessage( + mockTransportFactory.transport.addStatusCodeAndMessage( HttpStatusCodes.STATUS_CODE_MOVED_PERMANENTLY, "Redirect"); String targetAudience = "https://foo.bar"; diff --git a/oauth2_http/javatests/com/google/auth/oauth2/MockIAMCredentialsServiceTransport.java b/oauth2_http/javatests/com/google/auth/oauth2/MockIAMCredentialsServiceTransport.java index d3da05aa2..e5ce82d81 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/MockIAMCredentialsServiceTransport.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/MockIAMCredentialsServiceTransport.java @@ -42,22 +42,35 @@ import com.google.auth.TestUtils; import com.google.common.io.BaseEncoding; import java.io.IOException; +import java.util.ArrayDeque; +import java.util.Deque; /** Transport that simulates the IAMCredentials server for access tokens. */ public class MockIAMCredentialsServiceTransport extends MockHttpTransport { + private static class ServerResponse { + private final int statusCode; + private final String response; + private final boolean repeatServerResponse; + + public ServerResponse(int statusCode, String response, boolean repeatServerResponse) { + this.statusCode = statusCode; + this.response = response; + this.repeatServerResponse = repeatServerResponse; + } + } + private static final String DEFAULT_IAM_ACCESS_TOKEN_ENDPOINT = "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/%s:generateAccessToken"; private static final String IAM_ID_TOKEN_ENDPOINT = "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/%s:generateIdToken"; private static final String IAM_SIGN_ENDPOINT = "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/%s:signBlob"; - private Integer tokenResponseErrorCode; - private String tokenResponseErrorContent; + + private final Deque serverResponses; + private String targetPrincipal; private byte[] signedBlob; - private int responseCode = HttpStatusCodes.STATUS_CODE_OK; - private String errorMessage; private String iamAccessTokenEndpoint; private String accessToken; @@ -67,14 +80,12 @@ public class MockIAMCredentialsServiceTransport extends MockHttpTransport { private MockLowLevelHttpRequest request; - public MockIAMCredentialsServiceTransport() {} - - public void setTokenResponseErrorCode(Integer tokenResponseErrorCode) { - this.tokenResponseErrorCode = tokenResponseErrorCode; - } + // Store the number of requests that are sent to the Mock Server. This is used to track the + // number of retries attempts made to ensure that retry boundaries are respected. + private int numRequests; - public void setTokenResponseErrorContent(String tokenResponseErrorContent) { - this.tokenResponseErrorContent = tokenResponseErrorContent; + public MockIAMCredentialsServiceTransport() { + this.serverResponses = new ArrayDeque<>(); } public void setTargetPrincipal(String targetPrincipal) { @@ -93,9 +104,17 @@ public void setSignedBlob(byte[] signedBlob) { this.signedBlob = signedBlob; } - public void setErrorResponseCodeAndMessage(int responseCode, String errorMessage) { - this.responseCode = responseCode; - this.errorMessage = errorMessage; + // Enqueue the status code + message. Each request to the mock server will pop off the + // status code + message in the order it was enqueued + public void addStatusCodeAndMessage(int responseCode, String message) { + addStatusCodeAndMessage(responseCode, message, false); + } + + // repeat to ensure simulate scenarios where retrying returns the same status over and over. + // Setting repeat will result in this status code being returned until the connection is + // terminated. + public void addStatusCodeAndMessage(int responseCode, String message, boolean repeat) { + serverResponses.offer(new ServerResponse(responseCode, message, repeat)); } public void setIdToken(String idToken) { @@ -110,26 +129,33 @@ public MockLowLevelHttpRequest getRequest() { return request; } + int getNumRequests() { + return numRequests; + } + @Override public LowLevelHttpRequest buildRequest(String method, String url) throws IOException { - - String iamAccesssTokenformattedUrl = + String iamAccessTokenFormattedUrl = iamAccessTokenEndpoint != null ? iamAccessTokenEndpoint : String.format(DEFAULT_IAM_ACCESS_TOKEN_ENDPOINT, this.targetPrincipal); String iamSignBlobformattedUrl = String.format(IAM_SIGN_ENDPOINT, this.targetPrincipal); String iamIdTokenformattedUrl = String.format(IAM_ID_TOKEN_ENDPOINT, this.targetPrincipal); - if (url.equals(iamAccesssTokenformattedUrl)) { + ServerResponse serverResponse = serverResponses.poll(); + // Status code was configured to be repeated until connection is terminated + if (serverResponse.repeatServerResponse) { + serverResponses.offerFirst(serverResponse); + } + if (url.equals(iamAccessTokenFormattedUrl)) { this.request = new MockLowLevelHttpRequest(url) { @Override public LowLevelHttpResponse execute() throws IOException { - - if (tokenResponseErrorCode != null) { + if (serverResponse.statusCode != HttpStatusCodes.STATUS_CODE_OK) { return new MockLowLevelHttpResponse() - .setStatusCode(tokenResponseErrorCode) + .setStatusCode(serverResponse.statusCode) .setContentType(Json.MEDIA_TYPE) - .setContent(tokenResponseErrorContent); + .setContent(serverResponse.response); } // Create the JSON response @@ -143,45 +169,20 @@ public LowLevelHttpResponse execute() throws IOException { .setContent(refreshText); } }; - } else if (url.equals(iamSignBlobformattedUrl) - && responseCode != HttpStatusCodes.STATUS_CODE_OK) { + } else if (url.equals(iamSignBlobformattedUrl)) { this.request = new MockLowLevelHttpRequest(url) { @Override public LowLevelHttpResponse execute() throws IOException { - - if (tokenResponseErrorCode != null) { - return new MockLowLevelHttpResponse() - .setStatusCode(tokenResponseErrorCode) - .setContentType(Json.MEDIA_TYPE) - .setContent(tokenResponseErrorContent); - } - BaseEncoding base64 = BaseEncoding.base64(); GenericJson refreshContents = new GenericJson(); refreshContents.setFactory(OAuth2Utils.JSON_FACTORY); - refreshContents.put("signedBlob", base64.encode(signedBlob)); - return new MockLowLevelHttpResponse() - .setStatusCode(responseCode) - .setContent(TestUtils.errorJson(errorMessage)); - } - }; - } else if (url.equals(iamSignBlobformattedUrl)) { - this.request = - new MockLowLevelHttpRequest(url) { - @Override - public LowLevelHttpResponse execute() throws IOException { - if (tokenResponseErrorCode != null) { + if (serverResponse.statusCode != HttpStatusCodes.STATUS_CODE_OK) { return new MockLowLevelHttpResponse() - .setStatusCode(tokenResponseErrorCode) - .setContentType(Json.MEDIA_TYPE) - .setContent(tokenResponseErrorContent); + .setStatusCode(serverResponse.statusCode) + .setContent(TestUtils.errorJson(serverResponse.response)); } - - BaseEncoding base64 = BaseEncoding.base64(); - GenericJson refreshContents = new GenericJson(); - refreshContents.setFactory(OAuth2Utils.JSON_FACTORY); refreshContents.put("signedBlob", base64.encode(signedBlob)); String refreshText = refreshContents.toPrettyString(); return new MockLowLevelHttpResponse() @@ -194,12 +195,11 @@ public LowLevelHttpResponse execute() throws IOException { new MockLowLevelHttpRequest(url) { @Override public LowLevelHttpResponse execute() throws IOException { - - if (responseCode != HttpStatusCodes.STATUS_CODE_OK) { + if (serverResponse.statusCode != HttpStatusCodes.STATUS_CODE_OK) { return new MockLowLevelHttpResponse() - .setStatusCode(responseCode) + .setStatusCode(serverResponse.statusCode) .setContentType(Json.MEDIA_TYPE) - .setContent(errorMessage); + .setContent(serverResponse.response); } GenericJson refreshContents = new GenericJson(); @@ -214,6 +214,7 @@ public LowLevelHttpResponse execute() throws IOException { } else { return super.buildRequest(method, url); } + numRequests++; return this.request; } From 72b16e93c230beebfec7ccbd92f14d810c50671b Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 15 Aug 2024 19:44:24 +0200 Subject: [PATCH 47/89] chore(deps): update dependency com.google.auth:google-auth-library-oauth2-http to v1.24.1 (#1467) Co-authored-by: Lawrence Qiu --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 9c11dd6bd..afbdc5118 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -43,7 +43,7 @@ com.google.auth google-auth-library-oauth2-http - 1.24.0 + 1.24.1 From 1cba6e69838e3041952f24f05c2740e17aaacd7d Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 15 Aug 2024 19:54:15 +0200 Subject: [PATCH 48/89] chore(deps): update dependency com.google.cloud:google-cloud-shared-config to v1.10.0 (#1468) Co-authored-by: Lawrence Qiu --- .kokoro/presubmit/graalvm-native-a.cfg | 2 +- .kokoro/presubmit/graalvm-native-b.cfg | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.kokoro/presubmit/graalvm-native-a.cfg b/.kokoro/presubmit/graalvm-native-a.cfg index 1a2406a5c..9a34e1cfe 100644 --- a/.kokoro/presubmit/graalvm-native-a.cfg +++ b/.kokoro/presubmit/graalvm-native-a.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_a:1.9.1" + value: "gcr.io/cloud-devrel-public-resources/graalvm_a:1.10.0" } env_vars: { diff --git a/.kokoro/presubmit/graalvm-native-b.cfg b/.kokoro/presubmit/graalvm-native-b.cfg index 24c1b2809..af0b6ecd2 100644 --- a/.kokoro/presubmit/graalvm-native-b.cfg +++ b/.kokoro/presubmit/graalvm-native-b.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_b:1.9.1" + value: "gcr.io/cloud-devrel-public-resources/graalvm_b:1.10.0" } env_vars: { diff --git a/pom.xml b/pom.xml index d6767283b..8fd2f4738 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ com.google.cloud google-cloud-shared-config - 1.9.1 + 1.10.0 From 71a9dd77fc3b246fa1954f0a2540a2ce6375455f Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 27 Aug 2024 21:07:28 +0200 Subject: [PATCH 49/89] chore(deps): update dependency com.google.cloud:google-cloud-shared-config to v1.11.0 (#1471) --- .kokoro/presubmit/graalvm-native-a.cfg | 2 +- .kokoro/presubmit/graalvm-native-b.cfg | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.kokoro/presubmit/graalvm-native-a.cfg b/.kokoro/presubmit/graalvm-native-a.cfg index 9a34e1cfe..640724a1f 100644 --- a/.kokoro/presubmit/graalvm-native-a.cfg +++ b/.kokoro/presubmit/graalvm-native-a.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_a:1.10.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_a:1.11.0" } env_vars: { diff --git a/.kokoro/presubmit/graalvm-native-b.cfg b/.kokoro/presubmit/graalvm-native-b.cfg index af0b6ecd2..a8faa2630 100644 --- a/.kokoro/presubmit/graalvm-native-b.cfg +++ b/.kokoro/presubmit/graalvm-native-b.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_b:1.10.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_b:1.11.0" } env_vars: { diff --git a/pom.xml b/pom.xml index 8fd2f4738..78d627429 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ com.google.cloud google-cloud-shared-config - 1.10.0 + 1.11.0 From 855dc06ade7468da73d57188c8c020d79bedad5d Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 27 Aug 2024 21:21:10 +0200 Subject: [PATCH 50/89] chore(deps): update dependency org.apache.maven.plugins:maven-site-plugin to v3.20.0 (#1473) --- bom/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bom/pom.xml b/bom/pom.xml index 0b7e3671e..9895030c9 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -91,7 +91,7 @@ org.apache.maven.plugins maven-site-plugin - 3.12.1 + 3.20.0 true diff --git a/pom.xml b/pom.xml index 78d627429..d50c349ac 100644 --- a/pom.xml +++ b/pom.xml @@ -280,7 +280,7 @@ org.apache.maven.plugins maven-site-plugin - 3.12.1 + 3.20.0 true From 0f88ef871695c671ed1001d8d7842043f8529eb6 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 27 Aug 2024 21:50:11 +0200 Subject: [PATCH 51/89] chore(deps): update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.0 (#1474) --- oauth2_http/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oauth2_http/pom.xml b/oauth2_http/pom.xml index b9615748b..62eae4213 100644 --- a/oauth2_http/pom.xml +++ b/oauth2_http/pom.xml @@ -152,7 +152,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.3.1 + 3.5.0 1200 sponge_log From 4a9d32ab81ce5c25be60f8085dd47e017847981a Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 27 Aug 2024 21:57:32 +0200 Subject: [PATCH 52/89] chore(deps): update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.0 (#1475) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d50c349ac..b969b030a 100644 --- a/pom.xml +++ b/pom.xml @@ -211,7 +211,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.3.1 + 3.5.0 sponge_log From 23e06388bf68b7dbc6856091d458734ca46bb03e Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 27 Aug 2024 22:05:51 +0200 Subject: [PATCH 53/89] chore(deps): update dependency com.google.http-client:google-http-client-bom to v1.45.0 (#1476) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b969b030a..172e6d7d9 100644 --- a/pom.xml +++ b/pom.xml @@ -69,7 +69,7 @@ UTF-8 - 1.44.2 + 1.45.0 4.13.2 33.2.1-android 2.0.29 From 11505f64deedb13e7b6150c2658628ca051287f8 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 27 Aug 2024 22:13:54 +0200 Subject: [PATCH 54/89] chore(deps): update dependency com.google.cloud:google-iam-admin to v3.43.0 (#1477) --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index afbdc5118..351ab59c7 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -50,7 +50,7 @@ com.google.cloud google-iam-admin - 3.42.0 + 3.43.0 From a19f3fb8cea89eba9f2e7c65fe140a24b3378246 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 27 Aug 2024 22:20:03 +0200 Subject: [PATCH 55/89] chore(deps): update dependency org.apache.maven.plugins:maven-dependency-plugin to v3.8.0 (#1478) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 172e6d7d9..63147cb6a 100644 --- a/pom.xml +++ b/pom.xml @@ -219,7 +219,7 @@ org.apache.maven.plugins maven-dependency-plugin - 3.7.1 + 3.8.0 org.codehaus.mojo From 308c99b01ec8c2a85840eb4994d759330ae9211a Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 27 Aug 2024 22:26:24 +0200 Subject: [PATCH 56/89] chore(deps): update dependency org.apache.maven.plugins:maven-checkstyle-plugin to v3.5.0 (#1479) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 63147cb6a..d95e46a36 100644 --- a/pom.xml +++ b/pom.xml @@ -249,7 +249,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.4.0 + 3.5.0 checkstyle From 87b0a8fec9b53f058b9ff8f0cc3a3147f6c4e55b Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 27 Aug 2024 22:49:32 +0200 Subject: [PATCH 57/89] chore(deps): update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.10.0 (#1480) --- bom/pom.xml | 2 +- pom.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bom/pom.xml b/bom/pom.xml index 9895030c9..957bbb822 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -83,7 +83,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.8.0 + 3.10.0 true diff --git a/pom.xml b/pom.xml index d95e46a36..928ef19ca 100644 --- a/pom.xml +++ b/pom.xml @@ -182,7 +182,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.8.0 + 3.10.0 8 false @@ -332,7 +332,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.8.0 + 3.10.0 html @@ -400,7 +400,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.8.0 + 3.10.0 attach-javadocs From fe6887b6d89e6729e5737543525394566ae4e370 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 27 Aug 2024 22:55:46 +0200 Subject: [PATCH 58/89] chore(deps): update dependency com.google.guava:guava to v33.3.0-android (#1472) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 928ef19ca..39447442e 100644 --- a/pom.xml +++ b/pom.xml @@ -71,7 +71,7 @@ UTF-8 1.45.0 4.13.2 - 33.2.1-android + 33.3.0-android 2.0.29 3.0.2 false From d7c9da7272459902c786b5d049eb0415031bc526 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Wed, 28 Aug 2024 15:44:05 +0200 Subject: [PATCH 59/89] chore(deps): update dependency com.google.cloud:libraries-bom to v26.45.0 (#1482) --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 351ab59c7..a62f4a695 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -30,7 +30,7 @@ com.google.cloud libraries-bom - 26.44.0 + 26.45.0 pom import From eb85167e8bfe9915470172bb7d908ea13b29433c Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Wed, 28 Aug 2024 15:37:15 -0400 Subject: [PATCH 60/89] chore: disable major version updates in renovate config (#1484) --- renovate.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/renovate.json b/renovate.json index 7b57a41af..359ba1f7c 100644 --- a/renovate.json +++ b/renovate.json @@ -24,6 +24,15 @@ } ], "packageRules": [ + { + "matchUpdateTypes": [ + "major" + ], + "matchPackagePatterns": [ + "*" + ], + "enabled": false + }, { "packagePatterns": [ "^com.google.guava:" From 079a06563114e359b74694b78aec687601a2f628 Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Wed, 28 Aug 2024 20:35:53 -0400 Subject: [PATCH 61/89] fix: ComputeEngineCredentials.createScoped should invalidate existing AccessToken (#1428) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #1387 ☕️ As described in the original issue, this looks like a regression introduced in https://github.com/googleapis/google-auth-library-java/commit/7e268611d2c2152e84702b1c67ca846902bbe2d5 when migrating from deprecated constructor to use builder. [Access token](https://cloud.google.com/docs/authentication/token-types#access-contents) is scoped and should be invalidated when scope changes. This PR include changes: - ComputeEngineCredentials.createScoped() should invalidate existing AccessToken - ComputeEngineCredentials.createScoped(newScopes, newDefaultScopes) should respect universe domain settings. - For testing, update to mock transport to support returning access token when url is scoped. Should return a different access token compared to default url with no scopes. --- .../auth/oauth2/ComputeEngineCredentials.java | 17 ++-- .../google/auth/oauth2/GoogleCredentials.java | 4 +- .../oauth2/ComputeEngineCredentialsTest.java | 85 ++++++++++++++----- .../DefaultCredentialsProviderTest.java | 14 ++- .../oauth2/MockMetadataServerTransport.java | 37 ++++++-- 5 files changed, 118 insertions(+), 39 deletions(-) diff --git a/oauth2_http/java/com/google/auth/oauth2/ComputeEngineCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ComputeEngineCredentials.java index 4fd1c1014..9996c045d 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ComputeEngineCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ComputeEngineCredentials.java @@ -48,6 +48,7 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Joiner; import com.google.common.base.MoreObjects.ToStringHelper; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.io.BufferedReader; @@ -155,21 +156,19 @@ private ComputeEngineCredentials(ComputeEngineCredentials.Builder builder) { /** Clones the compute engine account with the specified scopes. */ @Override public GoogleCredentials createScoped(Collection newScopes) { - ComputeEngineCredentials.Builder builder = - this.toBuilder().setHttpTransportFactory(transportFactory).setScopes(newScopes); - return new ComputeEngineCredentials(builder); + return createScoped(newScopes, ImmutableList.of()); } /** Clones the compute engine account with the specified scopes and default scopes. */ @Override public GoogleCredentials createScoped( Collection newScopes, Collection newDefaultScopes) { - ComputeEngineCredentials.Builder builder = - ComputeEngineCredentials.newBuilder() - .setHttpTransportFactory(transportFactory) - .setScopes(newScopes) - .setDefaultScopes(newDefaultScopes); - return new ComputeEngineCredentials(builder); + return this.toBuilder() + .setHttpTransportFactory(transportFactory) + .setScopes(newScopes) + .setDefaultScopes(newDefaultScopes) + .setAccessToken(null) + .build(); } /** diff --git a/oauth2_http/java/com/google/auth/oauth2/GoogleCredentials.java b/oauth2_http/java/com/google/auth/oauth2/GoogleCredentials.java index c0c8c3035..565ef4d7e 100644 --- a/oauth2_http/java/com/google/auth/oauth2/GoogleCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/GoogleCredentials.java @@ -427,8 +427,8 @@ public boolean createScopedRequired() { } /** - * If the credentials support scopes, creates a copy of the identity with the specified scopes; - * otherwise, returns the same instance. + * If the credentials support scopes, creates a copy of the identity with the specified scopes, + * invalidates the existing scoped access token; otherwise, return the same instance. * * @param scopes Collection of scopes to request. * @return GoogleCredentials with requested scopes. diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ComputeEngineCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ComputeEngineCredentialsTest.java index 3e0dc56ba..399456187 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ComputeEngineCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ComputeEngineCredentialsTest.java @@ -63,7 +63,9 @@ import java.util.List; import java.util.Map; import java.util.Queue; +import java.util.stream.Collectors; import java.util.stream.IntStream; +import java.util.stream.Stream; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -111,6 +113,16 @@ public class ComputeEngineCredentialsTest extends BaseSerializationTest { + "iTElDRU5TRV8xIiwNCiAgICAgICAiTElDRU5TRV8yIg0KICAgIF0NCiAgfSwNCiAgImlhdCI6IDE1NjQ1MTU4OTY" + "sDQogICJpc3MiOiAiaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tIiwNCiAgInN1YiI6ICIxMTIxNzkwNjI3MjA" + "zOTEzMDU4ODUiDQp9.redacted"; + private static final String ACCESS_TOKEN = "1/MkSJoj1xsli0AccessToken_NKPY2"; + private static final List SCOPES = Arrays.asList("foo", "bar"); + private static final String ACCESS_TOKEN_WITH_SCOPES = "1/MkSJoj1xsli0AccessTokenScoped_NKPY2"; + private static final Map SCOPE_TO_ACCESS_TOKEN_MAP = + Stream.of( + new String[][] { + {"default", ACCESS_TOKEN}, + {SCOPES.toString().replaceAll("\\s", ""), ACCESS_TOKEN_WITH_SCOPES}, + }) + .collect(Collectors.toMap(data -> data[0], data -> data[1])); @Test public void buildTokenUrlWithScopes_null_scopes() { @@ -215,7 +227,7 @@ public void buildScoped_explicitUniverse() throws IOException { (ComputeEngineCredentials) credentials.createScoped(Arrays.asList("foo")); assertEquals("some-universe", scopedCredentials.getUniverseDomain()); - assertEquals(true, scopedCredentials.isExplicitUniverseDomain()); + assertTrue(scopedCredentials.isExplicitUniverseDomain()); } @Test @@ -228,6 +240,33 @@ public void createScoped_defaultScopes() { assertEquals("foo", scopes.toArray()[0]); } + @Test + public void buildScoped_quotaProjectId() throws IOException { + ComputeEngineCredentials credentials = + ComputeEngineCredentials.newBuilder() + .setScopes(null) + .setQuotaProjectId("some-project-id") + .build(); + ComputeEngineCredentials scopedCredentials = + (ComputeEngineCredentials) credentials.createScoped(Arrays.asList("foo")); + + assertEquals("some-project-id", scopedCredentials.getQuotaProjectId()); + } + + @Test + public void buildDefaultScoped_explicitUniverse() throws IOException { + ComputeEngineCredentials credentials = + ComputeEngineCredentials.newBuilder() + .setScopes(null) + .setUniverseDomain("some-universe") + .build(); + ComputeEngineCredentials scopedCredentials = + (ComputeEngineCredentials) credentials.createScoped(null, Arrays.asList("foo")); + + assertEquals("some-universe", scopedCredentials.getUniverseDomain()); + assertTrue(scopedCredentials.isExplicitUniverseDomain()); + } + @Test public void create_scoped_correctMargins() { GoogleCredentials credentials = @@ -240,21 +279,37 @@ public void create_scoped_correctMargins() { @Test public void getRequestMetadata_hasAccessToken() throws IOException { - String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2"; MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory(); - transportFactory.transport.setAccessToken(accessToken); ComputeEngineCredentials credentials = ComputeEngineCredentials.newBuilder().setHttpTransportFactory(transportFactory).build(); Map> metadata = credentials.getRequestMetadata(CALL_URI); - TestUtils.assertContainsBearerToken(metadata, accessToken); + TestUtils.assertContainsBearerToken(metadata, ACCESS_TOKEN); + } + + @Test + public void getRequestMetadata_shouldInvalidateAccessTokenWhenScoped_newAccessTokenFromRefresh() + throws IOException { + MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory(); + ComputeEngineCredentials credentials = + ComputeEngineCredentials.newBuilder().setHttpTransportFactory(transportFactory).build(); + Map> metadata = credentials.getRequestMetadata(CALL_URI); + + TestUtils.assertContainsBearerToken(metadata, ACCESS_TOKEN); + + assertNotNull(credentials.getAccessToken()); + ComputeEngineCredentials scopedCredentialCopy = + (ComputeEngineCredentials) credentials.createScoped(SCOPES); + assertNull(scopedCredentialCopy.getAccessToken()); + Map> metadataForCopiedCredentials = + scopedCredentialCopy.getRequestMetadata(CALL_URI); + TestUtils.assertContainsBearerToken(metadataForCopiedCredentials, ACCESS_TOKEN_WITH_SCOPES); + TestUtils.assertNotContainsBearerToken(metadataForCopiedCredentials, ACCESS_TOKEN); } @Test public void getRequestMetadata_missingServiceAccount_throws() { - String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2"; MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory(); - transportFactory.transport.setAccessToken(accessToken); transportFactory.transport.setRequestStatusCode(HttpStatusCodes.STATUS_CODE_NOT_FOUND); ComputeEngineCredentials credentials = ComputeEngineCredentials.newBuilder().setHttpTransportFactory(transportFactory).build(); @@ -271,9 +326,7 @@ public void getRequestMetadata_missingServiceAccount_throws() { @Test public void getRequestMetadata_serverError_throws() { - String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2"; MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory(); - transportFactory.transport.setAccessToken(accessToken); transportFactory.transport.setRequestStatusCode(HttpStatusCodes.STATUS_CODE_SERVER_ERROR); ComputeEngineCredentials credentials = ComputeEngineCredentials.newBuilder().setHttpTransportFactory(transportFactory).build(); @@ -481,11 +534,9 @@ public LowLevelHttpResponse execute() throws IOException { @Test public void sign_sameAs() throws IOException { MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory(); - final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2"; String defaultAccountEmail = "mail@mail.com"; byte[] expectedSignature = {0xD, 0xE, 0xA, 0xD}; - transportFactory.transport.setAccessToken(accessToken); transportFactory.transport.setServiceAccountEmail(defaultAccountEmail); transportFactory.transport.setSignature(expectedSignature); ComputeEngineCredentials credentials = @@ -497,10 +548,8 @@ public void sign_sameAs() throws IOException { @Test public void sign_getAccountFails() throws IOException { MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory(); - final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2"; byte[] expectedSignature = {0xD, 0xE, 0xA, 0xD}; - transportFactory.transport.setAccessToken(accessToken); transportFactory.transport.setSignature(expectedSignature); ComputeEngineCredentials credentials = ComputeEngineCredentials.newBuilder().setHttpTransportFactory(transportFactory).build(); @@ -517,7 +566,6 @@ public void sign_getAccountFails() throws IOException { @Test public void sign_accessDenied_throws() { MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory(); - final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2"; String defaultAccountEmail = "mail@mail.com"; transportFactory.transport = @@ -538,7 +586,7 @@ public LowLevelHttpResponse execute() throws IOException { } }; - transportFactory.transport.setAccessToken(accessToken); + transportFactory.transport.setAccessToken(ACCESS_TOKEN); transportFactory.transport.setServiceAccountEmail(defaultAccountEmail); ComputeEngineCredentials credentials = @@ -558,7 +606,6 @@ public LowLevelHttpResponse execute() throws IOException { @Test public void sign_serverError_throws() { MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory(); - final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2"; String defaultAccountEmail = "mail@mail.com"; transportFactory.transport = @@ -579,7 +626,7 @@ public LowLevelHttpResponse execute() throws IOException { } }; - transportFactory.transport.setAccessToken(accessToken); + transportFactory.transport.setAccessToken(ACCESS_TOKEN); transportFactory.transport.setServiceAccountEmail(defaultAccountEmail); ComputeEngineCredentials credentials = @@ -808,7 +855,6 @@ public void getUniverseDomain_fromMetadata_non404error_throws() throws IOExcepti @Test public void sign_emptyContent_throws() { MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory(); - String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2"; String defaultAccountEmail = "mail@mail.com"; transportFactory.transport = @@ -828,7 +874,7 @@ public LowLevelHttpResponse execute() throws IOException { } }; - transportFactory.transport.setAccessToken(accessToken); + transportFactory.transport.setAccessToken(ACCESS_TOKEN); transportFactory.transport.setServiceAccountEmail(defaultAccountEmail); ComputeEngineCredentials credentials = @@ -930,7 +976,8 @@ public void idTokenWithAudience_license() throws IOException { static class MockMetadataServerTransportFactory implements HttpTransportFactory { - MockMetadataServerTransport transport = new MockMetadataServerTransport(); + MockMetadataServerTransport transport = + new MockMetadataServerTransport(SCOPE_TO_ACCESS_TOKEN_MAP); @Override public HttpTransport create() { diff --git a/oauth2_http/javatests/com/google/auth/oauth2/DefaultCredentialsProviderTest.java b/oauth2_http/javatests/com/google/auth/oauth2/DefaultCredentialsProviderTest.java index 088600e04..3f0b2f1a5 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/DefaultCredentialsProviderTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/DefaultCredentialsProviderTest.java @@ -46,7 +46,6 @@ import com.google.api.client.testing.http.MockLowLevelHttpRequest; import com.google.auth.TestUtils; import com.google.auth.http.HttpTransportFactory; -import com.google.auth.oauth2.ComputeEngineCredentialsTest.MockMetadataServerTransportFactory; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.File; @@ -306,7 +305,6 @@ public void getDefaultCredentials_appEngineSkipWorks_retrievesCloudShellCredenti @Test public void getDefaultCredentials_compute_providesToken() throws IOException { MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory(); - transportFactory.transport.setAccessToken(ACCESS_TOKEN); TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider(); GoogleCredentials defaultCredentials = testProvider.getDefaultCredentials(transportFactory); @@ -331,7 +329,6 @@ public void getDefaultCredentials_cloudshell() throws IOException { @Test public void getDefaultCredentials_cloudshell_withComputCredentialsPresent() throws IOException { MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory(); - transportFactory.transport.setAccessToken(ACCESS_TOKEN); TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider(); testProvider.setEnv(DefaultCredentialsProvider.CLOUD_SHELL_ENV_VAR, "4"); @@ -463,7 +460,6 @@ public void getDefaultCredentials_quota_project() throws IOException { @Test public void getDefaultCredentials_compute_quotaProject() throws IOException { MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory(); - transportFactory.transport.setAccessToken(ACCESS_TOKEN); TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider(); testProvider.setEnv( DefaultCredentialsProvider.QUOTA_PROJECT_ENV_VAR, QUOTA_PROJECT_FROM_ENVIRONMENT); @@ -887,4 +883,14 @@ public HttpTransport create() { return transport; } } + + static class MockMetadataServerTransportFactory implements HttpTransportFactory { + + MockMetadataServerTransport transport = new MockMetadataServerTransport(ACCESS_TOKEN); + + @Override + public HttpTransport create() { + return transport; + } + } } diff --git a/oauth2_http/javatests/com/google/auth/oauth2/MockMetadataServerTransport.java b/oauth2_http/javatests/com/google/auth/oauth2/MockMetadataServerTransport.java index 66878d4c6..c1f0ac4b0 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/MockMetadataServerTransport.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/MockMetadataServerTransport.java @@ -38,6 +38,7 @@ import com.google.api.client.testing.http.MockHttpTransport; import com.google.api.client.testing.http.MockLowLevelHttpRequest; import com.google.api.client.testing.http.MockLowLevelHttpResponse; +import com.google.common.base.Splitter; import com.google.common.io.BaseEncoding; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -45,13 +46,14 @@ import java.net.URL; import java.net.URLDecoder; import java.util.HashMap; +import java.util.List; import java.util.Map; /** Transport that simulates the GCE metadata server for access tokens. */ public class MockMetadataServerTransport extends MockHttpTransport { - private String accessToken; - + // key are scopes as in request url string following "?scopes=" + private Map scopesToAccessToken; private Integer requestStatusCode; private String serviceAccountEmail; @@ -62,8 +64,25 @@ public class MockMetadataServerTransport extends MockHttpTransport { public MockMetadataServerTransport() {} + public MockMetadataServerTransport(String accessToken) { + setAccessToken(accessToken); + } + + public MockMetadataServerTransport(Map accessTokenMap) { + for (String scope : accessTokenMap.keySet()) { + setAccessToken(scope, accessTokenMap.get(scope)); + } + } + public void setAccessToken(String accessToken) { - this.accessToken = accessToken; + setAccessToken("default", accessToken); + } + + public void setAccessToken(String scopes, String accessToken) { + if (scopesToAccessToken == null) { + scopesToAccessToken = new HashMap<>(); + } + scopesToAccessToken.put(scopes, accessToken); } public void setRequestStatusCode(Integer requestStatusCode) { @@ -84,7 +103,7 @@ public void setIdToken(String idToken) { @Override public LowLevelHttpRequest buildRequest(String method, String url) throws IOException { - if (url.equals(ComputeEngineCredentials.getTokenServerEncodedUrl())) { + if (url.startsWith(ComputeEngineCredentials.getTokenServerEncodedUrl())) { return getMockRequestForTokenEndpoint(url); } else if (isGetServiceAccountsUrl(url)) { return getMockRequestForServiceAccount(url); @@ -164,7 +183,15 @@ public LowLevelHttpResponse execute() throws IOException { // Create the JSON response GenericJson refreshContents = new GenericJson(); refreshContents.setFactory(OAuth2Utils.JSON_FACTORY); - refreshContents.put("access_token", accessToken); + + List urlParsed = Splitter.on("?scopes=").splitToList(url); + if (urlParsed.size() == 1) { + // no scopes specified, return access token correspoinding to default scopes + refreshContents.put("access_token", scopesToAccessToken.get("default")); + } else { + refreshContents.put( + "access_token", scopesToAccessToken.get("[" + urlParsed.get(1) + "]")); + } refreshContents.put("expires_in", 3600000); refreshContents.put("token_type", "Bearer"); String refreshText = refreshContents.toPrettyString(); From 241869121b7e8497ed004a8b79fa09811253b9f6 Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Thu, 29 Aug 2024 10:08:53 -0400 Subject: [PATCH 62/89] chore: setup 1.23.x lts branch. (#1457) --- .github/release-please.yml | 4 ++++ .github/sync-repo-settings.yaml | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/.github/release-please.yml b/.github/release-please.yml index de249f23a..ef849857b 100644 --- a/.github/release-please.yml +++ b/.github/release-please.yml @@ -30,3 +30,7 @@ branches: handleGHRelease: true releaseType: java-backport branch: 1.20.x + - bumpMinorPreMajor: true + handleGHRelease: true + releaseType: java-backport + branch: 1.23.x \ No newline at end of file diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index e64489953..7cf623cb8 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -105,6 +105,18 @@ branchProtectionRules: requiredApprovingReviewCount: 1 requiresCodeOwnerReviews: true requiresStrictStatusChecks: true + - pattern: 1.23.x + isAdminEnforced: true + requiredStatusCheckContexts: + - dependencies (17) + - lint + - clirr + - units (8) + - units (11) + - cla/google + requiredApprovingReviewCount: 1 + requiresCodeOwnerReviews: true + requiresStrictStatusChecks: true permissionRules: - team: Googlers permission: pull From 4fcf83e0f96de0e6323b85b9a47119a257b37e90 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Thu, 29 Aug 2024 15:26:24 +0000 Subject: [PATCH 63/89] feat: Support retrieving ID Token from IAM endpoint for ServiceAccountCredentials (#1433) * feat: Support retrieving ID Token from IAM endpoint for ServiceAccountCredentials * chore: Update logic to use non-GDU IAM Endpoint URL * chore: Reformat the logic * chore: Refactor to use MockIAMCredentialsServiceTransportFactory * chore: Update tests * chore: Update tests * Update oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java Co-authored-by: Min Zhu * chore: Fix lint issues * chore: Fix lint issues * chore: Address PR comments * chore: Add comment for initializing iamIdTokenURI in method --------- Co-authored-by: Min Zhu --- .../com/google/auth/oauth2/OAuth2Utils.java | 4 + .../oauth2/ServiceAccountCredentials.java | 116 +++++++-- .../auth/oauth2/GoogleCredentialsTest.java | 37 +-- .../com/google/auth/oauth2/IamUtilsTest.java | 119 +++++---- .../oauth2/ImpersonatedCredentialsTest.java | 243 +++++++++--------- .../MockIAMCredentialsServiceTransport.java | 24 +- ...IAMCredentialsServiceTransportFactory.java | 56 ++++ .../oauth2/ServiceAccountCredentialsTest.java | 94 +++++-- 8 files changed, 455 insertions(+), 238 deletions(-) create mode 100644 oauth2_http/javatests/com/google/auth/oauth2/MockIAMCredentialsServiceTransportFactory.java diff --git a/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java b/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java index b83a571d3..2fb0bda66 100644 --- a/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java +++ b/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java @@ -75,6 +75,10 @@ class OAuth2Utils { static final String TOKEN_TYPE_TOKEN_EXCHANGE = "urn:ietf:params:oauth:token-type:token-exchange"; static final String GRANT_TYPE_JWT_BEARER = "urn:ietf:params:oauth:grant-type:jwt-bearer"; + // generateIdToken endpoint is to be formatted with universe domain and client email + static final String IAM_ID_TOKEN_ENDPOINT_FORMAT = + "https://iamcredentials.%s/v1/projects/-/serviceAccounts/%s:generateIdToken"; + static final URI TOKEN_SERVER_URI = URI.create("https://oauth2.googleapis.com/token"); static final URI TOKEN_REVOKE_URI = URI.create("https://oauth2.googleapis.com/revoke"); static final URI USER_AUTH_URI = URI.create("https://accounts.google.com/o/oauth2/auth"); diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java index e8264399a..21bf619b4 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java @@ -36,6 +36,8 @@ import com.google.api.client.http.GenericUrl; import com.google.api.client.http.HttpBackOffIOExceptionHandler; import com.google.api.client.http.HttpBackOffUnsuccessfulResponseHandler; +import com.google.api.client.http.HttpContent; +import com.google.api.client.http.HttpHeaders; import com.google.api.client.http.HttpRequest; import com.google.api.client.http.HttpRequestFactory; import com.google.api.client.http.HttpResponse; @@ -52,9 +54,12 @@ import com.google.auth.Credentials; import com.google.auth.RequestMetadataCallback; import com.google.auth.ServiceAccountSigner; +import com.google.auth.http.AuthHttpConstants; import com.google.auth.http.HttpTransportFactory; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.MoreObjects.ToStringHelper; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.io.IOException; @@ -547,7 +552,9 @@ public AccessToken refreshAccessToken() throws IOException { } /** - * Returns a Google ID Token from the metadata server on ComputeEngine. + * Returns a Google ID Token from either the Oauth or IAM Endpoint. For Credentials that are in + * the Google Default Universe (googleapis.com), the ID Token will be retrieved from the Oauth + * Endpoint. Otherwise, it will be retrieved from the IAM Endpoint. * * @param targetAudience the aud: field the IdToken should include. * @param options list of Credential specific options for the token. Currently, unused for @@ -558,21 +565,90 @@ public AccessToken refreshAccessToken() throws IOException { @Override public IdToken idTokenWithAudience(String targetAudience, List

This flow works as follows: + * + *

    + *
  1. Create a self-signed jwt with `https://www.googleapis.com/auth/iam` as the scope. + *
  2. Use the self-signed jwt as the access token, and make a POST request to IAM + * generateIdToken endpoint. + *
  3. If the request is successfully, it will return {"token":"the ID token"}. Extract the ID + * token. + *
+ */ + private IdToken getIdTokenIamEndpoint(String targetAudience) throws IOException { + JwtCredentials selfSignedJwtCredentials = + createSelfSignedJwtCredentials( + null, ImmutableList.of("https://www.googleapis.com/auth/iam")); + Map> responseMetadata = selfSignedJwtCredentials.getRequestMetadata(null); + // JwtCredentials will return a map with one entry ("Authorization" -> List with size 1) + String accessToken = responseMetadata.get(AuthHttpConstants.AUTHORIZATION).get(0); + + // Do not check user options. These params are always set regardless of options configured + Map requestParams = + ImmutableMap.of("audience", targetAudience, "includeEmail", "true", "useEmailAzp", "true"); + GenericData tokenRequest = new GenericData(); + requestParams.forEach(tokenRequest::set); UrlEncodedContent content = new UrlEncodedContent(tokenRequest); + // Create IAM Token URI in this method instead of in the constructor because + // `getUniverseDomain()` throws an IOException that would need to be caught + URI iamIdTokenUri = + URI.create( + String.format( + OAuth2Utils.IAM_ID_TOKEN_ENDPOINT_FORMAT, getUniverseDomain(), clientEmail)); + HttpRequest request = buildIdTokenRequest(iamIdTokenUri, transportFactory, content); + // Use the Access Token from the SSJWT to request the ID Token from IAM Endpoint + request.setHeaders(new HttpHeaders().set(AuthHttpConstants.AUTHORIZATION, accessToken)); + HttpResponse httpResponse = executeRequest(request); + + GenericData responseData = httpResponse.parseAs(GenericData.class); + // IAM Endpoint returns `token` instead of `id_token` + String rawToken = OAuth2Utils.validateString(responseData, "token", PARSE_ERROR_PREFIX); + return IdToken.create(rawToken); + } + + // Build a default POST HttpRequest to be used for both Oauth and IAM endpoints + private HttpRequest buildIdTokenRequest( + URI uri, HttpTransportFactory transportFactory, HttpContent content) throws IOException { + JsonFactory jsonFactory = OAuth2Utils.JSON_FACTORY; HttpRequestFactory requestFactory = transportFactory.create().createRequestFactory(); - HttpRequest request = requestFactory.buildPostRequest(new GenericUrl(tokenServerUri), content); + HttpRequest request = requestFactory.buildPostRequest(new GenericUrl(uri), content); request.setParser(new JsonObjectParser(jsonFactory)); + return request; + } + + private HttpResponse executeRequest(HttpRequest request) throws IOException { HttpResponse response; try { response = request.execute(); @@ -583,11 +659,7 @@ public IdToken idTokenWithAudience(String targetAudience, List
From d62d06e3076b0036ed27f0a469cbb6565e08879b Mon Sep 17 00:00:00 2001 From: Burke Davison <40617934+burkedavison@users.noreply.github.com> Date: Thu, 29 Aug 2024 11:54:31 -0400 Subject: [PATCH 65/89] chore: use assertEquals to improve test error message (#1470) * chore: use assertEquals to improve test error message * chore: lint --------- Co-authored-by: Min Zhu Co-authored-by: Lawrence Qiu --- .../com/google/auth/oauth2/ExecutableResponseTest.java | 8 ++++---- .../com/google/auth/oauth2/PluggableAuthHandlerTest.java | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ExecutableResponseTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ExecutableResponseTest.java index 6020ad51e..e6991776d 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ExecutableResponseTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ExecutableResponseTest.java @@ -63,8 +63,8 @@ public void constructor_successOidcResponse() throws IOException { assertEquals(EXECUTABLE_SUPPORTED_MAX_VERSION, response.getVersion()); assertEquals(TOKEN_TYPE_OIDC, response.getTokenType()); assertEquals(ID_TOKEN, response.getSubjectToken()); - assertTrue( - Instant.now().getEpochSecond() + EXPIRATION_DURATION == response.getExpirationTime()); + assertEquals( + Instant.now().getEpochSecond() + EXPIRATION_DURATION, (long) response.getExpirationTime()); } @Test @@ -93,8 +93,8 @@ public void constructor_successSamlResponse() throws IOException { assertEquals(EXECUTABLE_SUPPORTED_MAX_VERSION, response.getVersion()); assertEquals(TOKEN_TYPE_SAML, response.getTokenType()); assertEquals(SAML_RESPONSE, response.getSubjectToken()); - assertTrue( - Instant.now().getEpochSecond() + EXPIRATION_DURATION == response.getExpirationTime()); + assertEquals( + Instant.now().getEpochSecond() + EXPIRATION_DURATION, (long) response.getExpirationTime()); } @Test diff --git a/oauth2_http/javatests/com/google/auth/oauth2/PluggableAuthHandlerTest.java b/oauth2_http/javatests/com/google/auth/oauth2/PluggableAuthHandlerTest.java index 121a1186a..9211af7d5 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/PluggableAuthHandlerTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/PluggableAuthHandlerTest.java @@ -741,8 +741,8 @@ public void getExecutableResponse_oidcResponse() throws IOException, Interrupted assertTrue(response.isSuccessful()); assertEquals(TOKEN_TYPE_OIDC, response.getTokenType()); assertEquals(ID_TOKEN, response.getSubjectToken()); - assertTrue( - Instant.now().getEpochSecond() + EXPIRATION_DURATION == response.getExpirationTime()); + assertEquals( + Instant.now().getEpochSecond() + EXPIRATION_DURATION, (long) response.getExpirationTime()); // Current env map should include the mappings from options. assertEquals(4, currentEnv.size()); assertEquals(expectedMap, currentEnv); @@ -788,8 +788,8 @@ public void getExecutableResponse_samlResponse() throws IOException, Interrupted assertTrue(response.isSuccessful()); assertEquals(TOKEN_TYPE_SAML, response.getTokenType()); assertEquals(SAML_RESPONSE, response.getSubjectToken()); - assertTrue( - Instant.now().getEpochSecond() + EXPIRATION_DURATION == response.getExpirationTime()); + assertEquals( + Instant.now().getEpochSecond() + EXPIRATION_DURATION, (long) response.getExpirationTime()); // Current env map should include the mappings from options. assertEquals(4, currentEnv.size()); From 0412ec30e68a23aaac453784c3d41e4c0ba55bc2 Mon Sep 17 00:00:00 2001 From: Joe Wang <106995533+JoeWang1127@users.noreply.github.com> Date: Fri, 30 Aug 2024 11:48:08 +0000 Subject: [PATCH 66/89] chore: remove owlbot (#1490) --- .github/.OwlBot.lock.yaml | 17 ------- .github/.OwlBot.yaml | 16 ------- .github/generated-files-bot.yml | 12 ----- codecov.yaml | 4 -- owlbot.py | 44 ------------------ synth.metadata | 82 --------------------------------- 6 files changed, 175 deletions(-) delete mode 100644 .github/.OwlBot.lock.yaml delete mode 100644 .github/.OwlBot.yaml delete mode 100644 .github/generated-files-bot.yml delete mode 100644 codecov.yaml delete mode 100644 owlbot.py delete mode 100644 synth.metadata diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml deleted file mode 100644 index 359fe71c1..000000000 --- a/.github/.OwlBot.lock.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2024 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. -docker: - image: gcr.io/cloud-devrel-public-resources/owlbot-java:latest - digest: sha256:72f0d373307d128b2cb720c5cb4d90b31f0e86529dd138c632710ae0c69efae3 -# created: 2024-06-05T18:32:21.724930324Z diff --git a/.github/.OwlBot.yaml b/.github/.OwlBot.yaml deleted file mode 100644 index 5d9a9d8b5..000000000 --- a/.github/.OwlBot.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright 2021 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. - -docker: - image: "gcr.io/cloud-devrel-public-resources/owlbot-java:latest" diff --git a/.github/generated-files-bot.yml b/.github/generated-files-bot.yml deleted file mode 100644 index c644a24e1..000000000 --- a/.github/generated-files-bot.yml +++ /dev/null @@ -1,12 +0,0 @@ -externalManifests: -- type: json - file: 'synth.metadata' - jsonpath: '$.generatedFiles[*]' -- type: json - file: '.github/readme/synth.metadata/synth.metadata' - jsonpath: '$.generatedFiles[*]' -ignoreAuthors: -- 'renovate-bot' -- 'yoshi-automation' -- 'release-please[bot]' -- 'gcf-owl-bot[bot]' diff --git a/codecov.yaml b/codecov.yaml deleted file mode 100644 index 5724ea947..000000000 --- a/codecov.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -codecov: - ci: - - source.cloud.google.com diff --git a/owlbot.py b/owlbot.py deleted file mode 100644 index bb4d1145c..000000000 --- a/owlbot.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2021 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 -# -# https://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 synthtool as s -from synthtool.languages import java - - -for library in s.get_staging_dirs(): - # put any special-case replacements here - s.move(library) - -s.remove_staging_dirs() -java.common_templates( - excludes=[ - "LICENSE", - "README.md", - "java.header", - "checkstyle.xml", - "renovate.json", - "license-checks.xml", - "samples/**", - ".github/workflows/approve-readme.yaml", - ".github/workflows/samples.yaml", - ".github/CODEOWNERS", - ".kokoro/nightly/integration.cfg", - ".kokoro/presubmit/integration.cfg", - ".kokoro/presubmit/graalvm-native.cfg", - ".kokoro/presubmit/graalvm-native-17.cfg", - ".kokoro/build.sh", - ".kokoro/requirements.in", - ".kokoro/requirements.txt" - ] -) diff --git a/synth.metadata b/synth.metadata deleted file mode 100644 index 751e9d043..000000000 --- a/synth.metadata +++ /dev/null @@ -1,82 +0,0 @@ -{ - "sources": [ - { - "git": { - "name": ".", - "remote": "https://github.com/googleapis/google-auth-library-java.git", - "sha": "998b402420f9d309a1d432728c093f2fc7a7d51b" - } - }, - { - "git": { - "name": "synthtool", - "remote": "https://github.com/googleapis/synthtool.git", - "sha": "396d9b84a1e93880f5bf88b59ecd38a0a6dffc5e" - } - } - ], - "generatedFiles": [ - ".github/CODEOWNERS", - ".github/ISSUE_TEMPLATE/bug_report.md", - ".github/ISSUE_TEMPLATE/feature_request.md", - ".github/ISSUE_TEMPLATE/support_request.md", - ".github/PULL_REQUEST_TEMPLATE.md", - ".github/blunderbuss.yml", - ".github/generated-files-bot.yml", - ".github/release-please.yml", - ".github/release-trigger.yml", - ".github/snippet-bot.yml", - ".github/sync-repo-settings.yaml", - ".github/trusted-contribution.yml", - ".github/workflows/auto-release.yaml", - ".github/workflows/ci.yaml", - ".kokoro/build.bat", - ".kokoro/build.sh", - ".kokoro/coerce_logs.sh", - ".kokoro/common.cfg", - ".kokoro/common.sh", - ".kokoro/continuous/common.cfg", - ".kokoro/continuous/java8.cfg", - ".kokoro/dependencies.sh", - ".kokoro/nightly/common.cfg", - ".kokoro/nightly/java11.cfg", - ".kokoro/nightly/java7.cfg", - ".kokoro/nightly/java8-osx.cfg", - ".kokoro/nightly/java8-win.cfg", - ".kokoro/nightly/java8.cfg", - ".kokoro/nightly/samples.cfg", - ".kokoro/populate-secrets.sh", - ".kokoro/presubmit/clirr.cfg", - ".kokoro/presubmit/common.cfg", - ".kokoro/presubmit/dependencies.cfg", - ".kokoro/presubmit/java11.cfg", - ".kokoro/presubmit/java7.cfg", - ".kokoro/presubmit/java8-osx.cfg", - ".kokoro/presubmit/java8-win.cfg", - ".kokoro/presubmit/java8.cfg", - ".kokoro/presubmit/linkage-monitor.cfg", - ".kokoro/presubmit/lint.cfg", - ".kokoro/presubmit/samples.cfg", - ".kokoro/readme.sh", - ".kokoro/release/bump_snapshot.cfg", - ".kokoro/release/common.cfg", - ".kokoro/release/common.sh", - ".kokoro/release/drop.cfg", - ".kokoro/release/drop.sh", - ".kokoro/release/promote.cfg", - ".kokoro/release/promote.sh", - ".kokoro/release/publish_javadoc.cfg", - ".kokoro/release/publish_javadoc.sh", - ".kokoro/release/publish_javadoc11.cfg", - ".kokoro/release/publish_javadoc11.sh", - ".kokoro/release/snapshot.cfg", - ".kokoro/release/snapshot.sh", - ".kokoro/release/stage.cfg", - ".kokoro/release/stage.sh", - ".kokoro/trampoline.sh", - "CODE_OF_CONDUCT.md", - "CONTRIBUTING.md", - "SECURITY.md", - "codecov.yaml" - ] -} \ No newline at end of file From f07d19a505e0ff8c43c3366bcda6350df6dcb3bc Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Tue, 3 Sep 2024 16:02:15 +0000 Subject: [PATCH 67/89] chore: Add Cloud Java as Owners of Java Auth Library (#1469) * chore: Add Cloud Java as Owners of Java Auth Library * chore: Add Cloud Java as Owners of Java Auth Library --- .github/CODEOWNERS | 122 ++++++++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 63 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 08eaf507a..5e5216e71 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -4,71 +4,67 @@ # For syntax help see: # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax -# The @googleapis/googleapis-auth is the default owner for changes in this repo -* @googleapis/yoshi-java @googleapis/googleapis-auth - -# for handwritten libraries, keep codeowner_team in .repo-metadata.json as owner -**/*.java @googleapis/googleapis-auth - +# The @googleapis/cloud-java-team-teamsync is the default owner for changes in this repo +* @googleapis/cloud-java-team-teamsync @googleapis/googleapis-auth # The java-samples-reviewers team is the default owner for samples changes -samples/**/*.java @googleapis/java-samples-reviewers +samples/**/*.java @googleapis/java-samples-reviewers # Generated snippets should not be owned by samples reviewers -samples/snippets/generated/ @googleapis/yoshi-java +samples/snippets/generated/ @googleapis/cloud-java-team-teamsync -# 3PI-related files and related base classes - joint ownership between googleapis-auth and aion-sdk -oauth2_http/java/com/google/auth/oauth2/ActingParty.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/AwsCredentials.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/AwsSecurityCredentialsSupplier.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/AwsDates.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/AwsRequestSignature.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/AwsRequestSigner.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/AwsSecurityCredentials.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/CredentialAccessBoundary.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/DefaultCredentialsProvider.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/DownscopedCredentials.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/EnvironmentProvider.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/ExecutableHandler.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/ExecutableResponse.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/ExternalAccountCredentials.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/FileIdentityPoolSubjectTokenSupplier.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/GoogleCredentials.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/IdentityPoolCredentials.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/IdentityPoolSubjectTokenSupplier.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/ImpersonatedCredentials.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/InternalAwsSecurityCredentialsSupplier.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/OAuth2Credentials.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/OAuth2CredentialsWithRefresh.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/OAuthException.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/PluggableAuthCredentials.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/PluggableAuthException.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/PluggableAuthHandler.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/StsRequestHandler.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/StsTokenExchangeRequest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/StsTokenExchangeResponse.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/SystemEnvironmentProvider.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/java/com/google/auth/oauth2/UrlIdentityPoolSubjectTokenSupplier.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/AwsCredentialsTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/AwsRequestSignerTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/CredentialAccessBoundaryTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/DefaultCredentialsProviderTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/DownscopedCredentialsTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/ExecutableResponseTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/ExternalAccountCredentialsTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/ITDownscopingTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/ITWorkloadIdentityFederationTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/IdentityPoolCredentialsTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/ImpersonatedCredentialsTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/InternalAwsSecurityCredentialsSupplierTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/MockExternalAccountCredentialsTransport.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/MockStsTransport.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/OAuth2CredentialsTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/OAuth2CredentialsWithRefreshTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/OAuthExceptionTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/PluggableAuthCredentialsTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/PluggableAuthExceptionTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/PluggableAuthHandlerTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/StsRequestHandlerTest.java @googleapis/googleapis-auth @googleapis/aion-sdk -oauth2_http/javatests/com/google/auth/TestEnvironmentProvider.java @googleapis/googleapis-auth @googleapis/aion-sdk -README.md @googleapis/googleapis-auth @googleapis/aion-sdk +# 3PI-related files and related base classes - joint ownership between googleapis-auth, aion-sdk, and cloud-java-team +oauth2_http/java/com/google/auth/oauth2/ActingParty.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/AwsCredentials.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/AwsSecurityCredentialsSupplier.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/AwsDates.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/AwsRequestSignature.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/AwsRequestSigner.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/AwsSecurityCredentials.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/CredentialAccessBoundary.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/DefaultCredentialsProvider.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/DownscopedCredentials.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/EnvironmentProvider.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/ExecutableHandler.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/ExecutableResponse.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/ExternalAccountCredentials.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/FileIdentityPoolSubjectTokenSupplier.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/GoogleCredentials.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/IdentityPoolCredentials.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/IdentityPoolSubjectTokenSupplier.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/ImpersonatedCredentials.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/InternalAwsSecurityCredentialsSupplier.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/OAuth2Credentials.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/OAuth2CredentialsWithRefresh.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/OAuthException.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/PluggableAuthCredentials.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/PluggableAuthException.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/PluggableAuthHandler.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/StsRequestHandler.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/StsTokenExchangeRequest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/StsTokenExchangeResponse.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/SystemEnvironmentProvider.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/java/com/google/auth/oauth2/UrlIdentityPoolSubjectTokenSupplier.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/AwsCredentialsTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/AwsRequestSignerTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/CredentialAccessBoundaryTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/DefaultCredentialsProviderTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/DownscopedCredentialsTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/ExecutableResponseTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/ExternalAccountCredentialsTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/ITDownscopingTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/ITWorkloadIdentityFederationTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/IdentityPoolCredentialsTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/ImpersonatedCredentialsTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/InternalAwsSecurityCredentialsSupplierTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/MockExternalAccountCredentialsTransport.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/MockStsTransport.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/OAuth2CredentialsTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/OAuth2CredentialsWithRefreshTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/OAuthExceptionTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/PluggableAuthCredentialsTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/PluggableAuthExceptionTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/PluggableAuthHandlerTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/StsRequestHandlerTest.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +oauth2_http/javatests/com/google/auth/TestEnvironmentProvider.java @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync +README.md @googleapis/googleapis-auth @googleapis/aion-sdk @googleapis/cloud-java-team-teamsync \ No newline at end of file From f26fee78d69fce1aaa00dbd5548f3e0266ee6441 Mon Sep 17 00:00:00 2001 From: Lawrence Qiu Date: Tue, 3 Sep 2024 20:48:22 +0000 Subject: [PATCH 68/89] fix: Invalidate the SA's AccessToken when createScoped() is called (#1489) * fix: Invalidate the SA's AccessToken when createScoped() is called * chore: Add comments for invalidating the access token * chore: Fix formatting * chore: Address PR comments --- .../oauth2/ServiceAccountCredentials.java | 7 ++++-- .../oauth2/ServiceAccountCredentialsTest.java | 25 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java index 21bf619b4..65ed844a8 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java @@ -684,14 +684,17 @@ public GoogleCredentials createScoped(Collection newScopes) { } /** - * Clones the service account with the specified scopes. + * Clones the service account with the specified scopes. The Access Token is invalidated even if + * the same scopes are provided. Access Tokens contain information of the internal values (i.e. + * scope). If an internal value (scope) is modified, then the existing Access Token is no longer + * valid and should not be re-used. * *

Should be called before use for instances with empty scopes. */ @Override public GoogleCredentials createScoped( Collection newScopes, Collection newDefaultScopes) { - return this.toBuilder().setScopes(newScopes, newDefaultScopes).build(); + return this.toBuilder().setScopes(newScopes, newDefaultScopes).setAccessToken(null).build(); } /** diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java index 04555864e..f79338f7a 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java @@ -1705,6 +1705,31 @@ public void onFailure(Throwable exception) { assertTrue("Should have run onSuccess() callback", success.get()); } + @Test + public void createScopes_existingAccessTokenInvalidated() throws IOException { + PrivateKey privateKey = OAuth2Utils.privateKeyFromPkcs8(PRIVATE_KEY_PKCS8); + MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); + transportFactory.transport.addServiceAccount(CLIENT_EMAIL, ACCESS_TOKEN); + GoogleCredentials credentials = + ServiceAccountCredentials.newBuilder() + .setClientId(CLIENT_ID) + .setClientEmail(CLIENT_EMAIL) + .setPrivateKey(privateKey) + .setPrivateKeyId(PRIVATE_KEY_ID) + .setProjectId(PROJECT_ID) + .setQuotaProjectId("my-quota-project-id") + .setHttpTransportFactory(transportFactory) + .setScopes(SCOPES) + .build(); + TestUtils.assertContainsBearerToken(credentials.getRequestMetadata(CALL_URI), ACCESS_TOKEN); + + // Calling createScoped() again will invalidate the existing access token and calling + // `refresh()` is required to get a new Access Token. + credentials = credentials.createScoped("RANDOM_SCOPES"); + AccessToken newAccessToken = credentials.getAccessToken(); + assertNull(newAccessToken); + } + private void verifyJwtAccess(Map> metadata, String expectedScopeClaim) throws IOException { assertNotNull(metadata); From ed2e283a9a4c8b4ec8fc46c8c6f9a39345788a97 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Wed, 4 Sep 2024 17:25:45 -0400 Subject: [PATCH 69/89] chore(main): release 1.25.0 (#1488) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 13 +++++++++++++ appengine/pom.xml | 2 +- bom/pom.xml | 2 +- credentials/pom.xml | 2 +- oauth2_http/pom.xml | 2 +- pom.xml | 2 +- versions.txt | 12 ++++++------ 7 files changed, 24 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fc7b4f1c..b414daba7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## [1.25.0](https://github.com/googleapis/google-auth-library-java/compare/v1.24.1...v1.25.0) (2024-09-03) + + +### Features + +* Support retrieving ID Token from IAM endpoint for ServiceAccountCredentials ([#1433](https://github.com/googleapis/google-auth-library-java/issues/1433)) ([4fcf83e](https://github.com/googleapis/google-auth-library-java/commit/4fcf83e0f96de0e6323b85b9a47119a257b37e90)) + + +### Bug Fixes + +* ComputeEngineCredentials.createScoped should invalidate existing AccessToken ([#1428](https://github.com/googleapis/google-auth-library-java/issues/1428)) ([079a065](https://github.com/googleapis/google-auth-library-java/commit/079a06563114e359b74694b78aec687601a2f628)) +* Invalidate the SA's AccessToken when createScoped() is called ([#1489](https://github.com/googleapis/google-auth-library-java/issues/1489)) ([f26fee7](https://github.com/googleapis/google-auth-library-java/commit/f26fee78d69fce1aaa00dbd5548f3e0266ee6441)) + ## [1.24.1](https://github.com/googleapis/google-auth-library-java/compare/v1.24.0...v1.24.1) (2024-08-13) diff --git a/appengine/pom.xml b/appengine/pom.xml index 67db05102..f836d6421 100644 --- a/appengine/pom.xml +++ b/appengine/pom.xml @@ -5,7 +5,7 @@ com.google.auth google-auth-library-parent - 1.24.2-SNAPSHOT + 1.25.0 ../pom.xml diff --git a/bom/pom.xml b/bom/pom.xml index 957bbb822..2640b091a 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.auth google-auth-library-bom - 1.24.2-SNAPSHOT + 1.25.0 pom Google Auth Library for Java BOM diff --git a/credentials/pom.xml b/credentials/pom.xml index cdcdbabd7..554f405b9 100644 --- a/credentials/pom.xml +++ b/credentials/pom.xml @@ -4,7 +4,7 @@ com.google.auth google-auth-library-parent - 1.24.2-SNAPSHOT + 1.25.0 ../pom.xml diff --git a/oauth2_http/pom.xml b/oauth2_http/pom.xml index 62eae4213..8e0840751 100644 --- a/oauth2_http/pom.xml +++ b/oauth2_http/pom.xml @@ -7,7 +7,7 @@ com.google.auth google-auth-library-parent - 1.24.2-SNAPSHOT + 1.25.0 ../pom.xml diff --git a/pom.xml b/pom.xml index 30680d197..18d8f0951 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.google.auth google-auth-library-parent - 1.24.2-SNAPSHOT + 1.25.0 pom Google Auth Library for Java Client libraries providing authentication and diff --git a/versions.txt b/versions.txt index 9c9e98ff3..db614fb13 100644 --- a/versions.txt +++ b/versions.txt @@ -1,9 +1,9 @@ # Format: # module:released-version:current-version -google-auth-library:1.24.1:1.24.2-SNAPSHOT -google-auth-library-bom:1.24.1:1.24.2-SNAPSHOT -google-auth-library-parent:1.24.1:1.24.2-SNAPSHOT -google-auth-library-appengine:1.24.1:1.24.2-SNAPSHOT -google-auth-library-credentials:1.24.1:1.24.2-SNAPSHOT -google-auth-library-oauth2-http:1.24.1:1.24.2-SNAPSHOT +google-auth-library:1.25.0:1.25.0 +google-auth-library-bom:1.25.0:1.25.0 +google-auth-library-parent:1.25.0:1.25.0 +google-auth-library-appengine:1.25.0:1.25.0 +google-auth-library-credentials:1.25.0:1.25.0 +google-auth-library-oauth2-http:1.25.0:1.25.0 From 242a082568a330f008b1e9416270ca3809c715b0 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Wed, 4 Sep 2024 17:53:07 -0400 Subject: [PATCH 70/89] chore(main): release 1.25.1-SNAPSHOT (#1491) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- appengine/pom.xml | 2 +- bom/pom.xml | 2 +- credentials/pom.xml | 2 +- oauth2_http/pom.xml | 2 +- pom.xml | 2 +- versions.txt | 12 ++++++------ 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/appengine/pom.xml b/appengine/pom.xml index f836d6421..1ab7b13b7 100644 --- a/appengine/pom.xml +++ b/appengine/pom.xml @@ -5,7 +5,7 @@ com.google.auth google-auth-library-parent - 1.25.0 + 1.25.1-SNAPSHOT ../pom.xml diff --git a/bom/pom.xml b/bom/pom.xml index 2640b091a..4fb52c440 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.auth google-auth-library-bom - 1.25.0 + 1.25.1-SNAPSHOT pom Google Auth Library for Java BOM diff --git a/credentials/pom.xml b/credentials/pom.xml index 554f405b9..69481175d 100644 --- a/credentials/pom.xml +++ b/credentials/pom.xml @@ -4,7 +4,7 @@ com.google.auth google-auth-library-parent - 1.25.0 + 1.25.1-SNAPSHOT ../pom.xml diff --git a/oauth2_http/pom.xml b/oauth2_http/pom.xml index 8e0840751..3f1cb60b5 100644 --- a/oauth2_http/pom.xml +++ b/oauth2_http/pom.xml @@ -7,7 +7,7 @@ com.google.auth google-auth-library-parent - 1.25.0 + 1.25.1-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 18d8f0951..3b1dd21a2 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.google.auth google-auth-library-parent - 1.25.0 + 1.25.1-SNAPSHOT pom Google Auth Library for Java Client libraries providing authentication and diff --git a/versions.txt b/versions.txt index db614fb13..435dc6abb 100644 --- a/versions.txt +++ b/versions.txt @@ -1,9 +1,9 @@ # Format: # module:released-version:current-version -google-auth-library:1.25.0:1.25.0 -google-auth-library-bom:1.25.0:1.25.0 -google-auth-library-parent:1.25.0:1.25.0 -google-auth-library-appengine:1.25.0:1.25.0 -google-auth-library-credentials:1.25.0:1.25.0 -google-auth-library-oauth2-http:1.25.0:1.25.0 +google-auth-library:1.25.0:1.25.1-SNAPSHOT +google-auth-library-bom:1.25.0:1.25.1-SNAPSHOT +google-auth-library-parent:1.25.0:1.25.1-SNAPSHOT +google-auth-library-appengine:1.25.0:1.25.1-SNAPSHOT +google-auth-library-credentials:1.25.0:1.25.1-SNAPSHOT +google-auth-library-oauth2-http:1.25.0:1.25.1-SNAPSHOT From 16510064e861868f649b6bc8fdc54b8a39890812 Mon Sep 17 00:00:00 2001 From: Leo <39062083+lsirac@users.noreply.github.com> Date: Thu, 5 Sep 2024 11:05:35 -0700 Subject: [PATCH 71/89] feat: updates UserAuthorizer to support retrieving token response directly with different client auth types (#1486) * feat: updates UserAuthorizer to support retrieving token response directly * fix: cleanup * fix: review * fix: review suggestions * fix: incorrect import * fix: adds missing check --- .../com/google/auth/oauth2/OAuth2Utils.java | 24 + .../google/auth/oauth2/UserAuthorizer.java | 456 ++++++++++++++---- .../javatests/com/google/auth/TestUtils.java | 6 + .../auth/oauth2/MockTokenServerTransport.java | 408 ++++++++++------ .../google/auth/oauth2/OAuth2UtilsTest.java | 101 ++++ .../auth/oauth2/UserAuthorizerTest.java | 254 +++++++++- 6 files changed, 995 insertions(+), 254 deletions(-) create mode 100644 oauth2_http/javatests/com/google/auth/oauth2/OAuth2UtilsTest.java diff --git a/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java b/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java index 2fb0bda66..31c422bd4 100644 --- a/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java +++ b/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java @@ -43,6 +43,8 @@ import com.google.api.client.util.SecurityUtils; import com.google.auth.http.AuthHttpConstants; import com.google.auth.http.HttpTransportFactory; +import com.google.common.base.Strings; +import com.google.common.io.BaseEncoding; import com.google.common.io.ByteStreams; import java.io.ByteArrayInputStream; import java.io.File; @@ -80,6 +82,7 @@ class OAuth2Utils { "https://iamcredentials.%s/v1/projects/-/serviceAccounts/%s:generateIdToken"; static final URI TOKEN_SERVER_URI = URI.create("https://oauth2.googleapis.com/token"); + static final URI TOKEN_REVOKE_URI = URI.create("https://oauth2.googleapis.com/revoke"); static final URI USER_AUTH_URI = URI.create("https://accounts.google.com/o/oauth2/auth"); @@ -261,5 +264,26 @@ static PrivateKey privateKeyFromPkcs8(String privateKeyPkcs8) throws IOException throw new IOException("Unexpected exception reading PKCS#8 data", unexpectedException); } + /** + * Generates a Basic Authentication header string for the provided username and password. + * + *

This method constructs a Basic Authentication string using the provided username and + * password. The credentials are encoded in Base64 format and prefixed with the "Basic " scheme + * identifier. + * + * @param username The username for authentication. + * @param password The password for authentication. + * @return The Basic Authentication header value. + * @throws IllegalArgumentException if either username or password is null or empty. + */ + static String generateBasicAuthHeader(String username, String password) { + if (Strings.isNullOrEmpty(username) || Strings.isNullOrEmpty(password)) { + throw new IllegalArgumentException("Username and password cannot be null or empty."); + } + String credentials = username + ":" + password; + String encodedCredentials = BaseEncoding.base64().encode(credentials.getBytes()); + return "Basic " + encodedCredentials; + } + private OAuth2Utils() {} } diff --git a/oauth2_http/java/com/google/auth/oauth2/UserAuthorizer.java b/oauth2_http/java/com/google/auth/oauth2/UserAuthorizer.java index 19305180e..5a008c705 100644 --- a/oauth2_http/java/com/google/auth/oauth2/UserAuthorizer.java +++ b/oauth2_http/java/com/google/auth/oauth2/UserAuthorizer.java @@ -52,10 +52,22 @@ import java.util.Date; import java.util.List; import java.util.Map; +import javax.annotation.Nullable; /** Handles an interactive 3-Legged-OAuth2 (3LO) user consent authorization. */ public class UserAuthorizer { + /** + * Represents the client authentication types as specified in RFC 7591. + * + *

For more details, see RFC 7591. + */ + public enum ClientAuthenticationType { + CLIENT_SECRET_POST, + CLIENT_SECRET_BASIC, + NONE + } + static final URI DEFAULT_CALLBACK_URI = URI.create("/oauth2callback"); private final String TOKEN_STORE_ERROR = "Error parsing stored token data."; @@ -70,38 +82,27 @@ public class UserAuthorizer { private final URI tokenServerUri; private final URI userAuthUri; private final PKCEProvider pkce; + private final ClientAuthenticationType clientAuthenticationType; - /** - * Constructor with all parameters. - * - * @param clientId Client ID to identify the OAuth2 consent prompt - * @param scopes OAuth2 scopes defining the user consent - * @param tokenStore Implementation of a component for long term storage of tokens - * @param callbackUri URI for implementation of the OAuth2 web callback - * @param transportFactory HTTP transport factory, creates the transport used to get access - * tokens. - * @param tokenServerUri URI of the end point that provides tokens - * @param userAuthUri URI of the Web UI for user consent - * @param pkce PKCE implementation - */ - private UserAuthorizer( - ClientId clientId, - Collection scopes, - TokenStore tokenStore, - URI callbackUri, - HttpTransportFactory transportFactory, - URI tokenServerUri, - URI userAuthUri, - PKCEProvider pkce) { - this.clientId = Preconditions.checkNotNull(clientId); - this.scopes = ImmutableList.copyOf(Preconditions.checkNotNull(scopes)); - this.callbackUri = (callbackUri == null) ? DEFAULT_CALLBACK_URI : callbackUri; + /** Internal constructor. See {@link Builder}. */ + private UserAuthorizer(Builder builder) { + this.clientId = Preconditions.checkNotNull(builder.clientId); + this.scopes = ImmutableList.copyOf(Preconditions.checkNotNull(builder.scopes)); + this.callbackUri = (builder.callbackUri == null) ? DEFAULT_CALLBACK_URI : builder.callbackUri; this.transportFactory = - (transportFactory == null) ? OAuth2Utils.HTTP_TRANSPORT_FACTORY : transportFactory; - this.tokenServerUri = (tokenServerUri == null) ? OAuth2Utils.TOKEN_SERVER_URI : tokenServerUri; - this.userAuthUri = (userAuthUri == null) ? OAuth2Utils.USER_AUTH_URI : userAuthUri; - this.tokenStore = (tokenStore == null) ? new MemoryTokensStorage() : tokenStore; - this.pkce = pkce; + (builder.transportFactory == null) + ? OAuth2Utils.HTTP_TRANSPORT_FACTORY + : builder.transportFactory; + this.tokenServerUri = + (builder.tokenServerUri == null) ? OAuth2Utils.TOKEN_SERVER_URI : builder.tokenServerUri; + this.userAuthUri = + (builder.userAuthUri == null) ? OAuth2Utils.USER_AUTH_URI : builder.userAuthUri; + this.tokenStore = (builder.tokenStore == null) ? new MemoryTokensStorage() : builder.tokenStore; + this.pkce = builder.pkce; + this.clientAuthenticationType = + (builder.clientAuthenticationType == null) + ? ClientAuthenticationType.CLIENT_SECRET_POST + : builder.clientAuthenticationType; } /** @@ -162,7 +163,16 @@ public TokenStore getTokenStore() { } /** - * Return an URL that performs the authorization consent prompt web UI. + * Returns the client authentication type as defined in RFC 7591. + * + * @return The {@link ClientAuthenticationType} + */ + public ClientAuthenticationType getClientAuthenticationType() { + return clientAuthenticationType; + } + + /** + * Return a URL that performs the authorization consent prompt web UI. * * @param userId Application's identifier for the end user. * @param state State that is passed on to the OAuth2 callback URI after the consent. @@ -174,7 +184,7 @@ public URL getAuthorizationUrl(String userId, String state, URI baseUri) { } /** - * Return an URL that performs the authorization consent prompt web UI. + * Return a URL that performs the authorization consent prompt web UI. * * @param userId Application's identifier for the end user. * @param state State that is passed on to the OAuth2 callback URI after the consent. @@ -285,61 +295,35 @@ public UserCredentials getCredentialsFromCode(String code, URI baseUri) throws I */ public UserCredentials getCredentialsFromCode( String code, URI baseUri, Map additionalParameters) throws IOException { - Preconditions.checkNotNull(code); - URI resolvedCallbackUri = getCallbackUri(baseUri); - - GenericData tokenData = new GenericData(); - tokenData.put("code", code); - tokenData.put("client_id", clientId.getClientId()); - tokenData.put("client_secret", clientId.getClientSecret()); - tokenData.put("redirect_uri", resolvedCallbackUri); - tokenData.put("grant_type", "authorization_code"); - - if (additionalParameters != null) { - for (Map.Entry entry : additionalParameters.entrySet()) { - tokenData.put(entry.getKey(), entry.getValue()); - } - } - - if (pkce != null) { - tokenData.put("code_verifier", pkce.getCodeVerifier()); - } - - UrlEncodedContent tokenContent = new UrlEncodedContent(tokenData); - HttpRequestFactory requestFactory = transportFactory.create().createRequestFactory(); - HttpRequest tokenRequest = - requestFactory.buildPostRequest(new GenericUrl(tokenServerUri), tokenContent); - tokenRequest.setParser(new JsonObjectParser(OAuth2Utils.JSON_FACTORY)); - - HttpResponse tokenResponse = tokenRequest.execute(); - - GenericJson parsedTokens = tokenResponse.parseAs(GenericJson.class); - String accessTokenValue = - OAuth2Utils.validateString(parsedTokens, "access_token", FETCH_TOKEN_ERROR); - int expiresInSecs = OAuth2Utils.validateInt32(parsedTokens, "expires_in", FETCH_TOKEN_ERROR); - Date expirationTime = new Date(new Date().getTime() + expiresInSecs * 1000); - String scopes = - OAuth2Utils.validateOptionalString( - parsedTokens, OAuth2Utils.TOKEN_RESPONSE_SCOPE, FETCH_TOKEN_ERROR); - AccessToken accessToken = - AccessToken.newBuilder() - .setExpirationTime(expirationTime) - .setTokenValue(accessTokenValue) - .setScopes(scopes) - .build(); - String refreshToken = - OAuth2Utils.validateOptionalString(parsedTokens, "refresh_token", FETCH_TOKEN_ERROR); - + TokenResponseWithConfig tokenResponseWithConfig = + getCredentialsFromCodeInternal(code, baseUri, additionalParameters); return UserCredentials.newBuilder() - .setClientId(clientId.getClientId()) - .setClientSecret(clientId.getClientSecret()) - .setRefreshToken(refreshToken) - .setAccessToken(accessToken) - .setHttpTransportFactory(transportFactory) - .setTokenServerUri(tokenServerUri) + .setClientId(tokenResponseWithConfig.getClientId()) + .setClientSecret(tokenResponseWithConfig.getClientSecret()) + .setAccessToken(tokenResponseWithConfig.getAccessToken()) + .setRefreshToken(tokenResponseWithConfig.getRefreshToken()) + .setHttpTransportFactory(tokenResponseWithConfig.getHttpTransportFactory()) + .setTokenServerUri(tokenResponseWithConfig.getTokenServerUri()) .build(); } + /** + * Handles OAuth2 authorization code exchange and returns a {@link TokenResponseWithConfig} object + * containing the tokens and configuration details. + * + * @param code The authorization code received from the OAuth2 authorization server. + * @param callbackUri The URI to which the authorization server redirected the user after granting + * authorization. + * @param additionalParameters Additional parameters to include in the token exchange request. + * @return A {@link TokenResponseWithConfig} object containing the access token, refresh token (if + * granted), and configuration details used in the OAuth flow. + * @throws IOException If an error occurs during the token exchange process. + */ + public TokenResponseWithConfig getTokenResponseFromAuthCodeExchange( + String code, URI callbackUri, Map additionalParameters) throws IOException { + return getCredentialsFromCodeInternal(code, callbackUri, additionalParameters); + } + /** * Exchanges an authorization code for tokens and stores them. * @@ -418,7 +402,6 @@ public void storeCredentials(String userId, UserCredentials credentials) throws } AccessToken accessToken = credentials.getAccessToken(); String acessTokenValue = null; - String scopes = null; Date expiresBy = null; List grantedScopes = new ArrayList<>(); @@ -450,6 +433,74 @@ protected void monitorCredentials(String userId, UserCredentials credentials) { credentials.addChangeListener(new UserCredentialsListener(userId)); } + private TokenResponseWithConfig getCredentialsFromCodeInternal( + String code, URI baseUri, Map additionalParameters) throws IOException { + Preconditions.checkNotNull(code); + URI resolvedCallbackUri = getCallbackUri(baseUri); + + GenericData tokenData = new GenericData(); + tokenData.put("code", code); + tokenData.put("client_id", clientId.getClientId()); + tokenData.put("redirect_uri", resolvedCallbackUri); + tokenData.put("grant_type", "authorization_code"); + + if (additionalParameters != null) { + for (Map.Entry entry : additionalParameters.entrySet()) { + tokenData.put(entry.getKey(), entry.getValue()); + } + } + + if (pkce != null) { + tokenData.put("code_verifier", pkce.getCodeVerifier()); + } + + if (this.clientAuthenticationType == ClientAuthenticationType.CLIENT_SECRET_POST) { + tokenData.put("client_secret", clientId.getClientSecret()); + } + + HttpRequestFactory requestFactory = transportFactory.create().createRequestFactory(); + UrlEncodedContent tokenContent = new UrlEncodedContent(tokenData); + HttpRequest tokenRequest = + requestFactory.buildPostRequest(new GenericUrl(tokenServerUri), tokenContent); + tokenRequest.setParser(new JsonObjectParser(OAuth2Utils.JSON_FACTORY)); + + if (this.clientAuthenticationType == ClientAuthenticationType.CLIENT_SECRET_BASIC) { + tokenRequest + .getHeaders() + .setAuthorization( + OAuth2Utils.generateBasicAuthHeader( + clientId.getClientId(), clientId.getClientSecret())); + } + + HttpResponse tokenResponse = tokenRequest.execute(); + + GenericJson parsedTokens = tokenResponse.parseAs(GenericJson.class); + String accessTokenValue = + OAuth2Utils.validateString(parsedTokens, "access_token", FETCH_TOKEN_ERROR); + int expiresInSecs = OAuth2Utils.validateInt32(parsedTokens, "expires_in", FETCH_TOKEN_ERROR); + Date expirationTime = new Date(new Date().getTime() + expiresInSecs * 1000); + String scopes = + OAuth2Utils.validateOptionalString( + parsedTokens, OAuth2Utils.TOKEN_RESPONSE_SCOPE, FETCH_TOKEN_ERROR); + AccessToken accessToken = + AccessToken.newBuilder() + .setExpirationTime(expirationTime) + .setTokenValue(accessTokenValue) + .setScopes(scopes) + .build(); + String refreshToken = + OAuth2Utils.validateOptionalString(parsedTokens, "refresh_token", FETCH_TOKEN_ERROR); + + return TokenResponseWithConfig.newBuilder() + .setClientId(clientId.getClientId()) + .setClientSecret(clientId.getClientSecret()) + .setAccessToken(accessToken) + .setRefreshToken(refreshToken) + .setHttpTransportFactory(transportFactory) + .setTokenServerUri(tokenServerUri) + .build(); + } + /** * Implementation of listener used by monitorCredentials to rewrite the credentials when the * tokens are refreshed. @@ -488,6 +539,7 @@ public static class Builder { private Collection scopes; private HttpTransportFactory transportFactory; private PKCEProvider pkce; + private ClientAuthenticationType clientAuthenticationType; protected Builder() {} @@ -500,50 +552,102 @@ protected Builder(UserAuthorizer authorizer) { this.callbackUri = authorizer.callbackUri; this.userAuthUri = authorizer.userAuthUri; this.pkce = new DefaultPKCEProvider(); + this.clientAuthenticationType = authorizer.clientAuthenticationType; } + /** + * Sets the OAuth 2.0 client ID. + * + * @param clientId the client ID + * @return this {@code Builder} object + */ @CanIgnoreReturnValue public Builder setClientId(ClientId clientId) { this.clientId = clientId; return this; } + /** + * Sets the {@link TokenStore} to use for long term token storage. + * + * @param tokenStore the token store + * @return this {@code Builder} object + */ @CanIgnoreReturnValue public Builder setTokenStore(TokenStore tokenStore) { this.tokenStore = tokenStore; return this; } + /** + * Sets the OAuth 2.0 scopes to request. + * + * @param scopes the scopes to request + * @return this {@code Builder} object + */ @CanIgnoreReturnValue public Builder setScopes(Collection scopes) { this.scopes = scopes; return this; } + /** + * Sets the token exchange endpoint. + * + * @param tokenServerUri the token exchange endpoint to use + * @return this {@code Builder} object + */ @CanIgnoreReturnValue public Builder setTokenServerUri(URI tokenServerUri) { this.tokenServerUri = tokenServerUri; return this; } + /** + * Sets the redirect URI registered with your OAuth provider. This is where the user's browser + * will be redirected after granting or denying authorization. + * + * @param callbackUri the redirect URI + * @return this {@code Builder} object + */ @CanIgnoreReturnValue public Builder setCallbackUri(URI callbackUri) { this.callbackUri = callbackUri; return this; } + /** + * Sets the authorization URI where the user is directed to log in and grant authorization. + * + * @param userAuthUri the authorization URI + * @return this {@code Builder} object + */ @CanIgnoreReturnValue public Builder setUserAuthUri(URI userAuthUri) { this.userAuthUri = userAuthUri; return this; } + /** + * Sets the HTTP transport factory. + * + * @param transportFactory the {@code HttpTransportFactory} to set + * @return this {@code Builder} object + */ @CanIgnoreReturnValue public Builder setHttpTransportFactory(HttpTransportFactory transportFactory) { this.transportFactory = transportFactory; return this; } + /** + * Sets the optional {@link PKCEProvider} to enable Proof Key for Code Exchange to be used. This + * enhances security by using a code challenge and verifier to prevent authorization code + * interception attacks. + * + * @param pkce the {@code PKCEProvider} to set + * @return this {@code Builder} object + */ @CanIgnoreReturnValue public Builder setPKCEProvider(PKCEProvider pkce) { if (pkce != null) { @@ -559,6 +663,20 @@ public Builder setPKCEProvider(PKCEProvider pkce) { return this; } + /** + * Sets the optional {@link ClientAuthenticationType}, one of the client authentication methods + * defined in RFC 7591. This specifies how your application authenticates itself to the + * authorization server. + * + * @param clientAuthentication the {@code ClientAuthenticationType} to set + * @return this {@code Builder} object + */ + @CanIgnoreReturnValue + public Builder setClientAuthenticationType(ClientAuthenticationType clientAuthentication) { + this.clientAuthenticationType = clientAuthentication; + return this; + } + public ClientId getClientId() { return clientId; } @@ -591,16 +709,168 @@ public PKCEProvider getPKCEProvider() { return pkce; } + public ClientAuthenticationType getClientAuthenticationType() { + return clientAuthenticationType; + } + public UserAuthorizer build() { - return new UserAuthorizer( - clientId, - scopes, - tokenStore, - callbackUri, - transportFactory, - tokenServerUri, - userAuthUri, - pkce); + return new UserAuthorizer(this); + } + } + + /** + * Represents the response from an OAuth token exchange, including configuration details used to + * initiate the flow. + * + *

This response can be used to initialize the following credentials types: + * + *

{@code
+   * // UserCredentials when Google is the identity provider:
+   * UserCredentials userCredentials = UserCredentials.newBuilder()
+   *     .setHttpTransportFactory(tokenResponseWithConfig.getHttpTransportFactory())
+   *     .setClientId(tokenResponseWithConfig.getClientId())
+   *     .setClientSecret(tokenResponseWithConfig.getClientSecret())
+   *     .setAccessToken(tokenResponseWithConfig.getAccessToken())
+   *     .setRefreshToken(tokenResponseWithConfig.getRefreshToken())
+   *     .setTokenServerUri(tokenResponseWithConfig.getTokenServerUri())
+   *     .build();
+   *
+   * // ExternalAccountAuthorizedUserCredentials when using Workforce Identity Federation:
+   * ExternalAccountAuthorizedUserCredentials externalAccountAuthorizedUserCredentials =
+   *     ExternalAccountAuthorizedUserCredentials.newBuilder()
+   *         .setHttpTransportFactory(tokenResponseWithConfig.getHttpTransportFactory())
+   *         .setClientId(tokenResponseWithConfig.getClientId())
+   *         .setClientSecret(tokenResponseWithConfig.getClientSecret())
+   *         .setAccessToken(tokenResponseWithConfig.getAccessToken())
+   *         .setRefreshToken(tokenResponseWithConfig.getRefreshToken())
+   *         .setTokenUrl(tokenResponseWithConfig.getTokenServerUri().toURL().toString())
+   *         .build();
+   * }
+ */ + public static class TokenResponseWithConfig { + + private final String clientId; + private final String clientSecret; + private final String refreshToken; + private final AccessToken accessToken; + private URI tokenServerUri; + private final HttpTransportFactory httpTransportFactory; + + private TokenResponseWithConfig(Builder builder) { + this.clientId = builder.clientId; + this.clientSecret = builder.clientSecret; + this.accessToken = builder.accessToken; + this.httpTransportFactory = builder.httpTransportFactory; + this.tokenServerUri = builder.tokenServerUri; + this.refreshToken = builder.refreshToken; + } + + /** + * Returns the OAuth 2.0 client ID used. + * + * @return The client ID. + */ + public String getClientId() { + return clientId; + } + + /** + * Returns the OAuth 2.0 client secret used. + * + * @return The client secret. + */ + public String getClientSecret() { + return clientSecret; + } + + /** + * Returns the access token obtained from the token exchange. + * + * @return The access token. + */ + public AccessToken getAccessToken() { + return accessToken; + } + + /** + * Returns the HTTP transport factory used. + * + * @return The HTTP transport factory. + */ + public HttpTransportFactory getHttpTransportFactory() { + return httpTransportFactory; + } + + /** + * Returns the URI of the token server used. + * + * @return The token server URI. + */ + public URI getTokenServerUri() { + return tokenServerUri; + } + + /** + * Returns the refresh token obtained from the token exchange, if available. + * + * @return The refresh token, or null if not granted. + */ + @Nullable + public String getRefreshToken() { + return refreshToken; + } + + static Builder newBuilder() { + return new Builder(); + } + + static class Builder { + private String clientId; + private String clientSecret; + private String refreshToken; + private AccessToken accessToken; + private URI tokenServerUri; + private HttpTransportFactory httpTransportFactory; + + @CanIgnoreReturnValue + Builder setClientId(String clientId) { + this.clientId = clientId; + return this; + } + + @CanIgnoreReturnValue + Builder setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + return this; + } + + @CanIgnoreReturnValue + Builder setRefreshToken(String refreshToken) { + this.refreshToken = refreshToken; + return this; + } + + @CanIgnoreReturnValue + Builder setAccessToken(AccessToken accessToken) { + this.accessToken = accessToken; + return this; + } + + @CanIgnoreReturnValue + Builder setHttpTransportFactory(HttpTransportFactory httpTransportFactory) { + this.httpTransportFactory = httpTransportFactory; + return this; + } + + @CanIgnoreReturnValue + Builder setTokenServerUri(URI tokenServerUri) { + this.tokenServerUri = tokenServerUri; + return this; + } + + TokenResponseWithConfig build() { + return new TokenResponseWithConfig(this); + } } } } diff --git a/oauth2_http/javatests/com/google/auth/TestUtils.java b/oauth2_http/javatests/com/google/auth/TestUtils.java index f7c53c9f9..99d601da8 100644 --- a/oauth2_http/javatests/com/google/auth/TestUtils.java +++ b/oauth2_http/javatests/com/google/auth/TestUtils.java @@ -47,6 +47,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; +import java.net.URI; import java.net.URLDecoder; import java.text.SimpleDateFormat; import java.util.Calendar; @@ -59,6 +60,11 @@ /** Utilities for test code under com.google.auth. */ public class TestUtils { + public static final URI WORKFORCE_IDENTITY_FEDERATION_AUTH_URI = + URI.create("https://auth.cloud.google/authorize"); + public static final URI WORKFORCE_IDENTITY_FEDERATION_TOKEN_SERVER_URI = + URI.create("https://sts.googleapis.com/v1/oauthtoken"); + private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance(); public static void assertContainsBearerToken(Map> metadata, String token) { diff --git a/oauth2_http/javatests/com/google/auth/oauth2/MockTokenServerTransport.java b/oauth2_http/javatests/com/google/auth/oauth2/MockTokenServerTransport.java index 95680c02e..a61c185b5 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/MockTokenServerTransport.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/MockTokenServerTransport.java @@ -31,6 +31,8 @@ package com.google.auth.oauth2; +import static com.google.auth.TestUtils.WORKFORCE_IDENTITY_FEDERATION_TOKEN_SERVER_URI; + import com.google.api.client.http.LowLevelHttpRequest; import com.google.api.client.http.LowLevelHttpResponse; import com.google.api.client.json.GenericJson; @@ -42,6 +44,7 @@ import com.google.api.client.testing.http.MockLowLevelHttpRequest; import com.google.api.client.testing.http.MockLowLevelHttpResponse; import com.google.auth.TestUtils; +import com.google.auth.oauth2.UserAuthorizer.ClientAuthenticationType; import com.google.common.util.concurrent.Futures; import java.io.IOException; import java.net.URI; @@ -71,6 +74,9 @@ public class MockTokenServerTransport extends MockHttpTransport { private IOException error; private final Queue> responseSequence = new ArrayDeque<>(); private int expiresInSeconds = 3600; + private MockLowLevelHttpRequest request; + private ClientAuthenticationType clientAuthenticationType; + private PKCEProvider pkceProvider; public MockTokenServerTransport() {} @@ -82,6 +88,14 @@ public void setTokenServerUri(URI tokenServerUri) { this.tokenServerUri = tokenServerUri; } + public void setClientAuthType(ClientAuthenticationType type) { + this.clientAuthenticationType = type; + } + + public void setPkceProvider(PKCEProvider pkceProvider) { + this.pkceProvider = pkceProvider; + } + public void addAuthorizationCode( String code, String refreshToken, @@ -93,7 +107,7 @@ public void addAuthorizationCode( this.grantedScopes.put(refreshToken, grantedScopes); if (additionalParameters != null) { - this.additionalParameters.put(refreshToken, additionalParameters); + this.additionalParameters.put(code, additionalParameters); } } @@ -147,6 +161,10 @@ public void setExpiresInSeconds(int expiresInSeconds) { this.expiresInSeconds = expiresInSeconds; } + public MockLowLevelHttpRequest getRequest() { + return request; + } + @Override public LowLevelHttpRequest buildRequest(String method, String url) throws IOException { buildRequestCount++; @@ -158,183 +176,265 @@ public LowLevelHttpRequest buildRequest(String method, String url) throws IOExce final String query = (questionMarkPos > 0) ? url.substring(questionMarkPos + 1) : ""; if (!responseSequence.isEmpty()) { - return new MockLowLevelHttpRequest(url) { - @Override - public LowLevelHttpResponse execute() throws IOException { - try { - return responseSequence.poll().get(); - } catch (ExecutionException e) { - Throwable cause = e.getCause(); - throw (IOException) cause; - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new RuntimeException("Unexpectedly interrupted"); - } - } - }; + request = + new MockLowLevelHttpRequest(url) { + @Override + public LowLevelHttpResponse execute() throws IOException { + try { + return responseSequence.poll().get(); + } catch (ExecutionException e) { + Throwable cause = e.getCause(); + throw (IOException) cause; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException("Unexpectedly interrupted"); + } + } + }; + return request; } if (urlWithoutQuery.equals(tokenServerUri.toString())) { - return new MockLowLevelHttpRequest(url) { - @Override - public LowLevelHttpResponse execute() throws IOException { - - if (!responseSequence.isEmpty()) { - try { - return responseSequence.poll().get(); - } catch (ExecutionException e) { - Throwable cause = e.getCause(); - throw (IOException) cause; - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new RuntimeException("Unexpectedly interrupted"); - } - } - - String content = this.getContentAsString(); - Map query = TestUtils.parseQuery(content); - String accessToken = null; - String refreshToken = null; - String grantedScopesString = null; - boolean generateAccessToken = true; - - String foundId = query.get("client_id"); - boolean isUserEmailScope = false; - if (foundId != null) { - if (!clients.containsKey(foundId)) { - throw new IOException("Client ID not found."); - } - String foundSecret = query.get("client_secret"); - String expectedSecret = clients.get(foundId); - if (foundSecret == null || !foundSecret.equals(expectedSecret)) { - throw new IOException("Client secret not found."); - } - String grantType = query.get("grant_type"); - if (grantType != null && grantType.equals("authorization_code")) { - String foundCode = query.get("code"); - if (!codes.containsKey(foundCode)) { - throw new IOException("Authorization code not found"); + request = + new MockLowLevelHttpRequest(url) { + @Override + public LowLevelHttpResponse execute() throws IOException { + + if (!responseSequence.isEmpty()) { + try { + return responseSequence.poll().get(); + } catch (ExecutionException e) { + Throwable cause = e.getCause(); + throw (IOException) cause; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException("Unexpectedly interrupted"); + } } - refreshToken = codes.get(foundCode); - } else { - refreshToken = query.get("refresh_token"); - } - if (!refreshTokens.containsKey(refreshToken)) { - throw new IOException("Refresh Token not found."); - } - if (refreshToken.equals(REFRESH_TOKEN_WITH_USER_SCOPE)) { - isUserEmailScope = true; - } - accessToken = refreshTokens.get(refreshToken); - - if (grantedScopes.containsKey(refreshToken)) { - grantedScopesString = grantedScopes.get(refreshToken); - } - if (additionalParameters.containsKey(refreshToken)) { - Map additionalParametersMap = additionalParameters.get(refreshToken); - for (Map.Entry entry : additionalParametersMap.entrySet()) { - String key = entry.getKey(); - String expectedValue = entry.getValue(); - if (!query.containsKey(key)) { - throw new IllegalArgumentException("Missing additional parameter: " + key); + String content = this.getContentAsString(); + Map query = TestUtils.parseQuery(content); + String accessToken = null; + String refreshToken = null; + String grantedScopesString = null; + boolean generateAccessToken = true; + + String foundId = query.get("client_id"); + boolean isUserEmailScope = false; + if (foundId != null) { + if (!clients.containsKey(foundId)) { + throw new IOException("Client ID not found."); + } + String foundSecret = query.get("client_secret"); + String expectedSecret = clients.get(foundId); + if ((foundSecret == null || !foundSecret.equals(expectedSecret))) { + throw new IOException("Client secret not found."); + } + String grantType = query.get("grant_type"); + if (grantType != null && grantType.equals("authorization_code")) { + String foundCode = query.get("code"); + if (!codes.containsKey(foundCode)) { + throw new IOException("Authorization code not found"); + } + refreshToken = codes.get(foundCode); } else { - String actualValue = query.get(key); - if (!expectedValue.equals(actualValue)) { - throw new IllegalArgumentException( - "For additional parameter " - + key - + ", Actual value: " - + actualValue - + ", Expected value: " - + expectedValue); + refreshToken = query.get("refresh_token"); + } + if (!refreshTokens.containsKey(refreshToken)) { + throw new IOException("Refresh Token not found."); + } + if (refreshToken.equals(REFRESH_TOKEN_WITH_USER_SCOPE)) { + isUserEmailScope = true; + } + accessToken = refreshTokens.get(refreshToken); + + if (grantedScopes.containsKey(refreshToken)) { + grantedScopesString = grantedScopes.get(refreshToken); + } + validateAdditionalParameters(query); + } else if (query.containsKey("grant_type")) { + String grantType = query.get("grant_type"); + String assertion = query.get("assertion"); + JsonWebSignature signature = JsonWebSignature.parse(JSON_FACTORY, assertion); + if (OAuth2Utils.GRANT_TYPE_JWT_BEARER.equals(grantType)) { + String foundEmail = signature.getPayload().getIssuer(); + if (!serviceAccounts.containsKey(foundEmail)) {} + accessToken = serviceAccounts.get(foundEmail); + String foundTargetAudience = + (String) signature.getPayload().get("target_audience"); + String foundScopes = (String) signature.getPayload().get("scope"); + if ((foundScopes == null || foundScopes.length() == 0) + && (foundTargetAudience == null || foundTargetAudience.length() == 0)) { + throw new IOException("Either target_audience or scopes must be specified."); + } + + if (foundScopes != null && foundTargetAudience != null) { + throw new IOException( + "Only one of target_audience or scopes must be specified."); + } + if (foundTargetAudience != null) { + generateAccessToken = false; + } + + // For GDCH scenario + } else if (OAuth2Utils.TOKEN_TYPE_TOKEN_EXCHANGE.equals(grantType)) { + String foundServiceIdentityName = signature.getPayload().getIssuer(); + if (!gdchServiceAccounts.containsKey(foundServiceIdentityName)) { + throw new IOException( + "GDCH Service Account Service Identity Name not found as issuer."); + } + accessToken = gdchServiceAccounts.get(foundServiceIdentityName); + String foundApiAudience = (String) signature.getPayload().get("api_audience"); + if ((foundApiAudience == null || foundApiAudience.length() == 0)) { + throw new IOException("Api_audience must be specified."); } + } else { + throw new IOException("Service Account Email not found as issuer."); } + } else { + throw new IOException("Unknown token type."); } + + // Create the JSON response + // https://developers.google.com/identity/protocols/OpenIDConnect#server-flow + GenericJson responseContents = new GenericJson(); + responseContents.setFactory(JSON_FACTORY); + responseContents.put("token_type", "Bearer"); + responseContents.put("expires_in", expiresInSeconds); + if (generateAccessToken) { + responseContents.put("access_token", accessToken); + if (refreshToken != null) { + responseContents.put("refresh_token", refreshToken); + } + if (grantedScopesString != null) { + responseContents.put("scope", grantedScopesString); + } + } + if (isUserEmailScope || !generateAccessToken) { + responseContents.put("id_token", ServiceAccountCredentialsTest.DEFAULT_ID_TOKEN); + } + String refreshText = responseContents.toPrettyString(); + + return new MockLowLevelHttpResponse() + .setContentType(Json.MEDIA_TYPE) + .setContent(refreshText); } + }; + return request; + } else if (urlWithoutQuery.equals(OAuth2Utils.TOKEN_REVOKE_URI.toString())) { + request = + new MockLowLevelHttpRequest(url) { + @Override + public LowLevelHttpResponse execute() throws IOException { + Map parameters = TestUtils.parseQuery(this.getContentAsString()); + String token = parameters.get("token"); + if (token == null) { + throw new IOException("Token to revoke not found."); + } + // Token could be access token or refresh token so remove keys and values + refreshTokens.values().removeAll(Collections.singleton(token)); + refreshTokens.remove(token); + return new MockLowLevelHttpResponse().setContentType(Json.MEDIA_TYPE); + } + }; + return request; + } + if (urlWithoutQuery.equals(WORKFORCE_IDENTITY_FEDERATION_TOKEN_SERVER_URI.toString())) { + request = + new MockLowLevelHttpRequest(url) { + @Override + public LowLevelHttpResponse execute() throws IOException { + + if (!responseSequence.isEmpty()) { + try { + return responseSequence.poll().get(); + } catch (ExecutionException e) { + Throwable cause = e.getCause(); + throw (IOException) cause; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException("Unexpectedly interrupted"); + } + } - } else if (query.containsKey("grant_type")) { - String grantType = query.get("grant_type"); - String assertion = query.get("assertion"); - JsonWebSignature signature = JsonWebSignature.parse(JSON_FACTORY, assertion); - if (OAuth2Utils.GRANT_TYPE_JWT_BEARER.equals(grantType)) { - String foundEmail = signature.getPayload().getIssuer(); - if (!serviceAccounts.containsKey(foundEmail)) {} - accessToken = serviceAccounts.get(foundEmail); - String foundTargetAudience = (String) signature.getPayload().get("target_audience"); - String foundScopes = (String) signature.getPayload().get("scope"); - if ((foundScopes == null || foundScopes.length() == 0) - && (foundTargetAudience == null || foundTargetAudience.length() == 0)) { - throw new IOException("Either target_audience or scopes must be specified."); + String content = this.getContentAsString(); + Map query = TestUtils.parseQuery(content); + + // Validate required fields. + if (!query.containsKey("code") + || !query.containsKey("client_id") + || !query.containsKey("redirect_uri") + || !query.containsKey("grant_type")) { + throw new IOException("Invalid request, missing one or more fields."); } - if (foundScopes != null && foundTargetAudience != null) { - throw new IOException("Only one of target_audience or scopes must be specified."); + String clientId = query.get("client_id"); + if (!clients.containsKey(clientId)) { + throw new IOException("Client ID not registered."); } - if (foundTargetAudience != null) { - generateAccessToken = false; + + if (!clients.containsKey(query.get("client_id"))) { + throw new IOException("Client ID not registered."); } - // For GDCH scenario - } else if (OAuth2Utils.TOKEN_TYPE_TOKEN_EXCHANGE.equals(grantType)) { - String foundServiceIdentityName = signature.getPayload().getIssuer(); - if (!gdchServiceAccounts.containsKey(foundServiceIdentityName)) { - throw new IOException( - "GDCH Service Account Service Identity Name not found as issuer."); + String grantType = query.get("grant_type"); + if (!grantType.equals("authorization_code")) { + throw new IOException("Invalid grant_type. Must be authorization_code."); } - accessToken = gdchServiceAccounts.get(foundServiceIdentityName); - String foundApiAudience = (String) signature.getPayload().get("api_audience"); - if ((foundApiAudience == null || foundApiAudience.length() == 0)) { - throw new IOException("Api_audience must be specified."); + + if (pkceProvider != null && !query.containsKey("code_verifier")) { + throw new IOException("Code verifier must be provided."); } - } else { - throw new IOException("Service Account Email not found as issuer."); - } - } else { - throw new IOException("Unknown token type."); - } - // Create the JSON response - // https://developers.google.com/identity/protocols/OpenIDConnect#server-flow - GenericJson responseContents = new GenericJson(); - responseContents.setFactory(JSON_FACTORY); - responseContents.put("token_type", "Bearer"); - responseContents.put("expires_in", expiresInSeconds); - if (generateAccessToken) { - responseContents.put("access_token", accessToken); - if (refreshToken != null) { + validateAdditionalParameters(query); + + // Generate response. + String refreshToken = codes.get(query.get("code")); + String accessToken = getAccessToken(refreshToken); + GenericJson responseContents = new GenericJson(); + responseContents.setFactory(JSON_FACTORY); + responseContents.put("token_type", "Bearer"); + responseContents.put("expires_in", expiresInSeconds); + responseContents.put("access_token", accessToken); responseContents.put("refresh_token", refreshToken); + + if (query.containsKey("scopes")) { + responseContents.put("scope", query.get("scopes")); + } + + String refreshText = responseContents.toPrettyString(); + + return new MockLowLevelHttpResponse() + .setContentType(Json.MEDIA_TYPE) + .setContent(refreshText); } - if (grantedScopesString != null) { - responseContents.put("scope", grantedScopesString); - } - } - if (isUserEmailScope || !generateAccessToken) { - responseContents.put("id_token", ServiceAccountCredentialsTest.DEFAULT_ID_TOKEN); - } - String refreshText = responseContents.toPrettyString(); + }; + return request; + } + return super.buildRequest(method, url); + } - return new MockLowLevelHttpResponse() - .setContentType(Json.MEDIA_TYPE) - .setContent(refreshText); - } - }; - } else if (urlWithoutQuery.equals(OAuth2Utils.TOKEN_REVOKE_URI.toString())) { - return new MockLowLevelHttpRequest(url) { - @Override - public LowLevelHttpResponse execute() throws IOException { - Map parameters = TestUtils.parseQuery(this.getContentAsString()); - String token = parameters.get("token"); - if (token == null) { - throw new IOException("Token to revoke not found."); + private void validateAdditionalParameters(Map query) { + if (additionalParameters.containsKey(query.get("code"))) { + Map additionalParametersMap = additionalParameters.get(query.get("code")); + for (Map.Entry entry : additionalParametersMap.entrySet()) { + String key = entry.getKey(); + String expectedValue = entry.getValue(); + if (!query.containsKey(key)) { + throw new IllegalArgumentException("Missing additional parameter: " + key); + } else { + String actualValue = query.get(key); + if (!expectedValue.equals(actualValue)) { + throw new IllegalArgumentException( + "For additional parameter " + + key + + ", Actual value: " + + actualValue + + ", Expected value: " + + expectedValue); } - // Token could be access token or refresh token so remove keys and values - refreshTokens.values().removeAll(Collections.singleton(token)); - refreshTokens.remove(token); - return new MockLowLevelHttpResponse().setContentType(Json.MEDIA_TYPE); } - }; + } } - return super.buildRequest(method, url); } } diff --git a/oauth2_http/javatests/com/google/auth/oauth2/OAuth2UtilsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/OAuth2UtilsTest.java new file mode 100644 index 000000000..20f831917 --- /dev/null +++ b/oauth2_http/javatests/com/google/auth/oauth2/OAuth2UtilsTest.java @@ -0,0 +1,101 @@ +/* + * Copyright 2024 Google LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Google LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.google.auth.oauth2; + +import static com.google.auth.oauth2.OAuth2Utils.generateBasicAuthHeader; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +import org.junit.Test; + +/** Tests for {@link OAuth2Utils}. */ +public class OAuth2UtilsTest { + + @Test + public void testValidCredentials() { + String username = "testUser"; + String password = "testPassword"; + String expectedHeader = "Basic dGVzdFVzZXI6dGVzdFBhc3N3b3Jk"; + + String actualHeader = generateBasicAuthHeader(username, password); + + assertEquals(expectedHeader, actualHeader); + } + + @Test + public void testEmptyUsername_throws() { + String username = ""; + String password = "testPassword"; + + assertThrows( + IllegalArgumentException.class, + () -> { + generateBasicAuthHeader(username, password); + }); + } + + @Test + public void testEmptyPassword_throws() { + String username = "testUser"; + String password = ""; + + assertThrows( + IllegalArgumentException.class, + () -> { + generateBasicAuthHeader(username, password); + }); + } + + @Test + public void testNullUsername_throws() { + String username = null; + String password = "testPassword"; + + assertThrows( + IllegalArgumentException.class, + () -> { + generateBasicAuthHeader(username, password); + }); + } + + @Test + public void testNullPassword_throws() { + String username = "testUser"; + String password = null; + + assertThrows( + IllegalArgumentException.class, + () -> { + generateBasicAuthHeader(username, password); + }); + } +} diff --git a/oauth2_http/javatests/com/google/auth/oauth2/UserAuthorizerTest.java b/oauth2_http/javatests/com/google/auth/oauth2/UserAuthorizerTest.java index e0a8e2753..d53241fed 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/UserAuthorizerTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/UserAuthorizerTest.java @@ -31,17 +31,26 @@ package com.google.auth.oauth2; +import static com.google.auth.TestUtils.WORKFORCE_IDENTITY_FEDERATION_AUTH_URI; +import static com.google.auth.TestUtils.WORKFORCE_IDENTITY_FEDERATION_TOKEN_SERVER_URI; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import com.google.auth.TestUtils; +import com.google.auth.http.HttpTransportFactory; +import com.google.auth.oauth2.UserAuthorizer.ClientAuthenticationType; +import com.google.auth.oauth2.UserAuthorizer.TokenResponseWithConfig; import java.io.IOException; import java.net.URI; import java.net.URL; import java.util.Arrays; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -90,6 +99,9 @@ public void constructorMinimum() { assertSame(store, authorizer.getTokenStore()); assertEquals(DUMMY_SCOPES, authorizer.getScopes()); assertEquals(UserAuthorizer.DEFAULT_CALLBACK_URI, authorizer.getCallbackUri()); + assertEquals( + UserAuthorizer.ClientAuthenticationType.CLIENT_SECRET_POST, + authorizer.getClientAuthenticationType()); } @Test @@ -102,12 +114,38 @@ public void constructorCommon() { .setScopes(DUMMY_SCOPES) .setTokenStore(store) .setCallbackUri(CALLBACK_URI) + .setClientAuthenticationType( + UserAuthorizer.ClientAuthenticationType.CLIENT_SECRET_BASIC) .build(); assertSame(CLIENT_ID, authorizer.getClientId()); assertSame(store, authorizer.getTokenStore()); assertEquals(DUMMY_SCOPES, authorizer.getScopes()); assertEquals(CALLBACK_URI, authorizer.getCallbackUri()); + assertEquals( + UserAuthorizer.ClientAuthenticationType.CLIENT_SECRET_BASIC, + authorizer.getClientAuthenticationType()); + } + + @Test + public void constructorWithClientAuthenticationTypeNone() { + TokenStore store = new MemoryTokensStorage(); + + UserAuthorizer authorizer = + UserAuthorizer.newBuilder() + .setClientId(CLIENT_ID) + .setScopes(DUMMY_SCOPES) + .setTokenStore(store) + .setCallbackUri(CALLBACK_URI) + .setClientAuthenticationType(UserAuthorizer.ClientAuthenticationType.NONE) + .build(); + + assertSame(CLIENT_ID, authorizer.getClientId()); + assertSame(store, authorizer.getTokenStore()); + assertEquals(DUMMY_SCOPES, authorizer.getScopes()); + assertEquals(CALLBACK_URI, authorizer.getCallbackUri()); + assertEquals( + UserAuthorizer.ClientAuthenticationType.NONE, authorizer.getClientAuthenticationType()); } @Test(expected = NullPointerException.class) @@ -229,6 +267,157 @@ public void getCredentials_noCredentials_returnsNull() throws IOException { assertNull(credentials); } + @Test + public void testGetTokenResponseFromAuthCodeExchange_convertsCodeToTokens() throws IOException { + MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); + transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET); + transportFactory.transport.addAuthorizationCode( + CODE, + REFRESH_TOKEN, + ACCESS_TOKEN_VALUE, + GRANTED_SCOPES_STRING, + /* additionalParameters= */ null); + + UserAuthorizer authorizer = + UserAuthorizer.newBuilder() + .setClientId(CLIENT_ID) + .setScopes(DUMMY_SCOPES) + .setHttpTransportFactory(transportFactory) + .build(); + + TokenResponseWithConfig response = + authorizer.getTokenResponseFromAuthCodeExchange( + CODE, BASE_URI, /* additionalParameters= */ null); + + assertEquals(REFRESH_TOKEN, response.getRefreshToken()); + assertNotNull(response.getAccessToken()); + assertEquals(ACCESS_TOKEN_VALUE, response.getAccessToken().getTokenValue()); + assertEquals(GRANTED_SCOPES, response.getAccessToken().getScopes()); + } + + @Test + public void testGetTokenResponseFromAuthCodeExchange_workforceIdentityFederationClientAuthBasic() + throws IOException { + MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); + transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET); + transportFactory.transport.setClientAuthType(ClientAuthenticationType.CLIENT_SECRET_BASIC); + transportFactory.transport.setPkceProvider(new DefaultPKCEProvider()); + transportFactory.transport.addAuthorizationCode( + CODE, + REFRESH_TOKEN, + ACCESS_TOKEN_VALUE, + GRANTED_SCOPES_STRING, + /* additionalParameters= */ null); + + UserAuthorizer authorizer = + UserAuthorizer.newBuilder() + .setClientId(CLIENT_ID) + .setScopes(Collections.singletonList("https://www.googleapis.com/auth/cloud-platform")) + .setTokenServerUri(WORKFORCE_IDENTITY_FEDERATION_TOKEN_SERVER_URI) + .setUserAuthUri(WORKFORCE_IDENTITY_FEDERATION_AUTH_URI) + .setClientAuthenticationType(ClientAuthenticationType.CLIENT_SECRET_BASIC) + .setPKCEProvider(new DefaultPKCEProvider()) + .setHttpTransportFactory(transportFactory) + .build(); + + TokenResponseWithConfig response = + authorizer.getTokenResponseFromAuthCodeExchange( + CODE, BASE_URI, /* additionalParameters= */ null); + + assertEquals(REFRESH_TOKEN, response.getRefreshToken()); + assertNotNull(response.getAccessToken()); + assertEquals(ACCESS_TOKEN_VALUE, response.getAccessToken().getTokenValue()); + + Map> headers = transportFactory.transport.getRequest().getHeaders(); + List authHeader = headers.get("authorization"); + + assertEquals( + OAuth2Utils.generateBasicAuthHeader(CLIENT_ID_VALUE, CLIENT_SECRET), + authHeader.iterator().next()); + assertEquals(1, authHeader.size()); + } + + @Test + public void testGetTokenResponseFromAuthCodeExchange_workforceIdentityFederationNoClientAuth() + throws IOException { + MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); + transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET); + transportFactory.transport.setClientAuthType(ClientAuthenticationType.CLIENT_SECRET_POST); + transportFactory.transport.addAuthorizationCode( + CODE, + REFRESH_TOKEN, + ACCESS_TOKEN_VALUE, + GRANTED_SCOPES_STRING, + /* additionalParameters= */ null); + + UserAuthorizer authorizer = + UserAuthorizer.newBuilder() + .setClientId(CLIENT_ID) + .setScopes(Collections.singletonList("https://www.googleapis.com/auth/cloud-platform")) + .setTokenServerUri(WORKFORCE_IDENTITY_FEDERATION_TOKEN_SERVER_URI) + .setUserAuthUri(WORKFORCE_IDENTITY_FEDERATION_AUTH_URI) + .setClientAuthenticationType(ClientAuthenticationType.NONE) + .setHttpTransportFactory(transportFactory) + .build(); + + TokenResponseWithConfig response = + authorizer.getTokenResponseFromAuthCodeExchange( + CODE, BASE_URI, /* additionalParameters= */ null); + + assertEquals(REFRESH_TOKEN, response.getRefreshToken()); + assertNotNull(response.getAccessToken()); + assertEquals(ACCESS_TOKEN_VALUE, response.getAccessToken().getTokenValue()); + + Map> headers = transportFactory.transport.getRequest().getHeaders(); + assertNull(headers.get("authorization")); + } + + @Test + public void testGetTokenResponseFromAuthCodeExchange_missingAuthCode_throws() { + UserAuthorizer authorizer = + UserAuthorizer.newBuilder().setClientId(CLIENT_ID).setScopes(DUMMY_SCOPES).build(); + + assertThrows( + NullPointerException.class, + () -> { + authorizer.getTokenResponseFromAuthCodeExchange( + /* code= */ null, BASE_URI, /* additionalParameters= */ null); + }); + } + + @Test + public void testGetTokenResponseFromAuthCodeExchange_missingAccessToken_throws() + throws IOException { + MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); + transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET); + // Missing access token. + transportFactory.transport.addAuthorizationCode( + CODE, + REFRESH_TOKEN, + /* accessToken= */ null, + GRANTED_SCOPES_STRING, + /* additionalParameters= */ null); + + UserAuthorizer authorizer = + UserAuthorizer.newBuilder() + .setClientId(CLIENT_ID) + .setScopes(DUMMY_SCOPES) + .setHttpTransportFactory(transportFactory) + .build(); + + IOException e = + assertThrows( + IOException.class, + () -> { + authorizer.getTokenResponseFromAuthCodeExchange( + CODE, BASE_URI, /* additionalParameters= */ null); + }); + + assertTrue( + e.getMessage() + .contains("Error reading result of Token API:Expected value access_token not found.")); + } + @Test public void getCredentials_storedCredentials_returnsStored() throws IOException { TokenStore tokenStore = new MemoryTokensStorage(); @@ -381,7 +570,7 @@ public void getCredentials_refreshedToken_different_granted_scopes() throws IOEx } @Test - public void getCredentialsFromCode_conevertsCodeToTokens() throws IOException { + public void getCredentialsFromCode_convertsCodeToTokens() throws IOException { MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET); transportFactory.transport.addAuthorizationCode( @@ -645,12 +834,63 @@ public String getCodeChallenge() { } }; - UserAuthorizer authorizer = - UserAuthorizer.newBuilder() - .setClientId(CLIENT_ID) - .setScopes(DUMMY_SCOPES) - .setTokenStore(new MemoryTokensStorage()) - .setPKCEProvider(pkce) + UserAuthorizer.newBuilder() + .setClientId(CLIENT_ID) + .setScopes(DUMMY_SCOPES) + .setTokenStore(new MemoryTokensStorage()) + .setPKCEProvider(pkce) + .build(); + } + + @Test + public void testTokenResponseWithConfig() { + String clientId = "testClientId"; + String clientSecret = "testClientSecret"; + String refreshToken = "testRefreshToken"; + AccessToken accessToken = new AccessToken("token", new Date()); + URI tokenServerUri = URI.create("https://example.com/token"); + HttpTransportFactory httpTransportFactory = new MockTokenServerTransportFactory(); + + TokenResponseWithConfig tokenResponse = + TokenResponseWithConfig.newBuilder() + .setClientId(clientId) + .setClientSecret(clientSecret) + .setRefreshToken(refreshToken) + .setAccessToken(accessToken) + .setTokenServerUri(tokenServerUri) + .setHttpTransportFactory(httpTransportFactory) .build(); + + assertEquals(clientId, tokenResponse.getClientId()); + assertEquals(clientSecret, tokenResponse.getClientSecret()); + assertEquals(refreshToken, tokenResponse.getRefreshToken()); + assertEquals(accessToken, tokenResponse.getAccessToken()); + assertEquals(tokenServerUri, tokenResponse.getTokenServerUri()); + assertEquals(httpTransportFactory, tokenResponse.getHttpTransportFactory()); + } + + @Test + public void testTokenResponseWithConfig_noRefreshToken() { + String clientId = "testClientId"; + String clientSecret = "testClientSecret"; + AccessToken accessToken = new AccessToken("token", new Date()); + URI tokenServerUri = URI.create("https://example.com/token"); + HttpTransportFactory httpTransportFactory = new MockTokenServerTransportFactory(); + + TokenResponseWithConfig tokenResponse = + TokenResponseWithConfig.newBuilder() + .setClientId(clientId) + .setClientSecret(clientSecret) + .setAccessToken(accessToken) + .setTokenServerUri(tokenServerUri) + .setHttpTransportFactory(httpTransportFactory) + .build(); + + assertEquals(clientId, tokenResponse.getClientId()); + assertEquals(clientSecret, tokenResponse.getClientSecret()); + assertEquals(accessToken, tokenResponse.getAccessToken()); + assertEquals(tokenServerUri, tokenResponse.getTokenServerUri()); + assertEquals(httpTransportFactory, tokenResponse.getHttpTransportFactory()); + assertNull(tokenResponse.getRefreshToken()); } } From dad27295472593d7477b45a747fac6ba0df6a0d9 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 9 Sep 2024 17:03:21 +0200 Subject: [PATCH 72/89] chore(deps): update dependency com.google.cloud:google-cloud-shared-config to v1.11.1 (#1494) --- .kokoro/presubmit/graalvm-native-a.cfg | 2 +- .kokoro/presubmit/graalvm-native-b.cfg | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.kokoro/presubmit/graalvm-native-a.cfg b/.kokoro/presubmit/graalvm-native-a.cfg index 640724a1f..20592dfdc 100644 --- a/.kokoro/presubmit/graalvm-native-a.cfg +++ b/.kokoro/presubmit/graalvm-native-a.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_a:1.11.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_a:1.11.1" } env_vars: { diff --git a/.kokoro/presubmit/graalvm-native-b.cfg b/.kokoro/presubmit/graalvm-native-b.cfg index a8faa2630..ddbe56f0a 100644 --- a/.kokoro/presubmit/graalvm-native-b.cfg +++ b/.kokoro/presubmit/graalvm-native-b.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_b:1.11.0" + value: "gcr.io/cloud-devrel-public-resources/graalvm_b:1.11.1" } env_vars: { diff --git a/pom.xml b/pom.xml index 3b1dd21a2..1fcd43cc0 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ com.google.cloud google-cloud-shared-config - 1.11.0 + 1.11.1 From 791d1d7bd1bad0bdb4053247626d24bd21cb37e2 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 9 Sep 2024 17:10:25 +0200 Subject: [PATCH 73/89] chore(deps): update dependency com.google.auth:google-auth-library-oauth2-http to v1.25.0 (#1495) --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index a62f4a695..ea82c72e2 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -43,7 +43,7 @@ com.google.auth google-auth-library-oauth2-http - 1.24.1 + 1.25.0 From 59ed1626a8b73a174a1c35da5eff78e2baf5a8ce Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 16 Sep 2024 18:24:58 +0200 Subject: [PATCH 74/89] chore(deps): update dependency com.google.errorprone:error_prone_annotations to v2.32.0 (#1501) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1fcd43cc0..b60ebbf61 100644 --- a/pom.xml +++ b/pom.xml @@ -75,7 +75,7 @@ 2.0.29 3.0.2 false - 2.31.0 + 2.32.0 From cfb5640bbaccf495fa3efe192bd58a97f0c8932d Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 16 Sep 2024 18:36:53 +0200 Subject: [PATCH 75/89] chore(deps): update dependency com.google.cloud:google-iam-admin to v3.44.0 (#1502) Co-authored-by: Lawrence Qiu --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index ea82c72e2..19ab181dd 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -50,7 +50,7 @@ com.google.cloud google-iam-admin - 3.43.0 + 3.44.0 From dc680946d9e7f04af5d49a40dfadc816f4822968 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 16 Sep 2024 18:51:06 +0200 Subject: [PATCH 76/89] chore(deps): update dependency org.apache.maven.plugins:maven-gpg-plugin to v3.2.6 (#1504) Co-authored-by: Lawrence Qiu --- bom/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bom/pom.xml b/bom/pom.xml index 4fb52c440..5c0662e3b 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -122,7 +122,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.2.5 + 3.2.6 sign-artifacts diff --git a/pom.xml b/pom.xml index b60ebbf61..bc4dacedb 100644 --- a/pom.xml +++ b/pom.xml @@ -413,7 +413,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.2.5 + 3.2.6 sign-artifacts From 7bb8381e049fc343a47891b29a23fe72aed8d057 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Wed, 18 Sep 2024 19:51:46 +0200 Subject: [PATCH 77/89] chore(deps): update dependency com.google.cloud:libraries-bom to v26.46.0 (#1505) --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 19ab181dd..5a0b1aa11 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -30,7 +30,7 @@ com.google.cloud libraries-bom - 26.45.0 + 26.46.0 pom import From 247a54bdfb1deb8e98e6fac9b0ffc6fcd9a2bbcd Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Wed, 18 Sep 2024 20:17:01 +0200 Subject: [PATCH 78/89] chore(deps): update dependency com.google.appengine:appengine-api-1.0-sdk to v2.0.30 (#1506) Co-authored-by: Lawrence Qiu --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bc4dacedb..68b996fe3 100644 --- a/pom.xml +++ b/pom.xml @@ -72,7 +72,7 @@ 1.45.0 4.13.2 33.3.0-android - 2.0.29 + 2.0.30 3.0.2 false 2.32.0 From b7775108b4690c5feb64afbc976f94d04299ef6b Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:49:29 -0400 Subject: [PATCH 79/89] chore(main): release 1.26.0 (#1493) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Lawrence Qiu --- CHANGELOG.md | 7 +++++++ appengine/pom.xml | 2 +- bom/pom.xml | 2 +- credentials/pom.xml | 2 +- oauth2_http/pom.xml | 2 +- pom.xml | 2 +- versions.txt | 12 ++++++------ 7 files changed, 18 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b414daba7..30cc9aa5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.26.0](https://github.com/googleapis/google-auth-library-java/compare/v1.25.0...v1.26.0) (2024-09-18) + + +### Features + +* Updates UserAuthorizer to support retrieving token response directly with different client auth types ([#1486](https://github.com/googleapis/google-auth-library-java/issues/1486)) ([1651006](https://github.com/googleapis/google-auth-library-java/commit/16510064e861868f649b6bc8fdc54b8a39890812)) + ## [1.25.0](https://github.com/googleapis/google-auth-library-java/compare/v1.24.1...v1.25.0) (2024-09-03) diff --git a/appengine/pom.xml b/appengine/pom.xml index 1ab7b13b7..3899140c7 100644 --- a/appengine/pom.xml +++ b/appengine/pom.xml @@ -5,7 +5,7 @@ com.google.auth google-auth-library-parent - 1.25.1-SNAPSHOT + 1.26.0 ../pom.xml diff --git a/bom/pom.xml b/bom/pom.xml index 5c0662e3b..b5e9ae2fb 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.auth google-auth-library-bom - 1.25.1-SNAPSHOT + 1.26.0 pom Google Auth Library for Java BOM diff --git a/credentials/pom.xml b/credentials/pom.xml index 69481175d..3d331e2bc 100644 --- a/credentials/pom.xml +++ b/credentials/pom.xml @@ -4,7 +4,7 @@ com.google.auth google-auth-library-parent - 1.25.1-SNAPSHOT + 1.26.0 ../pom.xml diff --git a/oauth2_http/pom.xml b/oauth2_http/pom.xml index 3f1cb60b5..f380f7fc3 100644 --- a/oauth2_http/pom.xml +++ b/oauth2_http/pom.xml @@ -7,7 +7,7 @@ com.google.auth google-auth-library-parent - 1.25.1-SNAPSHOT + 1.26.0 ../pom.xml diff --git a/pom.xml b/pom.xml index 68b996fe3..953947d50 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.google.auth google-auth-library-parent - 1.25.1-SNAPSHOT + 1.26.0 pom Google Auth Library for Java Client libraries providing authentication and diff --git a/versions.txt b/versions.txt index 435dc6abb..c55311bd5 100644 --- a/versions.txt +++ b/versions.txt @@ -1,9 +1,9 @@ # Format: # module:released-version:current-version -google-auth-library:1.25.0:1.25.1-SNAPSHOT -google-auth-library-bom:1.25.0:1.25.1-SNAPSHOT -google-auth-library-parent:1.25.0:1.25.1-SNAPSHOT -google-auth-library-appengine:1.25.0:1.25.1-SNAPSHOT -google-auth-library-credentials:1.25.0:1.25.1-SNAPSHOT -google-auth-library-oauth2-http:1.25.0:1.25.1-SNAPSHOT +google-auth-library:1.26.0:1.26.0 +google-auth-library-bom:1.26.0:1.26.0 +google-auth-library-parent:1.26.0:1.26.0 +google-auth-library-appengine:1.26.0:1.26.0 +google-auth-library-credentials:1.26.0:1.26.0 +google-auth-library-oauth2-http:1.26.0:1.26.0 From 0a5ff2f1d9954327ed0341c4fca643e3b2700244 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Thu, 19 Sep 2024 13:25:10 -0400 Subject: [PATCH 80/89] chore(main): release 1.26.1-SNAPSHOT (#1507) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- appengine/pom.xml | 2 +- bom/pom.xml | 2 +- credentials/pom.xml | 2 +- oauth2_http/pom.xml | 2 +- pom.xml | 2 +- versions.txt | 12 ++++++------ 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/appengine/pom.xml b/appengine/pom.xml index 3899140c7..08f457587 100644 --- a/appengine/pom.xml +++ b/appengine/pom.xml @@ -5,7 +5,7 @@ com.google.auth google-auth-library-parent - 1.26.0 + 1.26.1-SNAPSHOT ../pom.xml diff --git a/bom/pom.xml b/bom/pom.xml index b5e9ae2fb..a487a5fe2 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.auth google-auth-library-bom - 1.26.0 + 1.26.1-SNAPSHOT pom Google Auth Library for Java BOM diff --git a/credentials/pom.xml b/credentials/pom.xml index 3d331e2bc..59860fb48 100644 --- a/credentials/pom.xml +++ b/credentials/pom.xml @@ -4,7 +4,7 @@ com.google.auth google-auth-library-parent - 1.26.0 + 1.26.1-SNAPSHOT ../pom.xml diff --git a/oauth2_http/pom.xml b/oauth2_http/pom.xml index f380f7fc3..f5b498c4d 100644 --- a/oauth2_http/pom.xml +++ b/oauth2_http/pom.xml @@ -7,7 +7,7 @@ com.google.auth google-auth-library-parent - 1.26.0 + 1.26.1-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 953947d50..8ce9a99ea 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.google.auth google-auth-library-parent - 1.26.0 + 1.26.1-SNAPSHOT pom Google Auth Library for Java Client libraries providing authentication and diff --git a/versions.txt b/versions.txt index c55311bd5..16f5a33e2 100644 --- a/versions.txt +++ b/versions.txt @@ -1,9 +1,9 @@ # Format: # module:released-version:current-version -google-auth-library:1.26.0:1.26.0 -google-auth-library-bom:1.26.0:1.26.0 -google-auth-library-parent:1.26.0:1.26.0 -google-auth-library-appengine:1.26.0:1.26.0 -google-auth-library-credentials:1.26.0:1.26.0 -google-auth-library-oauth2-http:1.26.0:1.26.0 +google-auth-library:1.26.0:1.26.1-SNAPSHOT +google-auth-library-bom:1.26.0:1.26.1-SNAPSHOT +google-auth-library-parent:1.26.0:1.26.1-SNAPSHOT +google-auth-library-appengine:1.26.0:1.26.1-SNAPSHOT +google-auth-library-credentials:1.26.0:1.26.1-SNAPSHOT +google-auth-library-oauth2-http:1.26.0:1.26.1-SNAPSHOT From 1660c20e8338032209c130ed09a2b7deaee5496f Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 19 Sep 2024 19:32:32 +0200 Subject: [PATCH 81/89] chore(deps): update dependency com.google.cloud.samples:shared-configuration to v1.2.2 (#1508) Co-authored-by: Lawrence Qiu --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 5a0b1aa11..9417d7818 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -13,7 +13,7 @@ com.google.cloud.samples shared-configuration - 1.2.0 + 1.2.2 From f30b064cb3699aca2f159d1ccfb11b9ddb670c8f Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 19 Sep 2024 19:38:40 +0200 Subject: [PATCH 82/89] chore(deps): update dependency com.google.auth:google-auth-library-oauth2-http to v1.26.0 (#1509) Co-authored-by: Lawrence Qiu --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 9417d7818..d980d8426 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -43,7 +43,7 @@ com.google.auth google-auth-library-oauth2-http - 1.25.0 + 1.26.0 From 8e321ecf21b545f75ca8f6b4c60b041aaa03dfbb Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 19 Sep 2024 19:45:05 +0200 Subject: [PATCH 83/89] chore(deps): update dependency com.google.cloud:libraries-bom to v26.47.0 (#1510) Co-authored-by: Lawrence Qiu --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index d980d8426..2fa430615 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -30,7 +30,7 @@ com.google.cloud libraries-bom - 26.46.0 + 26.47.0 pom import From ea0dca69717d7d557c323cd7cc7b0c1c05917dd6 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 20 Sep 2024 16:45:15 +0200 Subject: [PATCH 84/89] chore(deps): update dependency com.google.cloud:google-cloud-shared-config to v1.11.2 (#1511) --- .kokoro/presubmit/graalvm-native-a.cfg | 2 +- .kokoro/presubmit/graalvm-native-b.cfg | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.kokoro/presubmit/graalvm-native-a.cfg b/.kokoro/presubmit/graalvm-native-a.cfg index 20592dfdc..4f1bdf591 100644 --- a/.kokoro/presubmit/graalvm-native-a.cfg +++ b/.kokoro/presubmit/graalvm-native-a.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_a:1.11.1" + value: "gcr.io/cloud-devrel-public-resources/graalvm_a:1.11.2" } env_vars: { diff --git a/.kokoro/presubmit/graalvm-native-b.cfg b/.kokoro/presubmit/graalvm-native-b.cfg index ddbe56f0a..4490a987d 100644 --- a/.kokoro/presubmit/graalvm-native-b.cfg +++ b/.kokoro/presubmit/graalvm-native-b.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_b:1.11.1" + value: "gcr.io/cloud-devrel-public-resources/graalvm_b:1.11.2" } env_vars: { diff --git a/pom.xml b/pom.xml index 8ce9a99ea..20f5f8ae2 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ com.google.cloud google-cloud-shared-config - 1.11.1 + 1.11.2 From 6401e51c04fa6bd819e8dff98a62b7f079608a43 Mon Sep 17 00:00:00 2001 From: ldetmer <1771267+ldetmer@users.noreply.github.com> Date: Fri, 20 Sep 2024 12:48:43 -0400 Subject: [PATCH 85/89] feat: add api key credential as client library authorization type (#1483) * add api key credential * add no op * formatting fix * added tests for ApiKeyCredentials * formatting fix * added java docs * formatting fix * added error checking * removed PreCondition dependency * fixed * import * updated authenticationType to API-Key * updated to use assertThrows + expanded java docs --- .../com/google/auth/ApiKeyCredentials.java | 90 +++++++++++++++++++ .../google/auth/ApiKeyCredentialsTest.java | 89 ++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 credentials/java/com/google/auth/ApiKeyCredentials.java create mode 100644 credentials/javatests/com/google/auth/ApiKeyCredentialsTest.java diff --git a/credentials/java/com/google/auth/ApiKeyCredentials.java b/credentials/java/com/google/auth/ApiKeyCredentials.java new file mode 100644 index 000000000..8c454d0a9 --- /dev/null +++ b/credentials/java/com/google/auth/ApiKeyCredentials.java @@ -0,0 +1,90 @@ +/* + * Copyright 2024, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.auth; + +import java.io.IOException; +import java.net.URI; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * Credentials class for calling Google APIs using an API key. + * + *

Uses an API key directly in the request metadata to provide authorization. + * + *

Note: ApiKeyCredentials extends from base {@link Credentials} class rather than + * GoogleCredentials/OAuth2Credentials, as it does not provide an access token and is not considered + * an OAuth2 credential. + * + *


+ * Credentials credentials = ApiKeyCredentials.create("your api key");
+ * 
+ */ +public class ApiKeyCredentials extends Credentials { + static final String API_KEY_HEADER_KEY = "x-goog-api-key"; + private final String apiKey; + + ApiKeyCredentials(String apiKey) { + this.apiKey = apiKey; + } + + public static ApiKeyCredentials create(String apiKey) { + if (apiKey == null || apiKey.isEmpty()) { + throw new IllegalArgumentException("API key cannot be null or blank"); + } + return new ApiKeyCredentials(apiKey); + } + + @Override + public String getAuthenticationType() { + return "API-Key"; + } + + @Override + public Map> getRequestMetadata(URI uri) throws IOException { + return Collections.singletonMap(API_KEY_HEADER_KEY, Collections.singletonList(apiKey)); + } + + @Override + public boolean hasRequestMetadata() { + return true; + } + + @Override + public boolean hasRequestMetadataOnly() { + return true; + } + + /** There is no concept of refreshing an API tokens, this method is a no-op. */ + @Override + public void refresh() throws IOException {} +} diff --git a/credentials/javatests/com/google/auth/ApiKeyCredentialsTest.java b/credentials/javatests/com/google/auth/ApiKeyCredentialsTest.java new file mode 100644 index 000000000..661d06c18 --- /dev/null +++ b/credentials/javatests/com/google/auth/ApiKeyCredentialsTest.java @@ -0,0 +1,89 @@ +/* + * Copyright 2024, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.google.auth; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Map; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Test case for {@link ApiKeyCredentials}. */ +@RunWith(JUnit4.class) +public class ApiKeyCredentialsTest { + + private static final String TEST_API_KEY = "testApiKey"; + + @Test + public void testGetAuthenticationType() { + ApiKeyCredentials credentials = ApiKeyCredentials.create(TEST_API_KEY); + assertEquals("API-Key", credentials.getAuthenticationType()); + } + + @Test + public void testGetRequestMetadata() throws IOException, URISyntaxException { + ApiKeyCredentials credentials = ApiKeyCredentials.create(TEST_API_KEY); + Map> metadata = credentials.getRequestMetadata(new URI("http://test.com")); + assertEquals(1, metadata.size()); + assertTrue(metadata.containsKey(ApiKeyCredentials.API_KEY_HEADER_KEY)); + assertEquals(1, metadata.get(ApiKeyCredentials.API_KEY_HEADER_KEY).size()); + assertEquals(TEST_API_KEY, metadata.get(ApiKeyCredentials.API_KEY_HEADER_KEY).get(0)); + } + + @Test + public void testHasRequestMetadata() { + ApiKeyCredentials credentials = ApiKeyCredentials.create(TEST_API_KEY); + assertTrue(credentials.hasRequestMetadata()); + } + + @Test + public void testHasRequestMetadataOnly() { + ApiKeyCredentials credentials = ApiKeyCredentials.create(TEST_API_KEY); + assertTrue(credentials.hasRequestMetadataOnly()); + } + + @Test + public void testNullApiKey_ThrowsException() { + assertThrows(IllegalArgumentException.class, () -> ApiKeyCredentials.create(null)); + } + + @Test + public void testBlankApiKey_ThrowsException() { + assertThrows(IllegalArgumentException.class, () -> ApiKeyCredentials.create("")); + } +} From 12c018897862a41a303389cf96ec1097bcb95c37 Mon Sep 17 00:00:00 2001 From: Kurt Alfred Kluever Date: Fri, 20 Sep 2024 12:55:32 -0400 Subject: [PATCH 86/89] Migrate from deprecated Guava `Charsets` to the JDK's `StandardCharsets`. (#1456) Co-authored-by: Lawrence Qiu --- .../java/com/google/auth/oauth2/CloudShellCredentials.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/oauth2_http/java/com/google/auth/oauth2/CloudShellCredentials.java b/oauth2_http/java/com/google/auth/oauth2/CloudShellCredentials.java index c65b0c43d..7024e1e1e 100644 --- a/oauth2_http/java/com/google/auth/oauth2/CloudShellCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/CloudShellCredentials.java @@ -32,7 +32,6 @@ package com.google.auth.oauth2; import com.google.api.client.json.JsonParser; -import com.google.common.base.Charsets; import com.google.common.base.MoreObjects; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.io.BufferedReader; @@ -40,6 +39,7 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -59,7 +59,7 @@ public class CloudShellCredentials extends GoogleCredentials { protected static final String GET_AUTH_TOKEN_REQUEST = "2\n[]"; protected static final byte[] GET_AUTH_TOKEN_REQUEST_BYTES = - (GET_AUTH_TOKEN_REQUEST + "\n").getBytes(Charsets.UTF_8); + (GET_AUTH_TOKEN_REQUEST + "\n").getBytes(StandardCharsets.UTF_8); private final int authPort; From f1a91e5231b126b7702726df4ec324b46292ad52 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 20 Sep 2024 14:27:29 -0400 Subject: [PATCH 87/89] chore(main): release 1.27.0 (#1512) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Lawrence Qiu --- CHANGELOG.md | 7 +++++++ appengine/pom.xml | 2 +- bom/pom.xml | 2 +- credentials/pom.xml | 2 +- oauth2_http/pom.xml | 2 +- pom.xml | 2 +- versions.txt | 12 ++++++------ 7 files changed, 18 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30cc9aa5e..2920cd283 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.27.0](https://github.com/googleapis/google-auth-library-java/compare/v1.26.0...v1.27.0) (2024-09-20) + + +### Features + +* Add api key credential as client library authorization type ([#1483](https://github.com/googleapis/google-auth-library-java/issues/1483)) ([6401e51](https://github.com/googleapis/google-auth-library-java/commit/6401e51c04fa6bd819e8dff98a62b7f079608a43)) + ## [1.26.0](https://github.com/googleapis/google-auth-library-java/compare/v1.25.0...v1.26.0) (2024-09-18) diff --git a/appengine/pom.xml b/appengine/pom.xml index 08f457587..8f9cc8c5d 100644 --- a/appengine/pom.xml +++ b/appengine/pom.xml @@ -5,7 +5,7 @@ com.google.auth google-auth-library-parent - 1.26.1-SNAPSHOT + 1.27.0 ../pom.xml diff --git a/bom/pom.xml b/bom/pom.xml index a487a5fe2..b85c526fd 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.auth google-auth-library-bom - 1.26.1-SNAPSHOT + 1.27.0 pom Google Auth Library for Java BOM diff --git a/credentials/pom.xml b/credentials/pom.xml index 59860fb48..a2a3d5587 100644 --- a/credentials/pom.xml +++ b/credentials/pom.xml @@ -4,7 +4,7 @@ com.google.auth google-auth-library-parent - 1.26.1-SNAPSHOT + 1.27.0 ../pom.xml diff --git a/oauth2_http/pom.xml b/oauth2_http/pom.xml index f5b498c4d..a26102643 100644 --- a/oauth2_http/pom.xml +++ b/oauth2_http/pom.xml @@ -7,7 +7,7 @@ com.google.auth google-auth-library-parent - 1.26.1-SNAPSHOT + 1.27.0 ../pom.xml diff --git a/pom.xml b/pom.xml index 20f5f8ae2..cfc27f0b4 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.google.auth google-auth-library-parent - 1.26.1-SNAPSHOT + 1.27.0 pom Google Auth Library for Java Client libraries providing authentication and diff --git a/versions.txt b/versions.txt index 16f5a33e2..a72870097 100644 --- a/versions.txt +++ b/versions.txt @@ -1,9 +1,9 @@ # Format: # module:released-version:current-version -google-auth-library:1.26.0:1.26.1-SNAPSHOT -google-auth-library-bom:1.26.0:1.26.1-SNAPSHOT -google-auth-library-parent:1.26.0:1.26.1-SNAPSHOT -google-auth-library-appengine:1.26.0:1.26.1-SNAPSHOT -google-auth-library-credentials:1.26.0:1.26.1-SNAPSHOT -google-auth-library-oauth2-http:1.26.0:1.26.1-SNAPSHOT +google-auth-library:1.27.0:1.27.0 +google-auth-library-bom:1.27.0:1.27.0 +google-auth-library-parent:1.27.0:1.27.0 +google-auth-library-appengine:1.27.0:1.27.0 +google-auth-library-credentials:1.27.0:1.27.0 +google-auth-library-oauth2-http:1.27.0:1.27.0 From 24d1414993e7cd3cbebb195bea8aeba51f8fbab4 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 11:22:18 -0400 Subject: [PATCH 88/89] chore(main): release 1.27.1-SNAPSHOT (#1513) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- appengine/pom.xml | 2 +- bom/pom.xml | 2 +- credentials/pom.xml | 2 +- oauth2_http/pom.xml | 2 +- pom.xml | 2 +- versions.txt | 12 ++++++------ 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/appengine/pom.xml b/appengine/pom.xml index 8f9cc8c5d..956ae25b2 100644 --- a/appengine/pom.xml +++ b/appengine/pom.xml @@ -5,7 +5,7 @@ com.google.auth google-auth-library-parent - 1.27.0 + 1.27.1-SNAPSHOT ../pom.xml diff --git a/bom/pom.xml b/bom/pom.xml index b85c526fd..e6b6ca5ad 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.auth google-auth-library-bom - 1.27.0 + 1.27.1-SNAPSHOT pom Google Auth Library for Java BOM diff --git a/credentials/pom.xml b/credentials/pom.xml index a2a3d5587..015245690 100644 --- a/credentials/pom.xml +++ b/credentials/pom.xml @@ -4,7 +4,7 @@ com.google.auth google-auth-library-parent - 1.27.0 + 1.27.1-SNAPSHOT ../pom.xml diff --git a/oauth2_http/pom.xml b/oauth2_http/pom.xml index a26102643..42baaaa18 100644 --- a/oauth2_http/pom.xml +++ b/oauth2_http/pom.xml @@ -7,7 +7,7 @@ com.google.auth google-auth-library-parent - 1.27.0 + 1.27.1-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index cfc27f0b4..3035b62fa 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.google.auth google-auth-library-parent - 1.27.0 + 1.27.1-SNAPSHOT pom Google Auth Library for Java Client libraries providing authentication and diff --git a/versions.txt b/versions.txt index a72870097..4643ed989 100644 --- a/versions.txt +++ b/versions.txt @@ -1,9 +1,9 @@ # Format: # module:released-version:current-version -google-auth-library:1.27.0:1.27.0 -google-auth-library-bom:1.27.0:1.27.0 -google-auth-library-parent:1.27.0:1.27.0 -google-auth-library-appengine:1.27.0:1.27.0 -google-auth-library-credentials:1.27.0:1.27.0 -google-auth-library-oauth2-http:1.27.0:1.27.0 +google-auth-library:1.27.0:1.27.1-SNAPSHOT +google-auth-library-bom:1.27.0:1.27.1-SNAPSHOT +google-auth-library-parent:1.27.0:1.27.1-SNAPSHOT +google-auth-library-appengine:1.27.0:1.27.1-SNAPSHOT +google-auth-library-credentials:1.27.0:1.27.1-SNAPSHOT +google-auth-library-oauth2-http:1.27.0:1.27.1-SNAPSHOT From afe4ff9f1f3c406c72ecb66fba50d7463f620467 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 23 Sep 2024 17:53:29 +0200 Subject: [PATCH 89/89] chore(deps): update dependency com.google.auth:google-auth-library-oauth2-http to v1.27.0 (#1514) Co-authored-by: Lawrence Qiu --- samples/snippets/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 2fa430615..2fa4011ef 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -43,7 +43,7 @@ com.google.auth google-auth-library-oauth2-http - 1.26.0 + 1.27.0