diff --git a/oauth2_http/java/com/google/auth/oauth2/ImpersonatedCredentials.java b/oauth2_http/java/com/google/auth/oauth2/ImpersonatedCredentials.java index 9a86babc9..375d957a4 100644 --- a/oauth2_http/java/com/google/auth/oauth2/ImpersonatedCredentials.java +++ b/oauth2_http/java/com/google/auth/oauth2/ImpersonatedCredentials.java @@ -111,7 +111,7 @@ public class ImpersonatedCredentials extends GoogleCredentials private transient HttpTransportFactory transportFactory; - @VisibleForTesting transient Calendar calendar = Calendar.getInstance(); + private transient Calendar calendar; /** * @param sourceCredentials the source credential used to acquire the impersonated credentials. It @@ -432,6 +432,25 @@ public GoogleCredentials createScoped(Collection scopes) { .build(); } + /** + * Clones the impersonated credentials with a new calendar. + * + * @param calendar the calendar that will be used by the new ImpersonatedCredentials instance when + * parsing the received expiration time of the refreshed access token + * @return the cloned impersonated credentials with the given custom calendar + */ + public ImpersonatedCredentials createWithCustomCalendar(Calendar calendar) { + return toBuilder() + .setScopes(this.scopes) + .setLifetime(this.lifetime) + .setDelegates(this.delegates) + .setHttpTransportFactory(this.transportFactory) + .setQuotaProjectId(this.quotaProjectId) + .setIamEndpointOverride(this.iamEndpointOverride) + .setCalendar(calendar) + .build(); + } + @Override protected Map> getAdditionalHeaders() { Map> headers = super.getAdditionalHeaders(); @@ -454,6 +473,7 @@ private ImpersonatedCredentials(Builder builder) { this.quotaProjectId = builder.quotaProjectId; this.iamEndpointOverride = builder.iamEndpointOverride; this.transportFactoryClassName = this.transportFactory.getClass().getName(); + this.calendar = builder.getCalendar(); if (this.delegates == null) { this.delegates = new ArrayList(); } @@ -610,6 +630,7 @@ public static class Builder extends GoogleCredentials.Builder { private HttpTransportFactory transportFactory; private String quotaProjectId; private String iamEndpointOverride; + private Calendar calendar = Calendar.getInstance(); protected Builder() {} @@ -682,6 +703,15 @@ public Builder setIamEndpointOverride(String iamEndpointOverride) { return this; } + public Builder setCalendar(Calendar calendar) { + this.calendar = calendar; + return this; + } + + public Calendar getCalendar() { + return this.calendar; + } + public ImpersonatedCredentials build() { return new ImpersonatedCredentials(this); } diff --git a/oauth2_http/javatests/com/google/auth/oauth2/ImpersonatedCredentialsTest.java b/oauth2_http/javatests/com/google/auth/oauth2/ImpersonatedCredentialsTest.java index a02158873..4cbacb12d 100644 --- a/oauth2_http/javatests/com/google/auth/oauth2/ImpersonatedCredentialsTest.java +++ b/oauth2_http/javatests/com/google/auth/oauth2/ImpersonatedCredentialsTest.java @@ -567,7 +567,6 @@ void refreshAccessToken_delegates_success() throws IOException, IllegalStateExce @Test void refreshAccessToken_GMT_dateParsedCorrectly() throws IOException, IllegalStateException { - Calendar c = Calendar.getInstance(); c.add(Calendar.SECOND, VALID_LIFETIME); @@ -576,14 +575,15 @@ void refreshAccessToken_GMT_dateParsedCorrectly() throws IOException, IllegalSta mockTransportFactory.transport.setExpireTime(getFormattedTime(c.getTime())); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create( - sourceCredentials, - IMPERSONATED_CLIENT_EMAIL, - null, - IMMUTABLE_SCOPES_LIST, - VALID_LIFETIME, - mockTransportFactory); - // Set system timezone to GMT - targetCredentials.calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + sourceCredentials, + IMPERSONATED_CLIENT_EMAIL, + null, + IMMUTABLE_SCOPES_LIST, + VALID_LIFETIME, + mockTransportFactory) + .createWithCustomCalendar( + // Set system timezone to GMT + Calendar.getInstance(TimeZone.getTimeZone("GMT"))); assertEquals( c.getTime().toInstant().truncatedTo(ChronoUnit.SECONDS).toEpochMilli(), @@ -592,7 +592,6 @@ void refreshAccessToken_GMT_dateParsedCorrectly() throws IOException, IllegalSta @Test void refreshAccessToken_nonGMT_dateParsedCorrectly() throws IOException, IllegalStateException { - Calendar c = Calendar.getInstance(); c.add(Calendar.SECOND, VALID_LIFETIME); @@ -601,14 +600,15 @@ void refreshAccessToken_nonGMT_dateParsedCorrectly() throws IOException, Illegal mockTransportFactory.transport.setExpireTime(getFormattedTime(c.getTime())); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create( - sourceCredentials, - IMPERSONATED_CLIENT_EMAIL, - null, - IMMUTABLE_SCOPES_LIST, - VALID_LIFETIME, - mockTransportFactory); - // Set system timezone to one different than GMT - targetCredentials.calendar = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles")); + sourceCredentials, + IMPERSONATED_CLIENT_EMAIL, + null, + IMMUTABLE_SCOPES_LIST, + VALID_LIFETIME, + mockTransportFactory) + .createWithCustomCalendar( + // Set system timezone to one different than GMT + Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"))); assertEquals( c.getTime().toInstant().truncatedTo(ChronoUnit.SECONDS).toEpochMilli(),