Fetches access tokens from the App Identity service.
*/
public class AppEngineCredentials extends GoogleCredentials {
-
- private final AppIdentityService appIdentityService;
-
+
+ private static final long serialVersionUID = -2627708355455064660L;
+
+ private final String appIdentityServiceClassName;
private final Collection scopes;
-
- private final boolean scopesRequired;
-
+ private final boolean scopesRequired;
+
+ private transient AppIdentityService appIdentityService;
+
public AppEngineCredentials(Collection scopes) {
this(scopes, null);
}
public AppEngineCredentials(Collection scopes, AppIdentityService appIdentityService) {
- this.scopes = ImmutableList.copyOf(scopes);
+ this.scopes = scopes == null ? ImmutableSet.of() : ImmutableList.copyOf(scopes);
this.appIdentityService = appIdentityService != null ? appIdentityService
: AppIdentityServiceFactory.getAppIdentityService();
- scopesRequired = (scopes == null || scopes.isEmpty());
+ this.appIdentityServiceClassName = this.appIdentityService.getClass().getName();
+ scopesRequired = this.scopes.isEmpty();
}
-
+
/**
* Refresh the access token by getting it from the App Identity service
*/
@@ -88,5 +95,35 @@ public boolean createScopedRequired() {
@Override
public GoogleCredentials createScoped(Collection scopes) {
return new AppEngineCredentials(scopes, appIdentityService);
- }
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(scopes, scopesRequired, appIdentityServiceClassName);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("scopes", scopes)
+ .add("scopesRequired", scopesRequired)
+ .add("appIdentityServiceClassName", appIdentityServiceClassName)
+ .toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof AppEngineCredentials)) {
+ return false;
+ }
+ AppEngineCredentials other = (AppEngineCredentials) obj;
+ return this.scopesRequired == other.scopesRequired
+ && Objects.equals(this.scopes, other.scopes)
+ && Objects.equals(this.appIdentityServiceClassName, other.appIdentityServiceClassName);
+ }
+
+ private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException {
+ input.defaultReadObject();
+ appIdentityService = newInstance(appIdentityServiceClassName);
+ }
}
diff --git a/appengine/javatests/com/google/auth/appengine/AppEngineCredentialsTest.java b/appengine/javatests/com/google/auth/appengine/AppEngineCredentialsTest.java
index 79c02b7cc..4ff02dde9 100644
--- a/appengine/javatests/com/google/auth/appengine/AppEngineCredentialsTest.java
+++ b/appengine/javatests/com/google/auth/appengine/AppEngineCredentialsTest.java
@@ -32,13 +32,15 @@
package com.google.auth.appengine;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import static org.junit.Assert.assertNotSame;
import com.google.auth.Credentials;
import com.google.auth.oauth2.AccessToken;
+import com.google.auth.oauth2.BaseSerializationTest;
import com.google.auth.oauth2.GoogleCredentials;
import org.junit.Test;
@@ -58,7 +60,7 @@
* Unit tests for AppEngineCredentials
*/
@RunWith(JUnit4.class)
-public class AppEngineCredentialsTest {
+public class AppEngineCredentialsTest extends BaseSerializationTest {
private static final Collection SCOPES =
Collections.unmodifiableCollection(Arrays.asList("scope1", "scope2"));
@@ -117,7 +119,62 @@ public void createScoped_clonesWithScopes() throws IOException {
assertEquals(1, appIdentity.getGetAccessTokenCallCount());
assertContainsBearerToken(metadata, expectedAccessToken);
}
-
+
+ @Test
+ public void equals_true() throws IOException {
+ final Collection emptyScopes = Collections.emptyList();
+ MockAppIdentityService appIdentity = new MockAppIdentityService();
+ GoogleCredentials credentials = new AppEngineCredentials(emptyScopes, appIdentity);
+ GoogleCredentials otherCredentials = new AppEngineCredentials(emptyScopes, appIdentity);
+ assertTrue(credentials.equals(credentials));
+ assertTrue(credentials.equals(otherCredentials));
+ assertTrue(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_scopes() throws IOException {
+ final Collection emptyScopes = Collections.emptyList();
+ final Collection scopes = Collections.singleton("SomeScope");
+ MockAppIdentityService appIdentity = new MockAppIdentityService();
+ GoogleCredentials credentials = new AppEngineCredentials(emptyScopes, appIdentity);
+ GoogleCredentials otherCredentials = new AppEngineCredentials(scopes, appIdentity);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void toString_containsFields() throws IOException {
+ String expectedToString = String.format(
+ "AppEngineCredentials{scopes=[%s], scopesRequired=%b, appIdentityServiceClassName=%s}",
+ "SomeScope",
+ false,
+ MockAppIdentityService.class.getName());
+ final Collection scopes = Collections.singleton("SomeScope");
+ MockAppIdentityService appIdentity = new MockAppIdentityService();
+ GoogleCredentials credentials = new AppEngineCredentials(scopes, appIdentity);
+ assertEquals(expectedToString, credentials.toString());
+ }
+
+ @Test
+ public void hashCode_equals() throws IOException {
+ final Collection emptyScopes = Collections.emptyList();
+ MockAppIdentityService appIdentity = new MockAppIdentityService();
+ GoogleCredentials credentials = new AppEngineCredentials(emptyScopes, appIdentity);
+ GoogleCredentials otherCredentials = new AppEngineCredentials(emptyScopes, appIdentity);
+ assertEquals(credentials.hashCode(), otherCredentials.hashCode());
+ }
+
+ @Test
+ public void serialize() throws IOException, ClassNotFoundException {
+ final Collection scopes = Collections.singleton("SomeScope");
+ MockAppIdentityService appIdentity = new MockAppIdentityService();
+ GoogleCredentials credentials = new AppEngineCredentials(scopes, appIdentity);
+ GoogleCredentials deserializedCredentials = serializeAndDeserialize(credentials);
+ assertEquals(credentials, deserializedCredentials);
+ assertEquals(credentials.hashCode(), deserializedCredentials.hashCode());
+ assertEquals(credentials.toString(), deserializedCredentials.toString());
+ }
+
private static void assertContainsBearerToken(Map> metadata, String token) {
assertNotNull(metadata);
assertNotNull(token);
diff --git a/appengine/pom.xml b/appengine/pom.xml
index 759d79440..9fef8d895 100644
--- a/appengine/pom.xml
+++ b/appengine/pom.xml
@@ -61,13 +61,19 @@
com.google.guava
- guava-jdk5
+ guavajunitjunittest
+
+ com.google.auth
+ google-auth-library-oauth2-http
+ test-jar
+ test
+
diff --git a/credentials/java/com/google/auth/Credentials.java b/credentials/java/com/google/auth/Credentials.java
index 4dfe5c80e..05e19ff95 100644
--- a/credentials/java/com/google/auth/Credentials.java
+++ b/credentials/java/com/google/auth/Credentials.java
@@ -32,6 +32,7 @@
package com.google.auth;
import java.io.IOException;
+import java.io.Serializable;
import java.net.URI;
import java.util.List;
import java.util.Map;
@@ -40,7 +41,9 @@
/**
* Represents an abstract authorized identity instance.
*/
-public abstract class Credentials {
+public abstract class Credentials implements Serializable {
+
+ private static final long serialVersionUID = 808575179767517313L;
/**
* A constant string name describing the authentication technology.
diff --git a/oauth2_http/java/com/google/auth/http/HttpCredentialsAdapter.java b/oauth2_http/java/com/google/auth/http/HttpCredentialsAdapter.java
index f4eff5217..65e0dbd2f 100644
--- a/oauth2_http/java/com/google/auth/http/HttpCredentialsAdapter.java
+++ b/oauth2_http/java/com/google/auth/http/HttpCredentialsAdapter.java
@@ -99,7 +99,7 @@ public void initialize(HttpRequest request) throws IOException {
}
for (Map.Entry> entry : credentialHeaders.entrySet()) {
String headerName = entry.getKey();
- List requestValues = new ArrayList();
+ List requestValues = new ArrayList<>();
requestValues.addAll(entry.getValue());
requestHeaders.put(headerName, requestValues);
}
diff --git a/oauth2_http/java/com/google/auth/http/HttpTransportFactory.java b/oauth2_http/java/com/google/auth/http/HttpTransportFactory.java
new file mode 100644
index 000000000..c80bc9356
--- /dev/null
+++ b/oauth2_http/java/com/google/auth/http/HttpTransportFactory.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2016, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.google.auth.http;
+
+import com.google.api.client.http.HttpTransport;
+
+/**
+ * A base interface for all {@link HttpTransport} factories.
+ *
+ *
Implementation must provide a public no-arg constructor. Loading of a factory implementation
+ * is done via {@link java.util.ServiceLoader}.
+ */
+public interface HttpTransportFactory {
+
+ /**
+ * Creates a {@code HttpTransport} instance.
+ */
+ HttpTransport create();
+}
diff --git a/oauth2_http/java/com/google/auth/oauth2/AccessToken.java b/oauth2_http/java/com/google/auth/oauth2/AccessToken.java
index 605fffebb..090d3714a 100644
--- a/oauth2_http/java/com/google/auth/oauth2/AccessToken.java
+++ b/oauth2_http/java/com/google/auth/oauth2/AccessToken.java
@@ -31,12 +31,18 @@
package com.google.auth.oauth2;
+import com.google.common.base.MoreObjects;
+
+import java.io.Serializable;
import java.util.Date;
+import java.util.Objects;
/**
* Represents a temporary OAuth2 access token and its expiration information.
*/
-public class AccessToken {
+public class AccessToken implements Serializable {
+
+ private static final long serialVersionUID = -8514239465808977353L;
private final String tokenValue;
private final Long expirationTimeMillis;
@@ -70,4 +76,27 @@ public Date getExpirationTime() {
Long getExpirationTimeMillis() {
return expirationTimeMillis;
}
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(tokenValue, expirationTimeMillis);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("tokenValue", tokenValue)
+ .add("expirationTimeMillis", expirationTimeMillis)
+ .toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof AccessToken)) {
+ return false;
+ }
+ AccessToken other = (AccessToken) obj;
+ return Objects.equals(this.tokenValue, other.tokenValue)
+ && Objects.equals(this.expirationTimeMillis, other.expirationTimeMillis);
+ }
}
diff --git a/oauth2_http/java/com/google/auth/oauth2/CloudShellCredentials.java b/oauth2_http/java/com/google/auth/oauth2/CloudShellCredentials.java
index 1b0b07f34..2b7b08e21 100644
--- a/oauth2_http/java/com/google/auth/oauth2/CloudShellCredentials.java
+++ b/oauth2_http/java/com/google/auth/oauth2/CloudShellCredentials.java
@@ -31,28 +31,30 @@
package com.google.auth.oauth2;
-import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.JsonParser;
+import com.google.common.base.MoreObjects;
import java.io.BufferedReader;
-import java.io.InputStreamReader;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
/**
* OAuth2 credentials representing the built-in service account for Google Cloud Shell.
*/
public class CloudShellCredentials extends GoogleCredentials {
+ private static final long serialVersionUID = -2133257318957488451L;
private final static int ACCESS_TOKEN_INDEX = 2;
private final static int READ_TIMEOUT_MS = 5000;
/**
* The Cloud Shell back authorization channel uses serialized
- * Javascript Protobufers, preceeded by the message lengeth and a
+ * Javascript Protobufers, preceeded by the message length and a
* new line character. However, the request message has no content,
* so a token request consists of an empty JsPb, and its 2 character
* lenth prefix.
@@ -60,11 +62,9 @@ public class CloudShellCredentials extends GoogleCredentials {
protected final static String GET_AUTH_TOKEN_REQUEST = "2\n[]";
private final int authPort;
- private final JsonFactory jsonFactory;
-
+
public CloudShellCredentials(int authPort) {
this.authPort = authPort;
- this.jsonFactory = OAuth2Utils.JSON_FACTORY;
}
protected int getAuthPort() {
@@ -84,7 +84,7 @@ public AccessToken refreshAccessToken() throws IOException {
BufferedReader input =
new BufferedReader(new InputStreamReader(socket.getInputStream()));
input.readLine(); // Skip over the first line
- JsonParser parser = jsonFactory.createJsonParser(input);
+ JsonParser parser = OAuth2Utils.JSON_FACTORY.createJsonParser(input);
List
*
- * @param transport the transport for Http calls.
+ * @param transportFactory HTTP transport factory, creates the transport used to get access
+ * tokens.
* @return the credentials instance.
* @throws IOException if the credentials cannot be created in the current environment.
**/
- final GoogleCredentials getDefaultCredentials(HttpTransport transport)
+ final GoogleCredentials getDefaultCredentials(HttpTransportFactory transportFactory)
throws IOException {
synchronized (this) {
if (cachedCredentials == null) {
- cachedCredentials = getDefaultCredentialsUnsynchronized(transport);
+ cachedCredentials = getDefaultCredentialsUnsynchronized(transportFactory);
}
if (cachedCredentials != null) {
return cachedCredentials;
@@ -110,8 +111,8 @@ final GoogleCredentials getDefaultCredentials(HttpTransport transport)
HELP_PERMALINK));
}
- private final GoogleCredentials getDefaultCredentialsUnsynchronized(HttpTransport transport)
- throws IOException {
+ private final GoogleCredentials getDefaultCredentialsUnsynchronized(
+ HttpTransportFactory transportFactory) throws IOException {
// First try the environment variable
GoogleCredentials credentials = null;
@@ -125,7 +126,7 @@ private final GoogleCredentials getDefaultCredentialsUnsynchronized(HttpTranspor
throw new IOException("File does not exist.");
}
credentialsStream = readStream(credentialsFile);
- credentials = GoogleCredentials.fromStream(credentialsStream, transport);
+ credentials = GoogleCredentials.fromStream(credentialsStream, transportFactory);
} catch (IOException e) {
// Although it is also the cause, the message of the caught exception can have very
// important information for diagnosing errors, so include its message in the
@@ -149,7 +150,7 @@ private final GoogleCredentials getDefaultCredentialsUnsynchronized(HttpTranspor
try {
if (isFile(wellKnownFileLocation)) {
credentialsStream = readStream(wellKnownFileLocation);
- credentials = GoogleCredentials.fromStream(credentialsStream, transport);
+ credentials = GoogleCredentials.fromStream(credentialsStream, transportFactory);
}
} catch (IOException e) {
throw new IOException(String.format(
@@ -177,14 +178,14 @@ private final GoogleCredentials getDefaultCredentialsUnsynchronized(HttpTranspor
// Then try Compute Engine
if (credentials == null) {
- credentials = tryGetComputeCredentials(transport);
+ credentials = tryGetComputeCredentials(transportFactory);
}
return credentials;
}
private final File getWellKnownCredentialsFile() {
- File cloudConfigPath = null;
+ File cloudConfigPath;
String os = getProperty("os.name", "").toLowerCase(Locale.US);
String envPath = getEnv("CLOUDSDK_CONFIG");
if (envPath != null) {
@@ -196,8 +197,7 @@ private final File getWellKnownCredentialsFile() {
File configPath = new File(getProperty("user.home", ""), ".config");
cloudConfigPath = new File(configPath, CLOUDSDK_CONFIG_DIRECTORY);
}
- File credentialFilePath = new File(cloudConfigPath, WELL_KNOWN_CREDENTIALS_FILE);
- return credentialFilePath;
+ return new File(cloudConfigPath, WELL_KNOWN_CREDENTIALS_FILE);
}
private boolean runningOnAppEngine() {
@@ -208,7 +208,7 @@ private boolean runningOnAppEngine() {
// SystemProperty will always be present on App Engine.
return false;
}
- Exception cause = null;
+ Exception cause;
Field environmentField;
try {
environmentField = systemPropertyClass.getField("environment");
@@ -217,17 +217,8 @@ private boolean runningOnAppEngine() {
Method valueMethod = environmentType.getMethod("value");
Object environmentValueValue = valueMethod.invoke(environmentValue);
return (environmentValueValue != null);
- } catch (NoSuchFieldException exception) {
- cause = exception;
- } catch (SecurityException exception) {
- cause = exception;
- } catch (IllegalArgumentException exception) {
- cause = exception;
- } catch (IllegalAccessException exception) {
- cause = exception;
- } catch (NoSuchMethodException exception) {
- cause = exception;
- } catch (InvocationTargetException exception) {
+ } catch (NoSuchFieldException | SecurityException | IllegalArgumentException
+ | IllegalAccessException | NoSuchMethodException | InvocationTargetException exception) {
cause = exception;
}
throw OAuth2Utils.exceptionWithCause(new RuntimeException(String.format(
@@ -254,22 +245,15 @@ private GoogleCredentials tryGetAppEngineCredential() throws IOException {
if (!onAppEngine) {
return null;
}
- Exception innerException = null;
+ Exception innerException;
try {
Class> credentialClass = forName(APP_ENGINE_CREDENTIAL_CLASS);
Constructor> constructor = credentialClass
.getConstructor(Collection.class);
Collection emptyScopes = Collections.emptyList();
return (GoogleCredentials) constructor.newInstance(emptyScopes);
- } catch (ClassNotFoundException e) {
- innerException = e;
- } catch (NoSuchMethodException e) {
- innerException = e;
- } catch (InstantiationException e) {
- innerException = e;
- } catch (IllegalAccessException e) {
- innerException = e;
- } catch (InvocationTargetException e) {
+ } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException
+ | IllegalAccessException | InvocationTargetException e) {
innerException = e;
}
throw OAuth2Utils.exceptionWithCause(new IOException(String.format(
@@ -279,15 +263,16 @@ private GoogleCredentials tryGetAppEngineCredential() throws IOException {
APP_ENGINE_CREDENTIAL_CLASS)), innerException);
}
- private final GoogleCredentials tryGetComputeCredentials(HttpTransport transport) {
+ private final GoogleCredentials tryGetComputeCredentials(HttpTransportFactory transportFactory) {
// Checking compute engine requires a round-trip, so check only once
if (checkedComputeEngine) {
return null;
}
- boolean runningOnComputeEngine = ComputeEngineCredentials.runningOnComputeEngine(transport);
+ boolean runningOnComputeEngine =
+ ComputeEngineCredentials.runningOnComputeEngine(transportFactory);
checkedComputeEngine = true;
if (runningOnComputeEngine) {
- return new ComputeEngineCredentials(transport);
+ return new ComputeEngineCredentials(transportFactory);
}
return null;
}
diff --git a/oauth2_http/java/com/google/auth/oauth2/GoogleCredentials.java b/oauth2_http/java/com/google/auth/oauth2/GoogleCredentials.java
index 81e8bab8a..c27ba9a24 100644
--- a/oauth2_http/java/com/google/auth/oauth2/GoogleCredentials.java
+++ b/oauth2_http/java/com/google/auth/oauth2/GoogleCredentials.java
@@ -31,11 +31,11 @@
package com.google.auth.oauth2;
-import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.GenericJson;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.JsonObjectParser;
import com.google.api.client.util.Preconditions;
+import com.google.auth.http.HttpTransportFactory;
import java.io.IOException;
import java.io.InputStream;
@@ -46,6 +46,7 @@
*/
public class GoogleCredentials extends OAuth2Credentials {
+ private static final long serialVersionUID = -1522852442442473691L;
static final String USER_FILE_TYPE = "authorized_user";
static final String SERVICE_ACCOUNT_FILE_TYPE = "service_account";
@@ -64,7 +65,7 @@ public class GoogleCredentials extends OAuth2Credentials {
* @throws IOException if the credentials cannot be created in the current environment.
*/
public static GoogleCredentials getApplicationDefault() throws IOException {
- return getApplicationDefault(OAuth2Utils.HTTP_TRANSPORT);
+ return getApplicationDefault(OAuth2Utils.HTTP_TRANSPORT_FACTORY);
}
/**
@@ -75,14 +76,15 @@ public static GoogleCredentials getApplicationDefault() throws IOException {
* Compute Engine or the credentials file from the path in the environment variable
* GOOGLE_APPLICATION_CREDENTIALS.
*
- * @param transport the transport for Http calls.
+ * @param transportFactory HTTP transport factory, creates the transport used to get access
+ * tokens.
* @return the credentials instance.
* @throws IOException if the credentials cannot be created in the current environment.
**/
- public static GoogleCredentials getApplicationDefault(
- HttpTransport transport) throws IOException {
- Preconditions.checkNotNull(transport);
- return defaultCredentialsProvider.getDefaultCredentials(transport);
+ public static GoogleCredentials getApplicationDefault(HttpTransportFactory transportFactory)
+ throws IOException {
+ Preconditions.checkNotNull(transportFactory);
+ return defaultCredentialsProvider.getDefaultCredentials(transportFactory);
}
/**
@@ -96,7 +98,7 @@ public static GoogleCredentials getApplicationDefault(
* @throws IOException if the credential cannot be created from the stream.
**/
public static GoogleCredentials fromStream(InputStream credentialsStream) throws IOException {
- return fromStream(credentialsStream, OAuth2Utils.HTTP_TRANSPORT);
+ return fromStream(credentialsStream, OAuth2Utils.HTTP_TRANSPORT_FACTORY);
}
/**
@@ -106,14 +108,15 @@ public static GoogleCredentials fromStream(InputStream credentialsStream) throws
* Console or a stored user credential using the format supported by the Cloud SDK.
*
* @param credentialsStream the stream with the credential definition.
- * @param transport the transport for Http calls.
+ * @param transportFactory HTTP transport factory, creates the transport used to get access
+ * tokens.
* @return the credential defined by the credentialsStream.
* @throws IOException if the credential cannot be created from the stream.
**/
- public static GoogleCredentials fromStream(InputStream credentialsStream, HttpTransport transport)
- throws IOException {
+ public static GoogleCredentials fromStream(InputStream credentialsStream,
+ HttpTransportFactory transportFactory) throws IOException {
Preconditions.checkNotNull(credentialsStream);
- Preconditions.checkNotNull(transport);
+ Preconditions.checkNotNull(transportFactory);
JsonFactory jsonFactory = OAuth2Utils.JSON_FACTORY;
JsonObjectParser parser = new JsonObjectParser(jsonFactory);
@@ -125,10 +128,10 @@ public static GoogleCredentials fromStream(InputStream credentialsStream, HttpTr
throw new IOException("Error reading credentials from stream, 'type' field not specified.");
}
if (USER_FILE_TYPE.equals(fileType)) {
- return UserCredentials.fromJson(fileContents, transport);
+ return UserCredentials.fromJson(fileContents, transportFactory);
}
if (SERVICE_ACCOUNT_FILE_TYPE.equals(fileType)) {
- return ServiceAccountCredentials.fromJson(fileContents, transport);
+ return ServiceAccountCredentials.fromJson(fileContents, transportFactory);
}
throw new IOException(String.format(
"Error reading credentials from stream, 'type' value '%s' not recognized."
diff --git a/oauth2_http/java/com/google/auth/oauth2/OAuth2Credentials.java b/oauth2_http/java/com/google/auth/oauth2/OAuth2Credentials.java
index 6405d26da..c6f67c0e7 100644
--- a/oauth2_http/java/com/google/auth/oauth2/OAuth2Credentials.java
+++ b/oauth2_http/java/com/google/auth/oauth2/OAuth2Credentials.java
@@ -35,15 +35,22 @@
import com.google.auth.Credentials;
import com.google.auth.RequestMetadataCallback;
import com.google.auth.http.AuthHttpConstants;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
import java.io.IOException;
+import java.io.ObjectInputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import java.util.ServiceLoader;
import java.util.concurrent.Executor;
/**
@@ -51,15 +58,19 @@
*/
public class OAuth2Credentials extends Credentials {
+ private static final long serialVersionUID = 4556936364828217687L;
private static final int MINIMUM_TOKEN_MILLISECONDS = 60000;
- private final Object lock = new Object();
+ // byte[] is serializable, so the lock variable can be final
+ private final Object lock = new byte[0];
private Map> requestMetadata;
private AccessToken temporaryAccess;
- private List changeListeners;
- // Allow clock to be overridden by test code
- Clock clock = Clock.SYSTEM;
+ // Change listeners are not serialized
+ private transient List changeListeners;
+ // Until we expose this to the users it can remain transient and non-serializable
+ @VisibleForTesting
+ transient Clock clock = Clock.SYSTEM;
/**
* Default constructor.
@@ -184,7 +195,7 @@ public AccessToken refreshAccessToken() throws IOException {
public final void addChangeListener(CredentialsChangedListener listener) {
synchronized(lock) {
if (changeListeners == null) {
- changeListeners = new ArrayList();
+ changeListeners = new ArrayList<>();
}
changeListeners.add(listener);
}
@@ -224,4 +235,48 @@ public interface CredentialsChangedListener {
*/
void onChanged(OAuth2Credentials credentials) throws IOException;
}
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(requestMetadata, temporaryAccess);
+ }
+
+ protected ToStringHelper toStringHelper() {
+ return MoreObjects.toStringHelper(this)
+ .add("requestMetadata", requestMetadata)
+ .add("temporaryAccess", temporaryAccess);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper().toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof OAuth2Credentials)) {
+ return false;
+ }
+ OAuth2Credentials other = (OAuth2Credentials) obj;
+ return Objects.equals(this.requestMetadata, other.requestMetadata)
+ && Objects.equals(this.temporaryAccess, other.temporaryAccess);
+ }
+
+ private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException {
+ input.defaultReadObject();
+ clock = Clock.SYSTEM;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected static T newInstance(String className) throws IOException, ClassNotFoundException {
+ try {
+ return (T) Class.forName(className).newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ throw new IOException(e);
+ }
+ }
+
+ protected static T getFromServiceLoader(Class extends T> clazz, T defaultInstance) {
+ return Iterables.getFirst(ServiceLoader.load(clazz), defaultInstance);
+ }
}
diff --git a/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java b/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java
index 39673c514..33ee24f8d 100644
--- a/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java
+++ b/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java
@@ -39,6 +39,7 @@
import com.google.api.client.json.JsonObjectParser;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.auth.http.AuthHttpConstants;
+import com.google.auth.http.HttpTransportFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -60,6 +61,8 @@ class OAuth2Utils {
static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
+ static final HttpTransportFactory HTTP_TRANSPORT_FACTORY = new DefaultHttpTransportFactory();
+
static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
static final Charset UTF_8 = Charset.forName("UTF-8");
@@ -69,6 +72,13 @@ class OAuth2Utils {
static final String BEARER_PREFIX = AuthHttpConstants.BEARER + " ";
+ static class DefaultHttpTransportFactory implements HttpTransportFactory {
+
+ public HttpTransport create() {
+ return HTTP_TRANSPORT;
+ }
+ }
+
/**
* Returns whether the headers contain the specified value as one of the entries in the
* specified header.
diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java
index 2690110f8..c32d073d8 100644
--- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java
+++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java
@@ -31,11 +31,12 @@
package com.google.auth.oauth2;
+import static com.google.common.base.MoreObjects.firstNonNull;
+
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpResponse;
-import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.UrlEncodedContent;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.JsonObjectParser;
@@ -44,11 +45,15 @@
import com.google.api.client.util.GenericData;
import com.google.api.client.util.Joiner;
import com.google.api.client.util.PemReader;
-import com.google.api.client.util.SecurityUtils;
import com.google.api.client.util.PemReader.Section;
import com.google.api.client.util.Preconditions;
+import com.google.api.client.util.SecurityUtils;
+import com.google.auth.http.HttpTransportFactory;
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableSet;
import java.io.IOException;
+import java.io.ObjectInputStream;
import java.io.Reader;
import java.io.StringReader;
import java.net.URI;
@@ -60,8 +65,8 @@
import java.security.spec.PKCS8EncodedKeySpec;
import java.sql.Date;
import java.util.Collection;
-import java.util.Collections;
import java.util.Map;
+import java.util.Objects;
/**
* OAuth2 credentials representing a Service Account for calling Google APIs.
@@ -70,6 +75,7 @@
*/
public class ServiceAccountCredentials extends GoogleCredentials {
+ private static final long serialVersionUID = 7807543542681217978L;
private static final String GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer";
private static final String PARSE_ERROR_PREFIX = "Error parsing token refresh response. ";
@@ -77,10 +83,12 @@ public class ServiceAccountCredentials extends GoogleCredentials {
private final String clientEmail;
private final PrivateKey privateKey;
private final String privateKeyId;
- private final HttpTransport transport;
+ private final String transportFactoryClassName;
private final URI tokenServerUri;
private final Collection scopes;
+ private transient HttpTransportFactory transportFactory;
+
/**
* Constructor with minimum identifying information.
*
@@ -106,19 +114,21 @@ public ServiceAccountCredentials(
* @param privateKeyId Private key identifier for the service account. May be null.
* @param scopes Scope strings for the APIs to be called. May be null or an empty collection,
* which results in a credential that must have createScoped called before use.
- * @param transport HTTP object used to get access tokens.
+ * @param transportFactory HTTP transport factory, creates the transport used to get access
+ * tokens.
* @param tokenServerUri URI of the end point that provides tokens.
*/
public ServiceAccountCredentials(
String clientId, String clientEmail, PrivateKey privateKey, String privateKeyId,
- Collection scopes, HttpTransport transport, URI tokenServerUri) {
+ Collection scopes, HttpTransportFactory transportFactory, URI tokenServerUri) {
this.clientId = clientId;
this.clientEmail = Preconditions.checkNotNull(clientEmail);
this.privateKey = Preconditions.checkNotNull(privateKey);
this.privateKeyId = privateKeyId;
- this.scopes = (scopes == null) ? Collections.emptyList()
- : Collections.unmodifiableCollection(scopes);
- this.transport = (transport == null) ? OAuth2Utils.HTTP_TRANSPORT : transport;
+ this.scopes = (scopes == null) ? ImmutableSet.of() : ImmutableSet.copyOf(scopes);
+ this.transportFactory = firstNonNull(transportFactory,
+ getFromServiceLoader(HttpTransportFactory.class, OAuth2Utils.HTTP_TRANSPORT_FACTORY));
+ this.transportFactoryClassName = this.transportFactory.getClass().getName();
this.tokenServerUri = (tokenServerUri == null) ? OAuth2Utils.TOKEN_SERVER_URI : tokenServerUri;
}
@@ -127,12 +137,13 @@ public ServiceAccountCredentials(
* Developers Console.
*
* @param json a map from the JSON representing the credentials.
- * @param transport the transport for Http calls.
+ * @param transportFactory HTTP transport factory, creates the transport used to get access
+ * tokens.
* @return the credentials defined by the JSON.
* @throws IOException if the credential cannot be created from the JSON.
**/
static ServiceAccountCredentials fromJson(
- Map json, HttpTransport transport) throws IOException {
+ Map json, HttpTransportFactory transportFactory) throws IOException {
String clientId = (String) json.get("client_id");
String clientEmail = (String) json.get("client_email");
String privateKeyPkcs8 = (String) json.get("private_key");
@@ -143,7 +154,8 @@ static ServiceAccountCredentials fromJson(
+ "expecting 'client_id', 'client_email', 'private_key' and 'private_key_id'.");
}
- return fromPkcs8(clientId, clientEmail, privateKeyPkcs8, privateKeyId, null, transport, null);
+ return fromPkcs8(clientId, clientEmail, privateKeyPkcs8, privateKeyId, null, transportFactory,
+ null);
}
/**
@@ -172,15 +184,17 @@ public static ServiceAccountCredentials fromPkcs8(
* @param privateKeyId Private key identifier for the service account. May be null.
* @param scopes Scope strings for the APIs to be called. May be null or an emptt collection,
* which results in a credential that must have createScoped called before use.
- * @param transport HTTP object used to get access tokens.
+ * @param transportFactory HTTP transport factory, creates the transport used to get access
+ * tokens.
* @param tokenServerUri URI of the end point that provides tokens.
*/
public static ServiceAccountCredentials fromPkcs8(
String clientId, String clientEmail, String privateKeyPkcs8, String privateKeyId,
- Collection scopes, HttpTransport transport, URI tokenServerUri) throws IOException {
+ Collection scopes, HttpTransportFactory transportFactory, URI tokenServerUri)
+ throws IOException {
PrivateKey privateKey = privateKeyFromPkcs8(privateKeyPkcs8);
return new ServiceAccountCredentials(
- clientId, clientEmail, privateKey, privateKeyId, scopes, transport, tokenServerUri);
+ clientId, clientEmail, privateKey, privateKeyId, scopes, transportFactory, tokenServerUri);
}
/**
@@ -194,14 +208,11 @@ static PrivateKey privateKeyFromPkcs8(String privateKeyPkcs8) throws IOException
}
byte[] bytes = section.getBase64DecodedBytes();
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
- Exception unexpectedException = null;
+ Exception unexpectedException;
try {
KeyFactory keyFactory = SecurityUtils.getRsaKeyFactory();
- PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
- return privateKey;
- } catch (NoSuchAlgorithmException exception) {
- unexpectedException = exception;
- } catch (InvalidKeySpecException exception) {
+ return keyFactory.generatePrivate(keySpec);
+ } catch (NoSuchAlgorithmException | InvalidKeySpecException exception) {
unexpectedException = exception;
}
throw OAuth2Utils.exceptionWithCause(
@@ -234,7 +245,7 @@ public AccessToken refreshAccessToken() throws IOException {
JsonFactory jsonFactory = OAuth2Utils.JSON_FACTORY;
- String assertion = null;
+ String assertion;
try {
assertion = JsonWebSignature.signUsingRsaSha256(
privateKey, jsonFactory, header, payload);
@@ -247,7 +258,7 @@ public AccessToken refreshAccessToken() throws IOException {
tokenRequest.set("assertion", assertion);
UrlEncodedContent content = new UrlEncodedContent(tokenRequest);
- HttpRequestFactory requestFactory = transport.createRequestFactory();
+ HttpRequestFactory requestFactory = transportFactory.create().createRequestFactory();
HttpRequest request = requestFactory.buildPostRequest(new GenericUrl(tokenServerUri), content);
request.setParser(new JsonObjectParser(jsonFactory));
@@ -265,12 +276,11 @@ public AccessToken refreshAccessToken() throws IOException {
int expiresInSeconds = OAuth2Utils.validateInt32(
responseData, "expires_in", PARSE_ERROR_PREFIX);
long expiresAtMilliseconds = clock.currentTimeMillis() + expiresInSeconds * 1000;
- AccessToken access = new AccessToken(accessToken, new Date(expiresAtMilliseconds));
- return access;
+ return new AccessToken(accessToken, new Date(expiresAtMilliseconds));
}
/**
- * Returns whther the scopes are empty, meaning createScoped must be called before use.
+ * Returns whether the scopes are empty, meaning createScoped must be called before use.
*/
@Override
public boolean createScopedRequired() {
@@ -284,8 +294,8 @@ public boolean createScopedRequired() {
*/
@Override
public GoogleCredentials createScoped(Collection newScopes) {
- return new ServiceAccountCredentials(
- clientId, clientEmail, privateKey, privateKeyId, newScopes, transport, tokenServerUri);
+ return new ServiceAccountCredentials(clientId, clientEmail, privateKey, privateKeyId, newScopes,
+ transportFactory, tokenServerUri);
}
public final String getClientId() {
@@ -307,4 +317,42 @@ public final String getPrivateKeyId() {
public final Collection getScopes() {
return scopes;
}
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(clientId, clientEmail, privateKey, privateKeyId, transportFactoryClassName,
+ tokenServerUri, scopes);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("clientId", clientId)
+ .add("clientEmail", clientEmail)
+ .add("privateKeyId", privateKeyId)
+ .add("transportFactoryClassName", transportFactoryClassName)
+ .add("tokenServerUri", tokenServerUri)
+ .add("scopes", scopes)
+ .toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof ServiceAccountCredentials)) {
+ return false;
+ }
+ ServiceAccountCredentials other = (ServiceAccountCredentials) obj;
+ return Objects.equals(this.clientId, other.clientId)
+ && Objects.equals(this.clientEmail, other.clientEmail)
+ && Objects.equals(this.privateKey, other.privateKey)
+ && Objects.equals(this.privateKeyId, other.privateKeyId)
+ && Objects.equals(this.transportFactoryClassName, other.transportFactoryClassName)
+ && Objects.equals(this.tokenServerUri, other.tokenServerUri)
+ && Objects.equals(this.scopes, other.scopes);
+ }
+
+ private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException {
+ input.defaultReadObject();
+ transportFactory = newInstance(transportFactoryClassName);
+ }
}
diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java
index bd4e59d06..eef051e7b 100644
--- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java
+++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java
@@ -39,14 +39,18 @@
import com.google.auth.Credentials;
import com.google.auth.RequestMetadataCallback;
import com.google.auth.http.AuthHttpConstants;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.MoreObjects;
import java.io.IOException;
+import java.io.ObjectInputStream;
import java.net.URI;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.Executor;
/**
@@ -56,6 +60,7 @@
*/
public class ServiceAccountJwtAccessCredentials extends Credentials {
+ private static final long serialVersionUID = -7274955171379494197L;
static final String JWT_ACCESS_PREFIX = OAuth2Utils.BEARER_PREFIX;
private final String clientId;
@@ -64,8 +69,9 @@ public class ServiceAccountJwtAccessCredentials extends Credentials {
private final String privateKeyId;
private final URI defaultAudience;
- // Allow clock to be overriden by test code
- Clock clock = Clock.SYSTEM;
+ // Until we expose this to the users it can remain transient and non-serializable
+ @VisibleForTesting
+ transient Clock clock = Clock.SYSTEM;
/**
* Constructor with minimum identifying information.
@@ -201,9 +207,7 @@ public Map> getRequestMetadata(URI uri) throws IOException
String assertion = getJwtAccess(uri);
String authorizationHeader = JWT_ACCESS_PREFIX + assertion;
List newAuthorizationHeaders = Collections.singletonList(authorizationHeader);
- Map> newRequestMetadata =
- Collections.singletonMap(AuthHttpConstants.AUTHORIZATION, newAuthorizationHeaders);
- return newRequestMetadata;
+ return Collections.singletonMap(AuthHttpConstants.AUTHORIZATION, newAuthorizationHeaders);
}
/**
@@ -231,7 +235,7 @@ private String getJwtAccess(URI uri) throws IOException {
JsonFactory jsonFactory = OAuth2Utils.JSON_FACTORY;
- String assertion = null;
+ String assertion;
try {
assertion = JsonWebSignature.signUsingRsaSha256(
privateKey, jsonFactory, header, payload);
@@ -257,4 +261,37 @@ public final PrivateKey getPrivateKey() {
public final String getPrivateKeyId() {
return privateKeyId;
}
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(clientId, clientEmail, privateKey, privateKeyId, defaultAudience);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("clientId", clientId)
+ .add("clientEmail", clientEmail)
+ .add("privateKeyId", privateKeyId)
+ .add("defaultAudience", defaultAudience)
+ .toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof ServiceAccountJwtAccessCredentials)) {
+ return false;
+ }
+ ServiceAccountJwtAccessCredentials other = (ServiceAccountJwtAccessCredentials) obj;
+ return Objects.equals(this.clientId, other.clientId)
+ && Objects.equals(this.clientEmail, other.clientEmail)
+ && Objects.equals(this.privateKey, other.privateKey)
+ && Objects.equals(this.privateKeyId, other.privateKeyId)
+ && Objects.equals(this.defaultAudience, other.defaultAudience);
+ }
+
+ private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException {
+ input.defaultReadObject();
+ clock = Clock.SYSTEM;
+ }
}
diff --git a/oauth2_http/java/com/google/auth/oauth2/UserAuthorizer.java b/oauth2_http/java/com/google/auth/oauth2/UserAuthorizer.java
index 955e984c3..f1e495b5e 100644
--- a/oauth2_http/java/com/google/auth/oauth2/UserAuthorizer.java
+++ b/oauth2_http/java/com/google/auth/oauth2/UserAuthorizer.java
@@ -35,16 +35,13 @@
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpResponse;
-import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.UrlEncodedContent;
import com.google.api.client.json.GenericJson;
import com.google.api.client.json.JsonObjectParser;
import com.google.api.client.util.GenericData;
import com.google.api.client.util.Joiner;
import com.google.api.client.util.Preconditions;
-import com.google.auth.oauth2.AccessToken;
-import com.google.auth.oauth2.OAuth2Credentials;
-import com.google.auth.oauth2.UserCredentials;
+import com.google.auth.http.HttpTransportFactory;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
@@ -68,7 +65,7 @@ public class UserAuthorizer {
private final TokenStore tokenStore;
private final URI callbackUri;
- private final HttpTransport transport;
+ private final HttpTransportFactory transportFactory;
private final URI tokenServerUri;
private final URI userAuthUri;
@@ -103,16 +100,18 @@ public UserAuthorizer(ClientId clientId, Collection scopes, TokenStore t
* @param scopes OAUth2 scopes defining the user consent.
* @param tokenStore Implementation of a component for long term storage of tokens.
* @param callbackUri URI for implementation of the OAuth2 web callback.
- * @param transport HTTP transport implementation for OAuth2 API calls.
+ * @param transportFactory HTTP transport factory, creates the transport used to get access
+ * tokens.
* @param tokenServerUri URI of the end point that provides tokens.
* @param userAuthUri URI of the Web UI for user consent.
*/
public UserAuthorizer(ClientId clientId, Collection scopes, TokenStore tokenStore,
- URI callbackUri, HttpTransport transport, URI tokenServerUri, URI userAuthUri) {
+ URI callbackUri, HttpTransportFactory transportFactory, URI tokenServerUri, URI userAuthUri) {
this.clientId = Preconditions.checkNotNull(clientId);
this.scopes = ImmutableList.copyOf(Preconditions.checkNotNull(scopes));
this.callbackUri = (callbackUri == null) ? DEFAULT_CALLBACK_URI : callbackUri;
- this.transport = (transport == null) ? OAuth2Utils.HTTP_TRANSPORT : transport;
+ this.transportFactory =
+ (transportFactory == null) ? OAuth2Utils.HTTP_TRANSPORT_FACTORY : transportFactory;
this.tokenServerUri = (tokenServerUri == null) ? OAuth2Utils.TOKEN_SERVER_URI : tokenServerUri;
this.userAuthUri = (userAuthUri == null) ? OAuth2Utils.USER_AUTH_URI : userAuthUri;
this.tokenStore = tokenStore;
@@ -217,12 +216,12 @@ public UserCredentials getCredentials(String userId) throws IOException {
tokenJson, "access_token", TOKEN_STORE_ERROR);
Long expirationMillis = OAuth2Utils.validateLong(
tokenJson, "expiration_time_millis", TOKEN_STORE_ERROR);
- Date expirationTime = new Date(Long.valueOf(expirationMillis));
+ Date expirationTime = new Date(expirationMillis);
AccessToken accessToken = new AccessToken(accessTokenValue, expirationTime);
String refreshToken = OAuth2Utils.validateOptionalString(
tokenJson, "refresh_token", TOKEN_STORE_ERROR);
UserCredentials credentials = new UserCredentials(clientId.getClientId(),
- clientId.getClientSecret(), refreshToken, accessToken, transport, tokenServerUri);
+ clientId.getClientSecret(), refreshToken, accessToken, transportFactory, tokenServerUri);
monitorCredentials(userId, credentials);
return credentials;
}
@@ -246,7 +245,7 @@ public UserCredentials getCredentialsFromCode(String code, URI baseUri) throws I
tokenData.put("redirect_uri", resolvedCallbackUri);
tokenData.put("grant_type", "authorization_code");
UrlEncodedContent tokenContent = new UrlEncodedContent(tokenData);
- HttpRequestFactory requestFactory = transport.createRequestFactory();
+ HttpRequestFactory requestFactory = transportFactory.create().createRequestFactory();
HttpRequest tokenRequest = requestFactory.buildPostRequest(
new GenericUrl(tokenServerUri), tokenContent);
tokenRequest.setParser(new JsonObjectParser(OAuth2Utils.JSON_FACTORY));
@@ -262,9 +261,8 @@ public UserCredentials getCredentialsFromCode(String code, URI baseUri) throws I
String refreshToken = OAuth2Utils.validateOptionalString(
parsedTokens, "refresh_token", FETCH_TOKEN_ERROR);
- UserCredentials credentials = new UserCredentials(clientId.getClientId(),
- clientId.getClientSecret(), refreshToken, accessToken, transport, tokenServerUri);
- return credentials;
+ return new UserCredentials(clientId.getClientId(), clientId.getClientSecret(), refreshToken,
+ accessToken, transportFactory, tokenServerUri);
}
/**
@@ -318,7 +316,7 @@ public void revokeAuthorization(String userId) throws IOException {
String revokeToken = (refreshToken != null) ? refreshToken : accessTokenValue;
GenericUrl revokeUrl = new GenericUrl(OAuth2Utils.TOKEN_REVOKE_URI);
revokeUrl.put("token", revokeToken);
- HttpRequestFactory requestFactory = transport.createRequestFactory();
+ HttpRequestFactory requestFactory = transportFactory.create().createRequestFactory();
HttpRequest tokenRequest = requestFactory.buildGetRequest(revokeUrl);
tokenRequest.execute();
diff --git a/oauth2_http/java/com/google/auth/oauth2/UserCredentials.java b/oauth2_http/java/com/google/auth/oauth2/UserCredentials.java
index ea6bfa7c3..90d0928e0 100644
--- a/oauth2_http/java/com/google/auth/oauth2/UserCredentials.java
+++ b/oauth2_http/java/com/google/auth/oauth2/UserCredentials.java
@@ -31,20 +31,24 @@
package com.google.auth.oauth2;
+import static com.google.common.base.MoreObjects.firstNonNull;
+
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpResponse;
-import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.UrlEncodedContent;
import com.google.api.client.json.JsonObjectParser;
import com.google.api.client.util.GenericData;
import com.google.api.client.util.Preconditions;
+import com.google.auth.http.HttpTransportFactory;
import java.io.IOException;
+import java.io.ObjectInputStream;
import java.net.URI;
import java.util.Date;
import java.util.Map;
+import java.util.Objects;
/**
* OAuth2 Credentials representing a user's identity and consent.
@@ -53,12 +57,15 @@ public class UserCredentials extends GoogleCredentials {
private static final String GRANT_TYPE = "refresh_token";
private static final String PARSE_ERROR_PREFIX = "Error parsing token refresh response. ";
+ private static final long serialVersionUID = -4800758775038679176L;
private final String clientId;
private final String clientSecret;
private final String refreshToken;
- private final HttpTransport transport;
private final URI tokenServerUri;
+ private final String transportFactoryClassName;
+
+ private transient HttpTransportFactory transportFactory;
/**
* Constructor with minimum information and default behavior.
@@ -92,17 +99,20 @@ public UserCredentials(
* @param clientSecret Client ID of the credential from the console.
* @param refreshToken A refresh token resulting from a OAuth2 consent flow.
* @param accessToken Initial or temporary access token.
- * @param transport HTTP object used to get access tokens.
+ * @param transportFactory HTTP transport factory, creates the transport used to get access
+ * tokens.
* @param tokenServerUri URI of the end point that provides tokens.
*/
public UserCredentials(String clientId, String clientSecret, String refreshToken,
- AccessToken accessToken, HttpTransport transport, URI tokenServerUri) {
+ AccessToken accessToken, HttpTransportFactory transportFactory, URI tokenServerUri) {
super(accessToken);
this.clientId = Preconditions.checkNotNull(clientId);
this.clientSecret = Preconditions.checkNotNull(clientSecret);
this.refreshToken = refreshToken;
- this.transport = (transport == null) ? OAuth2Utils.HTTP_TRANSPORT : transport;
+ this.transportFactory = firstNonNull(transportFactory,
+ getFromServiceLoader(HttpTransportFactory.class, OAuth2Utils.HTTP_TRANSPORT_FACTORY));
this.tokenServerUri = (tokenServerUri == null) ? OAuth2Utils.TOKEN_SERVER_URI : tokenServerUri;
+ this.transportFactoryClassName = this.transportFactory.getClass().getName();
Preconditions.checkState(accessToken != null || refreshToken != null,
"Either accessToken or refreshToken must not be null");
}
@@ -111,11 +121,12 @@ public UserCredentials(String clientId, String clientSecret, String refreshToken
* Returns user crentials defined by JSON contents using the format supported by the Cloud SDK.
*
* @param json a map from the JSON representing the credentials.
- * @param transport the transport for Http calls.
+ * @param transportFactory HTTP transport factory, creates the transport used to get access
+ * tokens.
* @return the credentials defined by the JSON.
* @throws IOException if the credential cannot be created from the JSON.
**/
- static UserCredentials fromJson(Map json, HttpTransport transport)
+ static UserCredentials fromJson(Map json, HttpTransportFactory transportFactory)
throws IOException {
String clientId = (String) json.get("client_id");
String clientSecret = (String) json.get("client_secret");
@@ -124,9 +135,7 @@ static UserCredentials fromJson(Map json, HttpTransport transpor
throw new IOException("Error reading user credential from JSON, "
+ " expecting 'client_id', 'client_secret' and 'refresh_token'.");
}
- UserCredentials credentials =
- new UserCredentials(clientId, clientSecret, refreshToken, null, transport, null);
- return credentials;
+ return new UserCredentials(clientId, clientSecret, refreshToken, null, transportFactory, null);
}
/**
@@ -145,7 +154,7 @@ public AccessToken refreshAccessToken() throws IOException {
tokenRequest.set("grant_type", GRANT_TYPE);
UrlEncodedContent content = new UrlEncodedContent(tokenRequest);
- HttpRequestFactory requestFactory = transport.createRequestFactory();
+ HttpRequestFactory requestFactory = transportFactory.create().createRequestFactory();
HttpRequest request =
requestFactory.buildPostRequest(new GenericUrl(tokenServerUri), content);
request.setParser(new JsonObjectParser(OAuth2Utils.JSON_FACTORY));
@@ -156,8 +165,7 @@ public AccessToken refreshAccessToken() throws IOException {
int expiresInSeconds =
OAuth2Utils.validateInt32(responseData, "expires_in", PARSE_ERROR_PREFIX);
long expiresAtMilliseconds = clock.currentTimeMillis() + expiresInSeconds * 1000;
- AccessToken access = new AccessToken(accessToken, new Date(expiresAtMilliseconds));
- return access;
+ return new AccessToken(accessToken, new Date(expiresAtMilliseconds));
}
/**
@@ -186,4 +194,39 @@ public final String getClientSecret() {
public final String getRefreshToken() {
return refreshToken;
}
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), clientId, clientSecret, refreshToken, tokenServerUri,
+ transportFactoryClassName);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper()
+ .add("clientId", clientId)
+ .add("refreshToken", refreshToken)
+ .add("tokenServerUri", tokenServerUri)
+ .add("transportFactoryClassName", transportFactoryClassName)
+ .toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof UserCredentials)) {
+ return false;
+ }
+ UserCredentials other = (UserCredentials) obj;
+ return super.equals(other)
+ && Objects.equals(this.clientId, other.clientId)
+ && Objects.equals(this.clientSecret, other.clientSecret)
+ && Objects.equals(this.refreshToken, other.refreshToken)
+ && Objects.equals(this.tokenServerUri, other.tokenServerUri)
+ && Objects.equals(this.transportFactoryClassName, other.transportFactoryClassName);
+ }
+
+ private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException {
+ input.defaultReadObject();
+ transportFactory = newInstance(transportFactoryClassName);
+ }
}
diff --git a/oauth2_http/javatests/com/google/auth/TestUtils.java b/oauth2_http/javatests/com/google/auth/TestUtils.java
index f45d24d47..e09941a04 100644
--- a/oauth2_http/javatests/com/google/auth/TestUtils.java
+++ b/oauth2_http/javatests/com/google/auth/TestUtils.java
@@ -79,8 +79,7 @@ public static void assertContainsBearerToken(Map> metadata,
public static InputStream jsonToInputStream(GenericJson json) throws IOException {
json.setFactory(JSON_FACTORY);
String text = json.toPrettyString();
- InputStream stream = new ByteArrayInputStream(text.getBytes(UTF_8));
- return stream;
+ return new ByteArrayInputStream(text.getBytes(UTF_8));
}
public static InputStream stringToInputStream(String text) {
@@ -92,7 +91,7 @@ public static InputStream stringToInputStream(String text) {
}
public static Map parseQuery(String query) throws IOException {
- Map map = new HashMap();
+ Map map = new HashMap<>();
Iterable entries = Splitter.on('&').split(query);
for (String entry : entries) {
List sides = Lists.newArrayList(Splitter.on('=').split(entry));
diff --git a/oauth2_http/javatests/com/google/auth/http/HttpCredentialsAdapterTest.java b/oauth2_http/javatests/com/google/auth/http/HttpCredentialsAdapterTest.java
index 060a0054e..38c465280 100644
--- a/oauth2_http/javatests/com/google/auth/http/HttpCredentialsAdapterTest.java
+++ b/oauth2_http/javatests/com/google/auth/http/HttpCredentialsAdapterTest.java
@@ -39,8 +39,8 @@
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpTransport;
+import com.google.auth.oauth2.GoogleCredentialsTest.MockTokenServerTransportFactory;
import com.google.auth.oauth2.MockTokenCheckingTransport;
-import com.google.auth.oauth2.MockTokenServerTransport;
import com.google.auth.oauth2.OAuth2Credentials;
import com.google.auth.oauth2.UserCredentials;
@@ -64,13 +64,13 @@ public class HttpCredentialsAdapterTest {
public void initialize_populatesOAuth2Credentials() throws IOException {
final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2";
final String expectedAuthorization = InternalAuthHttpConstants.BEARER_PREFIX + accessToken;
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(CLIENT_ID, CLIENT_SECRET);
- transport.addRefreshToken(REFRESH_TOKEN, accessToken);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET);
+ transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken);
OAuth2Credentials credentials = new UserCredentials(
- CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, transport, null);
+ CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, transportFactory, null);
HttpCredentialsAdapter adapter = new HttpCredentialsAdapter(credentials);
- HttpRequestFactory requestFactory = transport.createRequestFactory();
+ HttpRequestFactory requestFactory = transportFactory.transport.createRequestFactory();
HttpRequest request = requestFactory.buildGetRequest(new GenericUrl("http://foo"));
adapter.initialize(request);
@@ -85,24 +85,25 @@ public void initialize_populatesOAuth2Credentials_handle401() throws IOException
final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2";
final String accessToken2 = "2/MkSJoj1xsli0AccessToken_NKPY2";
- final MockTokenServerTransport tokenServerTransport = new MockTokenServerTransport();
- tokenServerTransport.addClient(CLIENT_ID, CLIENT_SECRET);
- tokenServerTransport.addRefreshToken(REFRESH_TOKEN, accessToken);
+ MockTokenServerTransportFactory tokenServerTransportFactory =
+ new MockTokenServerTransportFactory();
+ tokenServerTransportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET);
+ tokenServerTransportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken);
OAuth2Credentials credentials = new UserCredentials(
- CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, tokenServerTransport, null);
+ CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, tokenServerTransportFactory, null);
credentials.refresh();
HttpCredentialsAdapter adapter = new HttpCredentialsAdapter(credentials);
HttpTransport primaryHttpTransport =
- new MockTokenCheckingTransport(tokenServerTransport, REFRESH_TOKEN);
+ new MockTokenCheckingTransport(tokenServerTransportFactory.transport, REFRESH_TOKEN);
HttpRequestFactory requestFactory = primaryHttpTransport.createRequestFactory();
HttpRequest request = requestFactory.buildGetRequest(new GenericUrl("http://foo"));
adapter.initialize(request);
// now switch out the access token so that the original one is invalid,
// requiring a refresh of the access token
- tokenServerTransport.addRefreshToken(REFRESH_TOKEN, accessToken2);
+ tokenServerTransportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken2);
HttpResponse response = request.execute();
@@ -115,13 +116,15 @@ public void initialize_populatesOAuth2Credentials_handle401() throws IOException
public void initialize_noURI() throws IOException {
final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2";
final String expectedAuthorization = InternalAuthHttpConstants.BEARER_PREFIX + accessToken;
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(CLIENT_ID, CLIENT_SECRET);
- transport.addRefreshToken(REFRESH_TOKEN, accessToken);
+ MockTokenServerTransportFactory tokenServerTransportFactory =
+ new MockTokenServerTransportFactory();
+ tokenServerTransportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET);
+ tokenServerTransportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken);
OAuth2Credentials credentials = new UserCredentials(
- CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, transport, null);
+ CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, tokenServerTransportFactory, null);
HttpCredentialsAdapter adapter = new HttpCredentialsAdapter(credentials);
- HttpRequestFactory requestFactory = transport.createRequestFactory();
+ HttpRequestFactory requestFactory =
+ tokenServerTransportFactory.transport.createRequestFactory();
HttpRequest request = requestFactory.buildGetRequest(null);
adapter.initialize(request);
diff --git a/oauth2_http/javatests/com/google/auth/oauth2/AccessTokenTest.java b/oauth2_http/javatests/com/google/auth/oauth2/AccessTokenTest.java
new file mode 100644
index 000000000..1c75dcd2f
--- /dev/null
+++ b/oauth2_http/javatests/com/google/auth/oauth2/AccessTokenTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2016, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.google.auth.oauth2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.IOException;
+import java.util.Date;
+
+/**
+ * Unit tests for AccessToken
+ */
+@RunWith(JUnit4.class)
+public class AccessTokenTest extends BaseSerializationTest {
+
+ private static final String TOKEN = "AccessToken";
+ private static final Date EXPIRATION_DATE = new Date();
+
+ @Test
+ public void constructor() {
+ AccessToken accessToken = new AccessToken(TOKEN, EXPIRATION_DATE);
+ assertEquals(TOKEN, accessToken.getTokenValue());
+ assertEquals(EXPIRATION_DATE, accessToken.getExpirationTime());
+ assertEquals(EXPIRATION_DATE.getTime(), (long) accessToken.getExpirationTimeMillis());
+ }
+
+ @Test
+ public void equals_true() throws IOException {
+ AccessToken accessToken = new AccessToken(TOKEN, EXPIRATION_DATE);
+ AccessToken otherAccessToken = new AccessToken(TOKEN, EXPIRATION_DATE);
+ assertTrue(accessToken.equals(otherAccessToken));
+ assertTrue(otherAccessToken.equals(accessToken));
+ }
+
+ @Test
+ public void equals_false_token() throws IOException {
+ AccessToken accessToken = new AccessToken(TOKEN, EXPIRATION_DATE);
+ AccessToken otherAccessToken = new AccessToken("otherToken", EXPIRATION_DATE);
+ assertFalse(accessToken.equals(otherAccessToken));
+ assertFalse(otherAccessToken.equals(accessToken));
+ }
+
+ @Test
+ public void equals_false_expirationDate() throws IOException {
+ AccessToken accessToken = new AccessToken(TOKEN, EXPIRATION_DATE);
+ AccessToken otherAccessToken = new AccessToken(TOKEN, new Date(EXPIRATION_DATE.getTime() + 42));
+ assertFalse(accessToken.equals(otherAccessToken));
+ assertFalse(otherAccessToken.equals(accessToken));
+ }
+
+ @Test
+ public void toString_containsFields() {
+ AccessToken accessToken = new AccessToken(TOKEN, EXPIRATION_DATE);
+ String expectedToString = String.format("AccessToken{tokenValue=%s, expirationTimeMillis=%d}",
+ TOKEN, EXPIRATION_DATE.getTime());
+ assertEquals(expectedToString, accessToken.toString());
+ }
+
+ @Test
+ public void hashCode_equals() throws IOException {
+ AccessToken accessToken = new AccessToken(TOKEN, EXPIRATION_DATE);
+ AccessToken otherAccessToken = new AccessToken(TOKEN, EXPIRATION_DATE);
+ assertEquals(accessToken.hashCode(), otherAccessToken.hashCode());
+ }
+
+ @Test
+ public void serialize() throws IOException, ClassNotFoundException {
+ AccessToken accessToken = new AccessToken(TOKEN, EXPIRATION_DATE);
+ AccessToken deserializedAccessToken = serializeAndDeserialize(accessToken);
+ assertEquals(accessToken, deserializedAccessToken);
+ assertEquals(accessToken.hashCode(), deserializedAccessToken.hashCode());
+ assertEquals(accessToken.toString(), deserializedAccessToken.toString());
+ }
+}
diff --git a/oauth2_http/javatests/com/google/auth/oauth2/BaseSerializationTest.java b/oauth2_http/javatests/com/google/auth/oauth2/BaseSerializationTest.java
new file mode 100644
index 000000000..5db5ca08f
--- /dev/null
+++ b/oauth2_http/javatests/com/google/auth/oauth2/BaseSerializationTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2016, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.google.auth.oauth2;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+/**
+ * Base class for serialization tests.
+ */
+public class BaseSerializationTest {
+
+ @SuppressWarnings("unchecked")
+ public T serializeAndDeserialize(T obj) throws IOException, ClassNotFoundException {
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ try (ObjectOutputStream output = new ObjectOutputStream(bytes)) {
+ output.writeObject(obj);
+ }
+ try (ObjectInputStream input =
+ new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) {
+ return (T) input.readObject();
+ }
+ }
+}
diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ClientIdTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ClientIdTest.java
index 2ae0fffb6..48031a007 100644
--- a/oauth2_http/javatests/com/google/auth/oauth2/ClientIdTest.java
+++ b/oauth2_http/javatests/com/google/auth/oauth2/ClientIdTest.java
@@ -167,6 +167,7 @@ public void fromStream_invalidJson_throws() {
ClientId.fromStream(stream);
fail();
} catch (IOException expected) {
+ // Expected
}
}
diff --git a/oauth2_http/javatests/com/google/auth/oauth2/CloudShellCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/CloudShellCredentialsTest.java
index 1a6e848ef..a527afe1a 100644
--- a/oauth2_http/javatests/com/google/auth/oauth2/CloudShellCredentialsTest.java
+++ b/oauth2_http/javatests/com/google/auth/oauth2/CloudShellCredentialsTest.java
@@ -32,17 +32,20 @@
package com.google.auth.oauth2;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import com.google.api.client.util.Clock;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.io.BufferedReader;
-import java.io.InputStreamReader;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.io.PrintWriter;
-import java.lang.Runnable;
-import java.lang.Thread;
import java.net.ServerSocket;
import java.net.Socket;
@@ -50,7 +53,7 @@
* Unit tests for CloudShellCredentials
*/
@RunWith(JUnit4.class)
-public class CloudShellCredentialsTest {
+public class CloudShellCredentialsTest extends BaseSerializationTest {
@Test
public void refreshAccessToken() throws IOException{
@@ -84,4 +87,44 @@ public void run() {
authSocket.close();
}
}
+
+ @Test
+ public void equals_true() throws IOException {
+ GoogleCredentials credentials = new CloudShellCredentials(42);
+ GoogleCredentials otherCredentials = new CloudShellCredentials(42);
+ assertTrue(credentials.equals(otherCredentials));
+ assertTrue(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_authPort() throws IOException {
+ GoogleCredentials credentials = new CloudShellCredentials(42);
+ GoogleCredentials otherCredentials = new CloudShellCredentials(43);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void toString_containsFields() throws IOException {
+ String expectedToString = String.format("CloudShellCredentials{authPort=%d}", 42);
+ GoogleCredentials credentials = new CloudShellCredentials(42);
+ assertEquals(expectedToString, credentials.toString());
+ }
+
+ @Test
+ public void hashCode_equals() throws IOException {
+ GoogleCredentials credentials = new CloudShellCredentials(42);
+ GoogleCredentials otherCredentials = new CloudShellCredentials(42);
+ assertEquals(credentials.hashCode(), otherCredentials.hashCode());
+ }
+
+ @Test
+ public void serialize() throws IOException, ClassNotFoundException {
+ GoogleCredentials credentials = new CloudShellCredentials(42);
+ GoogleCredentials deserializedCredentials = serializeAndDeserialize(credentials);
+ assertEquals(credentials, deserializedCredentials);
+ assertEquals(credentials.hashCode(), deserializedCredentials.hashCode());
+ assertEquals(credentials.toString(), deserializedCredentials.toString());
+ assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ }
}
diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ComputeEngineCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ComputeEngineCredentialsTest.java
index 24cbb7976..3a320395d 100644
--- a/oauth2_http/javatests/com/google/auth/oauth2/ComputeEngineCredentialsTest.java
+++ b/oauth2_http/javatests/com/google/auth/oauth2/ComputeEngineCredentialsTest.java
@@ -31,11 +31,18 @@
package com.google.auth.oauth2;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.google.api.client.http.HttpStatusCodes;
+import com.google.api.client.http.HttpTransport;
+import com.google.api.client.util.Clock;
import com.google.auth.TestUtils;
+import com.google.auth.http.HttpTransportFactory;
+import com.google.auth.oauth2.GoogleCredentialsTest.MockHttpTransportFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -50,16 +57,26 @@
* Test case for {@link ComputeEngineCredentials}.
*/
@RunWith(JUnit4.class)
-public class ComputeEngineCredentialsTest {
+public class ComputeEngineCredentialsTest extends BaseSerializationTest {
private static final URI CALL_URI = URI.create("http://googleapis.com/testapi/v1/foo");
+ static class MockMetadataServerTransportFactory implements HttpTransportFactory {
+
+ MockMetadataServerTransport transport = new MockMetadataServerTransport();
+
+ @Override
+ public HttpTransport create() {
+ return transport;
+ }
+ }
+
@Test
public void getRequestMetadata_hasAccessToken() throws IOException {
final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2";
- MockMetadataServerTransport transport = new MockMetadataServerTransport();
- transport.setAccessToken(accessToken);
- ComputeEngineCredentials credentials = new ComputeEngineCredentials(transport);
+ MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory();
+ transportFactory.transport.setAccessToken(accessToken);
+ ComputeEngineCredentials credentials = new ComputeEngineCredentials(transportFactory);
Map> metadata = credentials.getRequestMetadata(CALL_URI);
@@ -69,10 +86,10 @@ public void getRequestMetadata_hasAccessToken() throws IOException {
@Test
public void getRequestMetadata_missingServiceAccount_throws() {
final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2";
- MockMetadataServerTransport transport = new MockMetadataServerTransport();
- transport.setAccessToken(accessToken);
- transport.setTokenRequestStatusCode(HttpStatusCodes.STATUS_CODE_NOT_FOUND);
- ComputeEngineCredentials credentials = new ComputeEngineCredentials(transport);
+ MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory();
+ transportFactory.transport.setAccessToken(accessToken);
+ transportFactory.transport.setTokenRequestStatusCode(HttpStatusCodes.STATUS_CODE_NOT_FOUND);
+ ComputeEngineCredentials credentials = new ComputeEngineCredentials(transportFactory);
try {
credentials.getRequestMetadata(CALL_URI);
@@ -87,10 +104,10 @@ public void getRequestMetadata_missingServiceAccount_throws() {
public void getRequestMetadata_serverError_throws() {
final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2";
- MockMetadataServerTransport transport = new MockMetadataServerTransport();
- transport.setAccessToken(accessToken);
- transport.setTokenRequestStatusCode(HttpStatusCodes.STATUS_CODE_SERVER_ERROR);
- ComputeEngineCredentials credentials = new ComputeEngineCredentials(transport);
+ MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory();
+ transportFactory.transport.setAccessToken(accessToken);
+ transportFactory.transport.setTokenRequestStatusCode(HttpStatusCodes.STATUS_CODE_NOT_FOUND);
+ ComputeEngineCredentials credentials = new ComputeEngineCredentials(transportFactory);
try {
credentials.getRequestMetadata(CALL_URI);
@@ -101,4 +118,63 @@ public void getRequestMetadata_serverError_throws() {
assertTrue(message.contains("Unexpected"));
}
}
+
+ @Test
+ public void equals_true() throws IOException {
+ MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory();
+ ComputeEngineCredentials credentials = new ComputeEngineCredentials(transportFactory);
+ ComputeEngineCredentials otherCredentials = new ComputeEngineCredentials(transportFactory);
+ assertTrue(credentials.equals(otherCredentials));
+ assertTrue(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_transportFactory() throws IOException {
+ MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory();
+ MockMetadataServerTransportFactory serverTransportFactory =
+ new MockMetadataServerTransportFactory();
+ ComputeEngineCredentials credentials = new ComputeEngineCredentials(serverTransportFactory);
+ ComputeEngineCredentials otherCredentials = new ComputeEngineCredentials(httpTransportFactory);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void toString_containsFields() throws IOException {
+ MockMetadataServerTransportFactory serverTransportFactory =
+ new MockMetadataServerTransportFactory();
+ String expectedToString =
+ String.format("ComputeEngineCredentials{transportFactoryClassName=%s}",
+ MockMetadataServerTransportFactory.class.getName());
+ ComputeEngineCredentials credentials = new ComputeEngineCredentials(serverTransportFactory);
+ assertEquals(expectedToString, credentials.toString());
+ }
+
+ @Test
+ public void hashCode_equals() throws IOException {
+ MockMetadataServerTransportFactory serverTransportFactory =
+ new MockMetadataServerTransportFactory();
+ ComputeEngineCredentials credentials = new ComputeEngineCredentials(serverTransportFactory);
+ ComputeEngineCredentials otherCredentials =
+ new ComputeEngineCredentials(serverTransportFactory);
+ assertEquals(credentials.hashCode(), otherCredentials.hashCode());
+ }
+
+ @Test
+ public void serialize() throws IOException, ClassNotFoundException {
+ MockMetadataServerTransportFactory serverTransportFactory =
+ new MockMetadataServerTransportFactory();
+ ComputeEngineCredentials credentials = new ComputeEngineCredentials(serverTransportFactory);
+ GoogleCredentials deserializedCredentials = serializeAndDeserialize(credentials);
+ assertEquals(credentials, deserializedCredentials);
+ assertEquals(credentials.hashCode(), deserializedCredentials.hashCode());
+ assertEquals(credentials.toString(), deserializedCredentials.toString());
+ assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ credentials = new ComputeEngineCredentials();
+ deserializedCredentials = serializeAndDeserialize(credentials);
+ assertEquals(credentials, deserializedCredentials);
+ assertEquals(credentials.hashCode(), deserializedCredentials.hashCode());
+ assertEquals(credentials.toString(), deserializedCredentials.toString());
+ assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ }
}
diff --git a/oauth2_http/javatests/com/google/auth/oauth2/DefaultCredentialsProviderTest.java b/oauth2_http/javatests/com/google/auth/oauth2/DefaultCredentialsProviderTest.java
index 9a71d2e3f..b297f26e8 100644
--- a/oauth2_http/javatests/com/google/auth/oauth2/DefaultCredentialsProviderTest.java
+++ b/oauth2_http/javatests/com/google/auth/oauth2/DefaultCredentialsProviderTest.java
@@ -33,33 +33,37 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.LowLevelHttpRequest;
import com.google.api.client.http.LowLevelHttpResponse;
-import com.google.api.client.http.HttpTransport;
import com.google.api.client.testing.http.MockHttpTransport;
import com.google.api.client.testing.http.MockLowLevelHttpRequest;
import com.google.auth.TestUtils;
+import com.google.auth.http.HttpTransportFactory;
+import com.google.auth.oauth2.ComputeEngineCredentialsTest.MockMetadataServerTransportFactory;
+import com.google.auth.oauth2.GoogleCredentialsTest.MockHttpTransportFactory;
+import com.google.auth.oauth2.GoogleCredentialsTest.MockTokenServerTransportFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
-import java.io.InputStream;
-import java.io.IOException;
import java.io.File;
import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
import java.net.URI;
import java.security.AccessControlException;
import java.util.Collection;
import java.util.Collections;
-import java.util.Map;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* Test case for {@link DefaultCredentialsProvider}.
@@ -82,13 +86,23 @@ public class DefaultCredentialsProviderTest {
private static final Collection SCOPES = Collections.singletonList("dummy.scope");
private static final URI CALL_URI = URI.create("http://googleapis.com/testapi/v1/foo");
+ static class MockRequestCountingTransportFactory implements HttpTransportFactory {
+
+ MockRequestCountingTransport transport = new MockRequestCountingTransport();
+
+ @Override
+ public HttpTransport create() {
+ return transport;
+ }
+ }
+
@Test
public void getDefaultCredentials_noCredentials_throws() throws Exception {
- HttpTransport transport = new MockHttpTransport();
+ MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
try {
- testProvider.getDefaultCredentials(transport);
+ testProvider.getDefaultCredentials(transportFactory);
fail("No credential expected.");
} catch (IOException e) {
String message = e.getMessage();
@@ -98,12 +112,12 @@ public void getDefaultCredentials_noCredentials_throws() throws Exception {
@Test
public void getDefaultCredentials_noCredentialsSandbox_throwsNonSecurity() throws Exception {
- HttpTransport transport = new MockHttpTransport();
+ MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
testProvider.setFileSandbox(true);
try {
- testProvider.getDefaultCredentials(transport);
+ testProvider.getDefaultCredentials(transportFactory);
fail("No credential expected.");
} catch (IOException e) {
String message = e.getMessage();
@@ -113,7 +127,7 @@ public void getDefaultCredentials_noCredentialsSandbox_throwsNonSecurity() throw
@Test
public void getDefaultCredentials_envValidSandbox_throwsNonSecurity() throws Exception {
- HttpTransport transport = new MockHttpTransport();
+ MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
InputStream userStream =
UserCredentialsTest.writeUserStream(USER_CLIENT_ID, USER_CLIENT_SECRET, REFRESH_TOKEN);
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
@@ -123,7 +137,7 @@ public void getDefaultCredentials_envValidSandbox_throwsNonSecurity() throws Exc
testProvider.setEnv(DefaultCredentialsProvider.CREDENTIAL_ENV_VAR, userPath);
try {
- testProvider.getDefaultCredentials(transport);
+ testProvider.getDefaultCredentials(transportFactory);
fail("No credential expected.");
} catch (IOException e) {
String message = e.getMessage();
@@ -133,30 +147,33 @@ public void getDefaultCredentials_envValidSandbox_throwsNonSecurity() throws Exc
@Test
public void getDefaultCredentials_noCredentials_singleGceTestRequest() {
- MockRequestCountingTransport transport = new MockRequestCountingTransport();
+ MockRequestCountingTransportFactory transportFactory =
+ new MockRequestCountingTransportFactory();
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
try {
- testProvider.getDefaultCredentials(transport);
+ testProvider.getDefaultCredentials(transportFactory);
fail("No credential expected.");
} catch (IOException expected) {
+ // Expected
}
- assertEquals(1, transport.getRequestCount());
+ assertEquals(1, transportFactory.transport.getRequestCount());
try {
- testProvider.getDefaultCredentials(transport);
+ testProvider.getDefaultCredentials(transportFactory);
fail("No credential expected.");
} catch (IOException expected) {
+ // Expected
}
- assertEquals(1, transport.getRequestCount());
+ assertEquals(1, transportFactory.transport.getRequestCount());
}
@Test
public void getDefaultCredentials_caches() throws IOException {
- HttpTransport transport = new MockMetadataServerTransport();
+ MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory();
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
- GoogleCredentials firstCall = testProvider.getDefaultCredentials(transport);
- GoogleCredentials secondCall = testProvider.getDefaultCredentials(transport);
+ GoogleCredentials firstCall = testProvider.getDefaultCredentials(transportFactory);
+ GoogleCredentials secondCall = testProvider.getDefaultCredentials(transportFactory);
assertNotNull(firstCall);
assertSame(firstCall, secondCall);
@@ -164,14 +181,14 @@ public void getDefaultCredentials_caches() throws IOException {
@Test
public void getDefaultCredentials_appEngine_deployed() throws IOException {
- HttpTransport transport = new MockHttpTransport();
+ MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
testProvider.addType(DefaultCredentialsProvider.APP_ENGINE_CREDENTIAL_CLASS,
MockAppEngineCredentials.class);
testProvider.addType(DefaultCredentialsProvider.APP_ENGINE_SIGNAL_CLASS,
MockAppEngineSystemProperty.class);
- GoogleCredentials defaultCredential = testProvider.getDefaultCredentials(transport);
+ GoogleCredentials defaultCredential = testProvider.getDefaultCredentials(transportFactory);
assertNotNull(defaultCredential);
assertTrue(defaultCredential instanceof MockAppEngineCredentials);
@@ -179,7 +196,7 @@ public void getDefaultCredentials_appEngine_deployed() throws IOException {
@Test
public void getDefaultCredentials_appEngineClassWithoutRuntime_NotFoundError() {
- HttpTransport transport = new MockHttpTransport();
+ MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
testProvider.addType(DefaultCredentialsProvider.APP_ENGINE_CREDENTIAL_CLASS,
MockAppEngineCredentials.class);
@@ -187,7 +204,7 @@ public void getDefaultCredentials_appEngineClassWithoutRuntime_NotFoundError() {
MockOffAppEngineSystemProperty.class);
try {
- testProvider.getDefaultCredentials(transport);
+ testProvider.getDefaultCredentials(transportFactory);
fail("No credential expected when not on App Engine.");
} catch (IOException e) {
String message = e.getMessage();
@@ -197,13 +214,13 @@ public void getDefaultCredentials_appEngineClassWithoutRuntime_NotFoundError() {
@Test
public void getDefaultCredentials_appEngineRuntimeWithoutClass_throwsHelpfulLoadError() {
- HttpTransport transport = new MockHttpTransport();
+ MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
testProvider.addType(DefaultCredentialsProvider.APP_ENGINE_SIGNAL_CLASS,
MockAppEngineSystemProperty.class);
try {
- testProvider.getDefaultCredentials(transport);
+ testProvider.getDefaultCredentials(transportFactory);
fail("Credential expected to fail to load if credential class not present.");
} catch (IOException e) {
String message = e.getMessage();
@@ -214,30 +231,32 @@ public void getDefaultCredentials_appEngineRuntimeWithoutClass_throwsHelpfulLoad
@Test
public void getDefaultCredentials_appEngine_singleClassLoadAttempt() {
- HttpTransport transport = new MockHttpTransport();
+ MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
try {
- testProvider.getDefaultCredentials(transport);
+ testProvider.getDefaultCredentials(transportFactory);
fail("No credential expected for default test provider.");
} catch (IOException expected) {
+ // Expected
}
assertEquals(1, testProvider.getForNameCallCount());
// Try a second time.
try {
- testProvider.getDefaultCredentials(transport);
+ testProvider.getDefaultCredentials(transportFactory);
fail("No credential expected for default test provider.");
} catch (IOException expected) {
+ // Expected
}
assertEquals(1, testProvider.getForNameCallCount());
}
@Test
public void getDefaultCredentials_compute_providesToken() throws IOException {
- MockMetadataServerTransport transport = new MockMetadataServerTransport();
- transport.setAccessToken(ACCESS_TOKEN);
+ MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory();
+ transportFactory.transport.setAccessToken(ACCESS_TOKEN);
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
- GoogleCredentials defaultCredentials = testProvider.getDefaultCredentials(transport);
+ GoogleCredentials defaultCredentials = testProvider.getDefaultCredentials(transportFactory);
assertNotNull(defaultCredentials);
Map> metadata = defaultCredentials.getRequestMetadata(CALL_URI);
@@ -246,11 +265,11 @@ public void getDefaultCredentials_compute_providesToken() throws IOException {
@Test
public void getDefaultCredentials_cloudshell() throws IOException {
- HttpTransport transport = new MockHttpTransport();
+ MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
testProvider.setEnv(DefaultCredentialsProvider.CLOUD_SHELL_ENV_VAR, "4");
- GoogleCredentials defaultCredentials = testProvider.getDefaultCredentials(transport);
+ GoogleCredentials defaultCredentials = testProvider.getDefaultCredentials(transportFactory);
assertTrue(defaultCredentials instanceof CloudShellCredentials);
assertEquals(((CloudShellCredentials) defaultCredentials).getAuthPort(), 4);
@@ -258,12 +277,12 @@ public void getDefaultCredentials_cloudshell() throws IOException {
@Test
public void getDefaultCredentials_cloudshell_withComputCredentialsPresent() throws IOException {
- MockMetadataServerTransport transport = new MockMetadataServerTransport();
- transport.setAccessToken(ACCESS_TOKEN);
+ MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory();
+ transportFactory.transport.setAccessToken(ACCESS_TOKEN);
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
testProvider.setEnv(DefaultCredentialsProvider.CLOUD_SHELL_ENV_VAR, "4");
- GoogleCredentials defaultCredentials = testProvider.getDefaultCredentials(transport);
+ GoogleCredentials defaultCredentials = testProvider.getDefaultCredentials(transportFactory);
assertTrue(defaultCredentials instanceof CloudShellCredentials);
assertEquals(((CloudShellCredentials) defaultCredentials).getAuthPort(), 4);
@@ -272,12 +291,12 @@ public void getDefaultCredentials_cloudshell_withComputCredentialsPresent() thro
@Test
public void getDefaultCredentials_envMissingFile_throws() {
final String invalidPath = "/invalid/path";
- HttpTransport transport = new MockHttpTransport();
+ MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
testProvider.setEnv(DefaultCredentialsProvider.CREDENTIAL_ENV_VAR, invalidPath);
try {
- testProvider.getDefaultCredentials(transport);
+ testProvider.getDefaultCredentials(transportFactory);
fail("Non existent credential should throw exception");
} catch (IOException e) {
String message = e.getMessage();
@@ -288,8 +307,8 @@ public void getDefaultCredentials_envMissingFile_throws() {
@Test
public void getDefaultCredentials_envServiceAccount_providesToken() throws IOException {
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addServiceAccount(SA_CLIENT_EMAIL, ACCESS_TOKEN);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addServiceAccount(SA_CLIENT_EMAIL, ACCESS_TOKEN);
InputStream serviceAccountStream = ServiceAccountCredentialsTest
.writeServiceAccountAccountStream(
SA_CLIENT_ID, SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID);
@@ -299,7 +318,7 @@ public void getDefaultCredentials_envServiceAccount_providesToken() throws IOExc
testProvider.setEnv(
DefaultCredentialsProvider.CREDENTIAL_ENV_VAR, serviceAccountPath);
- GoogleCredentials defaultCredentials = testProvider.getDefaultCredentials(transport);
+ GoogleCredentials defaultCredentials = testProvider.getDefaultCredentials(transportFactory);
assertNotNull(defaultCredentials);
defaultCredentials = defaultCredentials.createScoped(SCOPES);
@@ -395,12 +414,12 @@ public void getDefaultCredentials_envAndWellKnownFile_envPrecedence() throws IOE
testProvider.setProperty("user.home", homeDir.getAbsolutePath());
testProvider.addFile(wellKnownFile.getAbsolutePath(), wkfStream);
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(USER_CLIENT_ID, USER_CLIENT_SECRET);
- transport.addRefreshToken(refreshTokenWkf, accessTokenWkf);
- transport.addRefreshToken(refreshTokenEnv, accessTokenEnv);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addClient(USER_CLIENT_ID, USER_CLIENT_SECRET);
+ transportFactory.transport.addRefreshToken(refreshTokenWkf, accessTokenWkf);
+ transportFactory.transport.addRefreshToken(refreshTokenEnv, accessTokenEnv);
- testUserProvidesToken(testProvider, transport, accessTokenEnv);
+ testUserProvidesToken(testProvider, transportFactory, accessTokenEnv);
}
private static File getTempDirectory() {
@@ -409,15 +428,15 @@ private static File getTempDirectory() {
private void testUserProvidesToken(TestDefaultCredentialsProvider testProvider, String clientId,
String clientSecret, String refreshToken) throws IOException {
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(clientId, clientSecret);
- transport.addRefreshToken(refreshToken, ACCESS_TOKEN);
- testUserProvidesToken(testProvider, transport, ACCESS_TOKEN);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addClient(clientId, clientSecret);
+ transportFactory.transport.addRefreshToken(refreshToken, ACCESS_TOKEN);
+ testUserProvidesToken(testProvider, transportFactory, ACCESS_TOKEN);
}
private void testUserProvidesToken(TestDefaultCredentialsProvider testProvider,
- HttpTransport transport, String accessToken) throws IOException {
- GoogleCredentials defaultCredentials = testProvider.getDefaultCredentials(transport);
+ HttpTransportFactory transportFactory, String accessToken) throws IOException {
+ GoogleCredentials defaultCredentials = testProvider.getDefaultCredentials(transportFactory);
assertNotNull(defaultCredentials);
Map> metadata = defaultCredentials.getRequestMetadata(CALL_URI);
@@ -425,6 +444,8 @@ private void testUserProvidesToken(TestDefaultCredentialsProvider testProvider,
}
public static class MockAppEngineCredentials extends GoogleCredentials {
+ private static final long serialVersionUID = 2695173591854484322L;
+
@SuppressWarnings("unused")
public MockAppEngineCredentials(Collection scopes) {
}
@@ -487,23 +508,22 @@ int getRequestCount() {
@Override
public LowLevelHttpRequest buildRequest(String method, String url) {
- MockLowLevelHttpRequest request = new MockLowLevelHttpRequest(url) {
+ return new MockLowLevelHttpRequest(url) {
@Override
public LowLevelHttpResponse execute() throws IOException {
requestCount++;
throw new IOException("MockRequestCountingTransport request failed.");
}
};
- return request;
}
}
private static class TestDefaultCredentialsProvider extends DefaultCredentialsProvider {
- private final Map> types = new HashMap>();
- private final Map variables = new HashMap();
- private final Map properties = new HashMap();
- private final Map files = new HashMap();
+ private final Map> types = new HashMap<>();
+ private final Map variables = new HashMap<>();
+ private final Map properties = new HashMap<>();
+ private final Map files = new HashMap<>();
private boolean fileSandbox = false;
private int forNameCallCount = 0;
diff --git a/oauth2_http/javatests/com/google/auth/oauth2/GoogleCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/GoogleCredentialsTest.java
index 103427202..dbe80e290 100644
--- a/oauth2_http/javatests/com/google/auth/oauth2/GoogleCredentialsTest.java
+++ b/oauth2_http/javatests/com/google/auth/oauth2/GoogleCredentialsTest.java
@@ -38,14 +38,15 @@
import com.google.api.client.http.HttpTransport;
import com.google.api.client.testing.http.MockHttpTransport;
import com.google.auth.TestUtils;
+import com.google.auth.http.HttpTransportFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.io.ByteArrayInputStream;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.net.URI;
import java.util.Arrays;
import java.util.Collection;
@@ -71,18 +72,40 @@ public class GoogleCredentialsTest {
private static final String USER_CLIENT_ID = "ya29.1.AADtN_UtlxN3PuGAxrN2XQnZTVRvDyVWnYq4I6dws";
private static final String REFRESH_TOKEN = "1/Tl6awhpFjkMkSJoj1xsli0H2eL5YsMgU_NKPY2TyGWY";
private static final String ACCESS_TOKEN = "1/MkSJoj1xsli0AccessToken_NKPY2";
- private static final HttpTransport DUMMY_TRANSPORT = new MockTokenServerTransport();
+ private static final HttpTransportFactory DUMMY_TRANSPORT_FACTORY =
+ new MockTokenServerTransportFactory();
private static final URI CALL_URI = URI.create("http://googleapis.com/testapi/v1/foo");
private static final Collection SCOPES =
Collections.unmodifiableCollection(Arrays.asList("scope1", "scope2"));
+ static class MockHttpTransportFactory implements HttpTransportFactory {
+
+ MockHttpTransport transport = new MockHttpTransport();
+
+ @Override
+ public HttpTransport create() {
+ return transport;
+ }
+ }
+
+ public static class MockTokenServerTransportFactory implements HttpTransportFactory {
+
+ public MockTokenServerTransport transport = new MockTokenServerTransport();
+
+ @Override
+ public HttpTransport create() {
+ return transport;
+ }
+ }
+
@Test
public void getApplicationDefault_nullTransport_throws() throws IOException {
try {
GoogleCredentials.getApplicationDefault(null);
fail();
} catch (NullPointerException expected) {
+ // Expected
}
}
@@ -93,28 +116,31 @@ public void fromStream_nullTransport_throws() throws IOException {
GoogleCredentials.fromStream(stream, null);
fail();
} catch (NullPointerException expected) {
+ // Expected
}
}
@Test
public void fromStream_nullStreamThrows() throws IOException {
- HttpTransport transport = new MockHttpTransport();
+ MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
try {
- GoogleCredentials.fromStream(null, transport);
+ GoogleCredentials.fromStream(null, transportFactory);
fail();
} catch (NullPointerException expected) {
+ // Expected
}
}
@Test
public void fromStream_serviceAccount_providesToken() throws IOException {
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addServiceAccount(SA_CLIENT_EMAIL, ACCESS_TOKEN);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addServiceAccount(SA_CLIENT_EMAIL, ACCESS_TOKEN);
InputStream serviceAccountStream = ServiceAccountCredentialsTest
.writeServiceAccountAccountStream(
SA_CLIENT_ID, SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID);
- GoogleCredentials credentials = GoogleCredentials.fromStream(serviceAccountStream, transport);
+ GoogleCredentials credentials =
+ GoogleCredentials.fromStream(serviceAccountStream, transportFactory);
assertNotNull(credentials);
credentials = credentials.createScoped(SCOPES);
@@ -160,13 +186,13 @@ public void fromStream_serviceAccountNoPrivateKeyId_throws() throws IOException
@Test
public void fromStream_user_providesToken() throws IOException {
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(USER_CLIENT_ID, USER_CLIENT_SECRET);
- transport.addRefreshToken(REFRESH_TOKEN, ACCESS_TOKEN);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addClient(USER_CLIENT_ID, USER_CLIENT_SECRET);
+ transportFactory.transport.addRefreshToken(REFRESH_TOKEN, ACCESS_TOKEN);
InputStream userStream =
UserCredentialsTest.writeUserStream(USER_CLIENT_ID, USER_CLIENT_SECRET, REFRESH_TOKEN);
- GoogleCredentials credentials = GoogleCredentials.fromStream(userStream, transport);
+ GoogleCredentials credentials = GoogleCredentials.fromStream(userStream, transportFactory);
assertNotNull(credentials);
Map> metadata = credentials.getRequestMetadata(CALL_URI);
@@ -199,7 +225,7 @@ public void fromStream_userNoRefreshToken_throws() throws IOException {
private void testFromStreamException(InputStream stream, String expectedMessageContent) {
try {
- GoogleCredentials.fromStream(stream, DUMMY_TRANSPORT);
+ GoogleCredentials.fromStream(stream, DUMMY_TRANSPORT_FACTORY);
fail();
} catch (IOException expected) {
assertTrue(expected.getMessage().contains(expectedMessageContent));
diff --git a/oauth2_http/javatests/com/google/auth/oauth2/MockMetadataServerTransport.java b/oauth2_http/javatests/com/google/auth/oauth2/MockMetadataServerTransport.java
index 0203b6090..afa94a1c2 100644
--- a/oauth2_http/javatests/com/google/auth/oauth2/MockMetadataServerTransport.java
+++ b/oauth2_http/javatests/com/google/auth/oauth2/MockMetadataServerTransport.java
@@ -65,15 +65,14 @@ public void setTokenRequestStatusCode(Integer tokenRequestStatusCode) {
public LowLevelHttpRequest buildRequest(String method, String url) throws IOException {
if (url.equals(ComputeEngineCredentials.TOKEN_SERVER_ENCODED_URL)) {
- MockLowLevelHttpRequest request = new MockLowLevelHttpRequest(url) {
+ return new MockLowLevelHttpRequest(url) {
@Override
public LowLevelHttpResponse execute() throws IOException {
if (tokenRequestStatusCode != null) {
- MockLowLevelHttpResponse response = new MockLowLevelHttpResponse()
+ return new MockLowLevelHttpResponse()
.setStatusCode(tokenRequestStatusCode)
.setContent("Token Fetch Error");
- return response;
}
String metadataRequestHeader = getFirstHeaderValue("Metadata-Flavor");
@@ -89,16 +88,13 @@ public LowLevelHttpResponse execute() throws IOException {
refreshContents.put("token_type", "Bearer");
String refreshText = refreshContents.toPrettyString();
- MockLowLevelHttpResponse response = new MockLowLevelHttpResponse()
+ return new MockLowLevelHttpResponse()
.setContentType(Json.MEDIA_TYPE)
.setContent(refreshText);
- return response;
-
}
};
- return request;
} else if (url.equals(ComputeEngineCredentials.METADATA_SERVER_URL)) {
- MockLowLevelHttpRequest request = new MockLowLevelHttpRequest(url) {
+ return new MockLowLevelHttpRequest(url) {
@Override
public LowLevelHttpResponse execute() {
MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
@@ -106,7 +102,6 @@ public LowLevelHttpResponse execute() {
return response;
}
};
- return request;
}
return super.buildRequest(method, url);
}
diff --git a/oauth2_http/javatests/com/google/auth/oauth2/MockTokenServerTransport.java b/oauth2_http/javatests/com/google/auth/oauth2/MockTokenServerTransport.java
index 056a7405a..06acb2eea 100644
--- a/oauth2_http/javatests/com/google/auth/oauth2/MockTokenServerTransport.java
+++ b/oauth2_http/javatests/com/google/auth/oauth2/MockTokenServerTransport.java
@@ -110,12 +110,12 @@ public LowLevelHttpRequest buildRequest(String method, String url) throws IOExce
final String urlWithoutQUery = (questionMarkPos > 0) ? url.substring(0, questionMarkPos) : url;
final String query = (questionMarkPos > 0) ? url.substring(questionMarkPos + 1) : "";
if (urlWithoutQUery.equals(tokenServerUri.toString())) {
- MockLowLevelHttpRequest request = new MockLowLevelHttpRequest(url) {
+ return new MockLowLevelHttpRequest(url) {
@Override
public LowLevelHttpResponse execute() throws IOException {
String content = this.getContentAsString();
Map query = TestUtils.parseQuery(content);
- String accessToken = null;
+ String accessToken;
String refreshToken = null;
String foundId = query.get("client_id");
@@ -173,15 +173,13 @@ public LowLevelHttpResponse execute() throws IOException {
}
String refreshText = refreshContents.toPrettyString();
- MockLowLevelHttpResponse response = new MockLowLevelHttpResponse()
+ return new MockLowLevelHttpResponse()
.setContentType(Json.MEDIA_TYPE)
.setContent(refreshText);
- return response;
}
};
- return request;
} else if (urlWithoutQUery.equals(OAuth2Utils.TOKEN_REVOKE_URI.toString())) {
- MockLowLevelHttpRequest request = new MockLowLevelHttpRequest(url) {
+ return new MockLowLevelHttpRequest(url) {
@Override
public LowLevelHttpResponse execute() throws IOException {
Map parameters = TestUtils.parseQuery(query);
@@ -192,12 +190,9 @@ public LowLevelHttpResponse execute() throws IOException {
// Token could be access token or refresh token so remove keys and values
refreshTokens.values().removeAll(Collections.singleton(token));
refreshTokens.remove(token);
- MockLowLevelHttpResponse response = new MockLowLevelHttpResponse()
- .setContentType(Json.MEDIA_TYPE);
- return response;
+ return new MockLowLevelHttpResponse().setContentType(Json.MEDIA_TYPE);
}
};
- return request;
}
return super.buildRequest(method, url);
}
diff --git a/oauth2_http/javatests/com/google/auth/oauth2/OAuth2CredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/OAuth2CredentialsTest.java
index 1bfb4d177..e1ab01528 100644
--- a/oauth2_http/javatests/com/google/auth/oauth2/OAuth2CredentialsTest.java
+++ b/oauth2_http/javatests/com/google/auth/oauth2/OAuth2CredentialsTest.java
@@ -31,15 +31,21 @@
package com.google.auth.oauth2;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
+import com.google.api.client.util.Clock;
import com.google.auth.TestClock;
import com.google.auth.TestUtils;
+import com.google.auth.http.AuthHttpConstants;
+import com.google.auth.oauth2.GoogleCredentialsTest.MockTokenServerTransportFactory;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -47,14 +53,14 @@
import java.io.IOException;
import java.net.URI;
-import java.util.Map;
import java.util.List;
+import java.util.Map;
/**
* Test case for {@link OAuth2Credentials}.
*/
@RunWith(JUnit4.class)
-public class OAuth2CredentialsTest {
+public class OAuth2CredentialsTest extends BaseSerializationTest {
private static final String CLIENT_SECRET = "jakuaL9YyieakhECKL2SwZcu";
private static final String CLIENT_ID = "ya29.1.AADtN_UtlxN3PuGAxrN2XQnZTVRvDyVWnYq4I6dws";
@@ -88,14 +94,14 @@ public void hasRequestMetadataOnly_returnsTrue() {
}
@Test
- public void addaddChangeListener_notifiesOnRefresh() throws IOException {
+ public void addChangeListener_notifiesOnRefresh() throws IOException {
final String accessToken1 = "1/MkSJoj1xsli0AccessToken_NKPY2";
final String accessToken2 = "2/MkSJoj1xsli0AccessToken_NKPY2";
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(CLIENT_ID, CLIENT_SECRET);
- transport.addRefreshToken(REFRESH_TOKEN, accessToken1);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET);
+ transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken1);
OAuth2Credentials userCredentials = new UserCredentials(
- CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, transport, null);
+ CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, transportFactory, null);
// Use a fixed clock so tokens don't expire
userCredentials.clock = new TestClock();
TestChangeListener listener = new TestChangeListener();
@@ -110,7 +116,7 @@ public void addaddChangeListener_notifiesOnRefresh() throws IOException {
assertEquals(1, listener.callCount);
// Change server to a different token and refresh
- transport.addRefreshToken(REFRESH_TOKEN, accessToken2);
+ transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken2);
// Refresh to force getting next token
userCredentials.refresh();
@@ -124,26 +130,26 @@ public void addaddChangeListener_notifiesOnRefresh() throws IOException {
public void getRequestMetadata_blocking_cachesExpiringToken() throws IOException {
final String accessToken1 = "1/MkSJoj1xsli0AccessToken_NKPY2";
final String accessToken2 = "2/MkSJoj1xsli0AccessToken_NKPY2";
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(CLIENT_ID, CLIENT_SECRET);
- transport.addRefreshToken(REFRESH_TOKEN, accessToken1);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET);
+ transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken1);
TestClock clock = new TestClock();
OAuth2Credentials credentials = new UserCredentials(
- CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, transport, null);
+ CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, transportFactory, null);
credentials.clock = clock;
// Verify getting the first token
- assertEquals(0, transport.buildRequestCount);
+ assertEquals(0, transportFactory.transport.buildRequestCount);
Map> metadata = credentials.getRequestMetadata(CALL_URI);
TestUtils.assertContainsBearerToken(metadata, accessToken1);
- assertEquals(1, transport.buildRequestCount--);
+ assertEquals(1, transportFactory.transport.buildRequestCount--);
// Change server to a different token
- transport.addRefreshToken(REFRESH_TOKEN, accessToken2);
+ transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken2);
// Make transport fail when used next time.
IOException error = new IOException("error");
- transport.setError(error);
+ transportFactory.transport.setError(error);
// Advance 5 minutes and verify original token
clock.addToCurrentTime(5 * 60 * 1000);
@@ -152,33 +158,33 @@ public void getRequestMetadata_blocking_cachesExpiringToken() throws IOException
// Advance 60 minutes and verify revised token
clock.addToCurrentTime(60 * 60 * 1000);
- assertEquals(0, transport.buildRequestCount);
+ assertEquals(0, transportFactory.transport.buildRequestCount);
try {
credentials.getRequestMetadata(CALL_URI);
fail("Should throw");
} catch (IOException e) {
assertSame(error, e);
- assertEquals(1, transport.buildRequestCount--);
+ assertEquals(1, transportFactory.transport.buildRequestCount--);
}
// Reset the error and try again
- transport.setError(null);
+ transportFactory.transport.setError(null);
metadata = credentials.getRequestMetadata(CALL_URI);
TestUtils.assertContainsBearerToken(metadata, accessToken2);
- assertEquals(1, transport.buildRequestCount--);
+ assertEquals(1, transportFactory.transport.buildRequestCount--);
}
@Test
public void getRequestMetadata_async() throws IOException {
final String accessToken1 = "1/MkSJoj1xsli0AccessToken_NKPY2";
final String accessToken2 = "2/MkSJoj1xsli0AccessToken_NKPY2";
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(CLIENT_ID, CLIENT_SECRET);
- transport.addRefreshToken(REFRESH_TOKEN, accessToken1);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET);
+ transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken1);
TestClock clock = new TestClock();
OAuth2Credentials credentials = new UserCredentials(
- CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, transport, null);
+ CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, transportFactory, null);
credentials.clock = clock;
MockExecutor executor = new MockExecutor();
@@ -186,20 +192,20 @@ public void getRequestMetadata_async() throws IOException {
// Verify getting the first token, which uses the transport and calls the callback in the
// executor.
credentials.getRequestMetadata(CALL_URI, executor, callback);
- assertEquals(0, transport.buildRequestCount);
+ assertEquals(0, transportFactory.transport.buildRequestCount);
assertNull(callback.metadata);
assertEquals(1, executor.runTasksExhaustively());
assertNotNull(callback.metadata);
TestUtils.assertContainsBearerToken(callback.metadata, accessToken1);
- assertEquals(1, transport.buildRequestCount--);
+ assertEquals(1, transportFactory.transport.buildRequestCount--);
// Change server to a different token
- transport.addRefreshToken(REFRESH_TOKEN, accessToken2);
+ transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken2);
// Make transport fail when used next time.
IOException error = new IOException("error");
- transport.setError(error);
+ transportFactory.transport.setError(error);
// Advance 5 minutes and verify original token. Callback is called inline.
callback.reset();
@@ -214,53 +220,53 @@ public void getRequestMetadata_async() throws IOException {
callback.reset();
clock.addToCurrentTime(60 * 60 * 1000);
credentials.getRequestMetadata(CALL_URI, executor, callback);
- assertEquals(0, transport.buildRequestCount);
+ assertEquals(0, transportFactory.transport.buildRequestCount);
assertNull(callback.exception);
assertEquals(1, executor.runTasksExhaustively());
assertSame(error, callback.exception);
- assertEquals(1, transport.buildRequestCount--);
+ assertEquals(1, transportFactory.transport.buildRequestCount--);
// Reset the error and try again
- transport.setError(null);
+ transportFactory.transport.setError(null);
callback.reset();
credentials.getRequestMetadata(CALL_URI, executor, callback);
- assertEquals(0, transport.buildRequestCount);
+ assertEquals(0, transportFactory.transport.buildRequestCount);
assertNull(callback.metadata);
assertEquals(1, executor.runTasksExhaustively());
assertNotNull(callback.metadata);
TestUtils.assertContainsBearerToken(callback.metadata, accessToken2);
- assertEquals(1, transport.buildRequestCount--);
+ assertEquals(1, transportFactory.transport.buildRequestCount--);
}
@Test
public void getRequestMetadata_async_refreshRace() throws IOException {
final String accessToken1 = "1/MkSJoj1xsli0AccessToken_NKPY2";
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(CLIENT_ID, CLIENT_SECRET);
- transport.addRefreshToken(REFRESH_TOKEN, accessToken1);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET);
+ transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken1);
TestClock clock = new TestClock();
OAuth2Credentials credentials = new UserCredentials(
- CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, transport, null);
+ CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, transportFactory, null);
credentials.clock = clock;
MockExecutor executor = new MockExecutor();
MockRequestMetadataCallback callback = new MockRequestMetadataCallback();
// Getting the first token, which uses the transport and calls the callback in the executor.
credentials.getRequestMetadata(CALL_URI, executor, callback);
- assertEquals(0, transport.buildRequestCount);
+ assertEquals(0, transportFactory.transport.buildRequestCount);
assertNull(callback.metadata);
// Asynchronous task is scheduled, but beaten by another blocking get call.
assertEquals(1, executor.numTasks());
Map> metadata = credentials.getRequestMetadata(CALL_URI);
- assertEquals(1, transport.buildRequestCount--);
+ assertEquals(1, transportFactory.transport.buildRequestCount--);
TestUtils.assertContainsBearerToken(metadata, accessToken1);
// When the task is run, the cached data is used.
assertEquals(1, executor.runTasksExhaustively());
- assertEquals(0, transport.buildRequestCount);
+ assertEquals(0, transportFactory.transport.buildRequestCount);
assertSame(metadata, callback.metadata);
}
@@ -277,31 +283,31 @@ public void getRequestMetadata_temporaryToken_hasToken() throws IOException {
public void refresh_refreshesToken() throws IOException {
final String accessToken1 = "1/MkSJoj1xsli0AccessToken_NKPY2";
final String accessToken2 = "2/MkSJoj1xsli0AccessToken_NKPY2";
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(CLIENT_ID, CLIENT_SECRET);
- transport.addRefreshToken(REFRESH_TOKEN, accessToken1);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET);
+ transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken1);
OAuth2Credentials userCredentials = new UserCredentials(
- CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, transport, null);
+ CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, transportFactory, null);
// Use a fixed clock so tokens don't exire
userCredentials.clock = new TestClock();
// Get a first token
Map> metadata = userCredentials.getRequestMetadata(CALL_URI);
TestUtils.assertContainsBearerToken(metadata, accessToken1);
- assertEquals(1, transport.buildRequestCount--);
+ assertEquals(1, transportFactory.transport.buildRequestCount--);
// Change server to a different token
- transport.addRefreshToken(REFRESH_TOKEN, accessToken2);
+ transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken2);
// Confirm token being cached
TestUtils.assertContainsBearerToken(metadata, accessToken1);
- assertEquals(0, transport.buildRequestCount);
+ assertEquals(0, transportFactory.transport.buildRequestCount);
// Refresh to force getting next token
userCredentials.refresh();
metadata = userCredentials.getRequestMetadata(CALL_URI);
TestUtils.assertContainsBearerToken(metadata, accessToken2);
- assertEquals(1, transport.buildRequestCount--);
+ assertEquals(1, transportFactory.transport.buildRequestCount--);
}
@Test(expected = IllegalStateException.class)
@@ -310,6 +316,56 @@ public void refresh_temporaryToken_throws() throws IOException {
credentials.refresh();
}
+ @Test
+ public void equals_true() throws IOException {
+ final String accessToken1 = "1/MkSJoj1xsli0AccessToken_NKPY2";
+ OAuth2Credentials credentials = new OAuth2Credentials(new AccessToken(accessToken1, null));
+ OAuth2Credentials otherCredentials = new OAuth2Credentials(new AccessToken(accessToken1, null));
+ assertTrue(credentials.equals(otherCredentials));
+ assertTrue(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_accessToken() throws IOException {
+ final String accessToken1 = "1/MkSJoj1xsli0AccessToken_NKPY2";
+ final String accessToken2 = "2/MkSJoj1xsli0AccessToken_NKPY2";
+ OAuth2Credentials credentials = new OAuth2Credentials(new AccessToken(accessToken1, null));
+ OAuth2Credentials otherCredentials = new OAuth2Credentials(new AccessToken(accessToken2, null));
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void toString_containsFields() throws IOException {
+ AccessToken accessToken = new AccessToken("1/MkSJoj1xsli0AccessToken_NKPY2", null);
+ OAuth2Credentials credentials = new OAuth2Credentials(accessToken);
+ String expectedToString =
+ String.format("OAuth2Credentials{requestMetadata=%s, temporaryAccess=%s}",
+ ImmutableMap.of(AuthHttpConstants.AUTHORIZATION,
+ ImmutableList.of(OAuth2Utils.BEARER_PREFIX + accessToken.getTokenValue())),
+ accessToken.toString());
+ assertEquals(expectedToString, credentials.toString());
+ }
+
+ @Test
+ public void hashCode_equals() throws IOException {
+ final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2";
+ OAuth2Credentials credentials = new OAuth2Credentials(new AccessToken(accessToken, null));
+ OAuth2Credentials otherCredentials = new OAuth2Credentials(new AccessToken(accessToken, null));
+ assertEquals(credentials.hashCode(), otherCredentials.hashCode());
+ }
+
+ @Test
+ public void serialize() throws IOException, ClassNotFoundException {
+ final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2";
+ OAuth2Credentials credentials = new OAuth2Credentials(new AccessToken(accessToken, null));
+ OAuth2Credentials deserializedCredentials = serializeAndDeserialize(credentials);
+ assertEquals(credentials, deserializedCredentials);
+ assertEquals(credentials.hashCode(), deserializedCredentials.hashCode());
+ assertEquals(credentials.toString(), deserializedCredentials.toString());
+ assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ }
+
private static class TestChangeListener implements OAuth2Credentials.CredentialsChangedListener {
public AccessToken accessToken = null;
diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java
index 5be555b38..05333a44b 100644
--- a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java
+++ b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java
@@ -35,18 +35,23 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.google.api.client.json.GenericJson;
+import com.google.api.client.util.Clock;
import com.google.auth.TestUtils;
+import com.google.auth.oauth2.GoogleCredentialsTest.MockHttpTransportFactory;
+import com.google.auth.oauth2.GoogleCredentialsTest.MockTokenServerTransportFactory;
+import com.google.common.collect.ImmutableSet;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.net.URI;
import java.security.PrivateKey;
import java.util.Arrays;
@@ -59,7 +64,7 @@
* Test case for {@link ServiceAccountCredentials}.
*/
@RunWith(JUnit4.class)
-public class ServiceAccountCredentialsTest {
+public class ServiceAccountCredentialsTest extends BaseSerializationTest {
private final static String SA_CLIENT_EMAIL =
"36680232662-vrd7ji19qe3nelgchd0ah2csanun6bnr@developer.gserviceaccount.com";
@@ -81,7 +86,7 @@ public class ServiceAccountCredentialsTest {
+ "==\n-----END PRIVATE KEY-----\n";
private static final String ACCESS_TOKEN = "1/MkSJoj1xsli0AccessToken_NKPY2";
private final static Collection SCOPES = Collections.singletonList("dummy.scope");
- private final static Collection EMPTY_SCOPES = Collections.emptyList();
+ private final static Collection EMPTY_SCOPES = Collections.emptyList();
private static final URI CALL_URI = URI.create("http://googleapis.com/testapi/v1/foo");
@Test
@@ -103,15 +108,16 @@ public void createdScoped_clones() throws IOException {
@Test
public void createdScoped_enablesAccessTokens() throws IOException {
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addServiceAccount(SA_CLIENT_EMAIL, ACCESS_TOKEN);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addServiceAccount(SA_CLIENT_EMAIL, ACCESS_TOKEN);
GoogleCredentials credentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
- SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, null, transport, null);
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, null, transportFactory, null);
try {
credentials.getRequestMetadata(CALL_URI);
fail("Should not be able to get token without scopes");
} catch (Exception expected) {
+ // Expected
}
GoogleCredentials scopedCredentials = credentials.createScoped(SCOPES);
@@ -138,12 +144,12 @@ public void createScopedRequired_nonEmptyScopes_false() throws IOException {
@Test
public void fromJSON_hasAccessToken() throws IOException {
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addServiceAccount(SA_CLIENT_EMAIL, ACCESS_TOKEN);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addServiceAccount(SA_CLIENT_EMAIL, ACCESS_TOKEN);
GenericJson json = writeServiceAccountJson(
SA_CLIENT_ID, SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID);
- GoogleCredentials credentials = ServiceAccountCredentials.fromJson(json, transport);
+ GoogleCredentials credentials = ServiceAccountCredentials.fromJson(json, transportFactory);
credentials = credentials.createScoped(SCOPES);
Map> metadata = credentials.getRequestMetadata(CALL_URI);
@@ -152,10 +158,10 @@ public void fromJSON_hasAccessToken() throws IOException {
@Test
public void getRequestMetadata_hasAccessToken() throws IOException {
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addServiceAccount(SA_CLIENT_EMAIL, ACCESS_TOKEN);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addServiceAccount(SA_CLIENT_EMAIL, ACCESS_TOKEN);
OAuth2Credentials credentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
- SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, transport, null);
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, transportFactory, null);
Map> metadata = credentials.getRequestMetadata(CALL_URI);
@@ -165,11 +171,12 @@ public void getRequestMetadata_hasAccessToken() throws IOException {
@Test
public void getRequestMetadata_customTokenServer_hasAccessToken() throws IOException {
final URI TOKEN_SERVER = URI.create("https://foo.com/bar");
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addServiceAccount(SA_CLIENT_EMAIL, ACCESS_TOKEN);
- transport.setTokenServerUri(TOKEN_SERVER);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addServiceAccount(SA_CLIENT_EMAIL, ACCESS_TOKEN);
+ transportFactory.transport.setTokenServerUri(TOKEN_SERVER);
OAuth2Credentials credentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
- SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, transport, TOKEN_SERVER);
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, transportFactory,
+ TOKEN_SERVER);
Map> metadata = credentials.getRequestMetadata(CALL_URI);
@@ -187,6 +194,152 @@ public void getScopes_nullReturnsEmpty() throws IOException {
assertTrue(scopes.isEmpty());
}
+ @Test
+ public void equals_true() throws IOException {
+ final URI tokenServer = URI.create("https://foo.com/bar");
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ OAuth2Credentials credentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, transportFactory,
+ tokenServer);
+ OAuth2Credentials otherCredentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, transportFactory,
+ tokenServer);
+ assertTrue(credentials.equals(otherCredentials));
+ assertTrue(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_clientId() throws IOException {
+ final URI tokenServer1 = URI.create("https://foo1.com/bar");
+ MockTokenServerTransportFactory serverTransportFactory = new MockTokenServerTransportFactory();
+ OAuth2Credentials credentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, serverTransportFactory,
+ tokenServer1);
+ OAuth2Credentials otherCredentials = ServiceAccountCredentials.fromPkcs8("otherClientId",
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, serverTransportFactory,
+ tokenServer1);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_email() throws IOException {
+ final URI tokenServer1 = URI.create("https://foo1.com/bar");
+ MockTokenServerTransportFactory serverTransportFactory = new MockTokenServerTransportFactory();
+ OAuth2Credentials credentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, serverTransportFactory,
+ tokenServer1);
+ OAuth2Credentials otherCredentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
+ "otherEmail", SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, serverTransportFactory,
+ tokenServer1);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_keyId() throws IOException {
+ final URI tokenServer1 = URI.create("https://foo1.com/bar");
+ MockTokenServerTransportFactory serverTransportFactory = new MockTokenServerTransportFactory();
+ OAuth2Credentials credentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, serverTransportFactory,
+ tokenServer1);
+ OAuth2Credentials otherCredentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, "otherId", SCOPES, serverTransportFactory,
+ tokenServer1);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_scopes() throws IOException {
+ final URI tokenServer1 = URI.create("https://foo1.com/bar");
+ MockTokenServerTransportFactory serverTransportFactory = new MockTokenServerTransportFactory();
+ OAuth2Credentials credentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, serverTransportFactory,
+ tokenServer1);
+ OAuth2Credentials otherCredentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, ImmutableSet.of(),
+ serverTransportFactory, tokenServer1);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_transportFactory() throws IOException {
+ final URI tokenServer1 = URI.create("https://foo1.com/bar");
+ MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory();
+ MockTokenServerTransportFactory serverTransportFactory = new MockTokenServerTransportFactory();
+ OAuth2Credentials credentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, serverTransportFactory,
+ tokenServer1);
+ OAuth2Credentials otherCredentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, httpTransportFactory,
+ tokenServer1);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_tokenServer() throws IOException {
+ final URI tokenServer1 = URI.create("https://foo1.com/bar");
+ final URI tokenServer2 = URI.create("https://foo2.com/bar");
+ MockTokenServerTransportFactory serverTransportFactory = new MockTokenServerTransportFactory();
+ OAuth2Credentials credentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, serverTransportFactory,
+ tokenServer1);
+ OAuth2Credentials otherCredentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, serverTransportFactory,
+ tokenServer2);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void toString_containsFields() throws IOException {
+ final URI tokenServer = URI.create("https://foo.com/bar");
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ OAuth2Credentials credentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, transportFactory,
+ tokenServer);
+ String expectedToString = String.format(
+ "ServiceAccountCredentials{clientId=%s, clientEmail=%s, privateKeyId=%s, "
+ + "transportFactoryClassName=%s, tokenServerUri=%s, scopes=%s}",
+ SA_CLIENT_ID,
+ SA_CLIENT_EMAIL,
+ SA_PRIVATE_KEY_ID,
+ MockTokenServerTransportFactory.class.getName(),
+ tokenServer,
+ SCOPES);
+ assertEquals(expectedToString, credentials.toString());
+ }
+
+ @Test
+ public void hashCode_equals() throws IOException {
+ final URI tokenServer = URI.create("https://foo.com/bar");
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ OAuth2Credentials credentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, transportFactory,
+ tokenServer);
+ OAuth2Credentials otherCredentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, transportFactory,
+ tokenServer);
+ assertEquals(credentials.hashCode(), otherCredentials.hashCode());
+ }
+
+ @Test
+ public void serialize() throws IOException, ClassNotFoundException {
+ final URI tokenServer = URI.create("https://foo.com/bar");
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ ServiceAccountCredentials credentials = ServiceAccountCredentials.fromPkcs8(SA_CLIENT_ID,
+ SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID, SCOPES, transportFactory,
+ tokenServer);
+ ServiceAccountCredentials deserializedCredentials = serializeAndDeserialize(credentials);
+ assertEquals(credentials, deserializedCredentials);
+ assertEquals(credentials.hashCode(), deserializedCredentials.hashCode());
+ assertEquals(credentials.toString(), deserializedCredentials.toString());
+ assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ }
+
static GenericJson writeServiceAccountJson(
String clientId, String clientEmail, String privateKeyPkcs8, String privateKeyId) {
GenericJson json = new GenericJson();
@@ -210,7 +363,6 @@ static InputStream writeServiceAccountAccountStream(String clientId, String clie
String privateKeyPkcs8, String privateKeyId) throws IOException {
GenericJson json =
writeServiceAccountJson(clientId, clientEmail, privateKeyPkcs8, privateKeyId);
- InputStream stream = TestUtils.jsonToInputStream(json);
- return stream;
+ return TestUtils.jsonToInputStream(json);
}
}
diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java
index 30859dd08..4caaa8c35 100644
--- a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java
+++ b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java
@@ -32,14 +32,17 @@
package com.google.auth.oauth2;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.json.webtoken.JsonWebSignature;
+import com.google.api.client.util.Clock;
import com.google.auth.Credentials;
import com.google.auth.http.AuthHttpConstants;
@@ -57,7 +60,7 @@
* Test case for {@link ServiceAccountCredentials}.
*/
@RunWith(JUnit4.class)
-public class ServiceAccountJwtAccessCredentialsTest {
+public class ServiceAccountJwtAccessCredentialsTest extends BaseSerializationTest {
private final static String SA_CLIENT_EMAIL =
"36680232662-vrd7ji19qe3nelgchd0ah2csanun6bnr@developer.gserviceaccount.com";
@@ -113,6 +116,7 @@ public void constructor_noEmail_throws() throws IOException {
new ServiceAccountJwtAccessCredentials(SA_CLIENT_ID, null, privateKey, SA_PRIVATE_KEY_ID);
fail("exception expected");
} catch (NullPointerException e) {
+ // Expected
}
}
@@ -123,6 +127,7 @@ public void constructor_noPrivateKey_throws() {
SA_CLIENT_ID, SA_CLIENT_EMAIL, null , SA_PRIVATE_KEY_ID);
fail("exception expected");
} catch (NullPointerException e) {
+ // Expected
}
}
@@ -179,6 +184,7 @@ public void getRequestMetadata_blocking_noURI_throws() throws IOException {
credentials.getRequestMetadata();
fail("exception expected");
} catch (IOException e) {
+ // Expected
}
}
@@ -223,6 +229,100 @@ public void getRequestMetadata_async_noURI_exception() throws IOException {
assertNotNull(callback.exception);
}
+ @Test
+ public void equals_true() throws IOException {
+ PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8);
+ ServiceAccountJwtAccessCredentials credentials = new ServiceAccountJwtAccessCredentials(
+ SA_CLIENT_ID, SA_CLIENT_EMAIL, privateKey, SA_PRIVATE_KEY_ID, CALL_URI);
+ ServiceAccountJwtAccessCredentials otherCredentials = new ServiceAccountJwtAccessCredentials(
+ SA_CLIENT_ID, SA_CLIENT_EMAIL, privateKey, SA_PRIVATE_KEY_ID, CALL_URI);
+ assertTrue(credentials.equals(otherCredentials));
+ assertTrue(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_clientId() throws IOException {
+ PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8);
+ ServiceAccountJwtAccessCredentials credentials = new ServiceAccountJwtAccessCredentials(
+ SA_CLIENT_ID, SA_CLIENT_EMAIL, privateKey, SA_PRIVATE_KEY_ID, CALL_URI);
+ ServiceAccountJwtAccessCredentials otherCredentials = new ServiceAccountJwtAccessCredentials(
+ "otherClientId", SA_CLIENT_EMAIL, privateKey, SA_PRIVATE_KEY_ID, CALL_URI);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_email() throws IOException {
+ PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8);
+ ServiceAccountJwtAccessCredentials credentials = new ServiceAccountJwtAccessCredentials(
+ SA_CLIENT_ID, SA_CLIENT_EMAIL, privateKey, SA_PRIVATE_KEY_ID, CALL_URI);
+ ServiceAccountJwtAccessCredentials otherCredentials = new ServiceAccountJwtAccessCredentials(
+ SA_CLIENT_ID, "otherClientEmail", privateKey, SA_PRIVATE_KEY_ID, CALL_URI);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_keyId() throws IOException {
+ PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8);
+ ServiceAccountJwtAccessCredentials credentials = new ServiceAccountJwtAccessCredentials(
+ SA_CLIENT_ID, SA_CLIENT_EMAIL, privateKey, SA_PRIVATE_KEY_ID, CALL_URI);
+ ServiceAccountJwtAccessCredentials otherCredentials = new ServiceAccountJwtAccessCredentials(
+ SA_CLIENT_ID, SA_CLIENT_EMAIL, privateKey, "otherKeyId", CALL_URI);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_callUri() throws IOException {
+ PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8);
+ final URI otherCallUri = URI.create("https://foo.com/bar");
+ ServiceAccountJwtAccessCredentials credentials = new ServiceAccountJwtAccessCredentials(
+ SA_CLIENT_ID, SA_CLIENT_EMAIL, privateKey, SA_PRIVATE_KEY_ID, CALL_URI);
+ ServiceAccountJwtAccessCredentials otherCredentials = new ServiceAccountJwtAccessCredentials(
+ SA_CLIENT_ID, SA_CLIENT_EMAIL, privateKey, SA_PRIVATE_KEY_ID, otherCallUri);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void toString_containsFields() throws IOException {
+ PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8);
+ ServiceAccountJwtAccessCredentials credentials = new ServiceAccountJwtAccessCredentials(
+ SA_CLIENT_ID, SA_CLIENT_EMAIL, privateKey, SA_PRIVATE_KEY_ID, CALL_URI);
+ String expectedToString = String.format(
+ "ServiceAccountJwtAccessCredentials{clientId=%s, clientEmail=%s, privateKeyId=%s, "
+ + "defaultAudience=%s}",
+ SA_CLIENT_ID,
+ SA_CLIENT_EMAIL,
+ SA_PRIVATE_KEY_ID,
+ CALL_URI);
+ assertEquals(expectedToString, credentials.toString());
+ }
+
+ @Test
+ public void hashCode_equals() throws IOException {
+ PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8);
+ ServiceAccountJwtAccessCredentials credentials = new ServiceAccountJwtAccessCredentials(
+ SA_CLIENT_ID, SA_CLIENT_EMAIL, privateKey, SA_PRIVATE_KEY_ID, CALL_URI);
+ ServiceAccountJwtAccessCredentials otherCredentials = new ServiceAccountJwtAccessCredentials(
+ SA_CLIENT_ID, SA_CLIENT_EMAIL, privateKey, SA_PRIVATE_KEY_ID, CALL_URI);
+ assertEquals(credentials.hashCode(), otherCredentials.hashCode());
+ }
+
+ @Test
+ public void serialize() throws IOException, ClassNotFoundException {
+ PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8);
+ ServiceAccountJwtAccessCredentials credentials = new ServiceAccountJwtAccessCredentials(
+ SA_CLIENT_ID, SA_CLIENT_EMAIL, privateKey, SA_PRIVATE_KEY_ID, CALL_URI);
+ ServiceAccountJwtAccessCredentials deserializedCredentials =
+ serializeAndDeserialize(credentials);
+ assertEquals(credentials, deserializedCredentials);
+ assertEquals(credentials.hashCode(), deserializedCredentials.hashCode());
+ assertEquals(credentials.toString(), deserializedCredentials.toString());
+ assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ }
+
private void verifyJwtAccess(Map> metadata, String expectedEmail,
URI expectedAudience, String expectedKeyId) throws IOException {
assertNotNull(metadata);
diff --git a/oauth2_http/javatests/com/google/auth/oauth2/UserAuthorizerTest.java b/oauth2_http/javatests/com/google/auth/oauth2/UserAuthorizerTest.java
index 9b9ecd0c3..36ed90899 100644
--- a/oauth2_http/javatests/com/google/auth/oauth2/UserAuthorizerTest.java
+++ b/oauth2_http/javatests/com/google/auth/oauth2/UserAuthorizerTest.java
@@ -38,6 +38,7 @@
import static org.junit.Assert.fail;
import com.google.auth.TestUtils;
+import com.google.auth.oauth2.GoogleCredentialsTest.MockTokenServerTransportFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -61,7 +62,7 @@ public class UserAuthorizerTest {
private static final String CLIENT_SECRET = "jakuaL9YyieakhECKL2SwZcu";
private static final String REFRESH_TOKEN = "1/Tl6awhpFjkMkSJoj1xsli0H2eL5YsMgU_NKPY2TyGWY";
private static final String ACCESS_TOKEN_VALUE = "1/MkSJoj1xsli0AccessToken_NKPY2";
- private static final Long EXPIRATION_TIME = Long.valueOf(504000300);
+ private static final Long EXPIRATION_TIME = 504000300L;
private static final AccessToken ACCESS_TOKEN =
new AccessToken(ACCESS_TOKEN_VALUE, new Date(EXPIRATION_TIME));
private static final ClientId CLIENT_ID = new ClientId(CLIENT_ID_VALUE, CLIENT_SECRET);
@@ -189,14 +190,14 @@ public void getCredentials_refreshedToken_stored() throws IOException {
final String accessTokenValue2 = "2/MkSJoj1xsli0AccessToken_NKPY2";
AccessToken acessToken1 =
new AccessToken(accessTokenValue1, new Date(EXPIRATION_TIME));
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET);
- transport.addRefreshToken(REFRESH_TOKEN, accessTokenValue2);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET);
+ transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessTokenValue2);
TestTokenStore tokenStore = new TestTokenStore();
UserAuthorizer authorizer =
- new UserAuthorizer(CLIENT_ID, SCOPES, tokenStore, null, transport, null, null);
+ new UserAuthorizer(CLIENT_ID, SCOPES, tokenStore, null, transportFactory, null, null);
UserCredentials originalCredentials = new UserCredentials(
- CLIENT_ID_VALUE, CLIENT_SECRET, REFRESH_TOKEN, acessToken1, transport, null);
+ CLIENT_ID_VALUE, CLIENT_SECRET, REFRESH_TOKEN, acessToken1, transportFactory, null);
authorizer.storeCredentials(USER_ID, originalCredentials);
UserCredentials credentials1 = authorizer.getCredentials(USER_ID);
@@ -219,12 +220,12 @@ public void getCredentials_refreshedToken_stored() throws IOException {
@Test
public void getCredentialsFromCode_conevertsCodeToTokens() throws IOException {
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET);
- transport.addAuthorizationCode(CODE, REFRESH_TOKEN, ACCESS_TOKEN_VALUE);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET);
+ transportFactory.transport.addAuthorizationCode(CODE, REFRESH_TOKEN, ACCESS_TOKEN_VALUE);
TestTokenStore tokenStore = new TestTokenStore();
UserAuthorizer authorizer =
- new UserAuthorizer(CLIENT_ID, SCOPES, tokenStore, null, transport, null, null);
+ new UserAuthorizer(CLIENT_ID, SCOPES, tokenStore, null, transportFactory, null, null);
UserCredentials credentials = authorizer.getCredentialsFromCode(CODE, BASE_URI);
@@ -244,12 +245,12 @@ public void getCredentialsFromCode_nullCode_throws() throws IOException {
public void getAndStoreCredentialsFromCode_getAndStoresCredentials() throws IOException {
final String accessTokenValue1 = "1/MkSJoj1xsli0AccessToken_NKPY2";
final String accessTokenValue2 = "2/MkSJoj1xsli0AccessToken_NKPY2";
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET);
- transport.addAuthorizationCode(CODE, REFRESH_TOKEN, accessTokenValue1);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET);
+ transportFactory.transport.addAuthorizationCode(CODE, REFRESH_TOKEN, accessTokenValue1);
TestTokenStore tokenStore = new TestTokenStore();
UserAuthorizer authorizer =
- new UserAuthorizer(CLIENT_ID, SCOPES, tokenStore, null, transport, null, null);
+ new UserAuthorizer(CLIENT_ID, SCOPES, tokenStore, null, transportFactory, null, null);
UserCredentials credentials1 =
authorizer.getAndStoreCredentialsFromCode(USER_ID, CODE, BASE_URI);
@@ -258,7 +259,7 @@ public void getAndStoreCredentialsFromCode_getAndStoresCredentials() throws IOEx
assertEquals(accessTokenValue1, credentials1.getAccessToken().getTokenValue());
// Refresh the token to get update from token server
- transport.addRefreshToken(REFRESH_TOKEN, accessTokenValue2);
+ transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessTokenValue2);
credentials1.refresh();
assertEquals(REFRESH_TOKEN, credentials1.getRefreshToken());
assertEquals(accessTokenValue2, credentials1.getAccessToken().getTokenValue());
@@ -290,13 +291,13 @@ public void getAndStoreCredentialsFromCode_nullUserId_throws() throws IOExceptio
@Test
public void revokeAuthorization_revokesAndClears() throws IOException {
TestTokenStore tokenStore = new TestTokenStore();
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET);
- transport.addRefreshToken(REFRESH_TOKEN, ACCESS_TOKEN_VALUE);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET);
+ transportFactory.transport.addRefreshToken(REFRESH_TOKEN, ACCESS_TOKEN_VALUE);
UserCredentials initialCredentials =
new UserCredentials(CLIENT_ID_VALUE, CLIENT_SECRET, REFRESH_TOKEN, ACCESS_TOKEN);
UserAuthorizer authorizer =
- new UserAuthorizer(CLIENT_ID, SCOPES, tokenStore, null, transport, null, null);
+ new UserAuthorizer(CLIENT_ID, SCOPES, tokenStore, null, transportFactory, null, null);
authorizer.storeCredentials(USER_ID, initialCredentials);
UserCredentials credentials1 = authorizer.getCredentials(USER_ID);
@@ -311,6 +312,7 @@ public void revokeAuthorization_revokesAndClears() throws IOException {
credentials1.refresh();
fail("Credentials should not refresh after revoke.");
} catch (IOException expected) {
+ // Expected
}
UserCredentials credentials2 = authorizer.getCredentials(USER_ID);
assertNull(credentials2);
@@ -318,7 +320,7 @@ public void revokeAuthorization_revokesAndClears() throws IOException {
private static class TestTokenStore implements TokenStore {
- private final Map map = new HashMap();
+ private final Map map = new HashMap<>();
@Override
public String load(String id) throws IOException {
diff --git a/oauth2_http/javatests/com/google/auth/oauth2/UserCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/UserCredentialsTest.java
index 28e6d4236..807b4704b 100644
--- a/oauth2_http/javatests/com/google/auth/oauth2/UserCredentialsTest.java
+++ b/oauth2_http/javatests/com/google/auth/oauth2/UserCredentialsTest.java
@@ -34,17 +34,24 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.google.api.client.json.GenericJson;
+import com.google.api.client.util.Clock;
import com.google.auth.TestUtils;
+import com.google.auth.http.AuthHttpConstants;
+import com.google.auth.oauth2.GoogleCredentialsTest.MockHttpTransportFactory;
+import com.google.auth.oauth2.GoogleCredentialsTest.MockTokenServerTransportFactory;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.net.URI;
import java.util.Collection;
import java.util.Collections;
@@ -55,7 +62,7 @@
* Test case for {@link UserCredentials}.
*/
@RunWith(JUnit4.class)
-public class UserCredentialsTest {
+public class UserCredentialsTest extends BaseSerializationTest {
private static final String CLIENT_SECRET = "jakuaL9YyieakhECKL2SwZcu";
private static final String CLIENT_ID = "ya29.1.AADtN_UtlxN3PuGAxrN2XQnZTVRvDyVWnYq4I6dws";
@@ -90,12 +97,12 @@ public void createScopedRequired_false() {
@Test
public void fromJson_hasAccessToken() throws IOException {
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(CLIENT_ID, CLIENT_SECRET);
- transport.addRefreshToken(REFRESH_TOKEN, ACCESS_TOKEN);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET);
+ transportFactory.transport.addRefreshToken(REFRESH_TOKEN, ACCESS_TOKEN);
GenericJson json = writeUserJson(CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN);
- GoogleCredentials credentials = UserCredentials.fromJson(json, transport);
+ GoogleCredentials credentials = UserCredentials.fromJson(json, transportFactory);
Map> metadata = credentials.getRequestMetadata(CALL_URI);
TestUtils.assertContainsBearerToken(metadata, ACCESS_TOKEN);
@@ -103,11 +110,11 @@ public void fromJson_hasAccessToken() throws IOException {
@Test
public void getRequestMetadata_initialToken_hasAccessToken() throws IOException {
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(CLIENT_ID, CLIENT_SECRET);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET);
AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
OAuth2Credentials userCredentials = new UserCredentials(
- CLIENT_ID, CLIENT_SECRET, null, accessToken, transport, null);
+ CLIENT_ID, CLIENT_SECRET, null, accessToken, transportFactory, null);
Map> metadata = userCredentials.getRequestMetadata(CALL_URI);
@@ -116,26 +123,27 @@ public void getRequestMetadata_initialToken_hasAccessToken() throws IOException
@Test
public void getRequestMetadata_initialTokenRefreshed_throws() throws IOException {
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(CLIENT_ID, CLIENT_SECRET);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET);
AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
OAuth2Credentials userCredentials = new UserCredentials(
- CLIENT_ID, CLIENT_SECRET, null, accessToken, transport, null);
+ CLIENT_ID, CLIENT_SECRET, null, accessToken, transportFactory, null);
try {
userCredentials.refresh();
fail("Should not be able to refresh without refresh token.");
} catch (IllegalStateException expected) {
+ // Expected
}
}
@Test
public void getRequestMetadata_fromRefreshToken_hasAccessToken() throws IOException {
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(CLIENT_ID, CLIENT_SECRET);
- transport.addRefreshToken(REFRESH_TOKEN, ACCESS_TOKEN);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET);
+ transportFactory.transport.addRefreshToken(REFRESH_TOKEN, ACCESS_TOKEN);
OAuth2Credentials userCredentials = new UserCredentials(
- CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, transport, null);
+ CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, transportFactory, null);
Map> metadata = userCredentials.getRequestMetadata(CALL_URI);
@@ -145,18 +153,158 @@ public void getRequestMetadata_fromRefreshToken_hasAccessToken() throws IOExcept
@Test
public void getRequestMetadata_customTokenServer_hasAccessToken() throws IOException {
final URI TOKEN_SERVER = URI.create("https://foo.com/bar");
- MockTokenServerTransport transport = new MockTokenServerTransport();
- transport.addClient(CLIENT_ID, CLIENT_SECRET);
- transport.addRefreshToken(REFRESH_TOKEN, ACCESS_TOKEN);
- transport.setTokenServerUri(TOKEN_SERVER);
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET);
+ transportFactory.transport.addRefreshToken(REFRESH_TOKEN, ACCESS_TOKEN);
+ transportFactory.transport.setTokenServerUri(TOKEN_SERVER);
OAuth2Credentials userCredentials = new UserCredentials(
- CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, transport, TOKEN_SERVER);
+ CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, null, transportFactory, TOKEN_SERVER);
Map> metadata = userCredentials.getRequestMetadata(CALL_URI);
TestUtils.assertContainsBearerToken(metadata, ACCESS_TOKEN);
}
+ @Test
+ public void equals_true() throws IOException {
+ final URI tokenServer = URI.create("https://foo.com/bar");
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
+ OAuth2Credentials credentials = new UserCredentials(
+ CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, accessToken, transportFactory, tokenServer);
+ OAuth2Credentials otherCredentials = new UserCredentials(
+ CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, accessToken, transportFactory, tokenServer);
+ assertTrue(credentials.equals(otherCredentials));
+ assertTrue(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_clientId() throws IOException {
+ final URI tokenServer1 = URI.create("https://foo1.com/bar");
+ AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
+ MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory();
+ OAuth2Credentials credentials = new UserCredentials(CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN,
+ accessToken, httpTransportFactory, tokenServer1);
+ OAuth2Credentials otherCredentials = new UserCredentials("otherClientId", CLIENT_SECRET,
+ REFRESH_TOKEN, accessToken, httpTransportFactory, tokenServer1);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_clientSecret() throws IOException {
+ final URI tokenServer1 = URI.create("https://foo1.com/bar");
+ AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
+ MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory();
+ OAuth2Credentials credentials = new UserCredentials(CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN,
+ accessToken, httpTransportFactory, tokenServer1);
+ OAuth2Credentials otherCredentials = new UserCredentials(CLIENT_ID, "otherClientSecret",
+ REFRESH_TOKEN, accessToken, httpTransportFactory, tokenServer1);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_refreshToken() throws IOException {
+ final URI tokenServer1 = URI.create("https://foo1.com/bar");
+ AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
+ MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory();
+ OAuth2Credentials credentials = new UserCredentials(CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN,
+ accessToken, httpTransportFactory, tokenServer1);
+ OAuth2Credentials otherCredentials = new UserCredentials(CLIENT_ID, CLIENT_SECRET,
+ "otherRefreshToken", accessToken, httpTransportFactory, tokenServer1);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_accessToken() throws IOException {
+ final URI tokenServer1 = URI.create("https://foo1.com/bar");
+ AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
+ AccessToken otherAccessToken = new AccessToken("otherAccessToken", null);
+ MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory();
+ OAuth2Credentials credentials = new UserCredentials(CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN,
+ accessToken, httpTransportFactory, tokenServer1);
+ OAuth2Credentials otherCredentials = new UserCredentials(CLIENT_ID, CLIENT_SECRET,
+ REFRESH_TOKEN, otherAccessToken, httpTransportFactory, tokenServer1);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_transportFactory() throws IOException {
+ final URI tokenServer1 = URI.create("https://foo1.com/bar");
+ AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
+ MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory();
+ MockTokenServerTransportFactory serverTransportFactory = new MockTokenServerTransportFactory();
+ OAuth2Credentials credentials = new UserCredentials(CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN,
+ accessToken, httpTransportFactory, tokenServer1);
+ OAuth2Credentials otherCredentials = new UserCredentials(CLIENT_ID, CLIENT_SECRET,
+ REFRESH_TOKEN, accessToken, serverTransportFactory, tokenServer1);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void equals_false_tokenServer() throws IOException {
+ final URI tokenServer1 = URI.create("https://foo1.com/bar");
+ final URI tokenServer2 = URI.create("https://foo2.com/bar");
+ AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
+ MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory();
+ OAuth2Credentials credentials = new UserCredentials(CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN,
+ accessToken, httpTransportFactory, tokenServer1);
+ OAuth2Credentials otherCredentials = new UserCredentials(CLIENT_ID, CLIENT_SECRET,
+ REFRESH_TOKEN, accessToken, httpTransportFactory, tokenServer2);
+ assertFalse(credentials.equals(otherCredentials));
+ assertFalse(otherCredentials.equals(credentials));
+ }
+
+ @Test
+ public void toString_containsFields() throws IOException {
+ AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
+ final URI tokenServer = URI.create("https://foo.com/bar");
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ OAuth2Credentials credentials = new UserCredentials(CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN,
+ accessToken, transportFactory, tokenServer);
+ String expectedToString = String.format(
+ "UserCredentials{requestMetadata=%s, temporaryAccess=%s, clientId=%s, refreshToken=%s, "
+ + "tokenServerUri=%s, transportFactoryClassName=%s}",
+ ImmutableMap.of(AuthHttpConstants.AUTHORIZATION,
+ ImmutableList.of(OAuth2Utils.BEARER_PREFIX + accessToken.getTokenValue())),
+ accessToken.toString(),
+ CLIENT_ID,
+ REFRESH_TOKEN,
+ tokenServer,
+ MockTokenServerTransportFactory.class.getName());
+ assertEquals(expectedToString, credentials.toString());
+ }
+
+ @Test
+ public void hashCode_equals() throws IOException {
+ final URI tokenServer = URI.create("https://foo.com/bar");
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
+ OAuth2Credentials credentials = new UserCredentials(
+ CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, accessToken, transportFactory, tokenServer);
+ OAuth2Credentials otherCredentials = new UserCredentials(
+ CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, accessToken, transportFactory, tokenServer);
+ assertEquals(credentials.hashCode(), otherCredentials.hashCode());
+ }
+
+ @Test
+ public void serialize() throws IOException, ClassNotFoundException {
+ final URI tokenServer = URI.create("https://foo.com/bar");
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
+ UserCredentials credentials = new UserCredentials(
+ CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, accessToken, transportFactory, tokenServer);
+ UserCredentials deserializedCredentials = serializeAndDeserialize(credentials);
+ assertEquals(credentials, deserializedCredentials);
+ assertEquals(credentials.hashCode(), deserializedCredentials.hashCode());
+ assertEquals(credentials.toString(), deserializedCredentials.toString());
+ assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ }
+
static GenericJson writeUserJson(String clientId, String clientSecret, String refreshToken) {
GenericJson json = new GenericJson();
if (clientId != null) {
@@ -175,7 +323,6 @@ static GenericJson writeUserJson(String clientId, String clientSecret, String re
static InputStream writeUserStream(String clientId, String clientSecret, String refreshToken)
throws IOException {
GenericJson json = writeUserJson(clientId, clientSecret, refreshToken);
- InputStream stream = TestUtils.jsonToInputStream(json);
- return stream;
+ return TestUtils.jsonToInputStream(json);
}
}
diff --git a/oauth2_http/pom.xml b/oauth2_http/pom.xml
index a9b5d288b..51c29d0c6 100644
--- a/oauth2_http/pom.xml
+++ b/oauth2_http/pom.xml
@@ -58,7 +58,7 @@
com.google.guava
- guava-jdk5
+ guavajunit
diff --git a/pom.xml b/pom.xml
index b6ecff0bb..235c11289 100644
--- a/pom.xml
+++ b/pom.xml
@@ -47,7 +47,7 @@
1.61.19.04.8.2
- 13.0
+ 19.01.9.34
@@ -85,7 +85,7 @@
com.google.guava
- guava-jdk5
+ guava${project.guava.version}
@@ -94,6 +94,12 @@
${project.junit.version}test
+
+ com.google.auth
+ google-auth-library-oauth2-http
+ ${project.version}
+ test-jar
+
@@ -138,9 +144,31 @@
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.0.2
+
+
+
+ test-jar
+
+
+
+
+
+ maven-compiler-plugin
+ 3.5.1
+
+
+ 1.7
+ UTF-8
+ -Xlint:unchecked
+
+ org.sonatype.pluginsnexus-staging-maven-plugin