/*
* Copyright (c) 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.api.client.googleapis.auth.oauth2;
import com.google.api.client.googleapis.testing.auth.oauth2.MockTokenServerTransport;
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.jackson2.JacksonFactory;
import com.google.api.client.testing.http.MockHttpTransport;
import com.google.api.client.testing.util.SecurityTestUtils;
import junit.framework.TestCase;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
/**
* Tests {@link GoogleCredential}.
*
* @author Yaniv Inbar
*/
public class GoogleCredentialTest extends TestCase {
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
private static final Collection<String> SCOPES =
Collections.unmodifiableCollection(Arrays.asList("scope1", "scope2"));
private static final Collection<String> EMPTY_SCOPES = Collections.emptyList();
private static final String SA_KEY_TEXT = "-----BEGIN PRIVATE KEY-----\n"
+ "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALX0PQoe1igW12i"
+ "kv1bN/r9lN749y2ijmbc/mFHPyS3hNTyOCjDvBbXYbDhQJzWVUikh4mvGBA07qTj79Xc3yBDfKP2IeyYQIFe0t0"
+ "zkd7R9Zdn98Y2rIQC47aAbDfubtkU1U72t4zL11kHvoa0/RuFZjncvlr42X7be7lYh4p3NAgMBAAECgYASk5wDw"
+ "4Az2ZkmeuN6Fk/y9H+Lcb2pskJIXjrL533vrDWGOC48LrsThMQPv8cxBky8HFSEklPpkfTF95tpD43iVwJRB/Gr"
+ "CtGTw65IfJ4/tI09h6zGc4yqvIo1cHX/LQ+SxKLGyir/dQM925rGt/VojxY5ryJR7GLbCzxPnJm/oQJBANwOCO6"
+ "D2hy1LQYJhXh7O+RLtA/tSnT1xyMQsGT+uUCMiKS2bSKx2wxo9k7h3OegNJIu1q6nZ6AbxDK8H3+d0dUCQQDTrP"
+ "SXagBxzp8PecbaCHjzNRSQE2in81qYnrAFNB4o3DpHyMMY6s5ALLeHKscEWnqP8Ur6X4PvzZecCWU9BKAZAkAut"
+ "LPknAuxSCsUOvUfS1i87ex77Ot+w6POp34pEX+UWb+u5iFn2cQacDTHLV1LtE80L8jVLSbrbrlH43H0DjU5AkEA"
+ "gidhycxS86dxpEljnOMCw8CKoUBd5I880IUahEiUltk7OLJYS/Ts1wbn3kPOVX3wyJs8WBDtBkFrDHW2ezth2QJ"
+ "ADj3e1YhMVdjJW5jqwlD/VNddGjgzyunmiZg0uOXsHXbytYmsA545S8KRQFaJKFXYYFo2kOjqOiC1T2cAzMDjCQ"
+ "==\n-----END PRIVATE KEY-----\n";
private static final String SA_KEY_ID = "key_id";
public void testRefreshToken_ServiceAccounts() throws Exception {
final String serviceAccountEmail =
"36680232662-vrd7ji19q3ne0ah2csanun6bnr@developer.gserviceaccount.com";
final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2";
MockTokenServerTransport transport = new MockTokenServerTransport();
transport.addServiceAccount(serviceAccountEmail, accessToken);
GoogleCredential credential = new GoogleCredential.Builder()
.setServiceAccountId(serviceAccountEmail)
.setServiceAccountScopes(SCOPES)
.setServiceAccountPrivateKey(SecurityTestUtils.newRsaPrivateKey())
.setTransport(transport)
.setJsonFactory(JSON_FACTORY)
.build();
assertTrue(credential.refreshToken());
assertEquals(accessToken, credential.getAccessToken());
}
public void testRefreshToken_User() throws Exception {
final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2";
final String clientSecret = "jakuaL9YyieakhECKL2SwZcu";
final String clientId = "ya29.1.AADtN_UtlxN3PuGAxrN2XQnZTVRvDyVWnYq4I6dws";
final String refreshToken = "1/Tl6awhpFjkMkSJoj1xsli0H2eL5YsMgU_NKPY2TyGWY";
MockTokenServerTransport transport = new MockTokenServerTransport();
transport.addClient(clientId, clientSecret);
transport.addRefreshToken(refreshToken, accessToken);
GoogleCredential credential = new GoogleCredential.Builder()
.setClientSecrets(clientId, clientSecret)
.setTransport(transport)
.setJsonFactory(JSON_FACTORY)
.build();
credential.setRefreshToken(refreshToken);
assertTrue(credential.refreshToken());
assertEquals(accessToken, credential.getAccessToken());
}
public void testCreateScoped() throws Exception {
final String serviceAccountEmail =
"36680232662-vrd7ji19q3ne0ah2csanun6bnr@developer.gserviceaccount.com";
final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2";
MockTokenServerTransport transport = new MockTokenServerTransport();
transport.addServiceAccount(serviceAccountEmail, accessToken);
GoogleCredential credential = new GoogleCredential.Builder()
.setServiceAccountId(serviceAccountEmail)
.setServiceAccountScopes(EMPTY_SCOPES)
.setServiceAccountPrivateKey(SecurityTestUtils.newRsaPrivateKey())
.setTransport(transport)
.setJsonFactory(JSON_FACTORY)
.build();
assertTrue(credential.createScopedRequired());
try {
credential.refreshToken();
fail("Should not be able to refresh token without scopes.");
} catch (Exception expected) {
}
GoogleCredential scopedCredential = credential.createScoped(SCOPES);
assertFalse(scopedCredential.createScopedRequired());
assertNotSame(credential, scopedCredential);
assertTrue(scopedCredential.refreshToken());
assertEquals(accessToken, scopedCredential.getAccessToken());
assertSame(credential.getTransport(), scopedCredential.getTransport());
assertSame(credential.getJsonFactory(), scopedCredential.getJsonFactory());
assertSame(credential.getServiceAccountId(), scopedCredential.getServiceAccountId());
assertSame(credential.getServiceAccountUser(), scopedCredential.getServiceAccountUser());
assertSame(credential.getServiceAccountPrivateKey(),
scopedCredential.getServiceAccountPrivateKey());
}
public void testGetApplicationDefaultNullTransportThrows() throws IOException {
try {
GoogleCredential.getApplicationDefault(null, JSON_FACTORY);
fail();
} catch (NullPointerException expected) {
}
}
public void testGetApplicationDefaultNullJsonFactoryThrows() throws IOException {
HttpTransport transport = new MockHttpTransport();
try {
GoogleCredential.getApplicationDefault(transport, null);
fail();
} catch (NullPointerException expected) {
}
}
public void testFromStreamNullTransportThrows() throws IOException {
InputStream stream = new ByteArrayInputStream("foo".getBytes());
try {
GoogleCredential.fromStream(stream, null, JSON_FACTORY);
fail();
} catch (NullPointerException expected) {
}
}
public void testFromStreamNullJsonFactoryThrows() throws IOException {
HttpTransport transport = new MockHttpTransport();
InputStream stream = new ByteArrayInputStream("foo".getBytes());
try {
GoogleCredential.fromStream(stream, transport, null);
fail();
} catch (NullPointerException expected) {
}
}
public void testFromStreamNullStreamThrows() throws IOException {
HttpTransport transport = new MockHttpTransport();
try {
GoogleCredential.fromStream(null, transport, JSON_FACTORY);
fail();
} catch (NullPointerException expected) {
}
}
public void testFromStreamServiceAccount() throws IOException {
final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2";
final String serviceAccountId =
"36680232662-vrd7ji19qe3nelgchd0ah2csanun6bnr.apps.googleusercontent.com";
final String serviceAccountEmail =
"36680232662-vrd7ji19qgchd0ah2csanun6bnr@developer.gserviceaccount.com";
MockTokenServerTransport transport = new MockTokenServerTransport();
transport.addServiceAccount(serviceAccountEmail, accessToken);
// Write out user file
GenericJson serviceAccountContents = new GenericJson();
serviceAccountContents.setFactory(JSON_FACTORY);
serviceAccountContents.put("client_id", serviceAccountId);
serviceAccountContents.put("client_email", serviceAccountEmail);
serviceAccountContents.put("private_key", SA_KEY_TEXT);
serviceAccountContents.put("private_key_id", SA_KEY_ID);
serviceAccountContents.put("type", GoogleCredential.SERVICE_ACCOUNT_FILE_TYPE);
String json = serviceAccountContents.toPrettyString();
InputStream serviceAccountStream = new ByteArrayInputStream(json.getBytes());
GoogleCredential defaultCredential = GoogleCredential
.fromStream(serviceAccountStream, transport, JSON_FACTORY);
assertNotNull(defaultCredential);
defaultCredential = defaultCredential.createScoped(SCOPES);
assertTrue(defaultCredential.refreshToken());
assertEquals(accessToken, defaultCredential.getAccessToken());
}
public void testFromStreamServiceAccountMissingClientIdThrows() throws IOException {
final String serviceAccountEmail =
"36680232662-vrd7ji19qgchd0ah2csanun6bnr@developer.gserviceaccount.com";
MockHttpTransport transport = new MockTokenServerTransport();
// Write out user file
GenericJson serviceAccountContents = new GenericJson();
serviceAccountContents.setFactory(JSON_FACTORY);
serviceAccountContents.put("client_email", serviceAccountEmail);
serviceAccountContents.put("private_key", SA_KEY_TEXT);
serviceAccountContents.put("private_key_id", SA_KEY_ID);
serviceAccountContents.put("type", GoogleCredential.SERVICE_ACCOUNT_FILE_TYPE);
String json = serviceAccountContents.toPrettyString();
InputStream serviceAccountStream = new ByteArrayInputStream(json.getBytes());
try {
GoogleCredential.fromStream(serviceAccountStream, transport, JSON_FACTORY);
fail();
} catch (IOException expected) {
assertTrue(expected.getMessage().contains("client_id"));
}
}
public void testFromStreamServiceAccountMissingClientEmailThrows() throws IOException {
final String serviceAccountId =
"36680232662-vrd7ji19qe3nelgchd0ah2csanun6bnr.apps.googleusercontent.com";
MockHttpTransport transport = new MockTokenServerTransport();
// Write out user file
GenericJson serviceAccountContents = new GenericJson();
serviceAccountContents.setFactory(JSON_FACTORY);
serviceAccountContents.put("client_id", serviceAccountId);
serviceAccountContents.put("private_key", SA_KEY_TEXT);
serviceAccountContents.put("private_key_id", SA_KEY_ID);
serviceAccountContents.put("type", GoogleCredential.SERVICE_ACCOUNT_FILE_TYPE);
String json = serviceAccountContents.toPrettyString();
InputStream serviceAccountStream = new ByteArrayInputStream(json.getBytes());
try {
GoogleCredential.fromStream(serviceAccountStream, transport, JSON_FACTORY);
fail();
} catch (IOException expected) {
assertTrue(expected.getMessage().contains("client_email"));
}
}
public void testFromStreamServiceAccountMissingPrivateKeyThrows() throws IOException {
final String serviceAccountId =
"36680232662-vrd7ji19qe3nelgchd0ah2csanun6bnr.apps.googleusercontent.com";
final String serviceAccountEmail =
"36680232662-vrd7ji19qgchd0ah2csanun6bnr@developer.gserviceaccount.com";
MockHttpTransport transport = new MockTokenServerTransport();
// Write out user file
GenericJson serviceAccountContents = new GenericJson();
serviceAccountContents.setFactory(JSON_FACTORY);
serviceAccountContents.put("client_id", serviceAccountId);
serviceAccountContents.put("client_email", serviceAccountEmail);
serviceAccountContents.put("private_key_id", SA_KEY_ID);
serviceAccountContents.put("type", GoogleCredential.SERVICE_ACCOUNT_FILE_TYPE);
String json = serviceAccountContents.toPrettyString();
InputStream serviceAccountStream = new ByteArrayInputStream(json.getBytes());
try {
GoogleCredential.fromStream(serviceAccountStream, transport, JSON_FACTORY);
fail();
} catch (IOException expected) {
assertTrue(expected.getMessage().contains("private_key"));
}
}
public void testFromStreamServiceAccountMissingPrivateKeyIdThrows() throws IOException {
final String serviceAccountId =
"36680232662-vrd7ji19qe3nelgchd0ah2csanun6bnr.apps.googleusercontent.com";
final String serviceAccountEmail =
"36680232662-vrd7ji19qgchd0ah2csanun6bnr@developer.gserviceaccount.com";
MockHttpTransport transport = new MockTokenServerTransport();
// Write out user file
GenericJson serviceAccountContents = new GenericJson();
serviceAccountContents.setFactory(JSON_FACTORY);
serviceAccountContents.put("client_id", serviceAccountId);
serviceAccountContents.put("client_email", serviceAccountEmail);
serviceAccountContents.put("private_key", SA_KEY_TEXT);
serviceAccountContents.put("type", GoogleCredential.SERVICE_ACCOUNT_FILE_TYPE);
String json = serviceAccountContents.toPrettyString();
InputStream serviceAccountStream = new ByteArrayInputStream(json.getBytes());
try {
GoogleCredential.fromStream(serviceAccountStream, transport, JSON_FACTORY);
fail();
} catch (IOException expected) {
assertTrue(expected.getMessage().contains("private_key_id"));
}
}
public void testFromStreamUser() throws IOException {
final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2";
final String clientSecret = "jakuaL9YyieakhECKL2SwZcu";
final String clientId =
"ya29.1.AADtN_UtlxN3PSc5yhCqfA9nDFp1dfvH8cruGAxrN2XQnZTVRvDyVWnYq4I6dws";
final String refreshToken = "1/Tl6awhpFjkMkSJoj1xsli0H2eL5YsMgU_NKPY2TyGWY";
MockTokenServerTransport transport = new MockTokenServerTransport();
transport.addClient(clientId, clientSecret);
transport.addRefreshToken(refreshToken, accessToken);
// Create user stream.
String json = createUserJson(clientId, clientSecret, refreshToken);
InputStream userStream = new ByteArrayInputStream(json.getBytes());
GoogleCredential defaultCredential = GoogleCredential
.fromStream(userStream, transport, JSON_FACTORY);
assertNotNull(defaultCredential);
assertEquals(defaultCredential.getRefreshToken(), refreshToken);
assertTrue(defaultCredential.refreshToken());
assertEquals(accessToken, defaultCredential.getAccessToken());
}
public void testFromStreamUsertMissingClientIdThrows() throws IOException {
final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2";
final String clientSecret = "jakuaL9YyieakhECKL2SwZcu";
final String clientId = "ya29.1.AADtN_UtlxN3PSruGAxrN2XQnZTVRvDyVWnYq4I6dws";
final String refreshToken = "1/Tl6awhpFjkMkSJoj1xsli0H2eL5YsMgU_NKPY2TyGWY";
MockTokenServerTransport transport = new MockTokenServerTransport();
transport.addClient(clientId, clientSecret);
transport.addRefreshToken(refreshToken, accessToken);
// Write out user file
String json = createUserJson(null, clientSecret, refreshToken);
InputStream userStream = new ByteArrayInputStream(json.getBytes());
try {
GoogleCredential.fromStream(userStream, transport, JSON_FACTORY);
fail();
} catch (IOException expected) {
assertTrue(expected.getMessage().contains("client_id"));
}
}
public void testFromStreamUsertMissingClientSecretThrows() throws IOException {
final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2";
final String clientSecret = "jakuaL9YyieakhECKL2SwZcu";
final String clientId = "ya29.1.AADtN_UtlxN3PSruGAxrN2XQnZTVRvDyVWnYq4I6dws";
final String refreshToken = "1/Tl6awhpFjkMkSJoj1xsli0H2eL5YsMgU_NKPY2TyGWY";
MockTokenServerTransport transport = new MockTokenServerTransport();
transport.addClient(clientId, clientSecret);
transport.addRefreshToken(refreshToken, accessToken);
// Write out user file
String json = createUserJson(clientId, null, refreshToken);
InputStream userStream = new ByteArrayInputStream(json.getBytes());
try {
GoogleCredential.fromStream(userStream, transport, JSON_FACTORY);
fail();
} catch (IOException expected) {
assertTrue(expected.getMessage().contains("client_secret"));
}
}
public void testFromStreamUsertMissingRefreshTokenThrows() throws IOException {
final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2";
final String clientSecret = "jakuaL9YyieakhECKL2SwZcu";
final String clientId = "ya29.1.AADtN_UtlxN3PSruGAxrN2XQnZTVRvDyVWnYq4I6dws";
final String refreshToken = "1/Tl6awhpFjkMkSJoj1xsli0H2eL5YsMgU_NKPY2TyGWY";
MockTokenServerTransport transport = new MockTokenServerTransport();
transport.addClient(clientId, clientSecret);
transport.addRefreshToken(refreshToken, accessToken);
// Write out user file
String json = createUserJson(clientId, clientSecret, null);
InputStream userStream = new ByteArrayInputStream(json.getBytes());
try {
GoogleCredential.fromStream(userStream, transport, JSON_FACTORY);
fail();
} catch (IOException expected) {
assertTrue(expected.getMessage().contains("refresh_token"));
}
}
static String createUserJson(String clientId, String clientSecret, String refreshToken)
throws IOException {
GenericJson userCredentialContents = new GenericJson();
userCredentialContents.setFactory(JSON_FACTORY);
if (clientId != null) {
userCredentialContents.put("client_id", clientId);
}
if (clientSecret != null) {
userCredentialContents.put("client_secret", clientSecret);
}
if (refreshToken != null) {
userCredentialContents.put("refresh_token", refreshToken);
}
userCredentialContents.put("type", GoogleCredential.USER_FILE_TYPE);
String json = userCredentialContents.toPrettyString();
return json;
}
}