diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index 886d09496..dcdda8c6d 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -1,3 +1,3 @@ docker: image: gcr.io/cloud-devrel-public-resources/owlbot-java:latest - digest: sha256:14ecf64ec36f67c7bf04e3dc0f68eafcc01df3955121c38862b695e2ae7515d8 + digest: sha256:9669c169d0582f13d6b2d319a43a78fc49f296a883aa48519bd0e5c7d34087c4 diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 21ade6ce5..596b6d910 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -21,7 +21,7 @@ If you are still having issues, please include as much information as possible: General, Core, and Other are also allowed as types 2. OS type and version: 3. Java version: -4. google-auth-library version(s): +4. version(s): #### Steps to reproduce diff --git a/.gitignore b/.gitignore index fe226042f..75c0e0cc1 100644 --- a/.gitignore +++ b/.gitignore @@ -5,10 +5,14 @@ target/ .classpath .project .settings +.factorypath # Intellij *.iml .idea/ # VS Code -.vscode/ \ No newline at end of file +.vscode/ + +# MacOS +.DS_Store \ No newline at end of file diff --git a/.kokoro/build.sh b/.kokoro/build.sh index 30e14cf64..317bf8686 100755 --- a/.kokoro/build.sh +++ b/.kokoro/build.sh @@ -47,15 +47,15 @@ set +e case ${JOB_TYPE} in test) - mvn test -B -Dclirr.skip=true -Denforcer.skip=true + mvn test -B -ntp -Dclirr.skip=true -Denforcer.skip=true RETURN_CODE=$? ;; lint) - mvn com.coveo:fmt-maven-plugin:check + mvn com.coveo:fmt-maven-plugin:check -B -ntp RETURN_CODE=$? ;; javadoc) - mvn javadoc:javadoc javadoc:test-javadoc + mvn javadoc:javadoc javadoc:test-javadoc -B -ntp RETURN_CODE=$? ;; integration) @@ -71,7 +71,7 @@ integration) ;; graalvm) # Run Unit and Integration Tests with Native Image - mvn test -Pnative -Penable-integration-tests + mvn -B ${INTEGRATION_TEST_ARGS} -ntp -Pnative -Penable-integration-tests test RETURN_CODE=$? ;; samples) @@ -91,7 +91,6 @@ samples) pushd ${SAMPLES_DIR} mvn -B \ - -Penable-samples \ -ntp \ -DtrimStackTrace=false \ -Dclirr.skip=true \ @@ -105,7 +104,7 @@ samples) fi ;; clirr) - mvn -B -Denforcer.skip=true clirr:check + mvn -B -ntp -Denforcer.skip=true clirr:check RETURN_CODE=$? ;; *) diff --git a/.repo-metadata.json b/.repo-metadata.json index dc3c5f3c0..29f18ace4 100644 --- a/.repo-metadata.json +++ b/.repo-metadata.json @@ -1,10 +1,11 @@ { - "name": "google-auth-library", + "api_shortname": "google-auth-library", "name_pretty": "Google Auth Library", "client_documentation": "https://googleapis.dev/java/google-auth-library/latest/", - "release_level": "ga", + "release_level": "stable", "language": "java", "repo": "googleapis/google-auth-library-java", "repo_short": "google-auth-library-java", + "library_type": "AUTH", "distribution_name": "com.google.auth:google-auth-library" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f0113b12..b1af9f06f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## [1.4.0](https://github.com/googleapis/google-auth-library-java/compare/v1.3.0...v1.4.0) (2022-01-19) + + +### Features + +* setting the audience to always point to google token endpoint ([#833](https://github.com/googleapis/google-auth-library-java/issues/833)) ([33bfe7a](https://github.com/googleapis/google-auth-library-java/commit/33bfe7a788a524324cd9b0a54acc8917f6b75556)) + + +### Bug Fixes + +* (WIF) remove erroneous check for the subject token field name for text credential source ([#822](https://github.com/googleapis/google-auth-library-java/issues/822)) ([6d35c68](https://github.com/googleapis/google-auth-library-java/commit/6d35c681cf397ff2a90363184e26ee5850294c41)) +* **java:** add -ntp flag to native image testing command ([#1299](https://github.com/googleapis/google-auth-library-java/issues/1299)) ([#807](https://github.com/googleapis/google-auth-library-java/issues/807)) ([aa6654a](https://github.com/googleapis/google-auth-library-java/commit/aa6654a639ea15bcce7c7a6e86f170b1345895f0)) +* **java:** run Maven in plain console-friendly mode ([#1301](https://github.com/googleapis/google-auth-library-java/issues/1301)) ([#818](https://github.com/googleapis/google-auth-library-java/issues/818)) ([4df45d0](https://github.com/googleapis/google-auth-library-java/commit/4df45d0d03a973f1beff43d8965c26289f217f22)) + ## [1.3.0](https://www.github.com/googleapis/google-auth-library-java/compare/v1.2.2...v1.3.0) (2021-11-10) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f2dbdee06..b65dd279c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,12 +53,12 @@ mvn -Penable-integration-tests clean verify ## Code Samples -Code Samples must be bundled in separate Maven modules, and guarded by a -Maven profile with the name `enable-samples`. +All code samples must be in compliance with the [java sample formatting guide][3]. +Code Samples must be bundled in separate Maven modules. The samples must be separate from the primary project for a few reasons: -1. Primary projects have a minimum Java version of Java 7 whereas samples have - a minimum Java version of Java 8. Due to this we need the ability to +1. Primary projects have a minimum Java version of Java 8 whereas samples can have + Java version of Java 11. Due to this we need the ability to selectively exclude samples from a build run. 2. Many code samples depend on external GCP services and need credentials to access the service. @@ -68,39 +68,16 @@ The samples must be separate from the primary project for a few reasons: ### Building ```bash -mvn -Penable-samples clean verify +mvn clean verify ``` Some samples require access to GCP services and require a service account: ```bash export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service/account.json -mvn -Penable-samples clean verify +mvn clean verify ``` -### Profile Config - -1. To add samples in a profile to your Maven project, add the following to your -`pom.xml` - - ```xml - - [...] - - - enable-samples - - sample - - - - [...] - - ``` - -2. [Activate](#profile-activation) the profile. -3. Define your samples in a normal Maven project in the `samples/` directory. - ### Code Formatting Code in this repo is formatted with @@ -110,30 +87,6 @@ To run formatting on your project, you can run: mvn com.coveo:fmt-maven-plugin:format ``` -### Profile Activation - -To include code samples when building and testing the project, enable the -`enable-samples` Maven profile. - -#### Command line - -To activate the Maven profile on the command line add `-Penable-samples` to your -Maven command. - -#### Maven `settings.xml` - -To activate the Maven profile in your `~/.m2/settings.xml` add an entry of -`enable-samples` following the instructions in [Active Profiles][2]. - -This method has the benefit of applying to all projects you build (and is -respected by IntelliJ IDEA) and is recommended if you are going to be -contributing samples to several projects. - -#### IntelliJ IDEA - -To activate the Maven Profile inside IntelliJ IDEA, follow the instructions in -[Activate Maven profiles][3] to activate `enable-samples`. - [1]: https://cloud.google.com/docs/authentication/getting-started#creating_a_service_account [2]: https://maven.apache.org/settings.html#Active_Profiles -[3]: https://www.jetbrains.com/help/idea/work-with-maven-profiles.html#activate_maven_profiles +[3]: https://github.com/GoogleCloudPlatform/java-docs-samples/blob/main/SAMPLE_FORMAT.md \ No newline at end of file diff --git a/README.md b/README.md index ca4e686e9..90f92a06d 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ If you are using Gradle, add this to your dependencies [//]: # ({x-version-update-start:google-auth-library-oauth2-http:released}) ```Groovy -compile 'com.google.auth:google-auth-library-oauth2-http:1.3.0' +implementation 'com.google.auth:google-auth-library-oauth2-http:1.3.0' ``` [//]: # ({x-version-update-end}) diff --git a/appengine/pom.xml b/appengine/pom.xml index a769c95fb..a3fe41c60 100644 --- a/appengine/pom.xml +++ b/appengine/pom.xml @@ -5,7 +5,7 @@ com.google.auth google-auth-library-parent - 1.3.0 + 1.4.0 ../pom.xml diff --git a/bom/pom.xml b/bom/pom.xml index 879b89fe0..009c6840d 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.auth google-auth-library-bom - 1.3.0 + 1.4.0 pom Google Auth Library for Java BOM @@ -100,18 +100,10 @@ com.coveo fmt-maven-plugin - 2.9 + 2.13 - true - - - com.google.googlejavaformat - google-java-format - 1.7 - - diff --git a/credentials/pom.xml b/credentials/pom.xml index 86cab3d92..23907e325 100644 --- a/credentials/pom.xml +++ b/credentials/pom.xml @@ -4,7 +4,7 @@ com.google.auth google-auth-library-parent - 1.3.0 + 1.4.0 ../pom.xml diff --git a/oauth2_http/java/com/google/auth/oauth2/IdentityPoolCredentials.java b/oauth2_http/java/com/google/auth/oauth2/IdentityPoolCredentials.java index 44e9c0e93..200d56fbb 100644 --- a/oauth2_http/java/com/google/auth/oauth2/IdentityPoolCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/IdentityPoolCredentials.java @@ -52,6 +52,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.Locale; import java.util.Map; import javax.annotation.Nullable; @@ -132,18 +133,21 @@ enum CredentialFormatType { Map formatMap = (Map) credentialSourceMap.get("format"); if (formatMap != null && formatMap.containsKey("type")) { String type = formatMap.get("type"); - if (!"text".equals(type) && !"json".equals(type)) { - throw new IllegalArgumentException( - String.format("Invalid credential source format type: %s.", type)); - } - credentialFormatType = - type.equals("text") ? CredentialFormatType.TEXT : CredentialFormatType.JSON; - if (!formatMap.containsKey("subject_token_field_name")) { + if (type != null && "json".equals(type.toLowerCase(Locale.US))) { + // For JSON, the subject_token field name must be provided. + if (!formatMap.containsKey("subject_token_field_name")) { + throw new IllegalArgumentException( + "When specifying a JSON credential type, the subject_token_field_name must be set."); + } + credentialFormatType = CredentialFormatType.JSON; + subjectTokenFieldName = formatMap.get("subject_token_field_name"); + } else if (type != null && "text".equals(type.toLowerCase(Locale.US))) { + credentialFormatType = CredentialFormatType.TEXT; + } else { throw new IllegalArgumentException( - "When specifying a JSON credential type, the subject_token_field_name must be set."); + String.format("Invalid credential source format type: %s.", type)); } - subjectTokenFieldName = formatMap.get("subject_token_field_name"); } } diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java index 201fdf593..1588c1613 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java @@ -567,7 +567,7 @@ public boolean createScopedRequired() { public AccessToken refreshAccessToken() throws IOException { JsonFactory jsonFactory = OAuth2Utils.JSON_FACTORY; long currentTime = clock.currentTimeMillis(); - String assertion = createAssertion(jsonFactory, currentTime, tokenServerUri.toString()); + String assertion = createAssertion(jsonFactory, currentTime); GenericData tokenRequest = new GenericData(); tokenRequest.set("grant_type", GRANT_TYPE); @@ -882,8 +882,7 @@ public boolean equals(Object obj) { && Objects.equals(this.useJwtAccessWithScope, other.useJwtAccessWithScope); } - String createAssertion(JsonFactory jsonFactory, long currentTime, String audience) - throws IOException { + String createAssertion(JsonFactory jsonFactory, long currentTime) throws IOException { JsonWebSignature.Header header = new JsonWebSignature.Header(); header.setAlgorithm("RS256"); header.setType("JWT"); @@ -900,13 +899,9 @@ String createAssertion(JsonFactory jsonFactory, long currentTime, String audienc payload.put("scope", Joiner.on(' ').join(scopes)); } - if (audience == null) { - payload.setAudience(OAuth2Utils.TOKEN_SERVER_URI.toString()); - } else { - payload.setAudience(audience); - } - + payload.setAudience(OAuth2Utils.TOKEN_SERVER_URI.toString()); String assertion; + try { assertion = JsonWebSignature.signUsingRsaSha256(privateKey, jsonFactory, header, payload); } catch (GeneralSecurityException e) { diff --git a/oauth2_http/javatests/com/google/auth/oauth2/IdentityPoolCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/IdentityPoolCredentialsTest.java index 33f55dfc6..5f8dc3ca0 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/IdentityPoolCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/IdentityPoolCredentialsTest.java @@ -415,6 +415,92 @@ void refreshAccessToken_workforceWithServiceAccountImpersonation() throws IOExce assertEquals(expectedInternalOptions.toString(), query.get("options")); } + @Test + void identityPoolCredentialSource_validFormats() { + Map credentialSourceMapWithFileTextSource = new HashMap<>(); + Map credentialSourceMapWithFileJsonTextSource = new HashMap<>(); + Map credentialSourceMapWithUrlTextSource = new HashMap<>(); + Map credentialSourceMapWithUrlJsonTextSource = new HashMap<>(); + + credentialSourceMapWithFileTextSource.put("file", "/path/to/file"); + credentialSourceMapWithFileJsonTextSource.put("file", "/path/to/file"); + + credentialSourceMapWithUrlTextSource.put("url", "https://google.com"); + credentialSourceMapWithUrlJsonTextSource.put("url", "https://google.com"); + Map headersMap = new HashMap<>(); + headersMap.put("header1", "value1"); + headersMap.put("header2", "value2"); + credentialSourceMapWithUrlTextSource.put("headers", headersMap); + credentialSourceMapWithUrlJsonTextSource.put("headers", headersMap); + + Map textFormat = new HashMap<>(); + textFormat.put("type", "text"); + + Map jsonTextFormat = new HashMap<>(); + jsonTextFormat.put("type", "json"); + jsonTextFormat.put("subject_token_field_name", "access_token"); + + credentialSourceMapWithFileTextSource.put("format", textFormat); + credentialSourceMapWithFileJsonTextSource.put("format", jsonTextFormat); + + credentialSourceMapWithUrlTextSource.put("format", textFormat); + credentialSourceMapWithUrlJsonTextSource.put("format", jsonTextFormat); + + List> sources = + Arrays.asList( + credentialSourceMapWithFileTextSource, + credentialSourceMapWithFileJsonTextSource, + credentialSourceMapWithUrlTextSource, + credentialSourceMapWithUrlJsonTextSource); + for (Map source : sources) { + // Should not throw. + new IdentityPoolCredentialSource(source); + } + } + + @Test + void identityPoolCredentialSource_caseInsensitive() { + Map credentialSourceMapWithFileTextSource = new HashMap<>(); + Map credentialSourceMapWithFileJsonTextSource = new HashMap<>(); + Map credentialSourceMapWithUrlTextSource = new HashMap<>(); + Map credentialSourceMapWithUrlJsonTextSource = new HashMap<>(); + + credentialSourceMapWithFileTextSource.put("file", "/path/to/file"); + credentialSourceMapWithFileJsonTextSource.put("file", "/path/to/file"); + + credentialSourceMapWithUrlTextSource.put("url", "https://google.com"); + credentialSourceMapWithUrlJsonTextSource.put("url", "https://google.com"); + Map headersMap = new HashMap<>(); + headersMap.put("HeaDer1", "Value1"); + headersMap.put("HeaDer2", "Value2"); + credentialSourceMapWithUrlTextSource.put("headers", headersMap); + credentialSourceMapWithUrlJsonTextSource.put("headers", headersMap); + + Map textFormat = new HashMap<>(); + textFormat.put("type", "TEXT"); + + Map jsonTextFormat = new HashMap<>(); + jsonTextFormat.put("type", "JSON"); + jsonTextFormat.put("subject_token_field_name", "access_token"); + + credentialSourceMapWithFileTextSource.put("format", textFormat); + credentialSourceMapWithFileJsonTextSource.put("format", jsonTextFormat); + + credentialSourceMapWithUrlTextSource.put("format", textFormat); + credentialSourceMapWithUrlJsonTextSource.put("format", jsonTextFormat); + + List> sources = + Arrays.asList( + credentialSourceMapWithFileTextSource, + credentialSourceMapWithFileJsonTextSource, + credentialSourceMapWithUrlTextSource, + credentialSourceMapWithUrlJsonTextSource); + for (Map source : sources) { + // Should not throw. + new IdentityPoolCredentialSource(source); + } + } + @Test void identityPoolCredentialSource_invalidSourceType() { IllegalArgumentException exception = diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java index 476bfbd5a..b25157a23 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java @@ -242,7 +242,7 @@ void createAssertion_correct() throws IOException { JsonFactory jsonFactory = OAuth2Utils.JSON_FACTORY; long currentTimeMillis = Clock.SYSTEM.currentTimeMillis(); - String assertion = credentials.createAssertion(jsonFactory, currentTimeMillis, null); + String assertion = credentials.createAssertion(jsonFactory, currentTimeMillis); JsonWebSignature signature = JsonWebSignature.parse(jsonFactory, assertion); JsonWebToken.Payload payload = signature.getPayload(); @@ -272,7 +272,7 @@ void createAssertion_defaultScopes_correct() throws IOException { JsonFactory jsonFactory = OAuth2Utils.JSON_FACTORY; long currentTimeMillis = Clock.SYSTEM.currentTimeMillis(); - String assertion = credentials.createAssertion(jsonFactory, currentTimeMillis, null); + String assertion = credentials.createAssertion(jsonFactory, currentTimeMillis); JsonWebSignature signature = JsonWebSignature.parse(jsonFactory, assertion); JsonWebToken.Payload payload = signature.getPayload(); @@ -290,7 +290,7 @@ void createAssertion_custom_lifetime() throws IOException { JsonFactory jsonFactory = OAuth2Utils.JSON_FACTORY; long currentTimeMillis = Clock.SYSTEM.currentTimeMillis(); - String assertion = credentials.createAssertion(jsonFactory, currentTimeMillis, null); + String assertion = credentials.createAssertion(jsonFactory, currentTimeMillis); JsonWebSignature signature = JsonWebSignature.parse(jsonFactory, assertion); JsonWebToken.Payload payload = signature.getPayload(); @@ -372,36 +372,6 @@ void createAssertionForIdToken_incorrect() throws IOException { assertEquals(USER, payload.getSubject()); } - @Test - void createAssertion_withTokenUri_correct() throws IOException { - PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(PRIVATE_KEY_PKCS8); - List scopes = Arrays.asList("scope1", "scope2"); - ServiceAccountCredentials credentials = - ServiceAccountCredentials.newBuilder() - .setClientId(CLIENT_ID) - .setClientEmail(CLIENT_EMAIL) - .setPrivateKey(privateKey) - .setPrivateKeyId(PRIVATE_KEY_ID) - .setScopes(scopes) - .setServiceAccountUser(USER) - .setProjectId(PROJECT_ID) - .build(); - - JsonFactory jsonFactory = OAuth2Utils.JSON_FACTORY; - long currentTimeMillis = Clock.SYSTEM.currentTimeMillis(); - String assertion = - credentials.createAssertion(jsonFactory, currentTimeMillis, "https://foo.com/bar"); - - JsonWebSignature signature = JsonWebSignature.parse(jsonFactory, assertion); - JsonWebToken.Payload payload = signature.getPayload(); - assertEquals(CLIENT_EMAIL, payload.getIssuer()); - assertEquals("https://foo.com/bar", payload.getAudience()); - assertEquals(currentTimeMillis / 1000, (long) payload.getIssuedAtTimeSeconds()); - assertEquals(currentTimeMillis / 1000 + 3600, (long) payload.getExpirationTimeSeconds()); - assertEquals(USER, payload.getSubject()); - assertEquals(String.join(" ", scopes), payload.get("scope")); - } - @Test void createdScoped_enablesAccessTokens() throws IOException { MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); diff --git a/oauth2_http/pom.xml b/oauth2_http/pom.xml index 0c7a505a8..bdd84fe36 100644 --- a/oauth2_http/pom.xml +++ b/oauth2_http/pom.xml @@ -5,7 +5,7 @@ com.google.auth google-auth-library-parent - 1.3.0 + 1.4.0 ../pom.xml diff --git a/pom.xml b/pom.xml index 1246251e8..160663fbf 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.auth google-auth-library-parent - 1.3.0 + 1.4.0 pom Google Auth Library for Java Client libraries providing authentication and @@ -59,10 +59,10 @@ UTF-8 - 1.40.1 - 5.8.1 + 1.41.0 + 5.8.2 31.0.1-android - 1.9.92 + 2.0.2 3.0.2 false 1.8.2 @@ -182,7 +182,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.2.0 + 3.2.2 @@ -207,18 +207,10 @@ com.coveo fmt-maven-plugin - 2.9 + 2.13 - true - - - com.google.googlejavaformat - google-java-format - 1.7 - - org.codehaus.mojo @@ -230,7 +222,7 @@ maven-compiler-plugin - 3.8.1 + 3.9.0 1.8 1.8 @@ -249,7 +241,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.0.0 + 3.1.2 checkstyle @@ -480,7 +472,7 @@ - java-docfx-doclet-1.3.0 + java-docfx-doclet-1.5.0 ${project.build.directory}/docfx-yml ${project.artifactId} diff --git a/versions.txt b/versions.txt index 9b3211db0..4ba03e3df 100644 --- a/versions.txt +++ b/versions.txt @@ -1,9 +1,9 @@ # Format: # module:released-version:current-version -google-auth-library:1.3.0:1.3.0 -google-auth-library-bom:1.3.0:1.3.0 -google-auth-library-parent:1.3.0:1.3.0 -google-auth-library-appengine:1.3.0:1.3.0 -google-auth-library-credentials:1.3.0:1.3.0 -google-auth-library-oauth2-http:1.3.0:1.3.0 +google-auth-library:1.4.0:1.4.0 +google-auth-library-bom:1.4.0:1.4.0 +google-auth-library-parent:1.4.0:1.4.0 +google-auth-library-appengine:1.4.0:1.4.0 +google-auth-library-credentials:1.4.0:1.4.0 +google-auth-library-oauth2-http:1.4.0:1.4.0