Commit da3aefca authored by Philippe Vienne's avatar Philippe Vienne Committed by Greg Messner
Browse files

Add support for DeployTokensApi (#539) (#541)

parent 4bf6b504
...@@ -803,4 +803,27 @@ public interface Constants { ...@@ -803,4 +803,27 @@ public interface Constants {
return (enumHelper.toString(this)); return (enumHelper.toString(this));
} }
} }
/** Enum to use for specifying the deploy token scope. */
public enum DeployTokenScope {
READ_REPOSITORY, READ_REGISTRY;
private static JacksonJsonEnumHelper<DeployTokenScope> enumHelper = new JacksonJsonEnumHelper<>(DeployTokenScope.class);
@JsonCreator
public static DeployTokenScope forValue(String value) {
return enumHelper.forValue(value);
}
@JsonValue
public String toValue() {
return (enumHelper.toString(this));
}
@Override
public String toString() {
return (enumHelper.toString(this));
}
}
} }
package org.gitlab4j.api;
import org.gitlab4j.api.models.DeployToken;
import javax.ws.rs.core.Response;
import java.util.Date;
import java.util.List;
import java.util.stream.Stream;
/**
* This class implements the client side API for the GitLab Deploy Tokens API calls.
* See https://docs.gitlab.com/ee/api/deploy_tokens.html
*
* Since GitLab 12.9
*
*/
public class DeployTokensApi extends AbstractApi {
public DeployTokensApi(GitLabApi gitLabApi) {
super(gitLabApi);
}
/* ************************************************************************************************
* Global Deploy Token API
*/
/**
* Get a list of all deploy tokens across the GitLab instance. This endpoint requires admin access.
*
* <pre><code>GitLab Endpoint: GET /deploy_tokens</code></pre>
*
* @return a list of DeployToken
* @throws GitLabApiException if any exception occurs
*/
public List<DeployToken> getDeployTokens() throws GitLabApiException {
return (getDeployTokens(getDefaultPerPage()).all());
}
/**
* Get a Pager of all deploy tokens across all projects of the GitLab instance. This method requires admin access.
*
* <pre><code>GitLab Endpoint: GET /deploy_tokens</code></pre>
*
* @param itemsPerPage the number of DeployToken instances that will be fetched per page
* @return a Pager of DeployToken
* @throws GitLabApiException if any exception occurs
*/
public Pager<DeployToken> getDeployTokens(int itemsPerPage) throws GitLabApiException {
return (new Pager<>(this, DeployToken.class, itemsPerPage, null, "deploy_tokens"));
}
/**
* Get a Stream of all deploy tokens across all projects of the GitLab instance. This method requires admin access.
*
* <pre><code>GitLab Endpoint: GET /deploy_tokens</code></pre>
*
* @return a list of DeployToken
* @throws GitLabApiException if any exception occurs
*/
public Stream<DeployToken> getDeployTokensStream() throws GitLabApiException {
return (getDeployTokens(getDefaultPerPage()).stream());
}
/* ************************************************************************************************
* Projects Deploy Token API
*/
/**
* Get a list of the deploy tokens for the specified project. This method requires admin access.
*
* <pre><code>GitLab Endpoint: GET /projects/:id/deploy_tokens</code></pre>
*
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
* @return a list of DeployToken
* @throws GitLabApiException if any exception occurs
*/
public List<DeployToken> getProjectDeployTokens(Object projectIdOrPath) throws GitLabApiException {
return (getProjectDeployTokens(projectIdOrPath, getDefaultPerPage()).all());
}
/**
* Get a Pager of the deploy tokens for the specified project. This method requires admin access.
*
* <pre><code>GitLab Endpoint: GET /projects/:id/deploy_tokens</code></pre>
*
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance@param projectId the ID of the project
* @param itemsPerPage the number of DeployToken instances that will be fetched per page
* @return a Pager of DeployToken
* @throws GitLabApiException if any exception occurs
*/
public Pager<DeployToken> getProjectDeployTokens(Object projectIdOrPath, int itemsPerPage) throws GitLabApiException {
return (new Pager<>(this, DeployToken.class, itemsPerPage, null,
"projects", getProjectIdOrPath(projectIdOrPath), "deploy_tokens"));
}
/**
* Get a list of the deploy tokens for the specified project. This method requires admin access.
*
* <pre><code>GitLab Endpoint: GET /projects/:id/deploy_tokens</code></pre>
*
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
* @return a list of DeployToken
* @throws GitLabApiException if any exception occurs
*/
public Stream<DeployToken> getProjectDeployTokensStream(Object projectIdOrPath) throws GitLabApiException {
return (getProjectDeployTokens(projectIdOrPath, getDefaultPerPage()).stream());
}
/**
* Creates a new deploy token for a project.
*
* <pre><code>GitLab Endpoint: POST /projects/:id/deploy_tokens</code></pre>
*
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
* @param name the new deploy token’s name, required
* @param expiresAt expiration date for the deploy token. Currently documented as not required but api fails if not provided. Does not expire if no value is provided.
* @param username the username for deploy token. Currently documented as not required but api fails if not provided. Default is gitlab+deploy-token-{n}
* @param scopes indicates the deploy token scopes. Must be at least one of {@link org.gitlab4j.api.Constants.DeployTokenScope}.
* @return an DeployToken instance with info on the added deploy token
* @throws GitLabApiException if any exception occurs
*/
public DeployToken addProjectDeployToken(Object projectIdOrPath, String name, Date expiresAt, String username, List<DeployTokenScope> scopes) throws GitLabApiException {
GitLabApiForm formData = new GitLabApiForm()
.withParam("name", name, true)
.withParam("expires_at", expiresAt, true) // Currently documented as not required but api fails if not provided
.withParam("username", username, true)// Currently documented as not required but api fails if not provided
.withParam("scopes", scopes, true);
Response response = post(Response.Status.CREATED, formData,
"projects", getProjectIdOrPath(projectIdOrPath), "deploy_tokens");
return (response.readEntity(DeployToken.class));
}
/**
* Removes a deploy token from the group.
*
* <pre><code>GitLab Endpoint: DELETE /projects/:id/deploy_tokens/:token_id</code></pre>
*
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
* @param tokenId the ID of the deploy token to delete
* @throws GitLabApiException if any exception occurs
*/
public void deleteProjectDeployToken(Object projectIdOrPath, Integer tokenId) throws GitLabApiException {
if (tokenId == null) {
throw new RuntimeException("tokenId cannot be null");
}
delete(Response.Status.OK, null, "projects", getProjectIdOrPath(projectIdOrPath), "deploy_tokens", tokenId);
}
/* ************************************************************************************************
* Groups Deploy Token API
*/
/**
* Get a list of the deploy tokens for the specified group. This method requires admin access.
*
* <pre><code>GitLab Endpoint: GET /groups/:id/deploy_tokens</code></pre>
*
* @param groupIdOrPath the group in the form of an Integer(ID), String(path), or Group instance
* @return a list of DeployToken
* @throws GitLabApiException if any exception occurs
*/
public List<DeployToken> getGroupDeployTokens(Object groupIdOrPath) throws GitLabApiException {
return (getGroupDeployTokens(groupIdOrPath, getDefaultPerPage()).all());
}
/**
* Get a Pager of the deploy tokens for the specified group. This method requires admin access.
*
* <pre><code>GitLab Endpoint: GET /groups/:id/deploy_tokens</code></pre>
*
* @param groupIdOrPath the group in the form of an Integer(ID), String(path), or Group instance@param groupId the ID of the group
* @param itemsPerPage the number of DeployToken instances that will be fetched per page
* @return a Pager of DeployToken
* @throws GitLabApiException if any exception occurs
*/
public Pager<DeployToken> getGroupDeployTokens(Object groupIdOrPath, int itemsPerPage) throws GitLabApiException {
return (new Pager<>(this, DeployToken.class, itemsPerPage, null,
"groups", getGroupIdOrPath(groupIdOrPath), "deploy_tokens"));
}
/**
* Get a list of the deploy tokens for the specified group. This method requires admin access.
*
* <pre><code>GitLab Endpoint: GET /groups/:id/deploy_tokens</code></pre>
*
* @param groupIdOrPath the group in the form of an Integer(ID), String(path), or Group instance
* @return a list of DeployToken
* @throws GitLabApiException if any exception occurs
*/
public Stream<DeployToken> getGroupDeployTokensStream(Object groupIdOrPath) throws GitLabApiException {
return (getGroupDeployTokens(groupIdOrPath, getDefaultPerPage()).stream());
}
/**
* Creates a new deploy token for a group.
*
* <pre><code>GitLab Endpoint: POST /groups/:id/deploy_tokens</code></pre>
*
* @param groupIdOrPath the group in the form of an Integer(ID), String(path), or Group instance
* @param name the new deploy token’s name, required
* @param expiresAt expiration date for the deploy token. Currently documented as not required but api fails if not provided. Does not expire if no value is provided.
* @param username the username for deploy token. Currently documented as not required but api fails if not provided. Default is gitlab+deploy-token-{n}
* @param scopes indicates the deploy token scopes. Must be at least one of {@link org.gitlab4j.api.Constants.DeployTokenScope}.
* @return an DeployToken instance with info on the added deploy token
* @throws GitLabApiException if any exception occurs
*/
public DeployToken addGroupDeployToken(Object groupIdOrPath, String name, Date expiresAt, String username, List<DeployTokenScope> scopes) throws GitLabApiException {
GitLabApiForm formData = new GitLabApiForm()
.withParam("name", name, true)
.withParam("expires_at", expiresAt, true) // Currently documented as not required but api fails if not provided
.withParam("username", username, true)// Currently documented as not required but api fails if not provided
.withParam("scopes", scopes, true);
Response response = post(Response.Status.CREATED, formData,
"groups", getGroupIdOrPath(groupIdOrPath), "deploy_tokens");
return (response.readEntity(DeployToken.class));
}
/**
* Removes a deploy token from the group.
*
* <pre><code>GitLab Endpoint: DELETE /groups/:id/deploy_tokens/:token_id</code></pre>
*
* @param groupIdOrPath the group in the form of an Integer(ID), String(path), or Group instance
* @param tokenId the ID of the deploy token to delete
* @throws GitLabApiException if any exception occurs
*/
public void deleteGroupDeployToken(Object groupIdOrPath, Integer tokenId) throws GitLabApiException {
if (tokenId == null) {
throw new RuntimeException("tokenId cannot be null");
}
delete(Response.Status.OK, null, "groups", getGroupIdOrPath(groupIdOrPath), "deploy_tokens", tokenId);
}
}
...@@ -57,6 +57,7 @@ public class GitLabApi implements AutoCloseable { ...@@ -57,6 +57,7 @@ public class GitLabApi implements AutoCloseable {
private ContainerRegistryApi containerRegistryApi; private ContainerRegistryApi containerRegistryApi;
private DiscussionsApi discussionsApi; private DiscussionsApi discussionsApi;
private DeployKeysApi deployKeysApi; private DeployKeysApi deployKeysApi;
private DeployTokensApi deployTokensApi;
private EnvironmentsApi environmentsApi; private EnvironmentsApi environmentsApi;
private EpicsApi epicsApi; private EpicsApi epicsApi;
private EventsApi eventsApi; private EventsApi eventsApi;
...@@ -940,6 +941,25 @@ public class GitLabApi implements AutoCloseable { ...@@ -940,6 +941,25 @@ public class GitLabApi implements AutoCloseable {
return (deployKeysApi); return (deployKeysApi);
} }
/**
* Gets the DeployTokensApi instance owned by this GitLabApi instance. The DeployTokensApi is used
* to perform all deploy token related API calls.
*
* @return the DeployTokensApi instance owned by this GitLabApi instance
*/
public DeployTokensApi getDeployTokensApi(){
if (deployTokensApi == null) {
synchronized (this) {
if (deployTokensApi == null) {
deployTokensApi = new DeployTokensApi(this);
}
}
}
return (deployTokensApi);
}
/** /**
* Gets the DiscussionsApi instance owned by this GitLabApi instance. The DiscussionsApi is used * Gets the DiscussionsApi instance owned by this GitLabApi instance. The DiscussionsApi is used
* to perform all discussion related API calls. * to perform all discussion related API calls.
......
package org.gitlab4j.api.models;
import org.gitlab4j.api.Constants;
import org.gitlab4j.api.utils.JacksonJson;
import java.util.Date;
import java.util.List;
public class DeployToken {
private Integer id;
private String name;
private String username;
private Date expiresAt;
private List<Constants.DeployTokenScope> scopes;
private String token;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getExpiresAt() {
return expiresAt;
}
public void setExpiresAt(Date expiresAt) {
this.expiresAt = expiresAt;
}
public List<Constants.DeployTokenScope> getScopes() {
return scopes;
}
public void setScopes(List<Constants.DeployTokenScope> scopes) {
this.scopes = scopes;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
@Override
public String toString() {
return JacksonJson.toJsonString(this);
}
}
package org.gitlab4j.api;
import org.gitlab4j.api.models.DeployToken;
import org.gitlab4j.api.models.DeployTokenScope;
import org.gitlab4j.api.models.Group;
import org.gitlab4j.api.models.Project;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
/**
* In order for these tests to run you must set the following properties in test-gitlab4j.properties
*
* TEST_HOST_URL
* TEST_PRIVATE_TOKEN
* TEST_USERNAME
*
* If any of the above are NULL, all tests in this class will be skipped.
*
*/
@Category(IntegrationTest.class)
public class TestDeployTokensApi extends AbstractIntegrationTest {
// The following needs to be set to your test repository
private static final String TEST_USERNAME = HelperUtils.getProperty(USERNAME_KEY);
private static GitLabApi gitLabApi;
private static Group testGroup;
private static Project testProject;
public TestDeployTokensApi() {
super();
}
@BeforeClass
public static void setup() {
// Must setup the connection to the GitLab test server
gitLabApi = baseTestSetup();
testProject = getTestProject();
String problems = "";
if (gitLabApi != null) {
Optional<Group> group = gitLabApi.getGroupApi().getOptionalGroup(TEST_GROUP);
if (group.isPresent()) {
testGroup = group.get();
} else {
problems += "Problem fetching test group\n";
}
}
if (!problems.isEmpty()) {
System.err.print(problems);
}
if (TEST_USERNAME == null || TEST_USERNAME.trim().isEmpty()) {
System.err.println("TEST_USER_NAME cannot be empty");
}
}
@Before
public void beforeMethod() {
assumeTrue(gitLabApi != null);
assumeTrue(testGroup != null);
assumeTrue(testProject != null);
}
@Test
public void testCreateProject() throws GitLabApiException {
assertNotNull(testProject);
String name = "token-test-" + HelperUtils.getRandomInt(1000);
int initialSize = gitLabApi.getDeployTokensApi().getProjectDeployTokens(testProject).size();
DeployToken test = gitLabApi.getDeployTokensApi().addProjectDeployToken(
testProject,
name,
Date.from(Instant.now().plus(1, ChronoUnit.DAYS)),
"test-user-name", // Currently ignored by the API but correction is on the way
// See: https://gitlab.com/gitlab-org/gitlab/-/issues/211963
Collections.singletonList(DeployTokenScope.READ_REGISTRY));
assertNotNull(test);
Assert.assertEquals(test.getName(), name);
Assert.assertNotNull(test.getToken());
Assert.assertNotEquals(test.getToken(), "");
gitLabApi.getDeployTokensApi().deleteProjectDeployToken(testProject, test.getId());
assertEquals(initialSize, gitLabApi.getDeployTokensApi().getProjectDeployTokens(testProject).size());
}
@Test
public void testCreateGroup() throws GitLabApiException {
assertNotNull(testGroup);
String name = "token-test-" + HelperUtils.getRandomInt(1000);
int initialSize = gitLabApi.getDeployTokensApi().getGroupDeployTokens(testGroup).size();
DeployToken test = gitLabApi.getDeployTokensApi().addGroupDeployToken(
testGroup,
name,
Date.from(Instant.now().plus(1, ChronoUnit.DAYS)),
"test-user-name", // Currently ignored by the API but correction is on the way
// See: https://gitlab.com/gitlab-org/gitlab/-/issues/211963
Arrays.asList(DeployTokenScope.READ_REPOSITORY, DeployTokenScope.READ_REGISTRY));
assertNotNull(test);
Assert.assertEquals(test.getName(), name);
Assert.assertNotNull(test.getToken());
Assert.assertNotEquals(test.getToken(), "");
gitLabApi.getDeployTokensApi().deleteGroupDeployToken(testGroup, test.getId());
List<DeployToken> deployTokens = gitLabApi.getDeployTokensApi().getGroupDeployTokens(testGroup);
assertEquals(initialSize, deployTokens.size());
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment