LCOV - code coverage report
Current view: top level - sshd/commands - Upload.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 49 59 83.1 %
Date: 2022-11-19 15:00:39 Functions: 4 4 100.0 %

          Line data    Source code
       1             : // Copyright (C) 2008 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.sshd.commands;
      16             : 
      17             : import com.google.common.collect.ImmutableList;
      18             : import com.google.common.collect.Lists;
      19             : import com.google.gerrit.extensions.registration.DynamicSet;
      20             : import com.google.gerrit.extensions.restapi.AuthException;
      21             : import com.google.gerrit.server.RequestInfo;
      22             : import com.google.gerrit.server.RequestListener;
      23             : import com.google.gerrit.server.git.PermissionAwareRepositoryManager;
      24             : import com.google.gerrit.server.git.TracingHook;
      25             : import com.google.gerrit.server.git.TransferConfig;
      26             : import com.google.gerrit.server.git.UploadPackInitializer;
      27             : import com.google.gerrit.server.git.UsersSelfAdvertiseRefsHook;
      28             : import com.google.gerrit.server.git.validators.UploadValidationException;
      29             : import com.google.gerrit.server.git.validators.UploadValidators;
      30             : import com.google.gerrit.server.logging.TraceContext;
      31             : import com.google.gerrit.server.permissions.PermissionBackend;
      32             : import com.google.gerrit.server.permissions.PermissionBackendException;
      33             : import com.google.gerrit.server.permissions.ProjectPermission;
      34             : import com.google.gerrit.server.plugincontext.PluginSetContext;
      35             : import com.google.gerrit.sshd.AbstractGitCommand;
      36             : import com.google.inject.Inject;
      37             : import java.io.IOException;
      38             : import java.util.List;
      39             : import org.eclipse.jgit.lib.Repository;
      40             : import org.eclipse.jgit.storage.pack.PackStatistics;
      41             : import org.eclipse.jgit.transport.PostUploadHook;
      42             : import org.eclipse.jgit.transport.PostUploadHookChain;
      43             : import org.eclipse.jgit.transport.PreUploadHook;
      44             : import org.eclipse.jgit.transport.PreUploadHookChain;
      45             : import org.eclipse.jgit.transport.UploadPack;
      46             : 
      47             : /** Publishes Git repositories over SSH using the Git upload-pack protocol. */
      48           3 : final class Upload extends AbstractGitCommand {
      49             :   @Inject private TransferConfig config;
      50             :   @Inject private DynamicSet<PreUploadHook> preUploadHooks;
      51             :   @Inject private DynamicSet<PostUploadHook> postUploadHooks;
      52             :   @Inject private DynamicSet<UploadPackInitializer> uploadPackInitializers;
      53             :   @Inject private PluginSetContext<RequestListener> requestListeners;
      54             :   @Inject private UploadValidators.Factory uploadValidatorsFactory;
      55             :   @Inject private PermissionBackend permissionBackend;
      56             :   @Inject private UsersSelfAdvertiseRefsHook usersSelfAdvertiseRefsHook;
      57             : 
      58             :   private PackStatistics stats;
      59             : 
      60             :   @Override
      61             :   protected void runImpl() throws IOException, Failure {
      62           3 :     PermissionBackend.ForProject perm =
      63           3 :         permissionBackend.user(user).project(projectState.getNameKey());
      64             :     try {
      65           3 :       perm.check(ProjectPermission.RUN_UPLOAD_PACK);
      66           0 :     } catch (AuthException e) {
      67           0 :       throw new Failure(1, "fatal: upload-pack not permitted on this server", e);
      68           0 :     } catch (PermissionBackendException e) {
      69           0 :       throw new Failure(1, "fatal: unable to check permissions ", e);
      70           3 :     }
      71             : 
      72           3 :     Repository permissionAwareRepo = PermissionAwareRepositoryManager.wrap(repo, perm);
      73           3 :     UploadPack up = new UploadPack(permissionAwareRepo);
      74             : 
      75           3 :     up.setPackConfig(config.getPackConfig());
      76           3 :     up.setTimeout(config.getTimeout());
      77           3 :     up.setPostUploadHook(PostUploadHookChain.newChain(Lists.newArrayList(postUploadHooks)));
      78           3 :     if (projectState.isAllUsers()) {
      79           0 :       up.setAdvertiseRefsHook(usersSelfAdvertiseRefsHook);
      80             :     }
      81           3 :     if (extraParameters != null) {
      82           3 :       up.setExtraParameters(ImmutableList.copyOf(extraParameters));
      83             :     }
      84             : 
      85           3 :     List<PreUploadHook> allPreUploadHooks = Lists.newArrayList(preUploadHooks);
      86           3 :     allPreUploadHooks.add(
      87           3 :         uploadValidatorsFactory.create(
      88           3 :             project, permissionAwareRepo, session.getRemoteAddressAsString()));
      89           3 :     up.setPreUploadHook(PreUploadHookChain.newChain(allPreUploadHooks));
      90           3 :     for (UploadPackInitializer initializer : uploadPackInitializers) {
      91           0 :       initializer.init(projectState.getNameKey(), up);
      92           0 :     }
      93           3 :     try (TraceContext traceContext = TraceContext.open();
      94           3 :         TracingHook tracingHook = new TracingHook()) {
      95           3 :       RequestInfo requestInfo =
      96           3 :           RequestInfo.builder(RequestInfo.RequestType.GIT_UPLOAD, user, traceContext)
      97           3 :               .project(projectState.getNameKey())
      98           3 :               .build();
      99           3 :       requestListeners.runEach(l -> l.onRequest(requestInfo));
     100           3 :       up.setProtocolV2Hook(tracingHook);
     101           3 :       up.upload(in, out, err);
     102           3 :       session.setPeerAgent(up.getPeerUserAgent());
     103           3 :       stats = up.getStatistics();
     104           0 :     } catch (UploadValidationException e) {
     105             :       // UploadValidationException is used by the UploadValidators to
     106             :       // stop the uploadPack. We do not want this exception to go beyond this
     107             :       // point otherwise it would print a stacktrace in the logs and return an
     108             :       // internal server error to the client.
     109           0 :       if (!e.isOutput()) {
     110           0 :         up.sendMessage(e.getMessage());
     111             :       }
     112           3 :     }
     113           3 :   }
     114             : 
     115             :   @Override
     116             :   protected void onExit(int rc) {
     117           3 :     exit.onExit(
     118             :         rc,
     119           3 :         stats != null
     120           2 :             ? stats.getTimeNegotiating()
     121             :                 + "ms "
     122           2 :                 + stats.getTimeSearchingForReuse()
     123             :                 + "ms "
     124           2 :                 + stats.getTimeSearchingForSizes()
     125             :                 + "ms "
     126           2 :                 + stats.getTimeCounting()
     127             :                 + "ms "
     128           2 :                 + stats.getTimeCompressing()
     129             :                 + "ms "
     130           2 :                 + stats.getTimeWriting()
     131             :                 + "ms "
     132           2 :                 + stats.getTimeTotal()
     133             :                 + "ms "
     134           2 :                 + stats.getBitmapIndexMisses()
     135             :                 + " "
     136           2 :                 + stats.getTotalDeltas()
     137             :                 + " "
     138           2 :                 + stats.getTotalObjects()
     139             :                 + " "
     140           2 :                 + stats.getTotalBytes()
     141           2 :             : "-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1");
     142           3 :     if (cleanup != null) {
     143           3 :       cleanup.run();
     144             :     }
     145           3 :   }
     146             : }

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