Skip to content

Commit 1a050e0

Browse files
author
Ajay Kannan
committed
Make AppEngineAuthCredentials Restorable
1 parent b5c1cae commit 1a050e0

File tree

2 files changed

+38
-43
lines changed

2 files changed

+38
-43
lines changed

gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ private static class AppEngineAuthCredentials extends AuthCredentials {
4343
private static class AppEngineCredentials extends GoogleCredentials {
4444

4545
private final Object appIdentityService;
46+
private final Method getAccessToken;
47+
private final Method getAccessTokenResult;
4648
private final Collection<String> scopes;
4749
private final boolean scopesRequired;
4850

@@ -52,17 +54,26 @@ private static class AppEngineCredentials extends GoogleCredentials {
5254
Class.forName("com.google.appengine.api.appidentity.AppIdentityServiceFactory");
5355
Method method = factoryClass.getMethod("getAppIdentityService");
5456
this.appIdentityService = method.invoke(null);
57+
Class<?> serviceClass =
58+
Class.forName("com.google.appengine.api.appidentity.AppIdentityService");
59+
Class<?> tokenResultClass = Class.forName(
60+
"com.google.appengine.api.appidentity.AppIdentityService$GetAccessTokenResult");
61+
this.getAccessTokenResult = serviceClass.getMethod("getAccessToken", Iterable.class);
62+
this.getAccessToken = tokenResultClass.getMethod("getAccessToken");
5563
this.scopes = null;
5664
this.scopesRequired = true;
5765
} catch (Exception e) {
5866
throw new RuntimeException("Could not create AppEngineCredentials using reflection.");
5967
}
6068
}
6169

62-
AppEngineCredentials(Collection<String> scopes, Object appIdentityService) {
63-
this.appIdentityService = appIdentityService;
64-
this.scopes = scopes;
65-
this.scopesRequired = (scopes == null || scopes.isEmpty());
70+
AppEngineCredentials(Collection<String> scopes, Object appIdentityService,
71+
Method getAccessToken, Method getAccessTokenResult) {
72+
this.appIdentityService = appIdentityService;
73+
this.getAccessToken = getAccessToken;
74+
this.getAccessTokenResult = getAccessTokenResult;
75+
this.scopes = scopes;
76+
this.scopesRequired = (scopes == null || scopes.isEmpty());
6677
}
6778

6879
/**
@@ -74,13 +85,7 @@ public AccessToken refreshAccessToken() throws IOException {
7485
throw new IOException("AppEngineCredentials requires createScoped call before use.");
7586
}
7687
try {
77-
Class<?> serviceClass =
78-
Class.forName("com.google.appengine.api.appidentity.AppIdentityService");
79-
Class<?> tokenResultClass = Class.forName(
80-
"com.google.appengine.api.appidentity.AppIdentityService$GetAccessTokenResult");
81-
Method getAccessTokenResult = serviceClass.getMethod("getAccessToken", Iterable.class);
8288
Object accessTokenResult = getAccessTokenResult.invoke(appIdentityService, scopes);
83-
Method getAccessToken = tokenResultClass.getMethod("getAccessToken");
8489
String accessToken = (String) getAccessToken.invoke(accessTokenResult);
8590
return new AccessToken(accessToken, null);
8691
} catch (Exception e) {
@@ -95,7 +100,8 @@ public boolean createScopedRequired() {
95100

96101
@Override
97102
public GoogleCredentials createScoped(Collection<String> scopes) {
98-
return new AppEngineCredentials(scopes, appIdentityService);
103+
return new AppEngineCredentials(
104+
scopes, appIdentityService, getAccessToken, getAccessTokenResult);
99105
}
100106
}
101107

@@ -121,7 +127,7 @@ public boolean equals(Object obj) {
121127
}
122128

123129
@Override
124-
protected GoogleCredentials credentials() {
130+
public GoogleCredentials credentials() {
125131
return new AppEngineCredentials();
126132
}
127133

@@ -176,7 +182,7 @@ public boolean equals(Object obj) {
176182
}
177183

178184
@Override
179-
protected GoogleCredentials credentials() {
185+
public GoogleCredentials credentials() {
180186
return new ServiceAccountCredentials(null, account, privateKey, null, null);
181187
}
182188

@@ -232,26 +238,17 @@ public boolean equals(Object obj) {
232238
}
233239

234240
@Override
235-
protected GoogleCredentials credentials() {
241+
public GoogleCredentials credentials() {
236242
return googleCredentials;
237243
}
238244

239-
public ServiceAccountAuthCredentials toServiceAccountCredentials() {
240-
if (googleCredentials instanceof ServiceAccountCredentials) {
241-
ServiceAccountCredentials credentials = (ServiceAccountCredentials) googleCredentials;
242-
return new ServiceAccountAuthCredentials(credentials.getClientEmail(),
243-
credentials.getPrivateKey());
244-
}
245-
return null;
246-
}
247-
248245
@Override
249246
public RestorableState<AuthCredentials> capture() {
250247
return STATE;
251248
}
252249
}
253250

254-
protected abstract GoogleCredentials credentials();
251+
public abstract GoogleCredentials credentials();
255252

256253
public static AuthCredentials createForAppEngine() {
257254
return AppEngineAuthCredentials.INSTANCE;
@@ -297,11 +294,12 @@ public static ServiceAccountAuthCredentials createFor(String account, PrivateKey
297294
* Account Authentication</a>.
298295
* </p>
299296
*
300-
* @param jsonCredentialStream stream for Service Account Credentials in JSON format
297+
* @param jsonCredentialStream stream for Service Account Credentials or User Credentials in JSON
298+
* format
301299
* @return the credentials instance.
302300
* @throws IOException if the credentials cannot be created from the stream.
303301
*/
304-
public static ServiceAccountAuthCredentials createForJson(InputStream jsonCredentialStream)
302+
public static AuthCredentials createForJson(InputStream jsonCredentialStream)
305303
throws IOException {
306304
GoogleCredentials tempCredentials = GoogleCredentials.fromStream(jsonCredentialStream);
307305
if (tempCredentials instanceof ServiceAccountCredentials) {
@@ -310,9 +308,9 @@ public static ServiceAccountAuthCredentials createForJson(InputStream jsonCreden
310308
return new ServiceAccountAuthCredentials(
311309
tempServiceAccountCredentials.getClientEmail(),
312310
tempServiceAccountCredentials.getPrivateKey());
313-
} else {
314-
throw new IOException(
315-
"The given JSON Credentials Stream is not a service account credential.");
316311
}
312+
throw new IOException(
313+
"The given JSON credentials stream could not be parsed as service account credentials or"
314+
+ " user credentials.");
317315
}
318316
}

gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,26 +31,26 @@
3131
import static java.nio.charset.StandardCharsets.UTF_8;
3232

3333
import com.google.api.services.storage.model.StorageObject;
34+
import com.google.auth.oauth2.GoogleCredentials;
35+
import com.google.auth.oauth2.ServiceAccountCredentials;
3436
import com.google.common.base.Function;
3537
import com.google.common.base.Functions;
3638
import com.google.common.collect.ImmutableList;
3739
import com.google.common.collect.ImmutableMap;
3840
import com.google.common.collect.Iterables;
3941
import com.google.common.collect.Lists;
4042
import com.google.common.collect.Maps;
41-
import com.google.common.collect.Sets;
4243
import com.google.common.hash.Hashing;
4344
import com.google.common.io.BaseEncoding;
4445
import com.google.common.primitives.Ints;
4546
import com.google.gcloud.AuthCredentials;
46-
import com.google.gcloud.AuthCredentials.ApplicationDefaultAuthCredentials;
4747
import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials;
48-
import com.google.gcloud.PageImpl;
4948
import com.google.gcloud.BaseService;
5049
import com.google.gcloud.ExceptionHandler;
5150
import com.google.gcloud.ExceptionHandler.Interceptor;
52-
import com.google.gcloud.RetryHelper.RetryHelperException;
5351
import com.google.gcloud.Page;
52+
import com.google.gcloud.PageImpl;
53+
import com.google.gcloud.RetryHelper.RetryHelperException;
5454
import com.google.gcloud.spi.StorageRpc;
5555
import com.google.gcloud.spi.StorageRpc.RewriteResponse;
5656
import com.google.gcloud.spi.StorageRpc.Tuple;
@@ -71,7 +71,6 @@
7171
import java.util.EnumMap;
7272
import java.util.List;
7373
import java.util.Map;
74-
import java.util.Set;
7574
import java.util.concurrent.Callable;
7675
import java.util.concurrent.TimeUnit;
7776

@@ -566,15 +565,13 @@ public URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOptio
566565
ServiceAccountAuthCredentials cred =
567566
(ServiceAccountAuthCredentials) optionMap.get(SignUrlOption.Option.SERVICE_ACCOUNT_CRED);
568567
if (cred == null) {
569-
AuthCredentials serviceCred = this.options().authCredentials();
570-
if (serviceCred instanceof ServiceAccountAuthCredentials) {
571-
cred = (ServiceAccountAuthCredentials) serviceCred;
572-
} else {
573-
if (serviceCred instanceof ApplicationDefaultAuthCredentials) {
574-
cred = ((ApplicationDefaultAuthCredentials) serviceCred).toServiceAccountCredentials();
575-
}
576-
}
577-
checkArgument(cred != null, "Signing key was not provided and could not be derived");
568+
AuthCredentials authCredentials = this.options().authCredentials();
569+
GoogleCredentials serviceCred =
570+
authCredentials != null ? authCredentials.credentials() : null;
571+
checkArgument(
572+
serviceCred instanceof ServiceAccountCredentials,
573+
"Signing key was not provided and could not be derived");
574+
cred = (ServiceAccountAuthCredentials) authCredentials;
578575
}
579576
// construct signature - see https://cloud.google.com/storage/docs/access-control#Signed-URLs
580577
StringBuilder stBuilder = new StringBuilder();

0 commit comments

Comments
 (0)