diff --git a/Documentation/access-control.txt b/Documentation/access-control.txt index e98ed2e6e0..2862287ce0 100644 --- a/Documentation/access-control.txt +++ b/Documentation/access-control.txt @@ -324,9 +324,9 @@ is already restricted to the correct set of users. Upload Access ~~~~~~~~~~~~~ -The `Read Access +2` permits the user to upload a commit to the -project's `refs/for/BRANCH` namespace, creating a new change for -code review. +The `Read Access +2` permits the user to upload a non-merge commit +to the project's `refs/for/BRANCH` namespace, creating a new change +for code review. Rather than place this permission in its own category, its chained into the Read Access category as a higher level of access. A user @@ -340,6 +340,15 @@ grant `Read Access +1..+2` to `Registered Users` in the `\-- All Projects \--` ACL. For more private installations, its common to simply grant `Read Access +1..+2` to all users of a project. +[[category_READ_3]] +Upload Merge Access +~~~~~~~~~~~~~~~~~~~ +The `Read Access +3` permits the user to upload merge commits, but is +otherwise identical to `Read Access +2`. Some projects wish to +restrict merges to being created by Gerrit. By granting, +`Read Access +1..+2`, the only merges that enter the system will be +those created by Gerrit, or those pushed directly. + [[category_pTAG]] Push Tag ~~~~~~~~ diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java index 31a56f1ca1..cf11c9bd89 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java @@ -1541,6 +1541,12 @@ public class ReceiveCommits implements PreReceiveHook, PostReceiveHook { final PersonIdent committer = c.getCommitterIdent(); final PersonIdent author = c.getAuthorIdent(); + // Require permission to upload merges. + if (c.getParentCount() > 1 && !ctl.canUploadMerges()) { + reject(cmd, "you are not allowed to upload merges"); + return false; + } + // Don't allow the user to amend a merge created by Gerrit Code Review. // This seems to happen all too often, due to users not paying any // attention to what they are doing. diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java index 7a27835460..4c9d0a4e8f 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java @@ -147,6 +147,11 @@ public class RefControl { return canPerform(READ, (short) 2); } + /** @return true if this user can submit merge patch sets to this ref */ + public boolean canUploadMerges() { + return canPerform(READ, (short) 3); + } + /** @return true if this user can submit patch sets to this ref */ public boolean canSubmit() { return canPerform(ApprovalCategory.SUBMIT, (short) 1); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaCreator.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaCreator.java index 9a266abb6b..a24471aff3 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaCreator.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaCreator.java @@ -250,6 +250,7 @@ public class SchemaCreator { cat.setPosition((short) -1); cat.setFunctionName(NoOpFunction.NAME); vals = new ArrayList(); + vals.add(value(cat, 3, "Upload merges permission")); vals.add(value(cat, 2, "Upload permission")); vals.add(value(cat, 1, "Read access")); vals.add(value(cat, -1, "No access")); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java index b7328b5394..1fb5e02962 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java @@ -32,7 +32,7 @@ import java.util.List; /** A version of the database schema. */ public abstract class SchemaVersion { /** The current schema version. */ - private static final Class C = Schema_47.class; + private static final Class C = Schema_48.class; public static class Module extends AbstractModule { @Override diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_48.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_48.java new file mode 100644 index 0000000000..4e8b94d6b5 --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_48.java @@ -0,0 +1,54 @@ +// Copyright (C) 2010 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server.schema; + +import com.google.gerrit.reviewdb.ApprovalCategory; +import com.google.gerrit.reviewdb.ApprovalCategoryValue; +import com.google.gerrit.reviewdb.ReviewDb; +import com.google.gwtorm.client.OrmException; +import com.google.gwtorm.jdbc.JdbcSchema; +import com.google.inject.Inject; +import com.google.inject.Provider; + +import java.sql.SQLException; +import java.sql.Statement; + +import java.util.Collections; + +public class Schema_48 extends SchemaVersion { + @Inject + Schema_48(Provider prior) { + super(prior); + } + + @Override + protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException, SQLException { + // Read +3 allows merges to be uploaded + db.approvalCategoryValues().insert( + Collections.singleton(new ApprovalCategoryValue( + new ApprovalCategoryValue.Id(ApprovalCategory.READ, (short) 3), + "Upload merges permission"))); + // Since we added Read +3, elevate any Read +2 to that level to provide + // access equivalent to prior schema versions. + Statement stmt = ((JdbcSchema) db).getConnection().createStatement(); + try { + stmt.execute("UPDATE ref_rights SET max_value = 3" + + " WHERE category_id = '" + ApprovalCategory.READ.get() + + "' AND max_value = 2"); + } finally { + stmt.close(); + } + } +} diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/schema/SchemaCreatorTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/schema/SchemaCreatorTest.java index e05ce2e65f..ee9af13add 100644 --- a/gerrit-server/src/test/java/com/google/gerrit/server/schema/SchemaCreatorTest.java +++ b/gerrit-server/src/test/java/com/google/gerrit/server/schema/SchemaCreatorTest.java @@ -205,7 +205,7 @@ public class SchemaCreatorTest extends TestCase { } finally { c.close(); } - assertValueRange(ApprovalCategory.READ, -1, 1, 2); + assertValueRange(ApprovalCategory.READ, -1, 1, 2, 3); } public void testCreateSchema_ApprovalCategory_Submit() throws OrmException {