Skip to content

UserApi implement createPersonalAccessToken #963

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 38 additions & 15 deletions src/main/java/org/gitlab4j/api/UserApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -904,21 +904,7 @@ public Optional<ImpersonationToken> getOptionalImpersonationToken(Object userIdO
* @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);
}

/**
Expand All @@ -940,6 +926,43 @@ public void revokeImpersonationToken(Object userIdOrUsername, Long tokenId) thro
delete(expectedStatus, null, "users", getUserIdOrUsername(userIdOrUsername), "impersonation_tokens", tokenId);
}

/**
* Create a personal access token. Available only for admin users.
*
* <pre><code>GitLab Endpoint: POST /users/:user_id/personal_access_tokens</code></pre>
*
* @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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Scope> enumHelper = new JacksonJsonEnumHelper<>(Scope.class);

Expand Down
41 changes: 37 additions & 4 deletions src/test/java/org/gitlab4j/api/TestUserApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -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" +
Expand Down Expand Up @@ -325,8 +326,8 @@ public void testCreateImpersonationToken() throws GitLabApiException, ParseExcep

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");

Expand Down Expand Up @@ -401,7 +402,7 @@ public void testGetImpersonationTokens() throws GitLabApiException, ParseExcepti
}

@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};
Expand All @@ -418,6 +419,38 @@ public void testDeleteImpersonationTokens() throws GitLabApiException, ParseExce
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 {

Expand Down