LCOV - code coverage report
Current view: top level - server/restapi/account - GetCapabilities.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 40 57 70.2 %
Date: 2022-11-19 15:00:39 Functions: 8 11 72.7 %

          Line data    Source code
       1             : // Copyright (C) 2012 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.restapi.account;
      16             : 
      17             : import static com.google.gerrit.common.data.GlobalCapability.PRIORITY;
      18             : import static com.google.gerrit.server.permissions.DefaultPermissionMappings.globalOrPluginPermissionName;
      19             : import static com.google.gerrit.server.permissions.DefaultPermissionMappings.globalPermissionName;
      20             : import static com.google.gerrit.server.permissions.DefaultPermissionMappings.pluginCapabilityName;
      21             : 
      22             : import com.google.common.collect.Iterables;
      23             : import com.google.gerrit.common.data.GlobalCapability;
      24             : import com.google.gerrit.entities.PermissionRange;
      25             : import com.google.gerrit.extensions.api.access.GlobalOrPluginPermission;
      26             : import com.google.gerrit.extensions.api.access.PluginPermission;
      27             : import com.google.gerrit.extensions.config.CapabilityDefinition;
      28             : import com.google.gerrit.extensions.registration.DynamicMap;
      29             : import com.google.gerrit.extensions.restapi.BinaryResult;
      30             : import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
      31             : import com.google.gerrit.extensions.restapi.Response;
      32             : import com.google.gerrit.extensions.restapi.RestApiException;
      33             : import com.google.gerrit.extensions.restapi.RestReadView;
      34             : import com.google.gerrit.server.CurrentUser;
      35             : import com.google.gerrit.server.OptionUtil;
      36             : import com.google.gerrit.server.account.AccountLimits;
      37             : import com.google.gerrit.server.account.AccountResource;
      38             : import com.google.gerrit.server.account.AccountResource.Capability;
      39             : import com.google.gerrit.server.git.QueueProvider;
      40             : import com.google.gerrit.server.permissions.GlobalPermission;
      41             : import com.google.gerrit.server.permissions.PermissionBackend;
      42             : import com.google.gerrit.server.permissions.PermissionBackendException;
      43             : import com.google.inject.Inject;
      44             : import com.google.inject.Provider;
      45             : import com.google.inject.Singleton;
      46             : import java.util.HashSet;
      47             : import java.util.LinkedHashMap;
      48             : import java.util.Map;
      49             : import java.util.Set;
      50             : import org.kohsuke.args4j.Option;
      51             : 
      52             : /**
      53             :  * REST endpoint to list the global capabilities that are assigned to an account.
      54             :  *
      55             :  * <p>This REST endpoint handles {@code GET /accounts/<account-identifier>/capabilities/} requests.
      56             :  */
      57             : public class GetCapabilities implements RestReadView<AccountResource> {
      58             :   @Option(name = "-q", metaVar = "CAP", usage = "Capability to inspect")
      59             :   void addQuery(String name) {
      60           0 :     if (query == null) {
      61           0 :       query = new HashSet<>();
      62             :     }
      63           0 :     Iterables.addAll(query, OptionUtil.splitOptionValue(name));
      64           0 :   }
      65             : 
      66             :   private Set<String> query;
      67             : 
      68             :   private final PermissionBackend permissionBackend;
      69             :   private final AccountLimits.Factory limitsFactory;
      70             :   private final Provider<CurrentUser> self;
      71             :   private final DynamicMap<CapabilityDefinition> pluginCapabilities;
      72             : 
      73             :   @Inject
      74             :   GetCapabilities(
      75             :       PermissionBackend permissionBackend,
      76             :       AccountLimits.Factory limitsFactory,
      77             :       Provider<CurrentUser> self,
      78           2 :       DynamicMap<CapabilityDefinition> pluginCapabilities) {
      79           2 :     this.permissionBackend = permissionBackend;
      80           2 :     this.limitsFactory = limitsFactory;
      81           2 :     this.self = self;
      82           2 :     this.pluginCapabilities = pluginCapabilities;
      83           2 :   }
      84             : 
      85             :   @Override
      86             :   public Response<Map<String, Object>> apply(AccountResource resource)
      87             :       throws RestApiException, PermissionBackendException {
      88           2 :     permissionBackend.checkUsesDefaultCapabilities();
      89           2 :     PermissionBackend.WithUser perm = permissionBackend.currentUser();
      90           2 :     if (!self.get().hasSameAccountId(resource.getUser())) {
      91           0 :       perm.check(GlobalPermission.ADMINISTRATE_SERVER);
      92           0 :       perm = permissionBackend.absentUser(resource.getUser().getAccountId());
      93             :     }
      94             : 
      95           2 :     Map<String, Object> have = new LinkedHashMap<>();
      96           2 :     for (GlobalOrPluginPermission p : perm.test(permissionsToTest())) {
      97           2 :       have.put(globalOrPluginPermissionName(p), true);
      98           2 :     }
      99             : 
     100           2 :     AccountLimits limits = limitsFactory.create(resource.getUser());
     101           2 :     addRanges(have, limits);
     102           2 :     addPriority(have, limits);
     103             : 
     104           2 :     return Response.ok(have);
     105             :   }
     106             : 
     107             :   private Set<GlobalOrPluginPermission> permissionsToTest() {
     108           2 :     Set<GlobalOrPluginPermission> toTest = new HashSet<>();
     109           2 :     for (GlobalPermission p : GlobalPermission.values()) {
     110           2 :       if (want(globalPermissionName(p))) {
     111           2 :         toTest.add(p);
     112             :       }
     113             :     }
     114             : 
     115           2 :     for (String pluginName : pluginCapabilities.plugins()) {
     116           0 :       for (String capability : pluginCapabilities.byPlugin(pluginName).keySet()) {
     117           0 :         PluginPermission p = new PluginPermission(pluginName, capability);
     118           0 :         if (want(pluginCapabilityName(p))) {
     119           0 :           toTest.add(p);
     120             :         }
     121           0 :       }
     122           0 :     }
     123           2 :     return toTest;
     124             :   }
     125             : 
     126             :   private boolean want(String name) {
     127           2 :     return query == null || query.contains(name.toLowerCase());
     128             :   }
     129             : 
     130             :   private void addRanges(Map<String, Object> have, AccountLimits limits) {
     131           2 :     for (String name : GlobalCapability.getRangeNames()) {
     132           2 :       if (want(name) && limits.hasExplicitRange(name)) {
     133           2 :         have.put(name, new Range(limits.getRange(name)));
     134             :       }
     135           2 :     }
     136           2 :   }
     137             : 
     138             :   private void addPriority(Map<String, Object> have, AccountLimits limits) {
     139           2 :     QueueProvider.QueueType queue = limits.getQueueType();
     140           2 :     if (queue != QueueProvider.QueueType.INTERACTIVE
     141           0 :         || (query != null && query.contains(PRIORITY))) {
     142           0 :       have.put(PRIORITY, queue);
     143             :     }
     144           2 :   }
     145             : 
     146             :   private static class Range {
     147             :     private transient PermissionRange range;
     148             : 
     149             :     @SuppressWarnings("unused")
     150             :     private int min;
     151             : 
     152             :     @SuppressWarnings("unused")
     153             :     private int max;
     154             : 
     155           2 :     Range(PermissionRange r) {
     156           2 :       range = r;
     157           2 :       min = r.getMin();
     158           2 :       max = r.getMax();
     159           2 :     }
     160             : 
     161             :     @Override
     162             :     public String toString() {
     163           0 :       return range.toString();
     164             :     }
     165             :   }
     166             : 
     167             :   /**
     168             :    * REST endpoint to check if a global capability is assigned to an account.
     169             :    *
     170             :    * <p>This REST endpoint handles {@code GET
     171             :    * /accounts/<account-identifier>/capabilities/<capability-identifier>} requests.
     172             :    */
     173             :   @Singleton
     174             :   public static class CheckOne implements RestReadView<AccountResource.Capability> {
     175             :     private final PermissionBackend permissionBackend;
     176             : 
     177             :     @Inject
     178         138 :     CheckOne(PermissionBackend permissionBackend) {
     179         138 :       this.permissionBackend = permissionBackend;
     180         138 :     }
     181             : 
     182             :     @Override
     183             :     public Response<BinaryResult> apply(Capability resource) throws ResourceNotFoundException {
     184           0 :       permissionBackend.checkUsesDefaultCapabilities();
     185           0 :       return Response.ok(BinaryResult.create("ok\n"));
     186             :     }
     187             :   }
     188             : }

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