public ImpersonatedCredentials build() { return new ImpersonatedCredentials(this); }
private ImpersonatedCredentials(Builder builder) { this.sourceCredentials = builder.getSourceCredentials(); this.targetPrincipal = builder.getTargetPrincipal(); this.delegates = builder.getDelegates(); this.scopes = builder.getScopes(); this.lifetime = builder.getLifetime(); this.transportFactory = firstNonNull(builder.getHttpTransportFactory(), getFromServiceLoader(HttpTransportFactory.class, OAuth2Utils.HTTP_TRANSPORT_FACTORY)); this.transportFactoryClassName = this.transportFactory.getClass().getName(); if (this.delegates == null) { this.delegates = new ArrayList<String>(); } if (this.scopes == null) { throw new IllegalStateException(SCOPE_EMPTY_ERROR); } if (this.lifetime > ONE_HOUR_IN_SECONDS) { throw new IllegalStateException(LIFETIME_EXCEEDED_ERROR); } }
@Test() public void credential_with_invalid_lifetime() throws IOException, IllegalStateException { GoogleCredentials sourceCredentials = getSourceCredentials(); try { ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create(sourceCredentials, IMPERSONATED_CLIENT_EMAIL, null, SCOPES, INVALID_LIFETIME); targetCredentials.refreshAccessToken().getTokenValue(); fail(String.format("Should throw exception with message containing '%s'", "lifetime must be less than or equal to 3600")); } catch (IllegalStateException expected) { assertTrue(expected.getMessage().contains("lifetime must be less than or equal to 3600")); } }
@Test public void serialize() throws IOException, ClassNotFoundException { GoogleCredentials sourceCredentials = getSourceCredentials(); MockIAMCredentialsServiceTransportFactory mtransportFactory = new MockIAMCredentialsServiceTransportFactory(); mtransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mtransportFactory.transport.setAccessToken(ACCESS_TOKEN); mtransportFactory.transport.setexpireTime(getDefaultExpireTime()); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create(sourceCredentials, IMPERSONATED_CLIENT_EMAIL, null, SCOPES, VALID_LIFETIME, mtransportFactory); GoogleCredentials deserializedCredentials = serializeAndDeserialize(targetCredentials); assertEquals(targetCredentials, deserializedCredentials); assertEquals(targetCredentials.hashCode(), deserializedCredentials.hashCode()); assertEquals(targetCredentials.toString(), deserializedCredentials.toString()); assertSame(deserializedCredentials.clock, Clock.SYSTEM); }
@Test public void hashCode_equals() throws IOException { GoogleCredentials sourceCredentials = getSourceCredentials(); MockIAMCredentialsServiceTransportFactory mtransportFactory = new MockIAMCredentialsServiceTransportFactory(); mtransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mtransportFactory.transport.setAccessToken(ACCESS_TOKEN); mtransportFactory.transport.setexpireTime(getDefaultExpireTime()); ImpersonatedCredentials credentials = ImpersonatedCredentials.create(sourceCredentials, IMPERSONATED_CLIENT_EMAIL, null, SCOPES, VALID_LIFETIME, mtransportFactory); ImpersonatedCredentials otherCredentials = ImpersonatedCredentials.create(sourceCredentials, IMPERSONATED_CLIENT_EMAIL, null, SCOPES, VALID_LIFETIME, mtransportFactory); assertEquals(credentials.hashCode(), otherCredentials.hashCode()); }
/** * @param sourceCredentials The source credential used as to acquire the impersonated credentials * @param targetPrincipal The service account to impersonate. * @param delegates The chained list of delegates required to grant the final access_token. If * set, the sequence of identities must have "Service Account Token Creator" capability granted to * the preceding identity. For example, if set to [serviceAccountB, serviceAccountC], the * sourceCredential must have the Token Creator role on serviceAccountB. serviceAccountB must have * the Token Creator on serviceAccountC. Finally, C must have Token Creator on target_principal. * If left unset, sourceCredential must have that role on targetPrincipal. * @param scopes Scopes to request during the authorization grant. * @param lifetime Number of seconds the delegated credential should be valid for (up to 3600). */ public static ImpersonatedCredentials create(GoogleCredentials sourceCredentials, String targetPrincipal, List<String> delegates, List<String> scopes, int lifetime) { return ImpersonatedCredentials.newBuilder() .setSourceCredentials(sourceCredentials) .setTargetPrincipal(targetPrincipal) .setDelegates(delegates) .setScopes(scopes) .setLifetime(lifetime) .build(); }
@Test() public void credential_with_invalid_scope() throws IOException, IllegalStateException { GoogleCredentials sourceCredentials = getSourceCredentials(); try { ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create(sourceCredentials, IMPERSONATED_CLIENT_EMAIL, null, null, VALID_LIFETIME); targetCredentials.refreshAccessToken().getTokenValue(); fail(String.format("Should throw exception with message containing '%s'", "Scopes cannot be null")); } catch (IllegalStateException expected) { assertTrue(expected.getMessage().contains("Scopes cannot be null")); } }
/** * @param sourceCredentials The source credential used as to acquire the impersonated credentials * @param targetPrincipal The service account to impersonate. * @param delegates The chained list of delegates required to grant the final access_token. If * set, the sequence of identities must have "Service Account Token Creator" capability granted to * the preceding identity. For example, if set to [serviceAccountB, serviceAccountC], the * sourceCredential must have the Token Creator role on serviceAccountB. serviceAccountB must have * the Token Creator on serviceAccountC. Finally, C must have Token Creator on target_principal. * If left unset, sourceCredential must have that role on targetPrincipal. * @param scopes Scopes to request during the authorization grant. * @param lifetime Number of seconds the delegated credential should be valid for (up to 3600). */ public static ImpersonatedCredentials create(GoogleCredentials sourceCredentials, String targetPrincipal, List<String> delegates, List<String> scopes, int lifetime) { return ImpersonatedCredentials.newBuilder() .setSourceCredentials(sourceCredentials) .setTargetPrincipal(targetPrincipal) .setDelegates(delegates) .setScopes(scopes) .setLifetime(lifetime) .build(); }
@Test() public void refreshAccessToken_invalidDate() throws IOException, IllegalStateException { GoogleCredentials sourceCredentials = getSourceCredentials(); String expectedMessage = "Unparseable date"; MockIAMCredentialsServiceTransportFactory mtransportFactory = new MockIAMCredentialsServiceTransportFactory(); mtransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mtransportFactory.transport.setAccessToken("foo"); mtransportFactory.transport.setexpireTime("1973-09-29T15:01:23"); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create(sourceCredentials, IMPERSONATED_CLIENT_EMAIL, null, SCOPES, VALID_LIFETIME, mtransportFactory); try { targetCredentials.refreshAccessToken().getTokenValue(); fail(String.format("Should throw exception with message containing '%s'", expectedMessage)); } catch (IOException expected) { assertTrue(expected.getMessage().contains(expectedMessage)); } }
/** * @param sourceCredentials The source credential used as to acquire the impersonated credentials * @param targetPrincipal The service account to impersonate. * @param delegates The chained list of delegates required to grant the final access_token. If * set, the sequence of identities must have "Service Account Token Creator" capability granted to * the preceding identity. For example, if set to [serviceAccountB, serviceAccountC], the * sourceCredential must have the Token Creator role on serviceAccountB. serviceAccountB must have * the Token Creator on serviceAccountC. Finally, C must have Token Creator on target_principal. * If left unset, sourceCredential must have that role on targetPrincipal. * @param scopes Scopes to request during the authorization grant. * @param lifetime Number of seconds the delegated credential should be valid for (up to 3600). * @param transportFactory HTTP transport factory, creates the transport used to get access * tokens. */ public static ImpersonatedCredentials create(GoogleCredentials sourceCredentials, String targetPrincipal, List<String> delegates, List<String> scopes, int lifetime, HttpTransportFactory transportFactory) { return ImpersonatedCredentials.newBuilder() .setSourceCredentials(sourceCredentials) .setTargetPrincipal(targetPrincipal) .setDelegates(delegates) .setScopes(scopes) .setLifetime(lifetime) .setHttpTransportFactory(transportFactory) .build(); }
public ImpersonatedCredentials build() { return new ImpersonatedCredentials(this); }
private ImpersonatedCredentials(Builder builder) { this.sourceCredentials = builder.getSourceCredentials(); this.targetPrincipal = builder.getTargetPrincipal(); this.delegates = builder.getDelegates(); this.scopes = builder.getScopes(); this.lifetime = builder.getLifetime(); this.transportFactory = firstNonNull(builder.getHttpTransportFactory(), getFromServiceLoader(HttpTransportFactory.class, OAuth2Utils.HTTP_TRANSPORT_FACTORY)); this.transportFactoryClassName = this.transportFactory.getClass().getName(); if (this.delegates == null) { this.delegates = new ArrayList<String>(); } if (this.scopes == null) { throw new IllegalStateException(SCOPE_EMPTY_ERROR); } if (this.lifetime > ONE_HOUR_IN_SECONDS) { throw new IllegalStateException(LIFETIME_EXCEEDED_ERROR); } }
@Test() public void refreshAccessToken_delegates_success() throws IOException, IllegalStateException { GoogleCredentials sourceCredentials = getSourceCredentials(); MockIAMCredentialsServiceTransportFactory mtransportFactory = new MockIAMCredentialsServiceTransportFactory(); mtransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mtransportFactory.transport.setAccessToken(ACCESS_TOKEN); mtransportFactory.transport.setexpireTime(getDefaultExpireTime()); List<String> delegates = Arrays.asList("delegate-account@iam.gserviceaccount.com"); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create(sourceCredentials, IMPERSONATED_CLIENT_EMAIL, delegates, SCOPES, VALID_LIFETIME, mtransportFactory); assertEquals(ACCESS_TOKEN, targetCredentials.refreshAccessToken().getTokenValue()); }
/** * @param sourceCredentials The source credential used as to acquire the impersonated credentials * @param targetPrincipal The service account to impersonate. * @param delegates The chained list of delegates required to grant the final access_token. If * set, the sequence of identities must have "Service Account Token Creator" capability granted to * the preceding identity. For example, if set to [serviceAccountB, serviceAccountC], the * sourceCredential must have the Token Creator role on serviceAccountB. serviceAccountB must have * the Token Creator on serviceAccountC. Finally, C must have Token Creator on target_principal. * If left unset, sourceCredential must have that role on targetPrincipal. * @param scopes Scopes to request during the authorization grant. * @param lifetime Number of seconds the delegated credential should be valid for (up to 3600). * @param transportFactory HTTP transport factory, creates the transport used to get access * tokens. */ public static ImpersonatedCredentials create(GoogleCredentials sourceCredentials, String targetPrincipal, List<String> delegates, List<String> scopes, int lifetime, HttpTransportFactory transportFactory) { return ImpersonatedCredentials.newBuilder() .setSourceCredentials(sourceCredentials) .setTargetPrincipal(targetPrincipal) .setDelegates(delegates) .setScopes(scopes) .setLifetime(lifetime) .setHttpTransportFactory(transportFactory) .build(); }
@Test() public void refreshAccessToken_malformedTarget() throws IOException { GoogleCredentials sourceCredentials = getSourceCredentials(); MockIAMCredentialsServiceTransportFactory mtransportFactory = new MockIAMCredentialsServiceTransportFactory(); String invalidTargetEmail = "foo"; String expectedMessage = "Request contains an invalid argument"; mtransportFactory.transport.setTargetPrincipal(invalidTargetEmail); mtransportFactory.transport.setTokenResponseErrorCode(HttpStatusCodes.STATUS_CODE_BAD_REQUEST); mtransportFactory.transport.setTokenResponseErrorContent( generateErrorJson(HttpStatusCodes.STATUS_CODE_BAD_REQUEST, expectedMessage, "global", "badRequest")); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create(sourceCredentials, invalidTargetEmail, null, SCOPES, VALID_LIFETIME, mtransportFactory); try { targetCredentials.refreshAccessToken().getTokenValue(); fail(String.format("Should throw exception with message containing '%s'", expectedMessage)); } catch (IOException expected) { assertEquals("Error requesting access token", expected.getMessage()); assertTrue(expected.getCause().getMessage().contains(expectedMessage)); } }
@Test() public void refreshAccessToken_unauthorized() throws IOException { GoogleCredentials sourceCredentials = getSourceCredentials(); String expectedMessage = "The caller does not have permission"; MockIAMCredentialsServiceTransportFactory mtransportFactory = new MockIAMCredentialsServiceTransportFactory(); mtransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mtransportFactory.transport.setTokenResponseErrorCode(HttpStatusCodes.STATUS_CODE_UNAUTHORIZED); mtransportFactory.transport.setTokenResponseErrorContent( generateErrorJson(HttpStatusCodes.STATUS_CODE_UNAUTHORIZED, expectedMessage, "global", "forbidden")); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create(sourceCredentials, IMPERSONATED_CLIENT_EMAIL, null, SCOPES, VALID_LIFETIME, mtransportFactory); try { targetCredentials.refreshAccessToken().getTokenValue(); fail(String.format("Should throw exception with message containing '%s'", expectedMessage)); } catch (IOException expected) { assertEquals("Error requesting access token", expected.getMessage()); assertTrue(expected.getCause().getMessage().contains(expectedMessage)); } }
@Test() public void refreshAccessToken_success() throws IOException, IllegalStateException { GoogleCredentials sourceCredentials = getSourceCredentials(); MockIAMCredentialsServiceTransportFactory mtransportFactory = new MockIAMCredentialsServiceTransportFactory(); mtransportFactory.transport.setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL); mtransportFactory.transport.setAccessToken(ACCESS_TOKEN); mtransportFactory.transport.setexpireTime(getDefaultExpireTime()); ImpersonatedCredentials targetCredentials = ImpersonatedCredentials.create(sourceCredentials, IMPERSONATED_CLIENT_EMAIL, null, SCOPES, VALID_LIFETIME, mtransportFactory); assertEquals(ACCESS_TOKEN, targetCredentials.refreshAccessToken().getTokenValue()); }