Merge changes from topic 'permission-backend'
* changes: Hide ProjectControl.isHidden Add ProjectPermission.CREATE_CHANGE for cherry picks Add RefPermission.MERGE to check creating merge commits Hide RefControl.canSubmit, adding UPDATE_BY_SUBMIT
This commit is contained in:
@@ -154,7 +154,7 @@ public class SubmitOnPushIT extends AbstractDaemonTest {
|
||||
@Test
|
||||
public void submitOnPushNotAllowed_Error() throws Exception {
|
||||
PushOneCommit.Result r = pushTo("refs/for/master%submit");
|
||||
r.assertErrorStatus("submit not allowed");
|
||||
r.assertErrorStatus("update by submit not permitted");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -166,7 +166,7 @@ public class SubmitOnPushIT extends AbstractDaemonTest {
|
||||
push(
|
||||
"refs/for/master%submit",
|
||||
PushOneCommit.SUBJECT, "a.txt", "other content", r.getChangeId());
|
||||
r.assertErrorStatus("submit not allowed");
|
||||
r.assertErrorStatus("update by submit not permitted");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@@ -26,6 +26,7 @@ import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.git.IntegrationException;
|
||||
import com.google.gerrit.server.permissions.PermissionBackend;
|
||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||
import com.google.gerrit.server.permissions.ProjectPermission;
|
||||
import com.google.gerrit.server.permissions.RefPermission;
|
||||
import com.google.gerrit.server.project.InvalidChangeOperationException;
|
||||
import com.google.gerrit.server.project.NoSuchChangeException;
|
||||
@@ -99,10 +100,15 @@ public class CherryPick
|
||||
}
|
||||
|
||||
@Override
|
||||
public UiAction.Description getDescription(RevisionResource resource) {
|
||||
public UiAction.Description getDescription(RevisionResource rsrc) {
|
||||
return new UiAction.Description()
|
||||
.setLabel("Cherry Pick")
|
||||
.setTitle("Cherry pick change to a different branch")
|
||||
.setVisible(resource.getControl().getProjectControl().canUpload() && resource.isCurrent());
|
||||
.setVisible(
|
||||
rsrc.isCurrent()
|
||||
&& permissionBackend
|
||||
.user(user)
|
||||
.project(rsrc.getProject())
|
||||
.testOrFalse(ProjectPermission.CREATE_CHANGE));
|
||||
}
|
||||
}
|
||||
|
@@ -1545,10 +1545,13 @@ public class ReceiveCommits {
|
||||
return;
|
||||
}
|
||||
|
||||
if (magicBranch.submit
|
||||
&& !projectControl.controlForRef(MagicBranch.NEW_CHANGE + ref).canSubmit(true)) {
|
||||
reject(cmd, "submit not allowed");
|
||||
return;
|
||||
if (magicBranch.submit) {
|
||||
try {
|
||||
permissions.ref(ref).check(RefPermission.UPDATE_BY_SUBMIT);
|
||||
} catch (AuthException e) {
|
||||
reject(cmd, e.getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RevWalk walk = rp.getRevWalk();
|
||||
|
@@ -111,7 +111,7 @@ public class CommitValidators {
|
||||
IdentifiedUser user = refctl.getUser().asIdentifiedUser();
|
||||
return new CommitValidators(
|
||||
ImmutableList.of(
|
||||
new UploadMergesPermissionValidator(refctl),
|
||||
new UploadMergesPermissionValidator(perm),
|
||||
new AmendedGerritMergeCommitValidationListener(perm, gerritIdent),
|
||||
new AuthorUploaderValidator(user, perm, canonicalWebUrl),
|
||||
new CommitterUploaderValidator(user, perm, canonicalWebUrl),
|
||||
@@ -128,7 +128,7 @@ public class CommitValidators {
|
||||
IdentifiedUser user = refctl.getUser().asIdentifiedUser();
|
||||
return new CommitValidators(
|
||||
ImmutableList.of(
|
||||
new UploadMergesPermissionValidator(refctl),
|
||||
new UploadMergesPermissionValidator(perm),
|
||||
new AmendedGerritMergeCommitValidationListener(perm, gerritIdent),
|
||||
new AuthorUploaderValidator(user, perm, canonicalWebUrl),
|
||||
new SignedOffByValidator(user, perm, refctl.getProjectControl().getProjectState()),
|
||||
@@ -155,7 +155,7 @@ public class CommitValidators {
|
||||
// formats, so we play it safe and exclude them.
|
||||
return new CommitValidators(
|
||||
ImmutableList.of(
|
||||
new UploadMergesPermissionValidator(refControl),
|
||||
new UploadMergesPermissionValidator(perm),
|
||||
new AuthorUploaderValidator(user, perm, canonicalWebUrl),
|
||||
new CommitterUploaderValidator(user, perm, canonicalWebUrl)));
|
||||
}
|
||||
@@ -407,21 +407,29 @@ public class CommitValidators {
|
||||
}
|
||||
}
|
||||
|
||||
/** Require permission to upload merges. */
|
||||
/** Require permission to upload merge commits. */
|
||||
public static class UploadMergesPermissionValidator implements CommitValidationListener {
|
||||
private final RefControl refControl;
|
||||
private final PermissionBackend.ForRef perm;
|
||||
|
||||
public UploadMergesPermissionValidator(RefControl refControl) {
|
||||
this.refControl = refControl;
|
||||
public UploadMergesPermissionValidator(PermissionBackend.ForRef perm) {
|
||||
this.perm = perm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent receiveEvent)
|
||||
throws CommitValidationException {
|
||||
if (receiveEvent.commit.getParentCount() > 1 && !refControl.canUploadMerges()) {
|
||||
throw new CommitValidationException("you are not allowed to upload merges");
|
||||
if (receiveEvent.commit.getParentCount() <= 1) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
try {
|
||||
perm.check(RefPermission.MERGE);
|
||||
return Collections.emptyList();
|
||||
} catch (AuthException e) {
|
||||
throw new CommitValidationException("you are not allowed to upload merges");
|
||||
} catch (PermissionBackendException e) {
|
||||
log.error("cannot check MERGE", e);
|
||||
throw new CommitValidationException("internal auth error");
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -47,7 +47,22 @@ public enum ProjectPermission {
|
||||
* .check(RefPermission.CREATE);
|
||||
* </pre>
|
||||
*/
|
||||
CREATE_REF;
|
||||
CREATE_REF,
|
||||
|
||||
/**
|
||||
* Can create at least one change in the project.
|
||||
*
|
||||
* <p>This project level permission only validates the user may create a change for some branch
|
||||
* within the project. The exact reference name must be checked at creation:
|
||||
*
|
||||
* <pre>permissionBackend
|
||||
* .user(user)
|
||||
* .project(proj)
|
||||
* .ref(ref)
|
||||
* .check(RefPermission.CREATE_CHANGE);
|
||||
* </pre>
|
||||
*/
|
||||
CREATE_CHANGE;
|
||||
|
||||
private final String name;
|
||||
|
||||
|
@@ -28,9 +28,20 @@ public enum RefPermission {
|
||||
FORGE_AUTHOR(Permission.FORGE_AUTHOR),
|
||||
FORGE_COMMITTER(Permission.FORGE_COMMITTER),
|
||||
FORGE_SERVER(Permission.FORGE_SERVER),
|
||||
MERGE,
|
||||
BYPASS_REVIEW,
|
||||
|
||||
CREATE_CHANGE;
|
||||
/** Create a change to code review a commit. */
|
||||
CREATE_CHANGE,
|
||||
|
||||
/**
|
||||
* Creates changes, then also immediately submits them during {@code push}.
|
||||
*
|
||||
* <p>This is similar to {@link #UPDATE} except it constructs changes first, then submits them
|
||||
* according to the submit strategy, which may include cherry-pick or rebase. By creating changes
|
||||
* for each commit, automatic server side rebase, and post-update review are enabled.
|
||||
*/
|
||||
UPDATE_BY_SUBMIT;
|
||||
|
||||
private final String name;
|
||||
|
||||
|
@@ -245,7 +245,7 @@ public class ProjectControl {
|
||||
}
|
||||
|
||||
/** Returns whether the project is hidden. */
|
||||
public boolean isHidden() {
|
||||
private boolean isHidden() {
|
||||
return getProject().getState().equals(com.google.gerrit.extensions.client.ProjectState.HIDDEN);
|
||||
}
|
||||
|
||||
@@ -253,7 +253,7 @@ public class ProjectControl {
|
||||
return (canPerformOnAnyRef(Permission.CREATE) || isOwnerAnyRef());
|
||||
}
|
||||
|
||||
public boolean canUpload() {
|
||||
private boolean canCreateChanges() {
|
||||
for (SectionMatcher matcher : access()) {
|
||||
AccessSection section = matcher.section;
|
||||
if (section.getName().startsWith("refs/for/")) {
|
||||
@@ -591,6 +591,8 @@ public class ProjectControl {
|
||||
|
||||
case CREATE_REF:
|
||||
return canAddRefs();
|
||||
case CREATE_CHANGE:
|
||||
return canCreateChanges();
|
||||
}
|
||||
throw new PermissionBackendException(perm + " unsupported");
|
||||
}
|
||||
|
@@ -165,7 +165,7 @@ public class RefControl {
|
||||
}
|
||||
|
||||
/** @return true if this user can submit merge patch sets to this ref */
|
||||
public boolean canUploadMerges() {
|
||||
private boolean canUploadMerges() {
|
||||
return projectControl
|
||||
.controlForRef("refs/for/" + getRefName())
|
||||
.canPerform(Permission.PUSH_MERGE)
|
||||
@@ -178,7 +178,7 @@ public class RefControl {
|
||||
}
|
||||
|
||||
/** @return true if this user can submit patch sets to this ref */
|
||||
public boolean canSubmit(boolean isChangeOwner) {
|
||||
boolean canSubmit(boolean isChangeOwner) {
|
||||
if (RefNames.REFS_CONFIG.equals(refName)) {
|
||||
// Always allow project owners to submit configuration changes.
|
||||
// Submitting configuration changes modifies the access control
|
||||
@@ -725,15 +725,22 @@ public class RefControl {
|
||||
return canUpdate();
|
||||
case FORCE_UPDATE:
|
||||
return canForceUpdate();
|
||||
|
||||
case FORGE_AUTHOR:
|
||||
return canForgeAuthor();
|
||||
case FORGE_COMMITTER:
|
||||
return canForgeCommitter();
|
||||
case FORGE_SERVER:
|
||||
return canForgeGerritServerIdentity();
|
||||
case MERGE:
|
||||
return canUploadMerges();
|
||||
|
||||
case CREATE_CHANGE:
|
||||
return canUpload();
|
||||
|
||||
case UPDATE_BY_SUBMIT:
|
||||
return projectControl.controlForRef("refs/for/" + getRefName()).canSubmit(true);
|
||||
|
||||
case BYPASS_REVIEW:
|
||||
return canForgeAuthor()
|
||||
&& canForgeCommitter()
|
||||
|
Reference in New Issue
Block a user