Skip to content

Commit

Permalink
fix: ImmutableSet converted to List for Impersonated Credentials (#732)
Browse files Browse the repository at this point in the history
As part of BigQueryOptions or StorageOptions the SCOPES is defined as an ImmutableSet.
When using an Impersonated Account, it fails when trying to get service, as the SCOPES are immutableSet and the previous code tries to cast it to List directly and fails.
Adding a fix for the same.

Fixes #731 ☕️
  • Loading branch information
dheerajpanangat authored Mar 15, 2022
1 parent 1e6de7e commit 7dcd549
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ public boolean createScopedRequired() {
@Override
public GoogleCredentials createScoped(Collection<String> scopes) {
return toBuilder()
.setScopes((List<String>) scopes)
.setScopes(new ArrayList(scopes))
.setLifetime(this.lifetime)
.setDelegates(this.delegates)
.setHttpTransportFactory(this.transportFactory)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import com.google.auth.http.HttpTransportFactory;
import com.google.auth.oauth2.GoogleCredentialsTest.MockTokenServerTransportFactory;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
Expand All @@ -66,6 +67,7 @@
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -107,11 +109,11 @@ class ImpersonatedCredentialsTest extends BaseSerializationTest {
+ "CJzdWIiOiIxMDIxMDE1NTA4MzQyMDA3MDg1NjgifQ.redacted";
public static final String ACCESS_TOKEN = "1/MkSJoj1xsli0AccessToken_NKPY2";

private static final Set<String> IMMUTABLE_SCOPES_SET = ImmutableSet.of("scope1", "scope2");
private static final String PROJECT_ID = "project-id";
public static final String IMPERSONATED_CLIENT_EMAIL =
"impersonated-account@iam.gserviceaccount.com";
private static final List<String> SCOPES =
Arrays.asList("https://www.googleapis.com/auth/devstorage.read_only");
private static final List<String> IMMUTABLE_SCOPES_LIST = ImmutableList.of("scope1", "scope2");
private static final int VALID_LIFETIME = 300;
private static final int INVALID_LIFETIME = 43210;
private static JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
Expand Down Expand Up @@ -156,7 +158,7 @@ private GoogleCredentials getSourceCredentials() throws IOException {
.setClientEmail(SA_CLIENT_EMAIL)
.setPrivateKey(privateKey)
.setPrivateKeyId(SA_PRIVATE_KEY_ID)
.setScopes(SCOPES)
.setScopes(IMMUTABLE_SCOPES_LIST)
.setProjectId(PROJECT_ID)
.setHttpTransportFactory(transportFactory)
.build();
Expand Down Expand Up @@ -275,7 +277,7 @@ void createScopedRequired_False() {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);
assertFalse(targetCredentials.createScopedRequired());
Expand All @@ -288,13 +290,36 @@ void createScoped() {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
DELEGATES,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory,
QUOTA_PROJECT_ID);

ImpersonatedCredentials scoped_credentials =
(ImpersonatedCredentials) targetCredentials.createScoped(Arrays.asList("scope1", "scope2"));
(ImpersonatedCredentials) targetCredentials.createScoped(IMMUTABLE_SCOPES_LIST);
assertEquals(targetCredentials.getAccount(), scoped_credentials.getAccount());
assertEquals(targetCredentials.getDelegates(), scoped_credentials.getDelegates());
assertEquals(targetCredentials.getLifetime(), scoped_credentials.getLifetime());
assertEquals(
targetCredentials.getSourceCredentials(), scoped_credentials.getSourceCredentials());
assertEquals(targetCredentials.getQuotaProjectId(), scoped_credentials.getQuotaProjectId());
assertEquals(Arrays.asList("scope1", "scope2"), scoped_credentials.getScopes());
}

@Test
void createScopedWithImmutableScopes() {
ImpersonatedCredentials targetCredentials =
ImpersonatedCredentials.create(
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
DELEGATES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory,
QUOTA_PROJECT_ID);

ImpersonatedCredentials scoped_credentials =
(ImpersonatedCredentials) targetCredentials.createScoped(IMMUTABLE_SCOPES_SET);
assertEquals(targetCredentials.getAccount(), scoped_credentials.getAccount());
assertEquals(targetCredentials.getDelegates(), scoped_credentials.getDelegates());
assertEquals(targetCredentials.getLifetime(), scoped_credentials.getLifetime());
Expand All @@ -319,7 +344,7 @@ void refreshAccessToken_unauthorized() throws IOException {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);

Expand Down Expand Up @@ -348,7 +373,7 @@ void refreshAccessToken_malformedTarget() throws IOException {
sourceCredentials,
invalidTargetEmail,
null,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);

Expand All @@ -365,7 +390,7 @@ void refreshAccessToken_malformedTarget() throws IOException {
void credential_with_zero_lifetime() throws IllegalStateException {
ImpersonatedCredentials targetCredentials =
ImpersonatedCredentials.create(
sourceCredentials, IMPERSONATED_CLIENT_EMAIL, null, SCOPES, 0);
sourceCredentials, IMPERSONATED_CLIENT_EMAIL, null, IMMUTABLE_SCOPES_LIST, 0);
assertEquals(3600, targetCredentials.getLifetime());
}

Expand All @@ -378,7 +403,11 @@ void credential_with_invalid_lifetime() throws IOException, IllegalStateExceptio
() -> {
ImpersonatedCredentials targetCredentials =
ImpersonatedCredentials.create(
sourceCredentials, IMPERSONATED_CLIENT_EMAIL, null, SCOPES, INVALID_LIFETIME);
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
IMMUTABLE_SCOPES_LIST,
INVALID_LIFETIME);
targetCredentials.refreshAccessToken().getTokenValue();
},
String.format(
Expand Down Expand Up @@ -415,7 +444,7 @@ void refreshAccessToken_success() throws IOException, IllegalStateException {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);

Expand All @@ -433,7 +462,7 @@ void getRequestMetadata_withQuotaProjectId() throws IOException, IllegalStateExc
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory,
QUOTA_PROJECT_ID);
Expand All @@ -456,7 +485,7 @@ void getRequestMetadata_withoutQuotaProjectId() throws IOException, IllegalState
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);

Expand All @@ -476,7 +505,7 @@ void refreshAccessToken_delegates_success() throws IOException, IllegalStateExce
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
delegates,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);

Expand All @@ -495,7 +524,7 @@ void refreshAccessToken_invalidDate() throws IllegalStateException {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);

Expand All @@ -517,7 +546,7 @@ void getAccount_sameAs() {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);

Expand All @@ -534,7 +563,7 @@ void sign_sameAs() {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);

Expand All @@ -556,7 +585,7 @@ void sign_requestIncludesDelegates() throws IOException {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
ImmutableList.of("delegate@example.com"),
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);

Expand Down Expand Up @@ -595,7 +624,7 @@ void sign_usesSourceCredentials() {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
ImmutableList.of("delegate@example.com"),
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);

Expand All @@ -620,7 +649,7 @@ void sign_accessDenied_throws() {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);

Expand Down Expand Up @@ -652,7 +681,7 @@ void sign_serverError_throws() {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);

Expand Down Expand Up @@ -685,7 +714,7 @@ void idTokenWithAudience_sameAs() throws IOException {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);

Expand Down Expand Up @@ -716,7 +745,7 @@ void idTokenWithAudience_withEmail() throws IOException {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);

Expand Down Expand Up @@ -746,7 +775,7 @@ void idToken_withServerError() {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);

Expand Down Expand Up @@ -776,7 +805,7 @@ void idToken_withOtherError() {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);

Expand Down Expand Up @@ -806,7 +835,7 @@ void hashCode_equals() throws IOException {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);

Expand All @@ -815,7 +844,7 @@ void hashCode_equals() throws IOException {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);

Expand All @@ -834,7 +863,7 @@ void serialize() throws IOException, ClassNotFoundException {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
SCOPES,
IMMUTABLE_SCOPES_LIST,
VALID_LIFETIME,
mockTransportFactory);
GoogleCredentials deserializedCredentials = serializeAndDeserialize(targetCredentials);
Expand Down

0 comments on commit 7dcd549

Please sign in to comment.