Commit 4119f463 authored by Greg Messner's avatar Greg Messner
Browse files

Mods to support user and group IDs with protected branches (#479).

parent e79e6be6
package org.gitlab4j.api; package org.gitlab4j.api;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.ws.rs.core.Form; import javax.ws.rs.core.Form;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import org.gitlab4j.api.models.AccessLevel; import org.gitlab4j.api.models.AccessLevel;
import org.gitlab4j.api.models.AllowedTo;
import org.gitlab4j.api.models.ProtectedBranch; import org.gitlab4j.api.models.ProtectedBranch;
/** /**
...@@ -60,6 +62,39 @@ public class ProtectedBranchesApi extends AbstractApi { ...@@ -60,6 +62,39 @@ public class ProtectedBranchesApi extends AbstractApi {
return (getProtectedBranches(projectIdOrPath, this.getDefaultPerPage()).stream()); return (getProtectedBranches(projectIdOrPath, this.getDefaultPerPage()).stream());
} }
/**
* Get a single protected branch or wildcard protected branch.
*
* <pre><code>GitLab Endpoint: GET /projects/:id/protected_branches/:branch_name</code></pre>
*
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
* @param branchName the name of the branch or wildcard
* @return a ProtectedBranch instance with info on the protected branch
* @throws GitLabApiException if any exception occurs
*/
public ProtectedBranch getProtectedBranch(Object projectIdOrPath, String branchName) throws GitLabApiException {
Response response = get(Response.Status.OK, null,
"projects", this.getProjectIdOrPath(projectIdOrPath), "protected_branches", urlEncode(branchName));
return (response.readEntity(ProtectedBranch.class));
}
/**
* Get an Optional instance with the value for the specific protected branch.
*
* <pre><code>GitLab Endpoint: GET /projects/:id/protected_branches/:branch_name</code></pre>
*
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
* @param branchName the name of the branch or wildcard
* @return an Optional instance with the specified protected branch as a value
*/
public Optional<ProtectedBranch> getOptionalProtectedBranch(Object projectIdOrPath, String branchName) {
try {
return (Optional.ofNullable(getProtectedBranch(projectIdOrPath, branchName)));
} catch (GitLabApiException glae) {
return (GitLabApi.createOptionalFromException(glae));
}
}
/** /**
* Unprotects the given protected branch or wildcard protected branch. * Unprotects the given protected branch or wildcard protected branch.
* *
...@@ -74,7 +109,8 @@ public class ProtectedBranchesApi extends AbstractApi { ...@@ -74,7 +109,8 @@ public class ProtectedBranchesApi extends AbstractApi {
} }
/** /**
* Protects a single repository branch or several project repository branches using a wildcard protected branch. * Protects a single repository branch or several project repository branches
* using a wildcard protected branch.
* *
* <pre><code>GitLab Endpoint: POST /projects/:id/protected_branches</code></pre> * <pre><code>GitLab Endpoint: POST /projects/:id/protected_branches</code></pre>
* *
...@@ -100,12 +136,101 @@ public class ProtectedBranchesApi extends AbstractApi { ...@@ -100,12 +136,101 @@ public class ProtectedBranchesApi extends AbstractApi {
* @throws GitLabApiException if any exception occurs * @throws GitLabApiException if any exception occurs
*/ */
public ProtectedBranch protectBranch(Object projectIdOrPath, String branchName, AccessLevel pushAccessLevel, AccessLevel mergeAccessLevel) throws GitLabApiException { public ProtectedBranch protectBranch(Object projectIdOrPath, String branchName, AccessLevel pushAccessLevel, AccessLevel mergeAccessLevel) throws GitLabApiException {
return (protectBranch(projectIdOrPath, branchName, pushAccessLevel, mergeAccessLevel, null, null));
}
/**
* Protects a single repository branch or several project repository branches using a wildcard protected branch.
*
* <pre><code>GitLab Endpoint: POST /projects/:id/protected_branches</code></pre>
*
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
* @param branchName the name of the branch to protect, can be a wildcard
* @param pushAccessLevel access levels allowed to push (defaults: 40, maintainer access level)
* @param mergeAccessLevel access levels allowed to merge (defaults: 40, maintainer access level)
* @param unprotectAccessLevel access levels allowed to unprotect (defaults: 40, maintainer access level)
* @param codeOwnerApprovalRequired prevent pushes to this branch if it matches an item in the CODEOWNERS file. (defaults: false)
* @return the branch info for the protected branch
* @throws GitLabApiException if any exception occurs
*/
public ProtectedBranch protectBranch(Object projectIdOrPath, String branchName,
AccessLevel pushAccessLevel, AccessLevel mergeAccessLevel, AccessLevel unprotectAccessLevel,
Boolean codeOwnerApprovalRequired) throws GitLabApiException {
Form formData = new GitLabApiForm() Form formData = new GitLabApiForm()
.withParam("name", branchName, true) .withParam("name", branchName, true)
.withParam("push_access_level", pushAccessLevel.toValue(), false) .withParam("push_access_level", pushAccessLevel)
.withParam("merge_access_level", mergeAccessLevel.toValue(), false); .withParam("merge_access_level", mergeAccessLevel)
.withParam("unprotect_access_level", unprotectAccessLevel)
.withParam("code_owner_approval_required", codeOwnerApprovalRequired);
Response response = post(Response.Status.CREATED, formData.asMap(),
"projects", getProjectIdOrPath(projectIdOrPath), "protected_branches");
return (response.readEntity(ProtectedBranch.class));
}
/**
* Protects a single repository branch or several project repository branches using a wildcard protected branch.
*
* <p>NOTE: This method is only available to GitLab Starter, Bronze, or higher.</p>
*
* <pre><code>GitLab Endpoint: POST /projects/:id/protected_branches</code></pre>
*
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
* @param branchName the name of the branch to protect, can be a wildcard
* @param allowedToPush user ID allowed to push, can be null
* @param allowedToMerge user ID allowed to merge, can be null
* @param allowedToUnprotect user ID allowed to unprotect, can be null
* @param codeOwnerApprovalRequired prevent pushes to this branch if it matches an item in the CODEOWNERS file. (defaults: false)
* @return the branch info for the protected branch
* @throws GitLabApiException if any exception occurs
*/
public ProtectedBranch protectBranch(Object projectIdOrPath, String branchName,
Integer allowedToPush, Integer allowedToMerge, Integer allowedToUnprotect,
Boolean codeOwnerApprovalRequired) throws GitLabApiException {
Form formData = new GitLabApiForm()
.withParam("name", branchName, true)
.withParam("allowed_to_push[][user_id]", allowedToPush)
.withParam("allowed_to_merge[][user_id]", allowedToMerge)
.withParam("allowed_to_merge[][user_id]", allowedToUnprotect)
.withParam("code_owner_approval_required", codeOwnerApprovalRequired);
Response response = post(Response.Status.CREATED, formData.asMap(), Response response = post(Response.Status.CREATED, formData.asMap(),
"projects", getProjectIdOrPath(projectIdOrPath), "protected_branches"); "projects", getProjectIdOrPath(projectIdOrPath), "protected_branches");
return (response.readEntity(ProtectedBranch.class)); return (response.readEntity(ProtectedBranch.class));
} }
/**
* Protects a single repository branch or several project repository branches using a wildcard protected branch.
*
* <p>NOTE: This method is only available to GitLab Starter, Bronze, or higher.</p>
*
* <pre><code>GitLab Endpoint: POST /projects/:id/protected_branches</code></pre>
*
* @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
* @param branchName the name of the branch to protect, can be a wildcard
* @param allowedToPush an AllowedTo instance holding the configuration for "allowed_to_push"
* @param allowedToMerge an AllowedTo instance holding the configuration for "allowed_to_merge"
* @param allowedToUnprotect an AllowedTo instance holding the configuration for "allowed_to_unprotect" be null
* @param codeOwnerApprovalRequired prevent pushes to this branch if it matches an item in the CODEOWNERS file. (defaults: false)
* @return the branch info for the protected branch
* @throws GitLabApiException if any exception occurs
*/
public ProtectedBranch protectBranch(Object projectIdOrPath, String branchName,
AllowedTo allowedToPush, AllowedTo allowedToMerge, AllowedTo allowedToUnprotect,
Boolean codeOwnerApprovalRequired) throws GitLabApiException {
GitLabApiForm formData = new GitLabApiForm()
.withParam("name", branchName, true)
.withParam("code_owner_approval_required", codeOwnerApprovalRequired);
if (allowedToPush != null)
allowedToPush.getForm(formData, "allowed_to_push");
if (allowedToMerge != null)
allowedToMerge.getForm(formData, "allowed_to_merge");
if (allowedToUnprotect != null)
allowedToUnprotect.getForm(formData, "allowed_to_unprotect");
Response response = post(Response.Status.CREATED, formData.asMap(),
"projects", getProjectIdOrPath(projectIdOrPath), "protected_branches");
return (response.readEntity(ProtectedBranch.class));
}
} }
package org.gitlab4j.api.models;
import org.gitlab4j.api.GitLabApiForm;
/**
* This class is used by the ProtectedBranchesAPi to set up the
* allowed_to_push, allowed_to_merge, and allowed_to_unprotect values.
*/
public class AllowedTo {
private AccessLevel accessLevel;
private Integer userId;
private Integer groupId;
public AllowedTo(AccessLevel accessLevel, Integer userId, Integer groupId) {
this.accessLevel = accessLevel;
this.userId = userId;
this.groupId = groupId;
}
public AllowedTo withAccessLevel(AccessLevel accessLevel) {
this.accessLevel = accessLevel;
return (this);
}
public AllowedTo withUserId(Integer userId) {
this.userId = userId;
return (this);
}
public AllowedTo withGroupId(Integer groupId) {
this.groupId = groupId;
return (this);
}
public GitLabApiForm getForm(GitLabApiForm form, String allowedToName) {
if (form == null) {
form = new GitLabApiForm();
}
return (form
.withParam(allowedToName + "[][access_level]", accessLevel)
.withParam(allowedToName + "[][user_id]", userId)
.withParam(allowedToName + "[][group_id]", groupId));
}
}
package org.gitlab4j.api.models; package org.gitlab4j.api.models;
import org.gitlab4j.api.utils.JacksonJson;
public class BranchAccessLevel { public class BranchAccessLevel {
private AccessLevel accessLevel; private AccessLevel accessLevel;
private String accessLevelDescription; private String accessLevelDescription;
private Integer userId;
private Integer groupId;
public AccessLevel getAccessLevel() { public AccessLevel getAccessLevel() {
return this.accessLevel; return this.accessLevel;
...@@ -20,4 +24,25 @@ public class BranchAccessLevel { ...@@ -20,4 +24,25 @@ public class BranchAccessLevel {
public void setAccessLevelDescription(String accessLevelDescription) { public void setAccessLevelDescription(String accessLevelDescription) {
this.accessLevelDescription = accessLevelDescription; this.accessLevelDescription = accessLevelDescription;
} }
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public Integer getGroupId() {
return groupId;
}
public void setGroupId(Integer groupId) {
this.groupId = groupId;
}
@Override
public String toString() {
return (JacksonJson.toJsonString(this));
}
} }
...@@ -10,6 +10,8 @@ public class ProtectedBranch { ...@@ -10,6 +10,8 @@ public class ProtectedBranch {
private String name; private String name;
private List<BranchAccessLevel> pushAccessLevels; private List<BranchAccessLevel> pushAccessLevels;
private List<BranchAccessLevel> mergeAccessLevels; private List<BranchAccessLevel> mergeAccessLevels;
private List<BranchAccessLevel> unprotectAccessLevels;
private Boolean codeOwnerApprovalRequired;
public String getName() { public String getName() {
return this.name; return this.name;
...@@ -35,6 +37,14 @@ public class ProtectedBranch { ...@@ -35,6 +37,14 @@ public class ProtectedBranch {
this.mergeAccessLevels = mergeAccessLevels; this.mergeAccessLevels = mergeAccessLevels;
} }
public List<BranchAccessLevel> getUnprotectAccessLevels() {
return unprotectAccessLevels;
}
public void setUnprotectAccessLevels(List<BranchAccessLevel> unprotectAccessLevels) {
this.unprotectAccessLevels = unprotectAccessLevels;
}
public static final boolean isValid(ProtectedBranch branch) { public static final boolean isValid(ProtectedBranch branch) {
return (branch != null && branch.getName() != null); return (branch != null && branch.getName() != null);
} }
...@@ -54,6 +64,19 @@ public class ProtectedBranch { ...@@ -54,6 +64,19 @@ public class ProtectedBranch {
return this; return this;
} }
public Boolean getCodeOwnerApprovalRequired() {
return codeOwnerApprovalRequired;
}
public void setCodeOwnerApprovalRequired(Boolean codeOwnerApprovalRequired) {
this.codeOwnerApprovalRequired = codeOwnerApprovalRequired;
}
public ProtectedBranch withCodeOwnerApprovalRequired(Boolean codeOwnerApprovalRequired) {
this.codeOwnerApprovalRequired = codeOwnerApprovalRequired;
return this;
}
@Override @Override
public String toString() { public String toString() {
return (JacksonJson.toJsonString(this)); return (JacksonJson.toJsonString(this));
......
...@@ -35,6 +35,7 @@ import org.junit.runners.MethodSorters; ...@@ -35,6 +35,7 @@ import org.junit.runners.MethodSorters;
public class TestProtectedBranchesApi extends AbstractIntegrationTest { public class TestProtectedBranchesApi extends AbstractIntegrationTest {
private static GitLabApi gitLabApi; private static GitLabApi gitLabApi;
private static Project testProject;
private static final String TEST_BRANCH_REF = "master"; private static final String TEST_BRANCH_REF = "master";
private static final String TEST_BRANCH_NAME = "feature/test_branch"; private static final String TEST_BRANCH_NAME = "feature/test_branch";
...@@ -42,28 +43,23 @@ public class TestProtectedBranchesApi extends AbstractIntegrationTest { ...@@ -42,28 +43,23 @@ public class TestProtectedBranchesApi extends AbstractIntegrationTest {
@BeforeClass @BeforeClass
public static void setup() { public static void setup() {
// Must setup the connection to the GitLab test server // Must setup the connection to the GitLab test server and get the test Project instance
gitLabApi = baseTestSetup(); gitLabApi = baseTestSetup();
testProject = getTestProject();
} }
@AfterClass @AfterClass
public static void teardown() { public static void teardown() {
if (gitLabApi != null) { if (testProject != null) {
try {
gitLabApi.getProtectedBranchesApi().unprotectBranch(testProject.getId(), TEST_BRANCH_NAME);
gitLabApi.getRepositoryApi().deleteBranch(testProject.getId(), TEST_BRANCH_NAME);
} catch (GitLabApiException ignore) {
}
try { try {
Project project = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME); gitLabApi.getProtectedBranchesApi().unprotectBranch(testProject.getId(), TEST_PROTECT_BRANCH_NAME);
gitLabApi.getRepositoryApi().deleteBranch(testProject.getId(), TEST_PROTECT_BRANCH_NAME);
try {
gitLabApi.getProtectedBranchesApi().unprotectBranch(project.getId(), TEST_BRANCH_NAME);
gitLabApi.getRepositoryApi().deleteBranch(project.getId(), TEST_BRANCH_NAME);
} catch (GitLabApiException ignore) {
}
try {
gitLabApi.getProtectedBranchesApi().unprotectBranch(project.getId(), TEST_PROTECT_BRANCH_NAME);
gitLabApi.getRepositoryApi().deleteBranch(project.getId(), TEST_PROTECT_BRANCH_NAME);
} catch (GitLabApiException ignore) {
}
} catch (GitLabApiException ignore) { } catch (GitLabApiException ignore) {
} }
} }
...@@ -71,22 +67,22 @@ public class TestProtectedBranchesApi extends AbstractIntegrationTest { ...@@ -71,22 +67,22 @@ public class TestProtectedBranchesApi extends AbstractIntegrationTest {
@Before @Before
public void beforeMethod() throws GitLabApiException { public void beforeMethod() throws GitLabApiException {
assumeNotNull(gitLabApi); assumeNotNull(testProject);
Project project = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME);
Branch protectedBranch; Branch protectedBranch;
try { try {
protectedBranch = gitLabApi.getRepositoryApi().getBranch(project.getId(), TEST_PROTECT_BRANCH_NAME); protectedBranch = gitLabApi.getRepositoryApi().getBranch(testProject, TEST_PROTECT_BRANCH_NAME);
} catch (GitLabApiException e) { } catch (GitLabApiException e) {
protectedBranch = gitLabApi.getRepositoryApi().createBranch(project.getId(), TEST_PROTECT_BRANCH_NAME, TEST_BRANCH_REF); protectedBranch = gitLabApi.getRepositoryApi().createBranch(testProject, TEST_PROTECT_BRANCH_NAME, TEST_BRANCH_REF);
} }
assertNotNull(protectedBranch); assertNotNull(protectedBranch);
gitLabApi.getRepositoryApi().protectBranch(project.getId(), TEST_PROTECT_BRANCH_NAME); gitLabApi.getRepositoryApi().protectBranch(testProject, TEST_PROTECT_BRANCH_NAME);
Branch branch; Branch branch;
try { try {
branch = gitLabApi.getRepositoryApi().getBranch(project.getId(), TEST_BRANCH_NAME); branch = gitLabApi.getRepositoryApi().getBranch(testProject, TEST_BRANCH_NAME);
} catch (GitLabApiException e) { } catch (GitLabApiException e) {
branch = gitLabApi.getRepositoryApi().createBranch(project.getId(), TEST_BRANCH_NAME, TEST_BRANCH_REF); branch = gitLabApi.getRepositoryApi().createBranch(testProject, TEST_BRANCH_NAME, TEST_BRANCH_REF);
} }
assertNotNull(branch); assertNotNull(branch);
} }
...@@ -94,10 +90,8 @@ public class TestProtectedBranchesApi extends AbstractIntegrationTest { ...@@ -94,10 +90,8 @@ public class TestProtectedBranchesApi extends AbstractIntegrationTest {
@Test @Test
public void testGetProtectedBranches() throws GitLabApiException { public void testGetProtectedBranches() throws GitLabApiException {
Project project = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME); assumeNotNull(testProject);
assertNotNull(project); List<ProtectedBranch> branches = gitLabApi.getProtectedBranchesApi().getProtectedBranches(testProject);
List<ProtectedBranch> branches = gitLabApi.getProtectedBranchesApi().getProtectedBranches(project.getId());
assertNotNull(branches); assertNotNull(branches);
assertTrue(branches.stream() assertTrue(branches.stream()
.anyMatch((branch) -> branch.getName().equals(TEST_PROTECT_BRANCH_NAME))); .anyMatch((branch) -> branch.getName().equals(TEST_PROTECT_BRANCH_NAME)));
...@@ -106,11 +100,9 @@ public class TestProtectedBranchesApi extends AbstractIntegrationTest { ...@@ -106,11 +100,9 @@ public class TestProtectedBranchesApi extends AbstractIntegrationTest {
@Test @Test
public void testUnprotectBranch() throws GitLabApiException { public void testUnprotectBranch() throws GitLabApiException {
Project project = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME); assumeNotNull(testProject);
assertNotNull(project); gitLabApi.getProtectedBranchesApi().unprotectBranch(testProject, TEST_PROTECT_BRANCH_NAME);
List<ProtectedBranch> branches = gitLabApi.getProtectedBranchesApi().getProtectedBranches(testProject);
gitLabApi.getProtectedBranchesApi().unprotectBranch(project.getId(), TEST_PROTECT_BRANCH_NAME);
List<ProtectedBranch> branches = gitLabApi.getProtectedBranchesApi().getProtectedBranches(project.getId());
assertNotNull(branches); assertNotNull(branches);
assertTrue(branches.stream() assertTrue(branches.stream()
.noneMatch((branch) -> branch.getName().equals(TEST_PROTECT_BRANCH_NAME))); .noneMatch((branch) -> branch.getName().equals(TEST_PROTECT_BRANCH_NAME)));
...@@ -119,14 +111,13 @@ public class TestProtectedBranchesApi extends AbstractIntegrationTest { ...@@ -119,14 +111,13 @@ public class TestProtectedBranchesApi extends AbstractIntegrationTest {
@Test @Test
public void testProtectBranch() throws GitLabApiException { public void testProtectBranch() throws GitLabApiException {
Project project = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME); assumeNotNull(testProject);
assertNotNull(project);
ProtectedBranch branch = gitLabApi.getProtectedBranchesApi().protectBranch(project.getId(), TEST_BRANCH_NAME); ProtectedBranch branch = gitLabApi.getProtectedBranchesApi().protectBranch(testProject, TEST_BRANCH_NAME);
assertNotNull(branch); assertNotNull(branch);
assertEquals(TEST_BRANCH_NAME, branch.getName()); assertEquals(TEST_BRANCH_NAME, branch.getName());
List<ProtectedBranch> branches = gitLabApi.getProtectedBranchesApi().getProtectedBranches(project.getId()); List<ProtectedBranch> branches = gitLabApi.getProtectedBranchesApi().getProtectedBranches(testProject);
assertNotNull(branches); assertNotNull(branches);
assertTrue(branches.stream() assertTrue(branches.stream()
.anyMatch((protectedBranch) -> protectedBranch.getName().equals(TEST_BRANCH_NAME))); .anyMatch((protectedBranch) -> protectedBranch.getName().equals(TEST_BRANCH_NAME)));
......
...@@ -6,8 +6,7 @@ ...@@ -6,8 +6,7 @@
"access_level_description": "Masters" "access_level_description": "Masters"
}, },
{ {
"access_level": 30, "user_id": 1
"access_level_description": "Developer access"
} }
], ],
"merge_access_levels": [ "merge_access_levels": [
...@@ -16,8 +15,7 @@ ...@@ -16,8 +15,7 @@
"access_level_description": "Masters" "access_level_description": "Masters"
}, },
{ {
"access_level": 30, "group_id": 2
"access_level_description": "Developer access"
} }
] ]
} }
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