From a2585ae8b9d5a9104322f1177e88e5825a447517 Mon Sep 17 00:00:00 2001 From: Solomon Duskis Date: Thu, 7 Apr 2016 08:53:09 -0400 Subject: [PATCH] Adding expiration date to AppEngineCredentials. The expiration information is passed in by the AppIdentityService. Pass along the expiration time for the App Engine Flexible Environment. Not having this causes problems such as https://github.com/GoogleCloudPlatform/cloud-bigtable-client/issues/750 and https://github.com/GoogleCloudPlatform/cloud-bigtable-examples/issues/145. --- .../auth/appengine/AppEngineCredentials.java | 8 ++++++-- .../auth/appengine/AppEngineCredentialsTest.java | 15 +++++++++++++++ .../auth/appengine/MockAppIdentityService.java | 12 +++++++++++- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/appengine/java/com/google/auth/appengine/AppEngineCredentials.java b/appengine/java/com/google/auth/appengine/AppEngineCredentials.java index b6ba7ff16..98e0389ac 100644 --- a/appengine/java/com/google/auth/appengine/AppEngineCredentials.java +++ b/appengine/java/com/google/auth/appengine/AppEngineCredentials.java @@ -35,10 +35,12 @@ import com.google.auth.oauth2.GoogleCredentials; import com.google.common.collect.ImmutableList; import com.google.appengine.api.appidentity.AppIdentityService; +import com.google.appengine.api.appidentity.AppIdentityService.GetAccessTokenResult; import com.google.appengine.api.appidentity.AppIdentityServiceFactory; import java.io.IOException; import java.util.Collection; +import java.util.Date; /** * OAuth2 credentials representing the built-in service account for Google App ENgine. @@ -72,8 +74,10 @@ public AccessToken refreshAccessToken() throws IOException { if (createScopedRequired()) { throw new IOException("AppEngineCredentials requires createScoped call before use."); } - String accessToken = appIdentityService.getAccessToken(scopes).getAccessToken(); - return new AccessToken(accessToken, null); + GetAccessTokenResult accessTokenResponse = appIdentityService.getAccessToken(scopes); + String accessToken = accessTokenResponse.getAccessToken(); + Date expirationTime = accessTokenResponse.getExpirationTime(); + return new AccessToken(accessToken, expirationTime); } @Override diff --git a/appengine/javatests/com/google/auth/appengine/AppEngineCredentialsTest.java b/appengine/javatests/com/google/auth/appengine/AppEngineCredentialsTest.java index 520386465..79c02b7cc 100644 --- a/appengine/javatests/com/google/auth/appengine/AppEngineCredentialsTest.java +++ b/appengine/javatests/com/google/auth/appengine/AppEngineCredentialsTest.java @@ -38,6 +38,7 @@ import static org.junit.Assert.assertNotSame; import com.google.auth.Credentials; +import com.google.auth.oauth2.AccessToken; import com.google.auth.oauth2.GoogleCredentials; import org.junit.Test; @@ -49,6 +50,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Date; import java.util.List; import java.util.Map; @@ -76,6 +78,19 @@ public void constructor_usesAppIdentityService() throws IOException { assertContainsBearerToken(metadata, expectedAccessToken); } + @Test + public void refreshAccessToken_sameAs() throws IOException { + final String expectedAccessToken = "ExpectedAccessToken"; + + MockAppIdentityService appIdentity = new MockAppIdentityService(); + appIdentity.setAccessTokenText(expectedAccessToken); + appIdentity.setExpiration(new Date(System.currentTimeMillis() + 60L * 60L * 100L)); + AppEngineCredentials credentials = new AppEngineCredentials(SCOPES, appIdentity); + AccessToken accessToken = credentials.refreshAccessToken(); + assertEquals(appIdentity.getAccessTokenText(), accessToken.getTokenValue()); + assertEquals(appIdentity.getExpiration(), accessToken.getExpirationTime()); + } + @Test public void createScoped_clonesWithScopes() throws IOException { final String expectedAccessToken = "ExpectedAccessToken"; diff --git a/appengine/javatests/com/google/auth/appengine/MockAppIdentityService.java b/appengine/javatests/com/google/auth/appengine/MockAppIdentityService.java index 2cbef163f..6f44d3755 100644 --- a/appengine/javatests/com/google/auth/appengine/MockAppIdentityService.java +++ b/appengine/javatests/com/google/auth/appengine/MockAppIdentityService.java @@ -36,6 +36,7 @@ import com.google.appengine.api.appidentity.PublicCertificate; import java.util.Collection; +import java.util.Date; /** * Mock implementation of AppIdentityService interface for testing. @@ -44,6 +45,7 @@ public class MockAppIdentityService implements AppIdentityService { private int getAccessTokenCallCount = 0; private String accessTokenText = null; + private Date expiration = null; public MockAppIdentityService() { } @@ -60,6 +62,14 @@ public void setAccessTokenText(String text) { accessTokenText = text; } + public Date getExpiration() { + return expiration; + } + + public void setExpiration(Date expiration) { + this.expiration = expiration; + } + @Override public SigningResult signForApp(byte[] signBlob) { return null; @@ -82,7 +92,7 @@ public GetAccessTokenResult getAccessToken(Iterable scopes) { if (scopeCount == 0) { throw new AppIdentityServiceFailureException("No scopes specified."); } - return new GetAccessTokenResult(accessTokenText, null); + return new GetAccessTokenResult(accessTokenText, expiration); } @Override