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
This commit is contained in:
@@ -1158,6 +1158,20 @@ able to grant any access right to any group. They will also have all
|
||||
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
|
||||
|
||||
|
||||
@@ -2663,10 +2663,14 @@ Common unit suffixes of 'k', 'm', or 'g' are supported.
|
||||
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::
|
||||
|
||||
@@ -35,6 +35,9 @@ public class GlobalCapability {
|
||||
*/
|
||||
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 @@ public class GlobalCapability {
|
||||
/** 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 @@ public class GlobalCapability {
|
||||
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 @@ public class GlobalCapability {
|
||||
|
||||
/** @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 @@ public class GlobalCapability {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -169,6 +169,10 @@ public class PermissionRuleEditor extends Composite implements
|
||||
deleteRule.removeFromParent();
|
||||
deleteRule = null;
|
||||
}
|
||||
|
||||
if (name.equals(GlobalCapability.BATCH_CHANGES_LIMIT)) {
|
||||
min.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isDeleted() {
|
||||
|
||||
@@ -34,6 +34,7 @@ public class CapabilityCollection {
|
||||
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 @@ public class CapabilityCollection {
|
||||
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);
|
||||
|
||||
@@ -24,6 +24,7 @@ public class CapabilityConstants extends TranslationBundle {
|
||||
|
||||
public String accessDatabase;
|
||||
public String administrateServer;
|
||||
public String batchChangesLimit;
|
||||
public String createAccount;
|
||||
public String createGroup;
|
||||
public String createProject;
|
||||
|
||||
@@ -1485,7 +1485,8 @@ public class ReceiveCommits {
|
||||
|
||||
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) {
|
||||
|
||||
@@ -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 @@ class ReceiveConfig {
|
||||
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 @@ class ReceiveConfig {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
accessDatabase = Access Database
|
||||
administrateServer = Administrate Server
|
||||
batchChangesLimit = Batch Changes Limit
|
||||
createAccount = Create Account
|
||||
createGroup = Create Group
|
||||
createProject = Create Project
|
||||
|
||||
Reference in New Issue
Block a user