diff options
Diffstat (limited to 'java/com/google/gerrit/server/account/AccountLimits.java')
-rw-r--r-- | java/com/google/gerrit/server/account/AccountLimits.java | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/java/com/google/gerrit/server/account/AccountLimits.java b/java/com/google/gerrit/server/account/AccountLimits.java new file mode 100644 index 0000000000..4d1d1b8e9f --- /dev/null +++ b/java/com/google/gerrit/server/account/AccountLimits.java @@ -0,0 +1,149 @@ +// Copyright (C) 2011 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.account; + +import com.google.gerrit.common.data.GlobalCapability; +import com.google.gerrit.common.data.PermissionRange; +import com.google.gerrit.common.data.PermissionRule; +import com.google.gerrit.index.query.QueryProcessor; +import com.google.gerrit.server.CurrentUser; +import com.google.gerrit.server.git.QueueProvider; +import com.google.gerrit.server.group.SystemGroupBackend; +import com.google.gerrit.server.project.ProjectCache; +import com.google.inject.Inject; +import com.google.inject.Singleton; +import java.util.ArrayList; +import java.util.List; + +/** Limits which QoS a user runs as, and how many search results it can request. */ +public class AccountLimits { + @Singleton + public static class Factory { + private final ProjectCache projectCache; + + @Inject + Factory(ProjectCache projectCache) { + this.projectCache = projectCache; + } + + public AccountLimits create(CurrentUser user) { + return new AccountLimits(projectCache, user); + } + } + + private final CapabilityCollection capabilities; + private final CurrentUser user; + + private AccountLimits(ProjectCache projectCache, CurrentUser currentUser) { + capabilities = projectCache.getAllProjects().getCapabilityCollection(); + user = currentUser; + } + + /** @return which priority queue the user's tasks should be submitted to. */ + public QueueProvider.QueueType getQueueType() { + // If a non-generic group (that is not Anonymous Users or Registered Users) + // grants us INTERACTIVE permission, use the INTERACTIVE queue even if + // BATCH was otherwise granted. This allows site administrators to grant + // INTERACTIVE to Registered Users, and BATCH to 'CI Servers' and have + // the 'CI Servers' actually use the BATCH queue while everyone else gets + // to use the INTERACTIVE queue without additional grants. + // + GroupMembership groups = user.getEffectiveGroups(); + boolean batch = false; + for (PermissionRule r : capabilities.priority) { + if (match(groups, r)) { + switch (r.getAction()) { + case INTERACTIVE: + if (!SystemGroupBackend.isAnonymousOrRegistered(r.getGroup())) { + return QueueProvider.QueueType.INTERACTIVE; + } + break; + + case BATCH: + batch = true; + break; + + case ALLOW: + case BLOCK: + case DENY: + break; + } + } + } + + if (batch) { + // If any of our groups matched to the BATCH queue, use it. + return QueueProvider.QueueType.BATCH; + } + return QueueProvider.QueueType.INTERACTIVE; + } + + /** + * Get the limit on a {@link QueryProcessor} for a given user. + * + * @return limit according to {@link GlobalCapability#QUERY_LIMIT}. + */ + public int getQueryLimit() { + return getRange(GlobalCapability.QUERY_LIMIT).getMax(); + } + + /** @return true if the user has a permission rule specifying the range. */ + public boolean hasExplicitRange(String permission) { + return GlobalCapability.hasRange(permission) && !getRules(permission).isEmpty(); + } + + /** The range of permitted values associated with a label permission. */ + public PermissionRange getRange(String permission) { + if (GlobalCapability.hasRange(permission)) { + return toRange(permission, getRules(permission)); + } + return null; + } + + private static PermissionRange toRange(String permissionName, List<PermissionRule> ruleList) { + int min = 0; + int max = 0; + if (ruleList.isEmpty()) { + PermissionRange.WithDefaults defaultRange = GlobalCapability.getRange(permissionName); + if (defaultRange != null) { + min = defaultRange.getDefaultMin(); + max = defaultRange.getDefaultMax(); + } + } else { + for (PermissionRule rule : ruleList) { + min = Math.min(min, rule.getMin()); + max = Math.max(max, rule.getMax()); + } + } + return new PermissionRange(permissionName, min, max); + } + + private List<PermissionRule> getRules(String permissionName) { + List<PermissionRule> rules = capabilities.getPermission(permissionName); + GroupMembership groups = user.getEffectiveGroups(); + + List<PermissionRule> mine = new ArrayList<>(rules.size()); + for (PermissionRule rule : rules) { + if (match(groups, rule)) { + mine.add(rule); + } + } + return mine; + } + + private static boolean match(GroupMembership groups, PermissionRule rule) { + return groups.contains(rule.getGroup().getUUID()); + } +} |