diff --git a/src/main/java/org/gitlab4j/api/UserApi.java b/src/main/java/org/gitlab4j/api/UserApi.java index ce52527c89071f6f486c9b67a4542acc859a65d6..5d0bb99561763f79533b61eb1b71cce30c5239ff 100644 --- a/src/main/java/org/gitlab4j/api/UserApi.java +++ b/src/main/java/org/gitlab4j/api/UserApi.java @@ -904,21 +904,7 @@ public class UserApi extends AbstractApi { * @throws GitLabApiException if any exception occurs */ public ImpersonationToken createImpersonationToken(Object userIdOrUsername, String name, Date expiresAt, Scope[] scopes) throws GitLabApiException { - - if (scopes == null || scopes.length == 0) { - throw new RuntimeException("scopes cannot be null or empty"); - } - - GitLabApiForm formData = new GitLabApiForm() - .withParam("name", name, true) - .withParam("expires_at", expiresAt); - - for (Scope scope : scopes) { - formData.withParam("scopes[]", scope.toString()); - } - - Response response = post(Response.Status.CREATED, formData, "users", getUserIdOrUsername(userIdOrUsername), "impersonation_tokens"); - return (response.readEntity(ImpersonationToken.class)); + return createPersonalAccessTokenOrImpersonationToken(userIdOrUsername, name, expiresAt, scopes, true); } /** @@ -940,6 +926,43 @@ public class UserApi extends AbstractApi { delete(expectedStatus, null, "users", getUserIdOrUsername(userIdOrUsername), "impersonation_tokens", tokenId); } + /** + * Create a personal access token. Available only for admin users. + * + *
GitLab Endpoint: POST /users/:user_id/personal_access_tokens
+ * + * @param userIdOrUsername the user in the form of an Integer(ID), String(username), or User instance + * @param name the name of the personal access token, required + * @param expiresAt the expiration date of the personal access token, optional + * @param scopes an array of scopes of the personal access token + * @return the created PersonalAccessToken instance + * @throws GitLabApiException if any exception occurs + */ + public ImpersonationToken createPersonalAccessToken(Object userIdOrUsername, String name, Date expiresAt, Scope[] scopes) throws GitLabApiException { + return createPersonalAccessTokenOrImpersonationToken(userIdOrUsername, name, expiresAt, scopes, false); + } + + // as per https://docs.gitlab.com/ee/api/README.html#impersonation-tokens, impersonation tokens are a type of + // personal access token + private ImpersonationToken createPersonalAccessTokenOrImpersonationToken(Object userIdOrUsername, String name, Date expiresAt, Scope[] scopes, boolean impersonation) throws GitLabApiException { + + if (scopes == null || scopes.length == 0) { + throw new RuntimeException("scopes cannot be null or empty"); + } + + GitLabApiForm formData = new GitLabApiForm() + .withParam("name", name, true) + .withParam("expires_at", expiresAt); + + for (Scope scope : scopes) { + formData.withParam("scopes[]", scope.toString()); + } + + String tokenTypePathArg = impersonation ? "impersonation_tokens" : "personal_access_tokens"; + Response response = post(Response.Status.CREATED, formData, "users", getUserIdOrUsername(userIdOrUsername), tokenTypePathArg); + return (response.readEntity(ImpersonationToken.class)); + } + /** * Populate the REST form with data from the User instance. * diff --git a/src/main/java/org/gitlab4j/api/models/ImpersonationToken.java b/src/main/java/org/gitlab4j/api/models/ImpersonationToken.java index 60b35ebb3997049c22a74df3043736766c07bcad..6c8a005de536f7feb249681958b9ab2ecb04ae47 100644 --- a/src/main/java/org/gitlab4j/api/models/ImpersonationToken.java +++ b/src/main/java/org/gitlab4j/api/models/ImpersonationToken.java @@ -14,7 +14,7 @@ public class ImpersonationToken { /** Enum to specify the scope of an ImpersonationToken. */ public enum Scope { - API, READ_USER, READ_REPOSITORY, WRITE_REPOSITORY, READ_REGISTRY, SUDO; + API, READ_API, READ_USER, READ_REPOSITORY, WRITE_REPOSITORY, READ_REGISTRY, WRITE_REGISTRY, SUDO; private static JacksonJsonEnumHelper enumHelper = new JacksonJsonEnumHelper<>(Scope.class); diff --git a/src/test/java/org/gitlab4j/api/TestUserApi.java b/src/test/java/org/gitlab4j/api/TestUserApi.java index 16199dfefb640744b3e8f324db740249e9d19e0b..ab02e073894c7a8a6dcc210cff5e028667eb4ece 100644 --- a/src/test/java/org/gitlab4j/api/TestUserApi.java +++ b/src/test/java/org/gitlab4j/api/TestUserApi.java @@ -61,7 +61,8 @@ public class TestUserApi extends AbstractIntegrationTest { private static final String TEST_BLOCK_USERNAME = HelperUtils.getProperty(BLOCK_USERNAME_KEY); private static final String TEST_SUDO_AS_USERNAME = HelperUtils.getProperty(SUDO_AS_USERNAME_KEY); - private static final String TEST_IMPERSONATION_TOKEN_NAME = "token1"; + private static final String TEST_IMPERSONATION_TOKEN_NAME = "ipt_1"; + private static final String TEST_PERSONAL_ACCESS_TOKEN_NAME = "pat_1"; private static final String TEST_SSH_KEY = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC3rWzl/oPAD+Em2iGTmR81HcYZsopvnKp7jelI4XS91fT1NjCRrGsxf5Mw/" + "KnmtBjhk+kQjkhIrnsBDcs6DZWtNcHJtyWJZrYsfxMTqWCaQv+OTRwVboqS2pmPcbK3gizUd5GCLFTKbg4OMpdywTwi6NAPwQ" + @@ -325,8 +326,8 @@ public class TestUserApi extends AbstractIntegrationTest { User user = gitLabApi.getUserApi().getCurrentUser(); - // NOTE: READ_REGISTRY scope is left out because the GitLab server docker instance does not have the - // registry configured and the test would thus fail. + // NOTE: READ_API, READ_REGISTRY & WRITE_REGISTRY scopes are left out because the GitLab server docker instance does not + // have the registry configured and the test would thus fail. Scope[] scopes = {Scope.API, Scope.READ_USER, Scope.READ_REPOSITORY, Scope.WRITE_REPOSITORY, Scope.SUDO}; Date expiresAt = ISO8601.toDate("2018-01-01T00:00:00Z"); @@ -401,7 +402,7 @@ public class TestUserApi extends AbstractIntegrationTest { } @Test - public void testDeleteImpersonationTokens() throws GitLabApiException, ParseException { + public void testRevokeImpersonationToken() throws GitLabApiException, ParseException { User user = gitLabApi.getUserApi().getCurrentUser(); Scope[] scopes = {Scope.API, Scope.READ_USER}; @@ -418,6 +419,38 @@ public class TestUserApi extends AbstractIntegrationTest { assertFalse(token.getActive()); } + @Test + public void testCreatePersonalAccessToken() throws GitLabApiException, ParseException { + + User user = gitLabApi.getUserApi().getCurrentUser(); + + // NOTE: READ_REGISTRY & WRITE_REGISTRY scopes are left out because the GitLab server docker instance does not + // have the registry configured and the test would thus fail. + Scope[] scopes = {Scope.API, Scope.READ_API, Scope.READ_USER, Scope.READ_REPOSITORY, Scope.WRITE_REPOSITORY, Scope.SUDO}; + Date expiresAt = ISO8601.toDate("2018-01-01T00:00:00Z"); + +// This does not work with the GitLab version we are using in the integration tests +// ImpersonationToken token = null; +// try { +// +// token = gitLabApi.getUserApi().createPersonalAccessToken(user, TEST_PERSONAL_ACCESS_TOKEN_NAME, expiresAt, scopes); +// +// assertNotNull(token); +// assertNotNull(token.getId()); +// assertEquals(TEST_PERSONAL_ACCESS_TOKEN_NAME, token.getName()); +// assertEquals(expiresAt.getTime(), token.getExpiresAt().getTime()); +// assertEquals(scopes.length, token.getScopes().size()); +// assertThat(token.getScopes(), contains(scopes)); +// +// } finally { +// if (user != null && token != null) { +// // GitLab doesn't have this API method yet - not a big issue since multiple tokens with the same name +// // can be created. Note that you won't see a token in the UI unless the expiry date is in the future. +// // gitLabApi.getUserApi().revokePersonalAccessToken(user.getId(), token.getId()); +// } +// } + } + @Test public void testGetSshKeys() throws GitLabApiException {