Skip to content

Commit

Permalink
Make AppEngineAuthCredentials Restorable
Browse files Browse the repository at this point in the history
  • Loading branch information
Ajay Kannan committed Dec 1, 2015
1 parent b5c1cae commit 78667fa
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> scopes;
private final boolean scopesRequired;

Expand All @@ -52,17 +54,26 @@ 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) {
throw new RuntimeException("Could not create AppEngineCredentials using reflection.");
}
}

AppEngineCredentials(Collection<String> scopes, Object appIdentityService) {
this.appIdentityService = appIdentityService;
this.scopes = scopes;
this.scopesRequired = (scopes == null || scopes.isEmpty());
AppEngineCredentials(Collection<String> 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());
}

/**
Expand All @@ -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) {
Expand All @@ -95,7 +100,8 @@ public boolean createScopedRequired() {

@Override
public GoogleCredentials createScoped(Collection<String> scopes) {
return new AppEngineCredentials(scopes, appIdentityService);
return new AppEngineCredentials(
scopes, appIdentityService, getAccessToken, getAccessTokenResult);
}
}

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

@Override
protected GoogleCredentials credentials() {
public GoogleCredentials credentials() {
return new AppEngineCredentials();
}

Expand Down Expand Up @@ -176,7 +182,7 @@ public boolean equals(Object obj) {
}

@Override
protected GoogleCredentials credentials() {
public GoogleCredentials credentials() {
return new ServiceAccountCredentials(null, account, privateKey, null, null);
}

Expand Down Expand Up @@ -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<AuthCredentials> capture() {
return STATE;
}
}

protected abstract GoogleCredentials credentials();
public abstract GoogleCredentials credentials();

public static AuthCredentials createForAppEngine() {
return AppEngineAuthCredentials.INSTANCE;
Expand Down Expand Up @@ -297,7 +294,8 @@ public static ServiceAccountAuthCredentials createFor(String account, PrivateKey
* Account Authentication</a>.
* </p>
*
* @param jsonCredentialStream stream for Service Account Credentials in JSON format
* @param jsonCredentialStream stream for Service Account Credentials or User Credentials in JSON
* format
* @return the credentials instance.
* @throws IOException if the credentials cannot be created from the stream.
*/
Expand All @@ -310,9 +308,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.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,26 @@
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;
import com.google.common.collect.ImmutableMap;
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;
Expand All @@ -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;

Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 78667fa

Please sign in to comment.