Skip to content

Commit

Permalink
googleapis#1007 - adding option to impersonate a user with backward c…
Browse files Browse the repository at this point in the history
…ompatibility
  • Loading branch information
netp-dany committed May 25, 2018
1 parent ff02edd commit ae2d8db
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,17 @@ public GoogleCredential createScoped(Collection<String> scopes) {
.build();
}

/**
* {@link Beta} <br/>
* For credentials that require scopes, creates a copy of the credential with the specified
* scopes for specified user.
*/
@Beta
public GoogleCredential createScoped(Collection<String> scopes, String serviceAccountUser) {
this.serviceAccountUser = serviceAccountUser;
return createScoped(scopes);
}

/**
* Google credential builder.
*
Expand Down Expand Up @@ -862,11 +873,10 @@ private static PrivateKey privateKeyFromPkcs8(String privateKeyPem) throws IOExc
}
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;
return keyFactory.generatePrivate(keySpec);
} catch (NoSuchAlgorithmException exception) {
unexpectedException = exception;
} catch (InvalidKeySpecException exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.testing.http.MockHttpTransport;
import com.google.api.client.testing.http.MockLowLevelHttpRequest;
import junit.framework.TestCase;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
Expand All @@ -40,7 +41,6 @@
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import junit.framework.TestCase;

/**
* Tests {@link DefaultCredentialProvider}.
Expand Down Expand Up @@ -74,6 +74,11 @@ public class DefaultCredentialProviderTest extends TestCase {

private static File tempDirectory = null;

private static final String SERVICE_ACCOUNT_ID =
"36680232662-vrd7ji19qe3nelgchd0ah2csanun6bnr.apps.googleusercontent.com";
private static final String SERVICE_ACCOUNT_EMAIL =
"36680232662-vrd7ji19qe3nelgchdcsanun6bnr@developer.gserviceaccount.com";

public void testDefaultCredentialAppEngineDeployed() throws IOException {
HttpTransport transport = new MockHttpTransport();
TestDefaultCredentialProvider testProvider = new TestDefaultCredentialProvider();
Expand Down Expand Up @@ -288,31 +293,14 @@ public void testDefaultCredentialNotFoundError() {
public void testDefaultCredentialServiceAccount() throws IOException {
File serviceAccountFile = new java.io.File(getTempDirectory(),
"DefaultCredentialServiceAccount.json");
if (serviceAccountFile.exists()) {
serviceAccountFile.delete();
}
final String serviceAccountId =
"36680232662-vrd7ji19qe3nelgchd0ah2csanun6bnr.apps.googleusercontent.com";
final String serviceAccountEmail =
"36680232662-vrd7ji19qe3nelgchdcsanun6bnr@developer.gserviceaccount.com";
deleteFile(serviceAccountFile);

MockTokenServerTransport transport = new MockTokenServerTransport();
transport.addServiceAccount(serviceAccountEmail, ACCESS_TOKEN);
transport.addServiceAccount(SERVICE_ACCOUNT_EMAIL, ACCESS_TOKEN);

TestDefaultCredentialProvider testProvider = new TestDefaultCredentialProvider();
try {
// Write out service account 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);
PrintWriter writer = new PrintWriter(serviceAccountFile);
String json = serviceAccountContents.toPrettyString();
writer.println(json);
writer.close();
writeOutServiceAccountFile(serviceAccountFile);

// Point the default credential to the file
testProvider.setEnv(DefaultCredentialProvider.CREDENTIAL_ENV_VAR,
Expand All @@ -325,17 +313,40 @@ public void testDefaultCredentialServiceAccount() throws IOException {
assertTrue(credential.refreshToken());
assertEquals(ACCESS_TOKEN, credential.getAccessToken());
} finally {
if (serviceAccountFile.exists()) {
serviceAccountFile.delete();
}
deleteFile(serviceAccountFile);
}
}

public void testDefaultCredentialServiceAccountWithCustomServiceAccountUser() throws IOException {
File serviceAccountFile = new java.io.File(getTempDirectory(),
"DefaultCredentialServiceAccount.json");
deleteFile(serviceAccountFile);

MockTokenServerTransport transport = new MockTokenServerTransport();
transport.addServiceAccount(SERVICE_ACCOUNT_EMAIL, ACCESS_TOKEN);

TestDefaultCredentialProvider testProvider = new TestDefaultCredentialProvider();
try {
writeOutServiceAccountFile(serviceAccountFile);

// Point the default credential to the file
testProvider.setEnv(DefaultCredentialProvider.CREDENTIAL_ENV_VAR,
serviceAccountFile.getAbsolutePath());

GoogleCredential credential = testProvider.getDefaultCredential(transport, JSON_FACTORY);
assertNotNull(credential);
credential = credential.createScoped(SCOPES, "[email protected]");

assertTrue(credential.refreshToken());
assertEquals(ACCESS_TOKEN, credential.getAccessToken());
} finally {
deleteFile(serviceAccountFile);
}
}

public void testDefaultCredentialUser() throws IOException {
File userCredentialFile = new java.io.File(getTempDirectory(), "DefaultCredentialUser.json");
if (userCredentialFile.exists()) {
userCredentialFile.delete();
}
deleteFile(userCredentialFile);

TestDefaultCredentialProvider testProvider = new TestDefaultCredentialProvider();
// Point the default credential to the file
Expand All @@ -349,18 +360,15 @@ public void testDefaultCredentialWellKnownFileNonWindows() throws IOException {
// Simulate where the SDK puts the well-known file on non-Windows platforms
File homeDir = getTempDirectory();
File configDir = new File(homeDir, ".config");
if (!configDir.exists()) {
configDir.mkdir();
}
mkdir(configDir);

File cloudConfigDir = new File(configDir, DefaultCredentialProvider.CLOUDSDK_CONFIG_DIRECTORY);
if (!cloudConfigDir.exists()) {
cloudConfigDir.mkdir();
}
mkdir(cloudConfigDir);

File wellKnownFile = new File(
cloudConfigDir, DefaultCredentialProvider.WELL_KNOWN_CREDENTIALS_FILE);
if (wellKnownFile.exists()) {
wellKnownFile.delete();
}
deleteFile(wellKnownFile);

TestDefaultCredentialProvider testProvider = new TestDefaultCredentialProvider();
testProvider.addFile(wellKnownFile.getAbsolutePath());
testProvider.setProperty("os.name", "linux");
Expand All @@ -373,14 +381,12 @@ public void testDefaultCredentialWellKnownFileWindows() throws IOException {
// Simulate where the SDK puts the well-known file on Windows
File appDataDir = getTempDirectory();
File cloudConfigDir = new File(appDataDir, DefaultCredentialProvider.CLOUDSDK_CONFIG_DIRECTORY);
if (!cloudConfigDir.exists()) {
cloudConfigDir.mkdir();
}
mkdir(cloudConfigDir);

File wellKnownFile = new File(
cloudConfigDir, DefaultCredentialProvider.WELL_KNOWN_CREDENTIALS_FILE);
if (wellKnownFile.exists()) {
wellKnownFile.delete();
}
deleteFile(wellKnownFile);

TestDefaultCredentialProvider testProvider = new TestDefaultCredentialProvider();
testProvider.addFile(wellKnownFile.getAbsolutePath());
testProvider.setProperty("os.name", "windows");
Expand All @@ -401,27 +407,23 @@ public void testDefaultCredentialEnvironmentVariableWinsOverWellKnownFile() thro

// Set up an environment variable file
File environmentVariableFile = new java.io.File(getTempDirectory(), "EnvVarUser.json");
if (environmentVariableFile.exists()) {
environmentVariableFile.delete();
}
deleteFile(environmentVariableFile);

testProvider.setEnv(DefaultCredentialProvider.CREDENTIAL_ENV_VAR,
environmentVariableFile.getAbsolutePath());

// Also set up a well-known-location file
File homeDir = getTempDirectory();
File configDir = new File(homeDir, ".config");
if (!configDir.exists()) {
configDir.mkdir();
}
mkdir(configDir);

File cloudConfigDir = new File(configDir, DefaultCredentialProvider.CLOUDSDK_CONFIG_DIRECTORY);
if (!cloudConfigDir.exists()) {
cloudConfigDir.mkdir();
}
mkdir(cloudConfigDir);

File wellKnownFile = new File(
cloudConfigDir, DefaultCredentialProvider.WELL_KNOWN_CREDENTIALS_FILE);
if (wellKnownFile.exists()) {
wellKnownFile.delete();
}
deleteFile(wellKnownFile);

testProvider.addFile(wellKnownFile.getAbsolutePath());
testProvider.setProperty("os.name", "linux");
testProvider.setProperty("user.home", homeDir.getAbsolutePath());
Expand Down Expand Up @@ -451,12 +453,8 @@ public void testDefaultCredentialEnvironmentVariableWinsOverWellKnownFile() thro
assertTrue(credential.refreshToken());
assertEquals(accessTokenEnv, credential.getAccessToken());
} finally {
if (wellKnownFile.exists()) {
wellKnownFile.delete();
}
if (environmentVariableFile.exists()) {
environmentVariableFile.delete();
}
deleteFile(wellKnownFile);
deleteFile(environmentVariableFile);
}
}

Expand Down Expand Up @@ -487,9 +485,7 @@ private void testDefaultCredentialUser(File userFile, TestDefaultCredentialProvi
assertTrue(credential.refreshToken());
assertEquals(ACCESS_TOKEN, credential.getAccessToken());
} finally {
if (userFile.exists()) {
userFile.delete();
}
deleteFile(userFile);
}
}

Expand All @@ -512,6 +508,32 @@ private static File getTempDirectory() {
return tempDirectory;
}

private void writeOutServiceAccountFile(File serviceAccountFile) throws IOException {
GenericJson serviceAccountContents = new GenericJson();
serviceAccountContents.setFactory(JSON_FACTORY);
serviceAccountContents.put("client_id", SERVICE_ACCOUNT_ID);
serviceAccountContents.put("client_email", SERVICE_ACCOUNT_EMAIL);
serviceAccountContents.put("private_key", SA_KEY_TEXT);
serviceAccountContents.put("private_key_id", SA_KEY_ID);
serviceAccountContents.put("type", GoogleCredential.SERVICE_ACCOUNT_FILE_TYPE);
PrintWriter writer = new PrintWriter(serviceAccountFile);
String json = serviceAccountContents.toPrettyString();
writer.println(json);
writer.close();
}

private void deleteFile(File file) {
if (file.exists()) {
file.delete();
}
}

private void mkdir(File dir) {
if (!dir.exists()) {
dir.mkdir();
}
}

public static class MockAppEngineCredential extends GoogleCredential {
public MockAppEngineCredential(HttpTransport transport, JsonFactory jsonFactory) {
super(new GoogleCredential.Builder().setTransport(transport).setJsonFactory(jsonFactory));
Expand Down

0 comments on commit ae2d8db

Please sign in to comment.