LCOV - code coverage report
Current view: top level - server/restapi/project - ListDashboards.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 32 59 54.2 %
Date: 2022-11-19 15:00:39 Functions: 5 6 83.3 %

          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.project;
      16             : 
      17             : import static com.google.gerrit.entities.RefNames.REFS_DASHBOARDS;
      18             : 
      19             : import com.google.common.collect.ImmutableList;
      20             : import com.google.common.flogger.FluentLogger;
      21             : import com.google.gerrit.entities.Project;
      22             : import com.google.gerrit.extensions.api.projects.DashboardInfo;
      23             : import com.google.gerrit.extensions.restapi.AuthException;
      24             : import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
      25             : import com.google.gerrit.extensions.restapi.Response;
      26             : import com.google.gerrit.extensions.restapi.RestReadView;
      27             : import com.google.gerrit.server.git.GitRepositoryManager;
      28             : import com.google.gerrit.server.permissions.PermissionBackend;
      29             : import com.google.gerrit.server.permissions.PermissionBackendException;
      30             : import com.google.gerrit.server.permissions.ProjectPermission;
      31             : import com.google.gerrit.server.permissions.RefPermission;
      32             : import com.google.gerrit.server.project.ProjectResource;
      33             : import com.google.gerrit.server.project.ProjectState;
      34             : import com.google.inject.Inject;
      35             : import java.io.IOException;
      36             : import java.util.ArrayList;
      37             : import java.util.Collection;
      38             : import java.util.LinkedHashMap;
      39             : import java.util.List;
      40             : import java.util.Map;
      41             : import org.eclipse.jgit.errors.ConfigInvalidException;
      42             : import org.eclipse.jgit.errors.RepositoryNotFoundException;
      43             : import org.eclipse.jgit.lib.BlobBasedConfig;
      44             : import org.eclipse.jgit.lib.FileMode;
      45             : import org.eclipse.jgit.lib.Ref;
      46             : import org.eclipse.jgit.lib.Repository;
      47             : import org.eclipse.jgit.revwalk.RevWalk;
      48             : import org.eclipse.jgit.treewalk.TreeWalk;
      49             : import org.kohsuke.args4j.Option;
      50             : 
      51             : public class ListDashboards implements RestReadView<ProjectResource> {
      52           2 :   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
      53             : 
      54             :   private final GitRepositoryManager gitManager;
      55             :   private final PermissionBackend permissionBackend;
      56             : 
      57             :   @Option(name = "--inherited", usage = "include inherited dashboards")
      58             :   private boolean inherited;
      59             : 
      60             :   @Inject
      61           2 :   ListDashboards(GitRepositoryManager gitManager, PermissionBackend permissionBackend) {
      62           2 :     this.gitManager = gitManager;
      63           2 :     this.permissionBackend = permissionBackend;
      64           2 :   }
      65             : 
      66             :   @Override
      67             :   public Response<List<?>> apply(ProjectResource rsrc)
      68             :       throws ResourceNotFoundException, IOException, PermissionBackendException {
      69           2 :     String project = rsrc.getName();
      70           2 :     if (!inherited) {
      71           2 :       return Response.ok(scan(rsrc.getProjectState(), project, true));
      72             :     }
      73             : 
      74           0 :     List<List<DashboardInfo>> all = new ArrayList<>();
      75           0 :     boolean setDefault = true;
      76           0 :     for (ProjectState ps : tree(rsrc)) {
      77           0 :       List<DashboardInfo> list = scan(ps, project, setDefault);
      78           0 :       for (DashboardInfo d : list) {
      79           0 :         if (d.isDefault != null && Boolean.TRUE.equals(d.isDefault)) {
      80           0 :           setDefault = false;
      81             :         }
      82           0 :       }
      83           0 :       if (!list.isEmpty()) {
      84           0 :         all.add(list);
      85             :       }
      86           0 :     }
      87           0 :     return Response.ok(all);
      88             :   }
      89             : 
      90             :   private Collection<ProjectState> tree(ProjectResource rsrc) throws PermissionBackendException {
      91           0 :     Map<Project.NameKey, ProjectState> tree = new LinkedHashMap<>();
      92           0 :     for (ProjectState ps : rsrc.getProjectState().tree()) {
      93           0 :       if (ps.statePermitsRead()) {
      94           0 :         tree.put(ps.getNameKey(), ps);
      95             :       }
      96           0 :     }
      97             : 
      98           0 :     tree.keySet()
      99           0 :         .retainAll(permissionBackend.currentUser().filter(ProjectPermission.ACCESS, tree.keySet()));
     100           0 :     return tree.values();
     101             :   }
     102             : 
     103             :   private ImmutableList<DashboardInfo> scan(ProjectState state, String project, boolean setDefault)
     104             :       throws ResourceNotFoundException, IOException, PermissionBackendException {
     105           2 :     if (!state.statePermitsRead()) {
     106           0 :       return ImmutableList.of();
     107             :     }
     108             : 
     109           2 :     PermissionBackend.ForProject perm = permissionBackend.currentUser().project(state.getNameKey());
     110           2 :     try (Repository git = gitManager.openRepository(state.getNameKey());
     111           2 :         RevWalk rw = new RevWalk(git)) {
     112           2 :       ImmutableList.Builder<DashboardInfo> all = ImmutableList.builder();
     113           2 :       for (Ref ref : git.getRefDatabase().getRefsByPrefix(REFS_DASHBOARDS)) {
     114             :         try {
     115           1 :           perm.ref(ref.getName()).check(RefPermission.READ);
     116           1 :           all.addAll(scanDashboards(state.getProject(), git, rw, ref, project, setDefault));
     117           0 :         } catch (AuthException e) {
     118             :           // Do nothing.
     119           1 :         }
     120           1 :       }
     121           2 :       return all.build();
     122           0 :     } catch (RepositoryNotFoundException e) {
     123           0 :       throw new ResourceNotFoundException(project, e);
     124             :     }
     125             :   }
     126             : 
     127             :   private ImmutableList<DashboardInfo> scanDashboards(
     128             :       Project definingProject,
     129             :       Repository git,
     130             :       RevWalk rw,
     131             :       Ref ref,
     132             :       String project,
     133             :       boolean setDefault)
     134             :       throws IOException {
     135           1 :     ImmutableList.Builder<DashboardInfo> list = ImmutableList.builder();
     136           1 :     try (TreeWalk tw = new TreeWalk(rw.getObjectReader())) {
     137           1 :       tw.addTree(rw.parseTree(ref.getObjectId()));
     138           1 :       tw.setRecursive(true);
     139           1 :       while (tw.next()) {
     140           1 :         if (tw.getFileMode(0) == FileMode.REGULAR_FILE) {
     141             :           try {
     142           1 :             list.add(
     143           1 :                 DashboardsCollection.parse(
     144             :                     definingProject,
     145           1 :                     ref.getName().substring(REFS_DASHBOARDS.length()),
     146           1 :                     tw.getPathString(),
     147           1 :                     new BlobBasedConfig(null, git, tw.getObjectId(0)),
     148             :                     project,
     149             :                     setDefault));
     150           0 :           } catch (ConfigInvalidException e) {
     151           0 :             logger.atWarning().log(
     152             :                 "Cannot parse dashboard %s:%s:%s: %s",
     153           0 :                 definingProject.getName(), ref.getName(), tw.getPathString(), e.getMessage());
     154           1 :           }
     155             :         }
     156             :       }
     157             :     }
     158           1 :     return list.build();
     159             :   }
     160             : }

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