LCOV - code coverage report
Current view: top level - server/restapi/project - SetAccess.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 46 51 90.2 %
Date: 2022-11-19 15:00:39 Functions: 2 2 100.0 %

          Line data    Source code
       1             : // Copyright (C) 2016 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.project;
      16             : 
      17             : import com.google.common.base.Strings;
      18             : import com.google.common.collect.Iterables;
      19             : import com.google.gerrit.entities.AccessSection;
      20             : import com.google.gerrit.entities.Project;
      21             : import com.google.gerrit.exceptions.InvalidNameException;
      22             : import com.google.gerrit.extensions.api.access.ProjectAccessInfo;
      23             : import com.google.gerrit.extensions.api.access.ProjectAccessInput;
      24             : import com.google.gerrit.extensions.restapi.BadRequestException;
      25             : import com.google.gerrit.extensions.restapi.ResourceConflictException;
      26             : import com.google.gerrit.extensions.restapi.Response;
      27             : import com.google.gerrit.extensions.restapi.RestModifyView;
      28             : import com.google.gerrit.server.CreateGroupPermissionSyncer;
      29             : import com.google.gerrit.server.IdentifiedUser;
      30             : import com.google.gerrit.server.account.GroupBackend;
      31             : import com.google.gerrit.server.git.meta.MetaDataUpdate;
      32             : import com.google.gerrit.server.permissions.GlobalPermission;
      33             : import com.google.gerrit.server.permissions.PermissionBackend;
      34             : import com.google.gerrit.server.permissions.RefPermission;
      35             : import com.google.gerrit.server.project.ProjectCache;
      36             : import com.google.gerrit.server.project.ProjectConfig;
      37             : import com.google.gerrit.server.project.ProjectResource;
      38             : import com.google.inject.Inject;
      39             : import com.google.inject.Provider;
      40             : import com.google.inject.Singleton;
      41             : import java.util.List;
      42             : import org.eclipse.jgit.errors.ConfigInvalidException;
      43             : 
      44             : @Singleton
      45             : public class SetAccess implements RestModifyView<ProjectResource, ProjectAccessInput> {
      46             :   protected final GroupBackend groupBackend;
      47             :   private final PermissionBackend permissionBackend;
      48             :   private final Provider<MetaDataUpdate.User> metaDataUpdateFactory;
      49             :   private final GetAccess getAccess;
      50             :   private final ProjectCache projectCache;
      51             :   private final Provider<IdentifiedUser> identifiedUser;
      52             :   private final SetAccessUtil accessUtil;
      53             :   private final CreateGroupPermissionSyncer createGroupPermissionSyncer;
      54             :   private final ProjectConfig.Factory projectConfigFactory;
      55             : 
      56             :   @Inject
      57             :   private SetAccess(
      58             :       GroupBackend groupBackend,
      59             :       PermissionBackend permissionBackend,
      60             :       Provider<MetaDataUpdate.User> metaDataUpdateFactory,
      61             :       ProjectCache projectCache,
      62             :       GetAccess getAccess,
      63             :       Provider<IdentifiedUser> identifiedUser,
      64             :       SetAccessUtil accessUtil,
      65             :       CreateGroupPermissionSyncer createGroupPermissionSyncer,
      66         146 :       ProjectConfig.Factory projectConfigFactory) {
      67         146 :     this.groupBackend = groupBackend;
      68         146 :     this.permissionBackend = permissionBackend;
      69         146 :     this.metaDataUpdateFactory = metaDataUpdateFactory;
      70         146 :     this.getAccess = getAccess;
      71         146 :     this.projectCache = projectCache;
      72         146 :     this.identifiedUser = identifiedUser;
      73         146 :     this.accessUtil = accessUtil;
      74         146 :     this.createGroupPermissionSyncer = createGroupPermissionSyncer;
      75         146 :     this.projectConfigFactory = projectConfigFactory;
      76         146 :   }
      77             : 
      78             :   @Override
      79             :   public Response<ProjectAccessInfo> apply(ProjectResource rsrc, ProjectAccessInput input)
      80             :       throws Exception {
      81           8 :     MetaDataUpdate.User metaDataUpdateUser = metaDataUpdateFactory.get();
      82             : 
      83             :     ProjectConfig config;
      84             : 
      85           8 :     List<AccessSection> removals =
      86           8 :         accessUtil.getAccessSections(input.remove, /* rejectNonResolvableGroups= */ false);
      87           8 :     List<AccessSection> additions =
      88           8 :         accessUtil.getAccessSections(input.add, /* rejectNonResolvableGroups= */ true);
      89           8 :     try (MetaDataUpdate md = metaDataUpdateUser.create(rsrc.getNameKey())) {
      90           8 :       config = projectConfigFactory.read(md);
      91             : 
      92             :       // Check that the user has the right permissions.
      93           8 :       boolean checkedAdmin = false;
      94           8 :       for (AccessSection section : Iterables.concat(additions, removals)) {
      95           7 :         boolean isGlobalCapabilities = AccessSection.GLOBAL_CAPABILITIES.equals(section.getName());
      96           7 :         if (isGlobalCapabilities) {
      97           3 :           if (!checkedAdmin) {
      98           3 :             permissionBackend.currentUser().check(GlobalPermission.ADMINISTRATE_SERVER);
      99           3 :             checkedAdmin = true;
     100             :           }
     101             :         } else {
     102           6 :           permissionBackend
     103           6 :               .currentUser()
     104           6 :               .project(rsrc.getNameKey())
     105           6 :               .ref(section.getName())
     106           6 :               .check(RefPermission.WRITE_CONFIG);
     107             :         }
     108           7 :       }
     109             : 
     110           8 :       accessUtil.validateChanges(config, removals, additions);
     111           8 :       accessUtil.applyChanges(config, removals, additions);
     112             : 
     113           8 :       accessUtil.setParentName(
     114           8 :           identifiedUser.get(),
     115             :           config,
     116           8 :           rsrc.getNameKey(),
     117           8 :           input.parent == null ? null : Project.nameKey(input.parent),
     118             :           !checkedAdmin);
     119             : 
     120           8 :       if (!Strings.isNullOrEmpty(input.message)) {
     121           0 :         if (!input.message.endsWith("\n")) {
     122           0 :           input.message += "\n";
     123             :         }
     124           0 :         md.setMessage(input.message);
     125             :       } else {
     126           8 :         md.setMessage("Modify access rules\n");
     127             :       }
     128             : 
     129           8 :       config.commit(md);
     130           8 :       projectCache.evictAndReindex(config.getProject());
     131           8 :       createGroupPermissionSyncer.syncIfNeeded();
     132           1 :     } catch (InvalidNameException e) {
     133           1 :       throw new BadRequestException(e.toString());
     134           0 :     } catch (ConfigInvalidException e) {
     135           0 :       throw new ResourceConflictException(rsrc.getName(), e);
     136           8 :     }
     137             : 
     138           8 :     return Response.ok(getAccess.apply(rsrc.getNameKey()));
     139             :   }
     140             : }

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