LCOV - code coverage report
Current view: top level - server/account - AccountLimits.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 41 48 85.4 %
Date: 2022-11-19 15:00:39 Functions: 10 10 100.0 %

          Line data    Source code
       1             : // Copyright (C) 2011 The Android Open Source Project
       2             : //
       3             : // Licensed under the Apache License, Version 2.0 (the "License");
       4             : // you may not use this file except in compliance with the License.
       5             : // You may obtain a copy of the License at
       6             : //
       7             : // http://www.apache.org/licenses/LICENSE-2.0
       8             : //
       9             : // Unless required by applicable law or agreed to in writing, software
      10             : // distributed under the License is distributed on an "AS IS" BASIS,
      11             : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             : // See the License for the specific language governing permissions and
      13             : // limitations under the License.
      14             : 
      15             : package com.google.gerrit.server.account;
      16             : 
      17             : import com.google.gerrit.common.Nullable;
      18             : import com.google.gerrit.common.data.GlobalCapability;
      19             : import com.google.gerrit.entities.PermissionRange;
      20             : import com.google.gerrit.entities.PermissionRule;
      21             : import com.google.gerrit.index.query.QueryProcessor;
      22             : import com.google.gerrit.server.CurrentUser;
      23             : import com.google.gerrit.server.git.QueueProvider;
      24             : import com.google.gerrit.server.group.SystemGroupBackend;
      25             : import com.google.gerrit.server.project.ProjectCache;
      26             : import com.google.inject.Inject;
      27             : import com.google.inject.Singleton;
      28             : import java.util.ArrayList;
      29             : import java.util.List;
      30             : 
      31             : /** Limits which QoS a user runs as, and how many search results it can request. */
      32             : public class AccountLimits {
      33             :   @Singleton
      34             :   public static class Factory {
      35             :     private final ProjectCache projectCache;
      36             : 
      37             :     @Inject
      38         151 :     Factory(ProjectCache projectCache) {
      39         151 :       this.projectCache = projectCache;
      40         151 :     }
      41             : 
      42             :     public AccountLimits create(CurrentUser user) {
      43         123 :       return new AccountLimits(projectCache, user);
      44             :     }
      45             :   }
      46             : 
      47             :   private final CapabilityCollection capabilities;
      48             :   private final CurrentUser user;
      49             : 
      50         123 :   private AccountLimits(ProjectCache projectCache, CurrentUser currentUser) {
      51         123 :     capabilities = projectCache.getAllProjects().getCapabilityCollection();
      52         123 :     user = currentUser;
      53         123 :   }
      54             : 
      55             :   /** Returns which priority queue the user's tasks should be submitted to. */
      56             :   public QueueProvider.QueueType getQueueType() {
      57             :     // If a non-generic group (that is not Anonymous Users or Registered Users)
      58             :     // grants us INTERACTIVE permission, use the INTERACTIVE queue even if
      59             :     // BATCH was otherwise granted. This allows site administrators to grant
      60             :     // INTERACTIVE to Registered Users, and BATCH to 'CI Servers' and have
      61             :     // the 'CI Servers' actually use the BATCH queue while everyone else gets
      62             :     // to use the INTERACTIVE queue without additional grants.
      63             :     //
      64          12 :     GroupMembership groups = user.getEffectiveGroups();
      65          12 :     boolean batch = false;
      66          12 :     for (PermissionRule r : capabilities.priority) {
      67          12 :       if (match(groups, r)) {
      68           0 :         switch (r.getAction()) {
      69             :           case INTERACTIVE:
      70           0 :             if (!SystemGroupBackend.isAnonymousOrRegistered(r.getGroup())) {
      71           0 :               return QueueProvider.QueueType.INTERACTIVE;
      72             :             }
      73             :             break;
      74             : 
      75             :           case BATCH:
      76           0 :             batch = true;
      77           0 :             break;
      78             : 
      79             :           case ALLOW:
      80             :           case BLOCK:
      81             :           case DENY:
      82             :             break;
      83             :         }
      84             :       }
      85          12 :     }
      86             : 
      87          12 :     if (batch) {
      88             :       // If any of our groups matched to the BATCH queue, use it.
      89           0 :       return QueueProvider.QueueType.BATCH;
      90             :     }
      91          12 :     return QueueProvider.QueueType.INTERACTIVE;
      92             :   }
      93             : 
      94             :   /**
      95             :    * Get the limit on a {@link QueryProcessor} for a given user.
      96             :    *
      97             :    * @return limit according to {@link GlobalCapability#QUERY_LIMIT}.
      98             :    */
      99             :   public int getQueryLimit() {
     100         122 :     return getRange(GlobalCapability.QUERY_LIMIT).getMax();
     101             :   }
     102             : 
     103             :   /** Returns true if the user has a permission rule specifying the range. */
     104             :   public boolean hasExplicitRange(String permission) {
     105          89 :     return GlobalCapability.hasRange(permission) && !getRules(permission).isEmpty();
     106             :   }
     107             : 
     108             :   /** The range of permitted values associated with a label permission. */
     109             :   @Nullable
     110             :   public PermissionRange getRange(String permission) {
     111         122 :     if (GlobalCapability.hasRange(permission)) {
     112         122 :       return toRange(permission, getRules(permission));
     113             :     }
     114           0 :     return null;
     115             :   }
     116             : 
     117             :   private static PermissionRange toRange(String permissionName, List<PermissionRule> ruleList) {
     118         122 :     int min = 0;
     119         122 :     int max = 0;
     120         122 :     if (ruleList.isEmpty()) {
     121          22 :       PermissionRange.WithDefaults defaultRange = GlobalCapability.getRange(permissionName);
     122          22 :       if (defaultRange != null) {
     123          22 :         min = defaultRange.getDefaultMin();
     124          22 :         max = defaultRange.getDefaultMax();
     125             :       }
     126          22 :     } else {
     127         122 :       for (PermissionRule rule : ruleList) {
     128         122 :         min = Math.min(min, rule.getMin());
     129         122 :         max = Math.max(max, rule.getMax());
     130         122 :       }
     131             :     }
     132         122 :     return new PermissionRange(permissionName, min, max);
     133             :   }
     134             : 
     135             :   private List<PermissionRule> getRules(String permissionName) {
     136         122 :     List<PermissionRule> rules = capabilities.getPermission(permissionName);
     137         122 :     GroupMembership groups = user.getEffectiveGroups();
     138             : 
     139         122 :     List<PermissionRule> mine = new ArrayList<>(rules.size());
     140         122 :     for (PermissionRule rule : rules) {
     141         122 :       if (match(groups, rule)) {
     142         122 :         mine.add(rule);
     143             :       }
     144         122 :     }
     145         122 :     return mine;
     146             :   }
     147             : 
     148             :   private static boolean match(GroupMembership groups, PermissionRule rule) {
     149         123 :     return groups.contains(rule.getGroup().getUUID());
     150             :   }
     151             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750