From 57d6e3f6eac16397fdef7ffc30b022b4faaf2a24 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 30 Nov 2015 20:29:57 -0800 Subject: [PATCH 1/6] Remove dependency on http initializer in AuthCredentials and remove dependency on com.google.api.client.googleapis.auth.oauth2.GoogleCredential --- .../com/google/gcloud/AuthCredentials.java | 114 +++++++++++++----- .../com/google/gcloud/ServiceOptions.java | 4 +- 2 files changed, 85 insertions(+), 33 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java index 3303e4f8a652..779a60fb8a1b 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java @@ -18,21 +18,17 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; -import com.google.api.client.googleapis.extensions.appengine.auth.oauth2.AppIdentityCredential; -import com.google.api.client.http.HttpRequestInitializer; -import com.google.api.client.http.HttpTransport; -import com.google.api.client.json.jackson.JacksonFactory; -import com.google.auth.http.HttpCredentialsAdapter; +import com.google.auth.oauth2.AccessToken; import com.google.auth.oauth2.GoogleCredentials; import com.google.auth.oauth2.ServiceAccountCredentials; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; +import java.lang.reflect.Method; import java.security.PrivateKey; +import java.util.Collection; import java.util.Objects; -import java.util.Set; /** * Credentials for accessing Google Cloud services. @@ -42,8 +38,66 @@ public abstract class AuthCredentials implements Restorable { private static class AppEngineAuthCredentials extends AuthCredentials { private static final AuthCredentials INSTANCE = new AppEngineAuthCredentials(); - private static final AppEngineAuthCredentialsState STATE = - new AppEngineAuthCredentialsState(); + private static final AppEngineAuthCredentialsState STATE = new AppEngineAuthCredentialsState(); + + private static class AppEngineCredentials extends GoogleCredentials { + + private final Object appIdentityService; + private final Collection scopes; + private final boolean scopesRequired; + + AppEngineCredentials() { + try { + Class factoryClass = + Class.forName("com.google.appengine.api.appidentity.AppIdentityServiceFactory"); + Method method = factoryClass.getMethod("getAppIdentityService"); + this.appIdentityService = method.invoke(null); + this.scopes = null; + this.scopesRequired = true; + } catch (Exception e) { + throw new RuntimeException("Could not create AppEngineCredentials using reflection."); + } + } + + AppEngineCredentials(Collection scopes, Object appIdentityService) { + this.appIdentityService = appIdentityService; + this.scopes = scopes; + this.scopesRequired = (scopes == null || scopes.isEmpty()); + } + + /** + * Refresh the access token by getting it from the App Identity service + */ + @Override + public AccessToken refreshAccessToken() throws IOException { + if (createScopedRequired()) { + throw new IOException("AppEngineCredentials requires createScoped call before use."); + } + try { + Class serviceClass = + Class.forName("com.google.appengine.api.appidentity.AppIdentityService"); + Class tokenResultClass = Class.forName( + "com.google.appengine.api.appidentity.AppIdentityService$GetAccessTokenResult"); + Method getAccessTokenResult = serviceClass.getMethod("getAccessToken", Iterable.class); + Object accessTokenResult = getAccessTokenResult.invoke(appIdentityService, scopes); + Method getAccessToken = tokenResultClass.getMethod("getAccessToken"); + String accessToken = (String) getAccessToken.invoke(accessTokenResult); + return new AccessToken(accessToken, null); + } catch (Exception e) { + throw new RuntimeException("Could not get the access token using reflection."); + } + } + + @Override + public boolean createScopedRequired() { + return scopesRequired; + } + + @Override + public GoogleCredentials createScoped(Collection scopes) { + return new AppEngineCredentials(scopes, appIdentityService); + } + } private static class AppEngineAuthCredentialsState implements RestorableState, Serializable { @@ -67,9 +121,8 @@ public boolean equals(Object obj) { } @Override - protected HttpRequestInitializer httpRequestInitializer(HttpTransport transport, - Set scopes) { - return new AppIdentityCredential(scopes); + protected GoogleCredentials credentials() { + return new AppEngineCredentials(); } @Override @@ -133,17 +186,10 @@ public boolean equals(Object obj) { } @Override - protected HttpRequestInitializer httpRequestInitializer( - HttpTransport transport, Set scopes) { - GoogleCredential.Builder builder = new GoogleCredential.Builder() - .setTransport(transport) - .setJsonFactory(new JacksonFactory()); - if (privateKey != null) { - builder.setServiceAccountPrivateKey(privateKey); - builder.setServiceAccountId(account); - builder.setServiceAccountScopes(scopes); - } - return builder.build(); + protected GoogleCredentials credentials() { + return (privateKey == null) + ? new GoogleCredentials(null) + : new ServiceAccountCredentials(null, account, privateKey, null, null); } public String account() { @@ -198,9 +244,8 @@ public boolean equals(Object obj) { } @Override - protected HttpRequestInitializer httpRequestInitializer(HttpTransport transport, - Set scopes) { - return new HttpCredentialsAdapter(googleCredentials.createScoped(scopes)); + protected GoogleCredentials credentials() { + return googleCredentials; } public ServiceAccountAuthCredentials toServiceAccountCredentials() { @@ -218,8 +263,7 @@ public RestorableState capture() { } } - protected abstract HttpRequestInitializer httpRequestInitializer(HttpTransport transport, - Set scopes); + protected abstract GoogleCredentials credentials(); public static AuthCredentials createForAppEngine() { return AppEngineAuthCredentials.INSTANCE; @@ -271,9 +315,17 @@ public static ServiceAccountAuthCredentials createFor(String account, PrivateKey */ public static ServiceAccountAuthCredentials createForJson(InputStream jsonCredentialStream) throws IOException { - GoogleCredential tempCredentials = GoogleCredential.fromStream(jsonCredentialStream); - return new ServiceAccountAuthCredentials(tempCredentials.getServiceAccountId(), - tempCredentials.getServiceAccountPrivateKey()); + GoogleCredentials tempCredentials = GoogleCredentials.fromStream(jsonCredentialStream); + if (tempCredentials instanceof ServiceAccountCredentials) { + ServiceAccountCredentials tempServiceAccountCredentials = + (ServiceAccountCredentials) tempCredentials; + return new ServiceAccountAuthCredentials( + tempServiceAccountCredentials.getClientEmail(), + tempServiceAccountCredentials.getPrivateKey()); + } else { + throw new IOException( + "The given JSON Credentials Stream is not a service account credential."); + } } public static AuthCredentials noCredentials() { diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java index 25fda29c363d..bc0e91d0a694 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java @@ -25,6 +25,7 @@ import com.google.api.client.http.HttpRequestInitializer; import com.google.api.client.http.HttpTransport; import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.auth.http.HttpCredentialsAdapter; import com.google.common.collect.Iterables; import com.google.gcloud.spi.ServiceRpcFactory; @@ -508,9 +509,8 @@ public RetryParams retryParams() { * options. */ public HttpRequestInitializer httpRequestInitializer() { - HttpTransport httpTransport = httpTransportFactory.create(); final HttpRequestInitializer baseRequestInitializer = - authCredentials().httpRequestInitializer(httpTransport, scopes()); + new HttpCredentialsAdapter(authCredentials().credentials().createScoped(scopes())); return new HttpRequestInitializer() { @Override public void initialize(HttpRequest httpRequest) throws IOException { From b5c1caec2a3d1cfe5a0b7a118154b3e333471b6f Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 1 Dec 2015 09:40:28 -0800 Subject: [PATCH 2/6] Use null instead of NO_CREDENTIALS --- .../com/google/gcloud/AuthCredentials.java | 18 +----------------- .../java/com/google/gcloud/ServiceOptions.java | 18 +++++++++++------- .../gcloud/datastore/SerializationTest.java | 2 +- .../gcloud/storage/SerializationTest.java | 4 +--- .../google/gcloud/storage/StorageImplTest.java | 4 +--- 5 files changed, 15 insertions(+), 31 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java index 779a60fb8a1b..9aaee77ea243 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java @@ -136,8 +136,6 @@ public static class ServiceAccountAuthCredentials extends AuthCredentials { private final String account; private final PrivateKey privateKey; - private static final AuthCredentials NO_CREDENTIALS = new ServiceAccountAuthCredentials(); - private static class ServiceAccountAuthCredentialsState implements RestorableState, Serializable { @@ -153,9 +151,6 @@ private ServiceAccountAuthCredentialsState(String account, PrivateKey privateKey @Override public AuthCredentials restore() { - if (account == null && privateKey == null) { - return NO_CREDENTIALS; - } return new ServiceAccountAuthCredentials(account, privateKey); } @@ -180,16 +175,9 @@ public boolean equals(Object obj) { this.privateKey = checkNotNull(privateKey); } - ServiceAccountAuthCredentials() { - account = null; - privateKey = null; - } - @Override protected GoogleCredentials credentials() { - return (privateKey == null) - ? new GoogleCredentials(null) - : new ServiceAccountCredentials(null, account, privateKey, null, null); + return new ServiceAccountCredentials(null, account, privateKey, null, null); } public String account() { @@ -327,8 +315,4 @@ public static ServiceAccountAuthCredentials createForJson(InputStream jsonCreden "The given JSON Credentials Stream is not a service account credential."); } } - - public static AuthCredentials noCredentials() { - return ServiceAccountAuthCredentials.NO_CREDENTIALS; - } } diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java index bc0e91d0a694..715b0b92ca98 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java @@ -312,8 +312,9 @@ protected ServiceOptions(Class> ser httpTransportFactory = firstNonNull(builder.httpTransportFactory, getFromServiceLoader(HttpTransportFactory.class, DefaultHttpTransportFactory.INSTANCE)); httpTransportFactoryClassName = httpTransportFactory.getClass().getName(); - authCredentials = firstNonNull(builder.authCredentials, defaultAuthCredentials()); - authCredentialsState = authCredentials.capture(); + authCredentials = + builder.authCredentials != null ? builder.authCredentials : defaultAuthCredentials(); + authCredentialsState = authCredentials != null ? authCredentials.capture() : null; retryParams = builder.retryParams; serviceFactory = firstNonNull(builder.serviceFactory, getFromServiceLoader(serviceFactoryClass, defaultServiceFactory())); @@ -349,7 +350,7 @@ private static AuthCredentials defaultAuthCredentials() { try { return AuthCredentials.createApplicationDefaults(); } catch (Exception ex) { - return AuthCredentials.noCredentials(); + return null; } } @@ -509,12 +510,15 @@ public RetryParams retryParams() { * options. */ public HttpRequestInitializer httpRequestInitializer() { - final HttpRequestInitializer baseRequestInitializer = - new HttpCredentialsAdapter(authCredentials().credentials().createScoped(scopes())); + final HttpRequestInitializer delegate = authCredentials() != null + ? new HttpCredentialsAdapter(authCredentials().credentials().createScoped(scopes())) + : null; return new HttpRequestInitializer() { @Override public void initialize(HttpRequest httpRequest) throws IOException { - baseRequestInitializer.initialize(httpRequest); + if (delegate != null) { + delegate.initialize(httpRequest); + } if (connectTimeout >= 0) { httpRequest.setConnectTimeout(connectTimeout); } @@ -580,7 +584,7 @@ private void readObject(ObjectInputStream input) throws IOException, ClassNotFou httpTransportFactory = newInstance(httpTransportFactoryClassName); serviceFactory = newInstance(serviceFactoryClassName); serviceRpcFactory = newInstance(serviceRpcFactoryClassName); - authCredentials = authCredentialsState.restore(); + authCredentials = authCredentialsState != null ? authCredentialsState.restore() : null; } private static T newInstance(String className) throws IOException, ClassNotFoundException { diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 32e14fb47ea0..3976be2cc383 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -144,7 +144,7 @@ public void testServiceOptions() throws Exception { options = options.toBuilder() .namespace("ns1") .retryParams(RetryParams.defaultInstance()) - .authCredentials(AuthCredentials.noCredentials()) + .authCredentials(null) .force(true) .build(); serializedCopy = serializeAndDeserialize(options); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java index 2d80191aeb2d..256f5fc23f9a 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java @@ -83,7 +83,7 @@ public void testServiceOptions() throws Exception { options = options.toBuilder() .projectId("p2") .retryParams(RetryParams.defaultInstance()) - .authCredentials(AuthCredentials.noCredentials()) + .authCredentials(null) .pathDelimiter(":") .build(); serializedCopy = serializeAndDeserialize(options); @@ -111,7 +111,6 @@ public void testReadChannelState() throws IOException, ClassNotFoundException { StorageOptions options = StorageOptions.builder() .projectId("p2") .retryParams(RetryParams.defaultInstance()) - .authCredentials(AuthCredentials.noCredentials()) .build(); BlobReadChannel reader = new BlobReadChannelImpl(options, BlobId.of("b", "n"), EMPTY_RPC_OPTIONS); @@ -127,7 +126,6 @@ public void testWriteChannelState() throws IOException, ClassNotFoundException { StorageOptions options = StorageOptions.builder() .projectId("p2") .retryParams(RetryParams.defaultInstance()) - .authCredentials(AuthCredentials.noCredentials()) .build(); BlobWriteChannelImpl writer = new BlobWriteChannelImpl( options, BlobInfo.builder(BlobId.of("b", "n")).build(), "upload-id"); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java index 32a466a9d551..42671d37c60c 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java @@ -31,11 +31,10 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import com.google.common.io.BaseEncoding; -import com.google.gcloud.AuthCredentials; import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; +import com.google.gcloud.Page; import com.google.gcloud.RetryParams; import com.google.gcloud.ServiceOptions; -import com.google.gcloud.Page; import com.google.gcloud.spi.StorageRpc; import com.google.gcloud.spi.StorageRpc.Tuple; import com.google.gcloud.spi.StorageRpcFactory; @@ -260,7 +259,6 @@ public void setUp() throws IOException, InterruptedException { EasyMock.replay(rpcFactoryMock); options = StorageOptions.builder() .projectId("projectId") - .authCredentials(AuthCredentials.noCredentials()) .clock(TIME_SOURCE) .serviceRpcFactory(rpcFactoryMock) .build(); From 12078e04dabf1790f02ea17888bde24a7515d8bf Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 1 Dec 2015 14:07:31 -0800 Subject: [PATCH 3/6] Make AppEngineAuthCredentials Restorable --- .../com/google/gcloud/AuthCredentials.java | 49 +++++++++---------- .../google/gcloud/storage/StorageImpl.java | 25 +++++----- 2 files changed, 33 insertions(+), 41 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java index 9aaee77ea243..7f5d7a8ab89b 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java @@ -43,6 +43,8 @@ private static class AppEngineAuthCredentials extends AuthCredentials { private static class AppEngineCredentials extends GoogleCredentials { private final Object appIdentityService; + private final Method getAccessToken; + private final Method getAccessTokenResult; private final Collection scopes; private final boolean scopesRequired; @@ -52,6 +54,12 @@ private static class AppEngineCredentials extends GoogleCredentials { Class.forName("com.google.appengine.api.appidentity.AppIdentityServiceFactory"); Method method = factoryClass.getMethod("getAppIdentityService"); this.appIdentityService = method.invoke(null); + Class serviceClass = + Class.forName("com.google.appengine.api.appidentity.AppIdentityService"); + Class tokenResultClass = Class.forName( + "com.google.appengine.api.appidentity.AppIdentityService$GetAccessTokenResult"); + this.getAccessTokenResult = serviceClass.getMethod("getAccessToken", Iterable.class); + this.getAccessToken = tokenResultClass.getMethod("getAccessToken"); this.scopes = null; this.scopesRequired = true; } catch (Exception e) { @@ -59,10 +67,13 @@ private static class AppEngineCredentials extends GoogleCredentials { } } - AppEngineCredentials(Collection scopes, Object appIdentityService) { - this.appIdentityService = appIdentityService; - this.scopes = scopes; - this.scopesRequired = (scopes == null || scopes.isEmpty()); + AppEngineCredentials(Collection scopes, Object appIdentityService, + Method getAccessToken, Method getAccessTokenResult) { + this.appIdentityService = appIdentityService; + this.getAccessToken = getAccessToken; + this.getAccessTokenResult = getAccessTokenResult; + this.scopes = scopes; + this.scopesRequired = (scopes == null || scopes.isEmpty()); } /** @@ -74,13 +85,7 @@ public AccessToken refreshAccessToken() throws IOException { throw new IOException("AppEngineCredentials requires createScoped call before use."); } try { - Class serviceClass = - Class.forName("com.google.appengine.api.appidentity.AppIdentityService"); - Class tokenResultClass = Class.forName( - "com.google.appengine.api.appidentity.AppIdentityService$GetAccessTokenResult"); - Method getAccessTokenResult = serviceClass.getMethod("getAccessToken", Iterable.class); Object accessTokenResult = getAccessTokenResult.invoke(appIdentityService, scopes); - Method getAccessToken = tokenResultClass.getMethod("getAccessToken"); String accessToken = (String) getAccessToken.invoke(accessTokenResult); return new AccessToken(accessToken, null); } catch (Exception e) { @@ -95,7 +100,8 @@ public boolean createScopedRequired() { @Override public GoogleCredentials createScoped(Collection scopes) { - return new AppEngineCredentials(scopes, appIdentityService); + return new AppEngineCredentials( + scopes, appIdentityService, getAccessToken, getAccessTokenResult); } } @@ -121,7 +127,7 @@ public boolean equals(Object obj) { } @Override - protected GoogleCredentials credentials() { + public GoogleCredentials credentials() { return new AppEngineCredentials(); } @@ -176,7 +182,7 @@ public boolean equals(Object obj) { } @Override - protected GoogleCredentials credentials() { + public GoogleCredentials credentials() { return new ServiceAccountCredentials(null, account, privateKey, null, null); } @@ -232,26 +238,17 @@ public boolean equals(Object obj) { } @Override - protected GoogleCredentials credentials() { + public GoogleCredentials credentials() { return googleCredentials; } - public ServiceAccountAuthCredentials toServiceAccountCredentials() { - if (googleCredentials instanceof ServiceAccountCredentials) { - ServiceAccountCredentials credentials = (ServiceAccountCredentials) googleCredentials; - return new ServiceAccountAuthCredentials(credentials.getClientEmail(), - credentials.getPrivateKey()); - } - return null; - } - @Override public RestorableState capture() { return STATE; } } - protected abstract GoogleCredentials credentials(); + public abstract GoogleCredentials credentials(); public static AuthCredentials createForAppEngine() { return AppEngineAuthCredentials.INSTANCE; @@ -310,9 +307,7 @@ public static ServiceAccountAuthCredentials createForJson(InputStream jsonCreden return new ServiceAccountAuthCredentials( tempServiceAccountCredentials.getClientEmail(), tempServiceAccountCredentials.getPrivateKey()); - } else { - throw new IOException( - "The given JSON Credentials Stream is not a service account credential."); } + throw new IOException("The given JSON Credentials Stream is not a service account credential."); } } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java index 91a408657847..fdb643c725ac 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java @@ -31,6 +31,8 @@ import static java.nio.charset.StandardCharsets.UTF_8; import com.google.api.services.storage.model.StorageObject; +import com.google.auth.oauth2.GoogleCredentials; +import com.google.auth.oauth2.ServiceAccountCredentials; import com.google.common.base.Function; import com.google.common.base.Functions; import com.google.common.collect.ImmutableList; @@ -38,19 +40,17 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.google.common.collect.Sets; import com.google.common.hash.Hashing; import com.google.common.io.BaseEncoding; import com.google.common.primitives.Ints; import com.google.gcloud.AuthCredentials; -import com.google.gcloud.AuthCredentials.ApplicationDefaultAuthCredentials; import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; -import com.google.gcloud.PageImpl; import com.google.gcloud.BaseService; import com.google.gcloud.ExceptionHandler; import com.google.gcloud.ExceptionHandler.Interceptor; -import com.google.gcloud.RetryHelper.RetryHelperException; import com.google.gcloud.Page; +import com.google.gcloud.PageImpl; +import com.google.gcloud.RetryHelper.RetryHelperException; import com.google.gcloud.spi.StorageRpc; import com.google.gcloud.spi.StorageRpc.RewriteResponse; import com.google.gcloud.spi.StorageRpc.Tuple; @@ -71,7 +71,6 @@ import java.util.EnumMap; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; @@ -566,15 +565,13 @@ public URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOptio ServiceAccountAuthCredentials cred = (ServiceAccountAuthCredentials) optionMap.get(SignUrlOption.Option.SERVICE_ACCOUNT_CRED); if (cred == null) { - AuthCredentials serviceCred = this.options().authCredentials(); - if (serviceCred instanceof ServiceAccountAuthCredentials) { - cred = (ServiceAccountAuthCredentials) serviceCred; - } else { - if (serviceCred instanceof ApplicationDefaultAuthCredentials) { - cred = ((ApplicationDefaultAuthCredentials) serviceCred).toServiceAccountCredentials(); - } - } - checkArgument(cred != null, "Signing key was not provided and could not be derived"); + AuthCredentials authCredentials = this.options().authCredentials(); + GoogleCredentials serviceCred = + authCredentials != null ? authCredentials.credentials() : null; + checkArgument( + serviceCred instanceof ServiceAccountCredentials, + "Signing key was not provided and could not be derived"); + cred = (ServiceAccountAuthCredentials) authCredentials; } // construct signature - see https://cloud.google.com/storage/docs/access-control#Signed-URLs StringBuilder stBuilder = new StringBuilder(); From af94b5312daa978b693ce38b5f2314a335f3d531 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 1 Dec 2015 15:33:03 -0800 Subject: [PATCH 4/6] cleanup + cast fix --- .../com/google/gcloud/AuthCredentials.java | 24 ++++++++----------- .../google/gcloud/storage/StorageImpl.java | 16 +++++++------ 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java index 7f5d7a8ab89b..f3a0024129d7 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java @@ -46,7 +46,6 @@ private static class AppEngineCredentials extends GoogleCredentials { private final Method getAccessToken; private final Method getAccessTokenResult; private final Collection scopes; - private final boolean scopesRequired; AppEngineCredentials() { try { @@ -61,19 +60,16 @@ private static class AppEngineCredentials extends GoogleCredentials { this.getAccessTokenResult = serviceClass.getMethod("getAccessToken", Iterable.class); this.getAccessToken = tokenResultClass.getMethod("getAccessToken"); this.scopes = null; - this.scopesRequired = true; } catch (Exception e) { - throw new RuntimeException("Could not create AppEngineCredentials using reflection."); + throw new RuntimeException("Could not create AppEngineCredentials.", e); } } - AppEngineCredentials(Collection scopes, Object appIdentityService, - Method getAccessToken, Method getAccessTokenResult) { - this.appIdentityService = appIdentityService; - this.getAccessToken = getAccessToken; - this.getAccessTokenResult = getAccessTokenResult; + AppEngineCredentials(Collection scopes, AppEngineCredentials unscoped) { + this.appIdentityService = unscoped.appIdentityService; + this.getAccessToken = unscoped.getAccessToken; + this.getAccessTokenResult = unscoped.getAccessTokenResult; this.scopes = scopes; - this.scopesRequired = (scopes == null || scopes.isEmpty()); } /** @@ -89,19 +85,18 @@ public AccessToken refreshAccessToken() throws IOException { String accessToken = (String) getAccessToken.invoke(accessTokenResult); return new AccessToken(accessToken, null); } catch (Exception e) { - throw new RuntimeException("Could not get the access token using reflection."); + throw new IOException("Could not get the access token.", e); } } @Override public boolean createScopedRequired() { - return scopesRequired; + return scopes == null || scopes.isEmpty(); } @Override public GoogleCredentials createScoped(Collection scopes) { - return new AppEngineCredentials( - scopes, appIdentityService, getAccessToken, getAccessTokenResult); + return new AppEngineCredentials(scopes, this); } } @@ -308,6 +303,7 @@ public static ServiceAccountAuthCredentials createForJson(InputStream jsonCreden tempServiceAccountCredentials.getClientEmail(), tempServiceAccountCredentials.getPrivateKey()); } - throw new IOException("The given JSON Credentials Stream is not a service account credential."); + throw new IOException( + "The given JSON Credentials Stream is not for a service account credential."); } } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java index fdb643c725ac..9207e4905c54 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java @@ -562,16 +562,18 @@ public URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOptio for (SignUrlOption option : options) { optionMap.put(option.option(), option.value()); } - ServiceAccountAuthCredentials cred = + ServiceAccountAuthCredentials serviceAccountAuthCred = (ServiceAccountAuthCredentials) optionMap.get(SignUrlOption.Option.SERVICE_ACCOUNT_CRED); - if (cred == null) { - AuthCredentials authCredentials = this.options().authCredentials(); + ServiceAccountCredentials cred = (ServiceAccountCredentials) (serviceAccountAuthCred != null + ? serviceAccountAuthCred.credentials() : null); + if (serviceAccountAuthCred == null) { + AuthCredentials authCred = this.options().authCredentials(); GoogleCredentials serviceCred = - authCredentials != null ? authCredentials.credentials() : null; + authCred != null ? authCred.credentials() : null; checkArgument( serviceCred instanceof ServiceAccountCredentials, "Signing key was not provided and could not be derived"); - cred = (ServiceAccountAuthCredentials) authCredentials; + cred = (ServiceAccountCredentials) serviceCred; } // construct signature - see https://cloud.google.com/storage/docs/access-control#Signed-URLs StringBuilder stBuilder = new StringBuilder(); @@ -607,12 +609,12 @@ public URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOptio stBuilder.append(path); try { Signature signer = Signature.getInstance("SHA256withRSA"); - signer.initSign(cred.privateKey()); + signer.initSign(cred.getPrivateKey()); signer.update(stBuilder.toString().getBytes(UTF_8)); String signature = URLEncoder.encode(BaseEncoding.base64().encode(signer.sign()), UTF_8.name()); stBuilder = new StringBuilder("https://storage.googleapis.com").append(path); - stBuilder.append("?GoogleAccessId=").append(cred.account()); + stBuilder.append("?GoogleAccessId=").append(cred.getClientEmail()); stBuilder.append("&Expires=").append(expiration); stBuilder.append("&Signature=").append(signature); return new URL(stBuilder.toString()); From 18cbb774258a77172a988d7a84c5e559d57b0c95 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 1 Dec 2015 15:54:32 -0800 Subject: [PATCH 5/6] style fix --- .../com/google/gcloud/storage/StorageImpl.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java index 9207e4905c54..7ff8ccd4d68d 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java @@ -31,7 +31,6 @@ import static java.nio.charset.StandardCharsets.UTF_8; import com.google.api.services.storage.model.StorageObject; -import com.google.auth.oauth2.GoogleCredentials; import com.google.auth.oauth2.ServiceAccountCredentials; import com.google.common.base.Function; import com.google.common.base.Functions; @@ -43,7 +42,6 @@ import com.google.common.hash.Hashing; import com.google.common.io.BaseEncoding; import com.google.common.primitives.Ints; -import com.google.gcloud.AuthCredentials; import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; import com.google.gcloud.BaseService; import com.google.gcloud.ExceptionHandler; @@ -562,18 +560,16 @@ public URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOptio for (SignUrlOption option : options) { optionMap.put(option.option(), option.value()); } - ServiceAccountAuthCredentials serviceAccountAuthCred = + ServiceAccountAuthCredentials authCred = (ServiceAccountAuthCredentials) optionMap.get(SignUrlOption.Option.SERVICE_ACCOUNT_CRED); - ServiceAccountCredentials cred = (ServiceAccountCredentials) (serviceAccountAuthCred != null - ? serviceAccountAuthCred.credentials() : null); - if (serviceAccountAuthCred == null) { - AuthCredentials authCred = this.options().authCredentials(); - GoogleCredentials serviceCred = - authCred != null ? authCred.credentials() : null; + ServiceAccountCredentials cred = + (ServiceAccountCredentials) (authCred != null ? authCred.credentials() : null); + if (authCred == null) { checkArgument( - serviceCred instanceof ServiceAccountCredentials, + this.options().authCredentials() != null + && this.options().authCredentials().credentials() instanceof ServiceAccountCredentials, "Signing key was not provided and could not be derived"); - cred = (ServiceAccountCredentials) serviceCred; + cred = (ServiceAccountCredentials) this.options().authCredentials().credentials(); } // construct signature - see https://cloud.google.com/storage/docs/access-control#Signed-URLs StringBuilder stBuilder = new StringBuilder(); From 942ceb40e3281593afb8da78ced1a9e476284c9c Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 1 Dec 2015 16:04:32 -0800 Subject: [PATCH 6/6] more style fixes --- .../src/main/java/com/google/gcloud/AuthCredentials.java | 2 +- .../src/main/java/com/google/gcloud/storage/StorageImpl.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java index f3a0024129d7..dab6b928374a 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java @@ -177,7 +177,7 @@ public boolean equals(Object obj) { } @Override - public GoogleCredentials credentials() { + public ServiceAccountCredentials credentials() { return new ServiceAccountCredentials(null, account, privateKey, null, null); } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java index 7ff8ccd4d68d..e31c4073548e 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java @@ -562,8 +562,7 @@ public URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOptio } ServiceAccountAuthCredentials authCred = (ServiceAccountAuthCredentials) optionMap.get(SignUrlOption.Option.SERVICE_ACCOUNT_CRED); - ServiceAccountCredentials cred = - (ServiceAccountCredentials) (authCred != null ? authCred.credentials() : null); + ServiceAccountCredentials cred = authCred != null ? authCred.credentials() : null; if (authCred == null) { checkArgument( this.options().authCredentials() != null