From 2243474edb015429650f24db6684dfc0865e0ef3 Mon Sep 17 00:00:00 2001 From: Jeff Ching Date: Mon, 30 Nov 2020 14:48:42 -0800 Subject: [PATCH] test: add more tests for quotaProjectId --- .../oauth2/ServiceAccountCredentials.java | 8 +- .../google/auth/oauth2/UserCredentials.java | 8 +- .../oauth2/ServiceAccountCredentialsTest.java | 93 +++++++++++++++++++ ...erviceAccountJwtAccessCredentialsTest.java | 72 ++++++++++++++ .../auth/oauth2/UserCredentialsTest.java | 41 ++++++++ 5 files changed, 216 insertions(+), 6 deletions(-) diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java index 77b9d4bb2..974959129 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountCredentials.java @@ -76,7 +76,6 @@ import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Collection; -import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; @@ -601,8 +600,11 @@ public JwtCredentials jwtWithClaims(JwtClaims newClaims) { @Override protected Map> getAdditionalHeaders() { - return Collections.singletonMap( - QUOTA_PROJECT_ID_HEADER_KEY, Collections.singletonList(quotaProjectId)); + Map> headers = super.getAdditionalHeaders(); + if (quotaProjectId != null) { + return addQuotaProjectIdToRequestMetadata(quotaProjectId, headers); + } + return headers; } @Override diff --git a/oauth2_http/java/com/google/auth/oauth2/UserCredentials.java b/oauth2_http/java/com/google/auth/oauth2/UserCredentials.java index 124719a68..bd8dcfd61 100644 --- a/oauth2_http/java/com/google/auth/oauth2/UserCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/UserCredentials.java @@ -52,7 +52,6 @@ import java.io.InputStream; import java.io.ObjectInputStream; import java.net.URI; -import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; @@ -279,8 +278,11 @@ public void save(String filePath) throws IOException { @Override protected Map> getAdditionalHeaders() { - return Collections.singletonMap( - QUOTA_PROJECT_ID_HEADER_KEY, Collections.singletonList(quotaProjectId)); + Map> headers = super.getAdditionalHeaders(); + if (quotaProjectId != null) { + return addQuotaProjectIdToRequestMetadata(quotaProjectId, headers); + } + return headers; } @Override diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java index 779c7f006..7d89ded8f 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java @@ -49,6 +49,7 @@ import com.google.api.client.testing.http.MockLowLevelHttpResponse; import com.google.api.client.util.Clock; import com.google.api.client.util.Joiner; +import com.google.auth.RequestMetadataCallback; import com.google.auth.TestUtils; import com.google.auth.http.HttpTransportFactory; import com.google.auth.oauth2.GoogleCredentialsTest.MockHttpTransportFactory; @@ -68,6 +69,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -1032,6 +1034,97 @@ public void fromStream_noPrivateKeyId_throws() throws IOException { testFromStreamException(serviceAccountStream, "private_key_id"); } + @Test + public void getRequestMetadataSetsQuotaProjectId() throws IOException { + MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); + transportFactory.transport.addClient(CLIENT_ID, "unused-client-secret"); + transportFactory.transport.addServiceAccount(CLIENT_EMAIL, ACCESS_TOKEN); + + PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(PRIVATE_KEY_PKCS8); + GoogleCredentials credentials = + ServiceAccountCredentials.newBuilder() + .setClientId(CLIENT_ID) + .setClientEmail(CLIENT_EMAIL) + .setPrivateKey(privateKey) + .setPrivateKeyId(PRIVATE_KEY_ID) + .setScopes(SCOPES) + .setServiceAccountUser(USER) + .setProjectId(PROJECT_ID) + .setQuotaProjectId("my-quota-project-id") + .setHttpTransportFactory(transportFactory) + .build(); + + Map> metadata = credentials.getRequestMetadata(); + assertTrue(metadata.containsKey("x-goog-user-project")); + List headerValues = metadata.get("x-goog-user-project"); + assertEquals(1, headerValues.size()); + assertEquals("my-quota-project-id", headerValues.get(0)); + } + + @Test + public void getRequestMetadataNoQuotaProjectId() throws IOException { + MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); + transportFactory.transport.addClient(CLIENT_ID, "unused-client-secret"); + transportFactory.transport.addServiceAccount(CLIENT_EMAIL, ACCESS_TOKEN); + + PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(PRIVATE_KEY_PKCS8); + GoogleCredentials credentials = + ServiceAccountCredentials.newBuilder() + .setClientId(CLIENT_ID) + .setClientEmail(CLIENT_EMAIL) + .setPrivateKey(privateKey) + .setPrivateKeyId(PRIVATE_KEY_ID) + .setScopes(SCOPES) + .setServiceAccountUser(USER) + .setProjectId(PROJECT_ID) + .setHttpTransportFactory(transportFactory) + .build(); + + Map> metadata = credentials.getRequestMetadata(); + assertFalse(metadata.containsKey("x-goog-user-project")); + } + + @Test + public void getRequestMetadataWithCallback() throws IOException { + MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); + transportFactory.transport.addClient(CLIENT_ID, "unused-client-secret"); + transportFactory.transport.addServiceAccount(CLIENT_EMAIL, ACCESS_TOKEN); + + PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(PRIVATE_KEY_PKCS8); + GoogleCredentials credentials = + ServiceAccountCredentials.newBuilder() + .setClientId(CLIENT_ID) + .setClientEmail(CLIENT_EMAIL) + .setPrivateKey(privateKey) + .setPrivateKeyId(PRIVATE_KEY_ID) + .setScopes(SCOPES) + .setServiceAccountUser(USER) + .setProjectId(PROJECT_ID) + .setQuotaProjectId("my-quota-project-id") + .setHttpTransportFactory(transportFactory) + .build(); + + final Map> plainMetadata = credentials.getRequestMetadata(); + final AtomicBoolean success = new AtomicBoolean(false); + credentials.getRequestMetadata( + null, + null, + new RequestMetadataCallback() { + @Override + public void onSuccess(Map> metadata) { + assertEquals(plainMetadata, metadata); + success.set(true); + } + + @Override + public void onFailure(Throwable exception) { + fail("Should not throw a failure."); + } + }); + + assertTrue("Should have run onSuccess() callback", success.get()); + } + static GenericJson writeServiceAccountJson( String clientId, String clientEmail, diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java index 64ca7d408..c3d73072f 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java @@ -46,6 +46,7 @@ import com.google.api.client.json.webtoken.JsonWebSignature; import com.google.api.client.util.Clock; import com.google.auth.Credentials; +import com.google.auth.RequestMetadataCallback; import com.google.auth.TestClock; import com.google.auth.http.AuthHttpConstants; import com.google.auth.oauth2.GoogleCredentialsTest.MockHttpTransportFactory; @@ -61,6 +62,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -758,6 +760,76 @@ public void jwtWithClaims_defaultAudience() throws IOException { verifyJwtAccess(metadata, SA_CLIENT_EMAIL, URI.create("default-audience"), SA_PRIVATE_KEY_ID); } + @Test + public void getRequestMetadataSetsQuotaProjectId() throws IOException { + PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8); + ServiceAccountJwtAccessCredentials credentials = + ServiceAccountJwtAccessCredentials.newBuilder() + .setClientId(SA_CLIENT_ID) + .setClientEmail(SA_CLIENT_EMAIL) + .setPrivateKey(privateKey) + .setPrivateKeyId(SA_PRIVATE_KEY_ID) + .setQuotaProjectId("my-quota-project-id") + .setDefaultAudience(URI.create("default-audience")) + .build(); + + Map> metadata = credentials.getRequestMetadata(); + assertTrue(metadata.containsKey("x-goog-user-project")); + List headerValues = metadata.get("x-goog-user-project"); + assertEquals(1, headerValues.size()); + assertEquals("my-quota-project-id", headerValues.get(0)); + } + + @Test + public void getRequestMetadataNoQuotaProjectId() throws IOException { + PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8); + ServiceAccountJwtAccessCredentials credentials = + ServiceAccountJwtAccessCredentials.newBuilder() + .setClientId(SA_CLIENT_ID) + .setClientEmail(SA_CLIENT_EMAIL) + .setPrivateKey(privateKey) + .setPrivateKeyId(SA_PRIVATE_KEY_ID) + .setDefaultAudience(URI.create("default-audience")) + .build(); + + Map> metadata = credentials.getRequestMetadata(); + assertFalse(metadata.containsKey("x-goog-user-project")); + } + + @Test + public void getRequestMetadataWithCallback() throws IOException { + PrivateKey privateKey = ServiceAccountCredentials.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8); + ServiceAccountJwtAccessCredentials credentials = + ServiceAccountJwtAccessCredentials.newBuilder() + .setClientId(SA_CLIENT_ID) + .setClientEmail(SA_CLIENT_EMAIL) + .setPrivateKey(privateKey) + .setPrivateKeyId(SA_PRIVATE_KEY_ID) + .setQuotaProjectId("my-quota-project-id") + .setDefaultAudience(URI.create("default-audience")) + .build(); + + final Map> plainMetadata = credentials.getRequestMetadata(); + final AtomicBoolean success = new AtomicBoolean(false); + credentials.getRequestMetadata( + null, + null, + new RequestMetadataCallback() { + @Override + public void onSuccess(Map> metadata) { + assertEquals(plainMetadata, metadata); + success.set(true); + } + + @Override + public void onFailure(Throwable exception) { + fail("Should not throw a failure."); + } + }); + + assertTrue("Should have run onSuccess() callback", success.get()); + } + private void verifyJwtAccess( Map> metadata, String expectedEmail, diff --git a/oauth2_http/javatests/com/google/auth/oauth2/UserCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/UserCredentialsTest.java index 037054ea6..b27e1b3e9 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/UserCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/UserCredentialsTest.java @@ -624,6 +624,47 @@ public void saveAndRestoreUserCredential_saveAndRestored_throws() throws IOExcep assertEquals(userCredentials.getRefreshToken(), restoredCredentials.getRefreshToken()); } + @Test + public void getRequestMetadataSetsQuotaProjectId() throws IOException { + MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); + transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET); + transportFactory.transport.addRefreshToken(REFRESH_TOKEN, ACCESS_TOKEN); + + UserCredentials userCredentials = + UserCredentials.newBuilder() + .setClientId(CLIENT_ID) + .setClientSecret(CLIENT_SECRET) + .setRefreshToken(REFRESH_TOKEN) + .setQuotaProjectId("my-quota-project-id") + .setHttpTransportFactory(transportFactory) + .build(); + + Map> metadata = userCredentials.getRequestMetadata(); + assertTrue(metadata.containsKey("x-goog-user-project")); + List headerValues = metadata.get("x-goog-user-project"); + assertEquals(1, headerValues.size()); + assertEquals("my-quota-project-id", headerValues.get(0)); + } + + @Test + public void getRequestMetadataNoQuotaProjectId() throws IOException { + MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory(); + transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET); + transportFactory.transport.addRefreshToken(REFRESH_TOKEN, ACCESS_TOKEN); + + UserCredentials userCredentials = + UserCredentials.newBuilder() + .setClientId(CLIENT_ID) + .setClientSecret(CLIENT_SECRET) + .setRefreshToken(REFRESH_TOKEN) + .setQuotaProjectId("my-quota-project-id") + .setHttpTransportFactory(transportFactory) + .build(); + + Map> metadata = userCredentials.getRequestMetadata(); + assertFalse(metadata.containsKey("x-goog-user-project")); + } + @Test public void getRequestMetadataWithCallback() throws IOException { MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();