From 5e4946381d126d0845839acb864cac7a21d8869f Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Wed, 16 Dec 2020 08:42:20 -0800 Subject: [PATCH 1/2] ci(java): ignore bot users for generate-files-bot (#524) This PR was generated using Autosynth. :rainbow: Synth log will be available here: https://source.cloud.google.com/results/invocations/5204afce-766b-4a81-9152-05f5c11b5df8/targets - [ ] To automatically regenerate this PR, check this box. Source-Link: https://github.com/googleapis/synthtool/commit/3f67ceece7e797a5736a25488aae35405649b90b --- .github/generated-files-bot.yml | 4 ++++ synth.metadata | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/generated-files-bot.yml b/.github/generated-files-bot.yml index 20f3acc28..47c2ba132 100644 --- a/.github/generated-files-bot.yml +++ b/.github/generated-files-bot.yml @@ -5,3 +5,7 @@ externalManifests: - type: json file: '.github/readme/synth.metadata/synth.metadata' jsonpath: '$.generatedFiles[*]' +ignoreAuthors: +- 'renovate-bot' +- 'yoshi-automation' +- 'release-please[bot]' diff --git a/synth.metadata b/synth.metadata index a56ccd435..cc2dca61f 100644 --- a/synth.metadata +++ b/synth.metadata @@ -3,15 +3,15 @@ { "git": { "name": ".", - "remote": "git@github.com:googleapis/google-auth-library-java.git", - "sha": "0a8412fcf9de4ac568b9f88618e44087dd31b144" + "remote": "https://github.com/googleapis/google-auth-library-java.git", + "sha": "5a1d5c0f56c62311b646ffbdc2e39affa55d5c0c" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "996775eca5fd934edac3c2ae34b80ff0395b1717" + "sha": "3f67ceece7e797a5736a25488aae35405649b90b" } } ], From edc8d6e0e7ca2c6749d026ba42854a09c4879fd6 Mon Sep 17 00:00:00 2001 From: arithmetic1728 <58957152+arithmetic1728@users.noreply.github.com> Date: Wed, 16 Dec 2020 14:24:12 -0800 Subject: [PATCH 2/2] feat: allow custom scopes for compute engine creds (#514) * feat: allow custom scopes for compute engine creds * update --- .../auth/oauth2/ComputeEngineCredentials.java | 61 +++++++++++++++-- .../oauth2/ComputeEngineCredentialsTest.java | 68 +++++++++++++++++++ 2 files changed, 124 insertions(+), 5 deletions(-) diff --git a/oauth2_http/java/com/google/auth/oauth2/ComputeEngineCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ComputeEngineCredentials.java index e65e94ea6..f4e95c2c9 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ComputeEngineCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ComputeEngineCredentials.java @@ -43,12 +43,17 @@ import com.google.auth.ServiceAccountSigner; import com.google.auth.http.HttpTransportFactory; import com.google.common.annotations.Beta; +import com.google.common.base.Joiner; import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableSet; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.net.SocketTimeoutException; import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; @@ -94,6 +99,8 @@ public class ComputeEngineCredentials extends GoogleCredentials private final String transportFactoryClassName; + private final Collection scopes; + private transient HttpTransportFactory transportFactory; private transient String serviceAccountEmail; @@ -102,13 +109,28 @@ public class ComputeEngineCredentials extends GoogleCredentials * * @param transportFactory HTTP transport factory, creates the transport used to get access * tokens. + * @param scopes scope strings for the APIs to be called. May be null or an empty collection. */ - private ComputeEngineCredentials(HttpTransportFactory transportFactory) { + private ComputeEngineCredentials( + HttpTransportFactory transportFactory, Collection scopes) { this.transportFactory = firstNonNull( transportFactory, getFromServiceLoader(HttpTransportFactory.class, OAuth2Utils.HTTP_TRANSPORT_FACTORY)); this.transportFactoryClassName = this.transportFactory.getClass().getName(); + if (scopes == null) { + this.scopes = ImmutableSet.of(); + } else { + List scopeList = new ArrayList(scopes); + scopeList.removeAll(Arrays.asList("", null)); + this.scopes = ImmutableSet.copyOf(scopeList); + } + } + + /** Clones the compute engine account with the specified scopes. */ + @Override + public GoogleCredentials createScoped(Collection newScopes) { + return new ComputeEngineCredentials(this.transportFactory, newScopes); } /** @@ -117,13 +139,30 @@ private ComputeEngineCredentials(HttpTransportFactory transportFactory) { * @return new ComputeEngineCredentials */ public static ComputeEngineCredentials create() { - return new ComputeEngineCredentials(null); + return new ComputeEngineCredentials(null, null); + } + + public final Collection getScopes() { + return scopes; + } + + /** + * If scopes is specified, add "?scopes=comma-separated-list-of-scopes" to the token url. + * + * @return token url with the given scopes + */ + String createTokenUrlWithScopes() { + GenericUrl tokenUrl = new GenericUrl(getTokenServerEncodedUrl()); + if (!scopes.isEmpty()) { + tokenUrl.set("scopes", Joiner.on(',').join(scopes)); + } + return tokenUrl.toString(); } /** Refresh the access token by getting it from the GCE metadata server */ @Override public AccessToken refreshAccessToken() throws IOException { - HttpResponse response = getMetadataResponse(getTokenServerEncodedUrl()); + HttpResponse response = getMetadataResponse(createTokenUrlWithScopes()); int statusCode = response.getStatusCode(); if (statusCode == HttpStatusCodes.STATUS_CODE_NOT_FOUND) { throw new IOException( @@ -307,7 +346,8 @@ public boolean equals(Object obj) { return false; } ComputeEngineCredentials other = (ComputeEngineCredentials) obj; - return Objects.equals(this.transportFactoryClassName, other.transportFactoryClassName); + return Objects.equals(this.transportFactoryClassName, other.transportFactoryClassName) + && Objects.equals(this.scopes, other.scopes); } private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { @@ -399,11 +439,13 @@ private String getDefaultServiceAccount() throws IOException { public static class Builder extends GoogleCredentials.Builder { private HttpTransportFactory transportFactory; + private Collection scopes; protected Builder() {} protected Builder(ComputeEngineCredentials credentials) { this.transportFactory = credentials.transportFactory; + this.scopes = credentials.scopes; } public Builder setHttpTransportFactory(HttpTransportFactory transportFactory) { @@ -411,12 +453,21 @@ public Builder setHttpTransportFactory(HttpTransportFactory transportFactory) { return this; } + public Builder setScopes(Collection scopes) { + this.scopes = scopes; + return this; + } + public HttpTransportFactory getHttpTransportFactory() { return transportFactory; } + public Collection getScopes() { + return scopes; + } + public ComputeEngineCredentials build() { - return new ComputeEngineCredentials(transportFactory); + return new ComputeEngineCredentials(transportFactory, scopes); } } } diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ComputeEngineCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ComputeEngineCredentialsTest.java index 5eca95e38..be8841cb2 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ComputeEngineCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ComputeEngineCredentialsTest.java @@ -56,6 +56,8 @@ import java.io.IOException; import java.net.URI; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Map; import org.junit.Test; @@ -68,6 +70,9 @@ public class ComputeEngineCredentialsTest extends BaseSerializationTest { private static final URI CALL_URI = URI.create("http://googleapis.com/testapi/v1/foo"); + private static final String TOKEN_URL = + "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"; + // Id Token which includes basic default claims public static final String STANDARD_ID_TOKEN = "eyJhbGciOiJSUzI1NiIsImtpZCI6ImRmMzc1ODkwOGI3OTIyO" @@ -113,6 +118,69 @@ public HttpTransport create() { } } + @Test + public void createTokenUrlWithScopes_null_scopes() { + ComputeEngineCredentials credentials = + ComputeEngineCredentials.newBuilder().setScopes(null).build(); + Collection scopes = credentials.getScopes(); + String tokenUrlWithScopes = credentials.createTokenUrlWithScopes(); + + assertEquals(TOKEN_URL, tokenUrlWithScopes); + assertTrue(scopes.isEmpty()); + } + + @Test + public void createTokenUrlWithScopes_empty_scopes() { + ComputeEngineCredentials.Builder builder = + ComputeEngineCredentials.newBuilder().setScopes(Collections.emptyList()); + ComputeEngineCredentials credentials = builder.build(); + Collection scopes = credentials.getScopes(); + String tokenUrlWithScopes = credentials.createTokenUrlWithScopes(); + + assertEquals(TOKEN_URL, tokenUrlWithScopes); + assertTrue(scopes.isEmpty()); + assertTrue(builder.getScopes().isEmpty()); + } + + @Test + public void createTokenUrlWithScopes_single_scope() { + ComputeEngineCredentials credentials = + ComputeEngineCredentials.newBuilder().setScopes(Arrays.asList("foo")).build(); + String tokenUrlWithScopes = credentials.createTokenUrlWithScopes(); + Collection scopes = credentials.getScopes(); + + assertEquals(TOKEN_URL + "?scopes=foo", tokenUrlWithScopes); + assertEquals(1, scopes.size()); + assertEquals("foo", scopes.toArray()[0]); + } + + @Test + public void createTokenUrlWithScopes_multiple_scopes() { + ComputeEngineCredentials credentials = + ComputeEngineCredentials.newBuilder() + .setScopes(Arrays.asList(null, "foo", "", "bar")) + .build(); + Collection scopes = credentials.getScopes(); + String tokenUrlWithScopes = credentials.createTokenUrlWithScopes(); + + assertEquals(TOKEN_URL + "?scopes=foo,bar", tokenUrlWithScopes); + assertEquals(2, scopes.size()); + assertEquals("foo", scopes.toArray()[0]); + assertEquals("bar", scopes.toArray()[1]); + } + + @Test + public void createScoped() { + ComputeEngineCredentials credentials = + ComputeEngineCredentials.newBuilder().setScopes(null).build(); + ComputeEngineCredentials credentialsWithScopes = + (ComputeEngineCredentials) credentials.createScoped(Arrays.asList("foo")); + Collection scopes = credentialsWithScopes.getScopes(); + + assertEquals(1, scopes.size()); + assertEquals("foo", scopes.toArray()[0]); + } + @Test public void getRequestMetadata_hasAccessToken() throws IOException { String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2";