Add UploadValidationListener extension point.

Add pre-upload extension point to allow plugins to validate upload
operations right before Gerrit begins to send a pack back to the git
client.

A plugin can interrupt the upload by throwing an exception which will
cause the upload to fail and the exception’s message text will be
reported to the git client.

For example, a plugin may want to deny fetches for a specific project.

Change-Id: I5d0aeac51b83bf14150fa3036f71965cf2051243
This commit is contained in:
Hugo Arès
2014-04-17 08:35:16 -04:00
parent 572d542b3d
commit 0c14990f6d
8 changed files with 233 additions and 14 deletions

View File

@@ -33,6 +33,7 @@ import com.google.gerrit.server.git.ReceivePackInitializer;
import com.google.gerrit.server.git.TagCache;
import com.google.gerrit.server.git.TransferConfig;
import com.google.gerrit.server.git.VisibleRefFilter;
import com.google.gerrit.server.git.validators.UploadValidators;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
import com.google.inject.AbstractModule;
@@ -213,12 +214,15 @@ public class GitOverHttpServlet extends GitServlet {
private final Provider<ReviewDb> db;
private final TagCache tagCache;
private final ChangeCache changeCache;
private final UploadValidators.Factory uploadValidatorsFactory;
@Inject
UploadFilter(Provider<ReviewDb> db, TagCache tagCache, ChangeCache changeCache) {
UploadFilter(Provider<ReviewDb> db, TagCache tagCache, ChangeCache changeCache,
UploadValidators.Factory uploadValidatorsFactory) {
this.db = db;
this.tagCache = tagCache;
this.changeCache = changeCache;
this.uploadValidatorsFactory = uploadValidatorsFactory;
}
@Override
@@ -235,9 +239,15 @@ public class GitOverHttpServlet extends GitServlet {
"upload-pack not permitted on this server");
return;
}
// We use getRemoteHost() here instead of getRemoteAddr() because REMOTE_ADDR
// may have been overridden by a proxy server -- we'll try to avoid this.
UploadValidators uploadValidators =
uploadValidatorsFactory.create(pc.getProject(), repo, request.getRemoteHost());
up.setPreUploadHook(PreUploadHookChain.newChain(
Lists.newArrayList(up.getPreUploadHook(), uploadValidators)));
if (!pc.allRefsAreVisible()) {
up.setAdvertiseRefsHook(new VisibleRefFilter(tagCache, changeCache, repo, pc, db.get(), true));
up.setAdvertiseRefsHook(new VisibleRefFilter(tagCache, changeCache,
repo, pc, db.get(), true));
}
next.doFilter(request, response);