From e87ed3152c018de8a45e5d176645bcfe74dac816 Mon Sep 17 00:00:00 2001 From: mpeddada1 Date: Wed, 21 May 2025 23:08:17 +0000 Subject: [PATCH 01/12] feat: support ability to set universe domain in ServiceAccountJwtAccessCredentials --- .../ServiceAccountJwtAccessCredentials.java | 59 ++++++++++++++----- ...erviceAccountJwtAccessCredentialsTest.java | 16 +++++ 2 files changed, 60 insertions(+), 15 deletions(-) diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java index 6fc338405..20f7472f1 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java @@ -88,6 +88,7 @@ public class ServiceAccountJwtAccessCredentials extends Credentials private final String privateKeyId; private final URI defaultAudience; private final String quotaProjectId; + private final String universeDomain; private transient LoadingCache credentialsCache; @@ -103,8 +104,8 @@ public class ServiceAccountJwtAccessCredentials extends Credentials * @param privateKeyId Private key identifier for the service account. May be null. */ private ServiceAccountJwtAccessCredentials( - String clientId, String clientEmail, PrivateKey privateKey, String privateKeyId) { - this(clientId, clientEmail, privateKey, privateKeyId, null, null); + String clientId, String clientEmail, PrivateKey privateKey, String privateKeyId) { + this(clientId, clientEmail, privateKey, privateKeyId, null, null,Credentials.GOOGLE_DEFAULT_UNIVERSE); } /** @@ -115,6 +116,7 @@ private ServiceAccountJwtAccessCredentials( * @param privateKey RSA private key object for the service account. * @param privateKeyId Private key identifier for the service account. May be null. * @param defaultAudience Audience to use if not provided by transport. May be null. + * @param universeDomain Universe domain */ private ServiceAccountJwtAccessCredentials( String clientId, @@ -122,7 +124,8 @@ private ServiceAccountJwtAccessCredentials( PrivateKey privateKey, String privateKeyId, URI defaultAudience, - String quotaProjectId) { + String quotaProjectId, + String universeDomain) { this.clientId = clientId; this.clientEmail = Preconditions.checkNotNull(clientEmail); this.privateKey = Preconditions.checkNotNull(privateKey); @@ -130,6 +133,11 @@ private ServiceAccountJwtAccessCredentials( this.defaultAudience = defaultAudience; this.credentialsCache = createCache(); this.quotaProjectId = quotaProjectId; + if (universeDomain == null || universeDomain.trim().isEmpty()) { + this.universeDomain = Credentials.GOOGLE_DEFAULT_UNIVERSE; + } else { + this.universeDomain = universeDomain; + } } /** @@ -160,6 +168,9 @@ static ServiceAccountJwtAccessCredentials fromJson(Map json, URI String privateKeyPkcs8 = (String) json.get("private_key"); String privateKeyId = (String) json.get("private_key_id"); String quoataProjectId = (String) json.get("quota_project_id"); + String rawUniverseDomain = (String) json.get("universe_domain"); + String resolvedUniverseDomain = (rawUniverseDomain == null) ? Credentials.GOOGLE_DEFAULT_UNIVERSE : rawUniverseDomain; + if (clientId == null || clientEmail == null || privateKeyPkcs8 == null @@ -169,9 +180,10 @@ static ServiceAccountJwtAccessCredentials fromJson(Map json, URI + "expecting 'client_id', 'client_email', 'private_key' and 'private_key_id'."); } return ServiceAccountJwtAccessCredentials.fromPkcs8( - clientId, clientEmail, privateKeyPkcs8, privateKeyId, defaultAudience, quoataProjectId); + clientId, clientEmail, privateKeyPkcs8, privateKeyId, defaultAudience, quoataProjectId, resolvedUniverseDomain); } + /** * Factory using PKCS#8 for the private key. * @@ -207,7 +219,7 @@ public static ServiceAccountJwtAccessCredentials fromPkcs8( URI defaultAudience) throws IOException { return ServiceAccountJwtAccessCredentials.fromPkcs8( - clientId, clientEmail, privateKeyPkcs8, privateKeyId, defaultAudience, null); + clientId, clientEmail, privateKeyPkcs8, privateKeyId, defaultAudience, null, Credentials.GOOGLE_DEFAULT_UNIVERSE); } static ServiceAccountJwtAccessCredentials fromPkcs8( @@ -216,11 +228,12 @@ static ServiceAccountJwtAccessCredentials fromPkcs8( String privateKeyPkcs8, String privateKeyId, URI defaultAudience, - String quotaProjectId) + String quotaProjectId, + String universeDomain) throws IOException { PrivateKey privateKey = OAuth2Utils.privateKeyFromPkcs8(privateKeyPkcs8); return new ServiceAccountJwtAccessCredentials( - clientId, clientEmail, privateKey, privateKeyId, defaultAudience, quotaProjectId); + clientId, clientEmail, privateKey, privateKeyId, defaultAudience, quotaProjectId, universeDomain); } /** @@ -352,14 +365,13 @@ public Map> getRequestMetadata(URI uri) throws IOException + "defaultAudience to be specified"); } } - try { JwtClaims defaultClaims = - JwtClaims.newBuilder() - .setAudience(uri.toString()) - .setIssuer(clientEmail) - .setSubject(clientEmail) - .build(); + JwtClaims.newBuilder() + .setAudience(uri.toString()) + .setIssuer(clientEmail) + .setSubject(clientEmail) + .build(); JwtCredentials credentials = credentialsCache.get(defaultClaims); Map> requestMetadata = credentials.getRequestMetadata(uri); return addQuotaProjectIdToRequestMetadata(quotaProjectId, requestMetadata); @@ -367,7 +379,7 @@ public Map> getRequestMetadata(URI uri) throws IOException Throwables.propagateIfPossible(e.getCause(), IOException.class); // Should never happen throw new IllegalStateException( - "generateJwtAccess threw an unexpected checked exception", e.getCause()); + "generateJwtAccess threw an unexpected checked exception", e.getCause()); } catch (UncheckedExecutionException e) { Throwables.throwIfUnchecked(e); @@ -399,6 +411,10 @@ public final String getPrivateKeyId() { return privateKeyId; } + public final String getUniverseDomain() { + return universeDomain; + } + @Override public String getAccount() { return getClientEmail(); @@ -474,6 +490,7 @@ public static class Builder { private String privateKeyId; private URI defaultAudience; private String quotaProjectId; + private String universeDomain; protected Builder() {} @@ -484,6 +501,7 @@ protected Builder(ServiceAccountJwtAccessCredentials credentials) { this.privateKeyId = credentials.privateKeyId; this.defaultAudience = credentials.defaultAudience; this.quotaProjectId = credentials.quotaProjectId; + this.universeDomain = credentials.universeDomain; } @CanIgnoreReturnValue @@ -522,6 +540,13 @@ public Builder setQuotaProjectId(String quotaProjectId) { return this; } + @CanIgnoreReturnValue + public Builder setUniverseDomain(String universeDomain) { + this.universeDomain = universeDomain; + return this; + } + + public String getClientId() { return clientId; } @@ -546,9 +571,13 @@ public String getQuotaProjectId() { return quotaProjectId; } + public String getUniverseDomain() { + return universeDomain; + } + public ServiceAccountJwtAccessCredentials build() { return new ServiceAccountJwtAccessCredentials( - clientId, clientEmail, privateKey, privateKeyId, defaultAudience, quotaProjectId); + clientId, clientEmail, privateKey, privateKeyId, defaultAudience, quotaProjectId, universeDomain); } } } diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java index df95ea2f3..a35c8169b 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java @@ -31,6 +31,7 @@ package com.google.auth.oauth2; +import static com.google.auth.Credentials.GOOGLE_DEFAULT_UNIVERSE; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -111,6 +112,7 @@ public void constructor_allParameters_constructs() throws IOException { assertEquals(privateKey, credentials.getPrivateKey()); assertEquals(SA_PRIVATE_KEY_ID, credentials.getPrivateKeyId()); assertEquals(QUOTA_PROJECT, credentials.getQuotaProjectId()); + assertEquals(GOOGLE_DEFAULT_UNIVERSE, credentials.getUniverseDomain()); } @Test @@ -829,6 +831,20 @@ public void onFailure(Throwable exception) { assertTrue("Should have run onSuccess() callback", success.get()); } + @Test + public void getUniverseDomain_defaultUniverse() throws IOException { + PrivateKey privateKey = OAuth2Utils.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(); + assertEquals(GOOGLE_DEFAULT_UNIVERSE, credentials.getUniverseDomain()); + } + private void verifyJwtAccess( Map> metadata, String expectedEmail, From 1f156e258c958f471ca2492ff8ef1d22072e4e03 Mon Sep 17 00:00:00 2001 From: mpeddada1 Date: Thu, 22 May 2025 00:45:12 +0000 Subject: [PATCH 02/12] include unit testing for fromJson --- ...erviceAccountJwtAccessCredentialsTest.java | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java index a35c8169b..9ccd98f2e 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java @@ -42,6 +42,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.api.client.json.GenericJson; import com.google.api.client.json.JsonFactory; import com.google.api.client.json.gson.GsonFactory; import com.google.api.client.json.webtoken.JsonWebSignature; @@ -831,6 +832,48 @@ public void onFailure(Throwable exception) { assertTrue("Should have run onSuccess() callback", success.get()); } + @Test + public void fromJSON_noUniverseDomain() throws IOException { + GenericJson json = + writeServiceAccountJson( + SA_CLIENT_ID, + SA_CLIENT_EMAIL, + SA_PRIVATE_KEY_PKCS8, + "test-project-id", + SA_PRIVATE_KEY_ID, + QUOTA_PROJECT, + null); + ServiceAccountJwtAccessCredentials credentials = + ServiceAccountJwtAccessCredentials.fromJson(json, URI.create("default-aud")); + assertEquals(SA_CLIENT_ID, credentials.getClientId()); + assertEquals(SA_CLIENT_EMAIL, credentials.getClientEmail()); + assertEquals( + OAuth2Utils.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8), credentials.getPrivateKey()); + assertEquals(QUOTA_PROJECT, credentials.getQuotaProjectId()); + assertEquals(GOOGLE_DEFAULT_UNIVERSE, credentials.getUniverseDomain()); + } + + @Test + public void fromJSON_UniverseDomain() throws IOException { + GenericJson json = + writeServiceAccountJson( + SA_CLIENT_ID, + SA_CLIENT_EMAIL, + SA_PRIVATE_KEY_PKCS8, + "test-project-id", + SA_PRIVATE_KEY_ID, + QUOTA_PROJECT, + "example.com"); + ServiceAccountJwtAccessCredentials credentials = + ServiceAccountJwtAccessCredentials.fromJson(json, URI.create("default-aud")); + assertEquals(SA_CLIENT_ID, credentials.getClientId()); + assertEquals(SA_CLIENT_EMAIL, credentials.getClientEmail()); + assertEquals( + OAuth2Utils.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8), credentials.getPrivateKey()); + assertEquals(QUOTA_PROJECT, credentials.getQuotaProjectId()); + assertEquals("example.com", credentials.getUniverseDomain()); + } + @Test public void getUniverseDomain_defaultUniverse() throws IOException { PrivateKey privateKey = OAuth2Utils.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8); @@ -879,4 +922,37 @@ private static void testFromStreamException(InputStream stream, String expectedM assertTrue(expected.getMessage().contains(expectedMessageContent)); } } + private GenericJson writeServiceAccountJson( + String clientId, + String clientEmail, + String privateKeyPkcs8, + String privateKeyId, + String projectId, + String quotaProjectId, + String universeDomain) { + GenericJson json = new GenericJson(); + if (clientId != null) { + json.put("client_id", clientId); + } + if (clientEmail != null) { + json.put("client_email", clientEmail); + } + if (privateKeyPkcs8 != null) { + json.put("private_key", privateKeyPkcs8); + } + if (privateKeyId != null) { + json.put("private_key_id", privateKeyId); + } + if (projectId != null) { + json.put("project_id", projectId); + } + if (quotaProjectId != null) { + json.put("quota_project_id", quotaProjectId); + } + if (universeDomain != null) { + json.put("universe_domain", universeDomain); + } + json.put("type", GoogleCredentials.SERVICE_ACCOUNT_FILE_TYPE); + return json; + } } From a39a4b95074b3e2d0eb117c4a5501a641bd80c7f Mon Sep 17 00:00:00 2001 From: mpeddada1 Date: Thu, 22 May 2025 01:48:50 +0000 Subject: [PATCH 03/12] adjust formatting --- .../ServiceAccountJwtAccessCredentials.java | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java index 20f7472f1..3a643b68a 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java @@ -116,7 +116,8 @@ private ServiceAccountJwtAccessCredentials( * @param privateKey RSA private key object for the service account. * @param privateKeyId Private key identifier for the service account. May be null. * @param defaultAudience Audience to use if not provided by transport. May be null. - * @param universeDomain Universe domain + * @param universeDomain universe domain in the format some-domain.xyz. By default, returns + * googleapis.com. */ private ServiceAccountJwtAccessCredentials( String clientId, @@ -169,7 +170,8 @@ static ServiceAccountJwtAccessCredentials fromJson(Map json, URI String privateKeyId = (String) json.get("private_key_id"); String quoataProjectId = (String) json.get("quota_project_id"); String rawUniverseDomain = (String) json.get("universe_domain"); - String resolvedUniverseDomain = (rawUniverseDomain == null) ? Credentials.GOOGLE_DEFAULT_UNIVERSE : rawUniverseDomain; + String resolvedUniverseDomain = + (rawUniverseDomain == null) ? Credentials.GOOGLE_DEFAULT_UNIVERSE : rawUniverseDomain; if (clientId == null || clientEmail == null @@ -180,10 +182,15 @@ static ServiceAccountJwtAccessCredentials fromJson(Map json, URI + "expecting 'client_id', 'client_email', 'private_key' and 'private_key_id'."); } return ServiceAccountJwtAccessCredentials.fromPkcs8( - clientId, clientEmail, privateKeyPkcs8, privateKeyId, defaultAudience, quoataProjectId, resolvedUniverseDomain); + clientId, + clientEmail, + privateKeyPkcs8, + privateKeyId, + defaultAudience, + quoataProjectId, + resolvedUniverseDomain); } - /** * Factory using PKCS#8 for the private key. * @@ -367,11 +374,11 @@ public Map> getRequestMetadata(URI uri) throws IOException } try { JwtClaims defaultClaims = - JwtClaims.newBuilder() - .setAudience(uri.toString()) - .setIssuer(clientEmail) - .setSubject(clientEmail) - .build(); + JwtClaims.newBuilder() + .setAudience(uri.toString()) + .setIssuer(clientEmail) + .setSubject(clientEmail) + .build(); JwtCredentials credentials = credentialsCache.get(defaultClaims); Map> requestMetadata = credentials.getRequestMetadata(uri); return addQuotaProjectIdToRequestMetadata(quotaProjectId, requestMetadata); @@ -379,7 +386,7 @@ public Map> getRequestMetadata(URI uri) throws IOException Throwables.propagateIfPossible(e.getCause(), IOException.class); // Should never happen throw new IllegalStateException( - "generateJwtAccess threw an unexpected checked exception", e.getCause()); + "generateJwtAccess threw an unexpected checked exception", e.getCause()); } catch (UncheckedExecutionException e) { Throwables.throwIfUnchecked(e); From fc405c38feb92e0182cc4a2a5c8082975b48f4b8 Mon Sep 17 00:00:00 2001 From: mpeddada1 Date: Thu, 22 May 2025 01:55:48 +0000 Subject: [PATCH 04/12] add verification for custom universe domain --- .../ServiceAccountJwtAccessCredentialsTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java index 9ccd98f2e..7a70bc216 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java @@ -888,6 +888,21 @@ public void getUniverseDomain_defaultUniverse() throws IOException { assertEquals(GOOGLE_DEFAULT_UNIVERSE, credentials.getUniverseDomain()); } + @Test + public void getUniverseDomain_customUniverse() throws IOException { + PrivateKey privateKey = OAuth2Utils.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")) + .setUniverseDomain("example.com") + .build(); + assertEquals("example.com", credentials.getUniverseDomain()); + } + private void verifyJwtAccess( Map> metadata, String expectedEmail, From 164f879cc41e9c881d3d48bc71ac6f2f7fdd776d Mon Sep 17 00:00:00 2001 From: mpeddada1 Date: Tue, 27 May 2025 20:35:33 +0000 Subject: [PATCH 05/12] Override getUniverseDomain --- .../google/auth/oauth2/ServiceAccountJwtAccessCredentials.java | 1 + 1 file changed, 1 insertion(+) diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java index 3a643b68a..36d25508a 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java @@ -418,6 +418,7 @@ public final String getPrivateKeyId() { return privateKeyId; } + @Override public final String getUniverseDomain() { return universeDomain; } From 9b40c417d446f608307359a18583b42652e6453f Mon Sep 17 00:00:00 2001 From: mpeddada1 Date: Tue, 27 May 2025 20:43:26 +0000 Subject: [PATCH 06/12] fix formatting --- ...erviceAccountJwtAccessCredentialsTest.java | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java index 7a70bc216..e6b2c09f8 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java @@ -878,13 +878,13 @@ public void fromJSON_UniverseDomain() throws IOException { public void getUniverseDomain_defaultUniverse() throws IOException { PrivateKey privateKey = OAuth2Utils.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(); + ServiceAccountJwtAccessCredentials.newBuilder() + .setClientId(SA_CLIENT_ID) + .setClientEmail(SA_CLIENT_EMAIL) + .setPrivateKey(privateKey) + .setPrivateKeyId(SA_PRIVATE_KEY_ID) + .setDefaultAudience(URI.create("default-audience")) + .build(); assertEquals(GOOGLE_DEFAULT_UNIVERSE, credentials.getUniverseDomain()); } @@ -937,14 +937,15 @@ private static void testFromStreamException(InputStream stream, String expectedM assertTrue(expected.getMessage().contains(expectedMessageContent)); } } + private GenericJson writeServiceAccountJson( - String clientId, - String clientEmail, - String privateKeyPkcs8, - String privateKeyId, - String projectId, - String quotaProjectId, - String universeDomain) { + String clientId, + String clientEmail, + String privateKeyPkcs8, + String privateKeyId, + String projectId, + String quotaProjectId, + String universeDomain) { GenericJson json = new GenericJson(); if (clientId != null) { json.put("client_id", clientId); From 3b81a5906f057806bcd4517fee12d55a0e0d20b0 Mon Sep 17 00:00:00 2001 From: mpeddada1 Date: Tue, 27 May 2025 21:02:43 +0000 Subject: [PATCH 07/12] fix formatting --- .../ServiceAccountJwtAccessCredentials.java | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java index 36d25508a..06ca5c1c4 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java @@ -104,8 +104,15 @@ public class ServiceAccountJwtAccessCredentials extends Credentials * @param privateKeyId Private key identifier for the service account. May be null. */ private ServiceAccountJwtAccessCredentials( - String clientId, String clientEmail, PrivateKey privateKey, String privateKeyId) { - this(clientId, clientEmail, privateKey, privateKeyId, null, null,Credentials.GOOGLE_DEFAULT_UNIVERSE); + String clientId, String clientEmail, PrivateKey privateKey, String privateKeyId) { + this( + clientId, + clientEmail, + privateKey, + privateKeyId, + null, + null, + Credentials.GOOGLE_DEFAULT_UNIVERSE); } /** @@ -226,7 +233,13 @@ public static ServiceAccountJwtAccessCredentials fromPkcs8( URI defaultAudience) throws IOException { return ServiceAccountJwtAccessCredentials.fromPkcs8( - clientId, clientEmail, privateKeyPkcs8, privateKeyId, defaultAudience, null, Credentials.GOOGLE_DEFAULT_UNIVERSE); + clientId, + clientEmail, + privateKeyPkcs8, + privateKeyId, + defaultAudience, + null, + Credentials.GOOGLE_DEFAULT_UNIVERSE); } static ServiceAccountJwtAccessCredentials fromPkcs8( @@ -240,7 +253,13 @@ static ServiceAccountJwtAccessCredentials fromPkcs8( throws IOException { PrivateKey privateKey = OAuth2Utils.privateKeyFromPkcs8(privateKeyPkcs8); return new ServiceAccountJwtAccessCredentials( - clientId, clientEmail, privateKey, privateKeyId, defaultAudience, quotaProjectId, universeDomain); + clientId, + clientEmail, + privateKey, + privateKeyId, + defaultAudience, + quotaProjectId, + universeDomain); } /** @@ -554,7 +573,6 @@ public Builder setUniverseDomain(String universeDomain) { return this; } - public String getClientId() { return clientId; } @@ -585,7 +603,13 @@ public String getUniverseDomain() { public ServiceAccountJwtAccessCredentials build() { return new ServiceAccountJwtAccessCredentials( - clientId, clientEmail, privateKey, privateKeyId, defaultAudience, quotaProjectId, universeDomain); + clientId, + clientEmail, + privateKey, + privateKeyId, + defaultAudience, + quotaProjectId, + universeDomain); } } } From 0a72e9ab58da4ab8a6f6e5651f9549c028fae221 Mon Sep 17 00:00:00 2001 From: mpeddada1 Date: Tue, 27 May 2025 21:26:16 +0000 Subject: [PATCH 08/12] include verification for pkcs and fix formatting --- ...erviceAccountJwtAccessCredentialsTest.java | 38 +++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java index e6b2c09f8..b1d658a28 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java @@ -854,7 +854,7 @@ public void fromJSON_noUniverseDomain() throws IOException { } @Test - public void fromJSON_UniverseDomain() throws IOException { + public void fromJSON_UniverseDomainSet() throws IOException { GenericJson json = writeServiceAccountJson( SA_CLIENT_ID, @@ -875,7 +875,39 @@ public void fromJSON_UniverseDomain() throws IOException { } @Test - public void getUniverseDomain_defaultUniverse() throws IOException { + public void fromPkcs8_DefaultUniverseDomain() throws IOException { + ServiceAccountJwtAccessCredentials credentials = + ServiceAccountJwtAccessCredentials.fromPkcs8( + SA_CLIENT_ID, SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID); + assertEquals(SA_CLIENT_ID, credentials.getClientId()); + assertEquals(SA_CLIENT_EMAIL, credentials.getClientEmail()); + assertEquals( + OAuth2Utils.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8), credentials.getPrivateKey()); + assertNull(credentials.getQuotaProjectId()); + assertEquals(GOOGLE_DEFAULT_UNIVERSE, credentials.getUniverseDomain()); + } + + @Test + public void fromPkcs8_CustomUniverseDomain() throws IOException { + ServiceAccountJwtAccessCredentials credentials = + ServiceAccountJwtAccessCredentials.fromPkcs8( + SA_CLIENT_ID, + SA_CLIENT_EMAIL, + SA_PRIVATE_KEY_PKCS8, + SA_PRIVATE_KEY_ID, + URI.create("default-aud"), + QUOTA_PROJECT, + "example.com"); + assertEquals(SA_CLIENT_ID, credentials.getClientId()); + assertEquals(SA_CLIENT_EMAIL, credentials.getClientEmail()); + assertEquals( + OAuth2Utils.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8), credentials.getPrivateKey()); + assertEquals(QUOTA_PROJECT, credentials.getQuotaProjectId()); + assertEquals("example.com", credentials.getUniverseDomain()); + } + + @Test + public void builder_defaultUniverseDomain() throws IOException { PrivateKey privateKey = OAuth2Utils.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8); ServiceAccountJwtAccessCredentials credentials = ServiceAccountJwtAccessCredentials.newBuilder() @@ -889,7 +921,7 @@ public void getUniverseDomain_defaultUniverse() throws IOException { } @Test - public void getUniverseDomain_customUniverse() throws IOException { + public void builder_customUniverseDomain() throws IOException { PrivateKey privateKey = OAuth2Utils.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8); ServiceAccountJwtAccessCredentials credentials = ServiceAccountJwtAccessCredentials.newBuilder() From 202c1d56a6f99c7b166405b338bba8b4dfd44dda Mon Sep 17 00:00:00 2001 From: mpeddada1 Date: Wed, 28 May 2025 20:14:29 +0000 Subject: [PATCH 09/12] rely on gax for validation --- .../auth/oauth2/ServiceAccountJwtAccessCredentials.java | 9 ++++----- .../oauth2/ServiceAccountJwtAccessCredentialsTest.java | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java index 06ca5c1c4..756e919ca 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java @@ -141,11 +141,7 @@ private ServiceAccountJwtAccessCredentials( this.defaultAudience = defaultAudience; this.credentialsCache = createCache(); this.quotaProjectId = quotaProjectId; - if (universeDomain == null || universeDomain.trim().isEmpty()) { - this.universeDomain = Credentials.GOOGLE_DEFAULT_UNIVERSE; - } else { - this.universeDomain = universeDomain; - } + this.universeDomain = universeDomain; } /** @@ -437,6 +433,7 @@ public final String getPrivateKeyId() { return privateKeyId; } + /** Returns the universe domain (example, googleapis.com) for the credentials instance. */ @Override public final String getUniverseDomain() { return universeDomain; @@ -568,6 +565,7 @@ public Builder setQuotaProjectId(String quotaProjectId) { } @CanIgnoreReturnValue + /** Sets the universe domain (example, googleapis.com). */ public Builder setUniverseDomain(String universeDomain) { this.universeDomain = universeDomain; return this; @@ -597,6 +595,7 @@ public String getQuotaProjectId() { return quotaProjectId; } + /** Returns the universe domain (example, googleapis.com) for the credentials instance. */ public String getUniverseDomain() { return universeDomain; } diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java index b1d658a28..4348aba69 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java @@ -113,7 +113,7 @@ public void constructor_allParameters_constructs() throws IOException { assertEquals(privateKey, credentials.getPrivateKey()); assertEquals(SA_PRIVATE_KEY_ID, credentials.getPrivateKeyId()); assertEquals(QUOTA_PROJECT, credentials.getQuotaProjectId()); - assertEquals(GOOGLE_DEFAULT_UNIVERSE, credentials.getUniverseDomain()); + assertNull(credentials.getUniverseDomain()); } @Test @@ -917,7 +917,7 @@ public void builder_defaultUniverseDomain() throws IOException { .setPrivateKeyId(SA_PRIVATE_KEY_ID) .setDefaultAudience(URI.create("default-audience")) .build(); - assertEquals(GOOGLE_DEFAULT_UNIVERSE, credentials.getUniverseDomain()); + assertNull(credentials.getUniverseDomain()); } @Test From 04e80562d89c2de60707a3f115c763fe564256ac Mon Sep 17 00:00:00 2001 From: mpeddada1 Date: Wed, 28 May 2025 20:27:48 +0000 Subject: [PATCH 10/12] update frompkcs8 --- .../auth/oauth2/ServiceAccountJwtAccessCredentials.java | 7 +++---- .../oauth2/ServiceAccountJwtAccessCredentialsTest.java | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java index 756e919ca..6977c446b 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java @@ -112,7 +112,7 @@ private ServiceAccountJwtAccessCredentials( privateKeyId, null, null, - Credentials.GOOGLE_DEFAULT_UNIVERSE); + null); } /** @@ -123,8 +123,7 @@ private ServiceAccountJwtAccessCredentials( * @param privateKey RSA private key object for the service account. * @param privateKeyId Private key identifier for the service account. May be null. * @param defaultAudience Audience to use if not provided by transport. May be null. - * @param universeDomain universe domain in the format some-domain.xyz. By default, returns - * googleapis.com. + * @param universeDomain universe domain in the format some-domain.xyz. */ private ServiceAccountJwtAccessCredentials( String clientId, @@ -235,7 +234,7 @@ public static ServiceAccountJwtAccessCredentials fromPkcs8( privateKeyId, defaultAudience, null, - Credentials.GOOGLE_DEFAULT_UNIVERSE); + null); } static ServiceAccountJwtAccessCredentials fromPkcs8( diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java index 4348aba69..503d97377 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java @@ -875,7 +875,7 @@ public void fromJSON_UniverseDomainSet() throws IOException { } @Test - public void fromPkcs8_DefaultUniverseDomain() throws IOException { + public void fromPkcs8_NoUniverseDomain() throws IOException { ServiceAccountJwtAccessCredentials credentials = ServiceAccountJwtAccessCredentials.fromPkcs8( SA_CLIENT_ID, SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID); @@ -884,7 +884,7 @@ public void fromPkcs8_DefaultUniverseDomain() throws IOException { assertEquals( OAuth2Utils.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8), credentials.getPrivateKey()); assertNull(credentials.getQuotaProjectId()); - assertEquals(GOOGLE_DEFAULT_UNIVERSE, credentials.getUniverseDomain()); + assertNull(credentials.getUniverseDomain()); } @Test From 07a1912a1f53e71cf5febe667bb215eca0212db3 Mon Sep 17 00:00:00 2001 From: mpeddada1 Date: Wed, 28 May 2025 20:31:36 +0000 Subject: [PATCH 11/12] revert changes to fromPkcs8 --- .../google/auth/oauth2/ServiceAccountJwtAccessCredentials.java | 2 +- .../auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java index 6977c446b..e57b88786 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java @@ -234,7 +234,7 @@ public static ServiceAccountJwtAccessCredentials fromPkcs8( privateKeyId, defaultAudience, null, - null); + Credentials.GOOGLE_DEFAULT_UNIVERSE); } static ServiceAccountJwtAccessCredentials fromPkcs8( diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java index 503d97377..ef1482274 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java @@ -884,7 +884,7 @@ public void fromPkcs8_NoUniverseDomain() throws IOException { assertEquals( OAuth2Utils.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8), credentials.getPrivateKey()); assertNull(credentials.getQuotaProjectId()); - assertNull(credentials.getUniverseDomain()); + assertEquals(Credentials.GOOGLE_DEFAULT_UNIVERSE, credentials.getUniverseDomain()); } @Test From 45f7a099f28d84e35d6b1df9ad53838245f99a02 Mon Sep 17 00:00:00 2001 From: mpeddada1 Date: Wed, 28 May 2025 20:53:00 +0000 Subject: [PATCH 12/12] keep default settings --- .../oauth2/ServiceAccountJwtAccessCredentials.java | 13 +++++++++---- .../ServiceAccountJwtAccessCredentialsTest.java | 4 ++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java index e57b88786..6e2ae2874 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ServiceAccountJwtAccessCredentials.java @@ -112,7 +112,7 @@ private ServiceAccountJwtAccessCredentials( privateKeyId, null, null, - null); + Credentials.GOOGLE_DEFAULT_UNIVERSE); } /** @@ -123,7 +123,8 @@ private ServiceAccountJwtAccessCredentials( * @param privateKey RSA private key object for the service account. * @param privateKeyId Private key identifier for the service account. May be null. * @param defaultAudience Audience to use if not provided by transport. May be null. - * @param universeDomain universe domain in the format some-domain.xyz. + * @param universeDomain universe domain in the format some-domain.xyz. By default, sets it to + * googleapis.com */ private ServiceAccountJwtAccessCredentials( String clientId, @@ -140,7 +141,11 @@ private ServiceAccountJwtAccessCredentials( this.defaultAudience = defaultAudience; this.credentialsCache = createCache(); this.quotaProjectId = quotaProjectId; - this.universeDomain = universeDomain; + if (universeDomain == null || universeDomain.trim().isEmpty()) { + this.universeDomain = Credentials.GOOGLE_DEFAULT_UNIVERSE; + } else { + this.universeDomain = universeDomain; + } } /** @@ -234,7 +239,7 @@ public static ServiceAccountJwtAccessCredentials fromPkcs8( privateKeyId, defaultAudience, null, - Credentials.GOOGLE_DEFAULT_UNIVERSE); + Credentials.GOOGLE_DEFAULT_UNIVERSE); } static ServiceAccountJwtAccessCredentials fromPkcs8( diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java index ef1482274..2505b200e 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java @@ -113,7 +113,7 @@ public void constructor_allParameters_constructs() throws IOException { assertEquals(privateKey, credentials.getPrivateKey()); assertEquals(SA_PRIVATE_KEY_ID, credentials.getPrivateKeyId()); assertEquals(QUOTA_PROJECT, credentials.getQuotaProjectId()); - assertNull(credentials.getUniverseDomain()); + assertEquals(Credentials.GOOGLE_DEFAULT_UNIVERSE, credentials.getUniverseDomain()); } @Test @@ -917,7 +917,7 @@ public void builder_defaultUniverseDomain() throws IOException { .setPrivateKeyId(SA_PRIVATE_KEY_ID) .setDefaultAudience(URI.create("default-audience")) .build(); - assertNull(credentials.getUniverseDomain()); + assertEquals(Credentials.GOOGLE_DEFAULT_UNIVERSE, credentials.getUniverseDomain()); } @Test