Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adds external account credentials to ADC #500

Merged
merged 1 commit into from
Oct 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@

package com.google.auth.oauth2;

import static com.google.auth.oauth2.IdentityPoolCredentials.EXTERNAL_ACCOUNT_FILE_TYPE;

import com.google.api.client.json.GenericJson;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.JsonObjectParser;
Expand All @@ -49,8 +51,8 @@
public class GoogleCredentials extends OAuth2Credentials {

private static final long serialVersionUID = -1522852442442473691L;
static final String QUOTA_PROJECT_ID_HEADER_KEY = "x-goog-user-project";

static final String QUOTA_PROJECT_ID_HEADER_KEY = "x-goog-user-project";
static final String USER_FILE_TYPE = "authorized_user";
static final String SERVICE_ACCOUNT_FILE_TYPE = "service_account";

Expand Down Expand Up @@ -165,6 +167,9 @@ public static GoogleCredentials fromStream(
if (SERVICE_ACCOUNT_FILE_TYPE.equals(fileType)) {
return ServiceAccountCredentials.fromJson(fileContents, transportFactory);
}
if (EXTERNAL_ACCOUNT_FILE_TYPE.equals(fileType)) {
return ExternalAccountCredentials.fromJson(fileContents, transportFactory);
}
throw new IOException(
String.format(
"Error reading credentials from stream, 'type' value '%s' not recognized."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@

import com.google.api.client.json.GenericJson;
import com.google.api.client.json.JsonParser;
import com.google.auth.TestUtils;
import com.google.auth.http.HttpTransportFactory;
import com.google.auth.oauth2.AwsCredentials.AwsCredentialSource;
import com.google.auth.oauth2.ExternalAccountCredentialsTest.MockExternalAccountCredentialsTransportFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.Arrays;
import java.util.Collection;
Expand Down Expand Up @@ -315,15 +317,34 @@ public void createdScoped_clonedCredentialWithAddedScopes() {
assertEquals(newScopes, newCredentials.getScopes());
}

private AwsCredentialSource buildAwsCredentialSource(
private static AwsCredentialSource buildAwsCredentialSource(
MockExternalAccountCredentialsTransportFactory transportFactory) {
Map<String, Object> credentialSourceMap = new HashMap<>();
credentialSourceMap.put("region_url", transportFactory.transport.getAwsRegionEndpoint());
credentialSourceMap.put("url", transportFactory.transport.getAwsCredentialsEndpoint());
credentialSourceMap.put("region_url", transportFactory.transport.getAwsRegionUrl());
credentialSourceMap.put("url", transportFactory.transport.getAwsCredentialsUrl());
credentialSourceMap.put("regional_cred_verification_url", GET_CALLER_IDENTITY_URL);
return new AwsCredentialSource(credentialSourceMap);
}

static InputStream writeAwsCredentialsStream(String stsUrl, String regionUrl, String metadataUrl)
throws IOException {
GenericJson json = new GenericJson();
json.put("audience", "audience");
json.put("subject_token_type", "subjectTokenType");
json.put("token_url", stsUrl);
json.put("token_info_url", "tokenInfoUrl");
json.put("type", ExternalAccountCredentials.EXTERNAL_ACCOUNT_FILE_TYPE);

GenericJson credentialSource = new GenericJson();
credentialSource.put("environment_id", "aws1");
credentialSource.put("region_url", regionUrl);
credentialSource.put("url", metadataUrl);
credentialSource.put("regional_cred_verification_url", GET_CALLER_IDENTITY_URL);
json.put("credential_source", credentialSource);

return TestUtils.jsonToInputStream(json);
}

/** Used to test the retrieval of AWS credentials from environment variables. */
private static class TestAwsCredentials extends AwsCredentials {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import com.google.api.client.testing.http.MockHttpTransport;
import com.google.auth.TestUtils;
import com.google.auth.http.HttpTransportFactory;
import com.google.auth.oauth2.IdentityPoolCredentialsTest.MockExternalAccountCredentialsTransportFactory;
import com.google.common.collect.ImmutableList;
import java.io.ByteArrayInputStream;
import java.io.IOException;
Expand Down Expand Up @@ -224,6 +225,43 @@ public void fromStream_userNoRefreshToken_throws() throws IOException {
testFromStreamException(userStream, "refresh_token");
}

@Test
public void fromStream_identityPoolCredentials_providesToken() throws IOException {
MockExternalAccountCredentialsTransportFactory transportFactory =
new MockExternalAccountCredentialsTransportFactory();
InputStream identityPoolCredentialStream =
IdentityPoolCredentialsTest.writeIdentityPoolCredentialsStream(
transportFactory.transport.getStsUrl(), transportFactory.transport.getMetadataUrl());

GoogleCredentials credentials =
GoogleCredentials.fromStream(identityPoolCredentialStream, transportFactory);

assertNotNull(credentials);
credentials = credentials.createScoped(SCOPES);
Map<String, List<String>> metadata = credentials.getRequestMetadata(CALL_URI);
TestUtils.assertContainsBearerToken(metadata, transportFactory.transport.getAccessToken());
}

@Test
public void fromStream_awsCredentials_providesToken() throws IOException {
MockExternalAccountCredentialsTransportFactory transportFactory =
new MockExternalAccountCredentialsTransportFactory();

InputStream awsCredentialStream =
AwsCredentialsTest.writeAwsCredentialsStream(
transportFactory.transport.getStsUrl(),
transportFactory.transport.getAwsRegionUrl(),
transportFactory.transport.getAwsCredentialsUrl());

GoogleCredentials credentials =
GoogleCredentials.fromStream(awsCredentialStream, transportFactory);

assertNotNull(credentials);
credentials = credentials.createScoped(SCOPES);
Map<String, List<String>> metadata = credentials.getRequestMetadata(CALL_URI);
TestUtils.assertContainsBearerToken(metadata, transportFactory.transport.getAccessToken());
}

@Test
public void createScoped_overloadCallsImplementation() {
final AtomicReference<Collection<String>> called = new AtomicReference<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@

import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.GenericJson;
import com.google.auth.TestUtils;
import com.google.auth.http.HttpTransportFactory;
import com.google.auth.oauth2.IdentityPoolCredentials.IdentityPoolCredentialSource;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -415,14 +417,30 @@ public void run() {
e.getMessage());
}

@Test
public void identityPoolCredentialSource_jsonFormatTypeWithoutSubjectTokenFieldName() {}
static InputStream writeIdentityPoolCredentialsStream(String tokenUrl, String url)
throws IOException {
GenericJson json = new GenericJson();
json.put("audience", "audience");
json.put("subject_token_type", "subjectTokenType");
json.put("token_url", tokenUrl);
json.put("token_info_url", "tokenInfoUrl");
json.put("type", ExternalAccountCredentials.EXTERNAL_ACCOUNT_FILE_TYPE);

GenericJson credentialSource = new GenericJson();
GenericJson headers = new GenericJson();
headers.put("Metadata-Flavor", "Google");
credentialSource.put("url", url);
credentialSource.put("headers", headers);

json.put("credential_source", credentialSource);
return TestUtils.jsonToInputStream(json);
}

private IdentityPoolCredentialSource buildUrlBasedCredentialSource(String url) {
private static IdentityPoolCredentialSource buildUrlBasedCredentialSource(String url) {
return buildUrlBasedCredentialSource(url, /* formatMap= */ null);
}

private IdentityPoolCredentialSource buildUrlBasedCredentialSource(
private static IdentityPoolCredentialSource buildUrlBasedCredentialSource(
String url, Map<String, String> formatMap) {
Map<String, Object> credentialSourceMap = new HashMap<>();
Map<String, String> headers = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,11 +228,11 @@ public String getMetadataUrl() {
return METADATA_SERVER_URL;
}

public String getAwsCredentialsEndpoint() {
public String getAwsCredentialsUrl() {
return AWS_CREDENTIALS_URL;
}

public String getAwsRegionEndpoint() {
public String getAwsRegionUrl() {
return AWS_REGION_URL;
}

Expand Down