Skip to content

Commit

Permalink
feat: allow custom lifespan for impersonated creds (#515)
Browse files Browse the repository at this point in the history
  • Loading branch information
arithmetic1728 authored Dec 16, 2020
1 parent b262c45 commit 0707ed4
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,15 @@ public class ImpersonatedCredentials extends GoogleCredentials

private static final long serialVersionUID = -2133257318957488431L;
private static final String RFC3339 = "yyyy-MM-dd'T'HH:mm:ss'Z'";
private static final int ONE_HOUR_IN_SECONDS = 3600;
private static final int TWELVE_HOURS_IN_SECONDS = 43200;
private static final String CLOUD_PLATFORM_SCOPE =
"https://www.googleapis.com/auth/cloud-platform";
private static final String IAM_ACCESS_TOKEN_ENDPOINT =
"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/%s:generateAccessToken";

private static final String SCOPE_EMPTY_ERROR = "Scopes cannot be null";
private static final String LIFETIME_EXCEEDED_ERROR =
"lifetime must be less than or equal to 3600";
"lifetime must be less than or equal to 43200";

private GoogleCredentials sourceCredentials;
private String targetPrincipal;
Expand All @@ -120,7 +120,11 @@ public class ImpersonatedCredentials extends GoogleCredentials
* 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 lifetime Number of seconds the delegated credential should be valid for. By default this
* value should be at most 3600. However, you can follow the instructions described in the
* following link to set up the service account, and extend the maximum lifetime to 43200 (12
* hours).
* https://cloud.google.com/iam/docs/creating-short-lived-service-account-credentials#sa-credentials-oauth
* @param transportFactory HTTP transport factory, creates the transport used to get access
* tokens.
* @return new credentials
Expand Down Expand Up @@ -153,7 +157,11 @@ public static ImpersonatedCredentials create(
* 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 lifetime Number of seconds the delegated credential should be valid for. By default this
* value should be at most 3600. However, you can follow the instructions described in the
* following link to set up the service account, and extend the maximum lifetime to 43200 (12
* hours).
* https://cloud.google.com/iam/docs/creating-short-lived-service-account-credentials#sa-credentials-oauth
* @return new credentials
*/
public static ImpersonatedCredentials create(
Expand Down Expand Up @@ -218,6 +226,9 @@ private ImpersonatedCredentials(Builder builder) {
if (this.scopes == null) {
throw new IllegalStateException(SCOPE_EMPTY_ERROR);
}
if (this.lifetime > TWELVE_HOURS_IN_SECONDS) {
throw new IllegalStateException(LIFETIME_EXCEEDED_ERROR);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ public class ImpersonatedCredentialsTest extends BaseSerializationTest {
Arrays.asList("https://www.googleapis.com/auth/devstorage.read_only");
private static final String ACCESS_TOKEN = "1/MkSJoj1xsli0AccessToken_NKPY2";
private static final int VALID_LIFETIME = 300;
private static final int INVALID_LIFETIME = 43210;
private static JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

private static final String RFC3339 = "yyyy-MM-dd'T'HH:mm:ss'Z'";
Expand Down Expand Up @@ -197,6 +198,24 @@ public void refreshAccessToken_malformedTarget() throws IOException {
}
}

@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 43200"));
} catch (IllegalStateException expected) {
assertTrue(expected.getMessage().contains("lifetime must be less than or equal to 43200"));
}
}

@Test()
public void credential_with_invalid_scope() throws IOException, IllegalStateException {

Expand Down

0 comments on commit 0707ed4

Please sign in to comment.