Enable configurable 'maxBatchChanges' limit
One use case is when a group is responsible for importing
large batches of changes delivered from external partners,
and those changes all require review. This group, and only
this group, should be allowed to bypass the limit that is
enforced for everyone else.
Allow site administrators to configure the 'maxBatchChanges'
limit for users from global capability UI of All-Projects
access. The min box does not make sense if its value is not 0,
so disable it after giving it the default value of 0.
The effective limit value will be the capability value if it
exists, or the value in gerrit.config if it exists, or else
no limit.
Change-Id: Ic929dc4a89cc8ccbd098035ce2ceac4f22fd54da
diff --git a/Documentation/access-control.txt b/Documentation/access-control.txt
index e814daf..e500e4a 100644
--- a/Documentation/access-control.txt
+++ b/Documentation/access-control.txt
@@ -1158,6 +1158,20 @@
capabilities granted to them automatically.
+[[capability_batchChangesLimit]]
+=== Batch Changes Limit
+
+Allow site administrators to configure the batch changes limit for
+users to override the system config
+link:config-gerrit.html#receive.maxBatchChanges['receive.maxBatchChanges'].
+
+Administrators can add a global block to `All-Projects` with group(s)
+that should have different limits.
+
+When applying a batch changes limit to a user the largest value
+granted by any of their groups is used. 0 means no limit.
+
+
[[capability_createAccount]]
=== Create Account
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index b99c899..ccf27c6 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -2663,10 +2663,14 @@
The maximum number of changes that Gerrit allows to be pushed
in a batch for review. When this number is exceeded Gerrit rejects
the push with an error message.
-
++
+May be overridden for certain groups by specifying a limit in the
+link:access-control.html#capability_batchChangesLimit['Batch Changes Limit']
+global capability.
++
This setting can be used to prevent users from uploading large
number of changes for review by mistake.
-
++
Default is zero, no limit.
[[receive.threadPoolSize]]receive.threadPoolSize::
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/GlobalCapability.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GlobalCapability.java
index e4b0381..93fd208 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/GlobalCapability.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/GlobalCapability.java
@@ -35,6 +35,9 @@
*/
public static final String ADMINISTRATE_SERVER = "administrateServer";
+ /** Maximum number of changes that may be pushed in a batch. */
+ public static final String BATCH_CHANGES_LIMIT = "batchChangesLimit";
+
/** Can create any account on the server. */
public static final String CREATE_ACCOUNT = "createAccount";
@@ -97,6 +100,13 @@
/** Can view all pending tasks in the queue (not just the filtered set). */
public static final String VIEW_QUEUE = "viewQueue";
+ /**
+ * Default maximum number of changes that may be pushed in a batch, 0 means no
+ * limit. This is just used as a suggestion for prepopulating the field in the
+ * access UI.
+ */
+ private static final int DEFAULT_MAX_BATCH_CHANGES = 0;
+
private static final List<String> NAMES_ALL;
private static final List<String> NAMES_LC;
@@ -104,6 +114,7 @@
NAMES_ALL = new ArrayList<>();
NAMES_ALL.add(ACCESS_DATABASE);
NAMES_ALL.add(ADMINISTRATE_SERVER);
+ NAMES_ALL.add(BATCH_CHANGES_LIMIT);
NAMES_ALL.add(CREATE_ACCOUNT);
NAMES_ALL.add(CREATE_GROUP);
NAMES_ALL.add(CREATE_PROJECT);
@@ -140,7 +151,8 @@
/** @return true if the capability should have a range attached. */
public static boolean hasRange(String varName) {
- return QUERY_LIMIT.equalsIgnoreCase(varName);
+ return QUERY_LIMIT.equalsIgnoreCase(varName)
+ || BATCH_CHANGES_LIMIT.equalsIgnoreCase(varName);
}
/** @return the valid range for the capability if it has one, otherwise null. */
@@ -151,6 +163,12 @@
0, Integer.MAX_VALUE,
0, DEFAULT_MAX_QUERY_LIMIT);
}
+ if (BATCH_CHANGES_LIMIT.equalsIgnoreCase(varName)) {
+ return new PermissionRange.WithDefaults(
+ varName,
+ 0, Integer.MAX_VALUE,
+ 0, DEFAULT_MAX_BATCH_CHANGES);
+ }
return null;
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/PermissionRuleEditor.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/PermissionRuleEditor.java
index 163702c..f66307c 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/PermissionRuleEditor.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/PermissionRuleEditor.java
@@ -169,6 +169,10 @@
deleteRule.removeFromParent();
deleteRule = null;
}
+
+ if (name.equals(GlobalCapability.BATCH_CHANGES_LIMIT)) {
+ min.setEnabled(false);
+ }
}
boolean isDeleted() {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityCollection.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityCollection.java
index f60c794..3017f73 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityCollection.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityCollection.java
@@ -34,6 +34,7 @@
private final Map<String, List<PermissionRule>> permissions;
public final List<PermissionRule> administrateServer;
+ public final List<PermissionRule> batchChangesLimit;
public final List<PermissionRule> emailReviewers;
public final List<PermissionRule> priority;
public final List<PermissionRule> queryLimit;
@@ -74,6 +75,7 @@
permissions = Collections.unmodifiableMap(res);
administrateServer = getPermission(GlobalCapability.ADMINISTRATE_SERVER);
+ batchChangesLimit = getPermission(GlobalCapability.BATCH_CHANGES_LIMIT);
emailReviewers = getPermission(GlobalCapability.EMAIL_REVIEWERS);
priority = getPermission(GlobalCapability.PRIORITY);
queryLimit = getPermission(GlobalCapability.QUERY_LIMIT);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/CapabilityConstants.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/CapabilityConstants.java
index 4c93ce0..99a4f52 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/config/CapabilityConstants.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/CapabilityConstants.java
@@ -24,6 +24,7 @@
public String accessDatabase;
public String administrateServer;
+ public String batchChangesLimit;
public String createAccount;
public String createGroup;
public String createProject;
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 b7c7679..585c072 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
@@ -1485,7 +1485,8 @@
List<ChangeLookup> pending = Lists.newArrayList();
final Set<Change.Key> newChangeIds = new HashSet<>();
- final int maxBatchChanges = receiveConfig.maxBatchChanges;
+ final int maxBatchChanges =
+ receiveConfig.getEffectiveMaxBatchChangesLimit(currentUser);
for (;;) {
final RevCommit c = walk.next();
if (c == null) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveConfig.java
index 6d37ae0..ac6116c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveConfig.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveConfig.java
@@ -14,6 +14,9 @@
package com.google.gerrit.server.git;
+import static com.google.gerrit.common.data.GlobalCapability.BATCH_CHANGES_LIMIT;
+
+import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -25,7 +28,7 @@
final boolean checkMagicRefs;
final boolean checkReferencedObjectsAreReachable;
final boolean allowDrafts;
- final int maxBatchChanges;
+ private final int systemMaxBatchChanges;
@Inject
ReceiveConfig(@GerritServerConfig Config config) {
@@ -38,6 +41,13 @@
allowDrafts = config.getBoolean(
"change", null, "allowDrafts",
true);
- maxBatchChanges = config.getInt("receive", "maxBatchChanges", 0);
+ systemMaxBatchChanges = config.getInt("receive", "maxBatchChanges", 0);
+ }
+
+ public int getEffectiveMaxBatchChangesLimit(CurrentUser user) {
+ if (user.getCapabilities().canPerform(BATCH_CHANGES_LIMIT)) {
+ return user.getCapabilities().getRange(BATCH_CHANGES_LIMIT).getMax();
+ }
+ return systemMaxBatchChanges;
}
}
diff --git a/gerrit-server/src/main/resources/com/google/gerrit/server/config/CapabilityConstants.properties b/gerrit-server/src/main/resources/com/google/gerrit/server/config/CapabilityConstants.properties
index c8e95bc..9c48292 100644
--- a/gerrit-server/src/main/resources/com/google/gerrit/server/config/CapabilityConstants.properties
+++ b/gerrit-server/src/main/resources/com/google/gerrit/server/config/CapabilityConstants.properties
@@ -1,5 +1,6 @@
accessDatabase = Access Database
administrateServer = Administrate Server
+batchChangesLimit = Batch Changes Limit
createAccount = Create Account
createGroup = Create Group
createProject = Create Project