From a502d96a860456ec5e8c96761db70f7cabb74751 Mon Sep 17 00:00:00 2001 From: Paul Martin <paul@paulsputer.com> Date: Sat, 30 Apr 2016 04:19:14 -0400 Subject: [PATCH] Merge pull request #1073 from gitblit/1062-DocEditorUpdates --- src/main/java/com/gitblit/git/GitblitReceivePackFactory.java | 143 +++++++++++++++++++++++++++++++++++------------ 1 files changed, 107 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/gitblit/git/GitblitReceivePackFactory.java b/src/main/java/com/gitblit/git/GitblitReceivePackFactory.java index 77a3df6..afda23b 100644 --- a/src/main/java/com/gitblit/git/GitblitReceivePackFactory.java +++ b/src/main/java/com/gitblit/git/GitblitReceivePackFactory.java @@ -15,6 +15,9 @@ */ package com.gitblit.git; +import java.util.HashSet; +import java.util.Set; + import javax.servlet.http.HttpServletRequest; import org.eclipse.jgit.lib.PersonIdent; @@ -26,15 +29,20 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.gitblit.GitBlit; +import com.gitblit.Constants.Transport; +import com.gitblit.IStoredSettings; +import com.gitblit.Keys; +import com.gitblit.manager.IGitblit; import com.gitblit.models.RepositoryModel; import com.gitblit.models.UserModel; +import com.gitblit.transport.git.GitDaemonClient; +import com.gitblit.transport.ssh.SshDaemonClient; import com.gitblit.utils.HttpUtils; +import com.gitblit.utils.StringUtils; /** - * The receive pack factory creates a receive pack which accepts pushes from - * clients. - * + * The receive pack factory creates the receive pack which processes pushes. + * * @author James Moger * * @param <X> the connection type @@ -42,62 +50,125 @@ public class GitblitReceivePackFactory<X> implements ReceivePackFactory<X> { protected final Logger logger = LoggerFactory.getLogger(GitblitReceivePackFactory.class); - + + private final IStoredSettings settings; + + private final IGitblit gitblit; + + public GitblitReceivePackFactory(IGitblit gitblit) { + super(); + this.settings = gitblit.getSettings(); + this.gitblit = gitblit; + } + @Override public ReceivePack create(X req, Repository db) throws ServiceNotEnabledException, ServiceNotAuthorizedException { - final ReceivePack rp = new ReceivePack(db); UserModel user = UserModel.ANONYMOUS; String repositoryName = ""; String origin = ""; String gitblitUrl = ""; int timeout = 0; - + Transport transport = null; + if (req instanceof HttpServletRequest) { - // http/https request may or may not be authenticated - HttpServletRequest request = (HttpServletRequest) req; - repositoryName = request.getAttribute("gitblitRepositoryName").toString(); - origin = request.getRemoteHost(); - gitblitUrl = HttpUtils.getGitblitURL(request); + // http/https request may or may not be authenticated + HttpServletRequest client = (HttpServletRequest) req; + repositoryName = client.getAttribute("gitblitRepositoryName").toString(); + origin = client.getRemoteHost(); + gitblitUrl = HttpUtils.getGitblitURL(client); // determine pushing user - String username = request.getRemoteUser(); - if (username != null && !"".equals(username)) { - user = GitBlit.self().getUserModel(username); - if (user == null) { - // anonymous push, create a temporary usermodel - user = new UserModel(username); + String username = client.getRemoteUser(); + if (!StringUtils.isEmpty(username)) { + UserModel u = gitblit.getUserModel(username); + if (u != null) { + user = u; } } + + // determine the transport + if ("http".equals(client.getScheme())) { + transport = Transport.HTTP; + } else if ("https".equals(client.getScheme())) { + transport = Transport.HTTPS; + } } else if (req instanceof GitDaemonClient) { - // git daemon request is alway anonymous + // git daemon request is always anonymous GitDaemonClient client = (GitDaemonClient) req; repositoryName = client.getRepositoryName(); origin = client.getRemoteAddress().getHostAddress(); + // set timeout from Git daemon timeout = client.getDaemon().getTimeout(); + + transport = Transport.GIT; + } else if (req instanceof SshDaemonClient) { + // SSH request is always authenticated + SshDaemonClient client = (SshDaemonClient) req; + repositoryName = client.getRepositoryName(); + origin = client.getRemoteAddress().toString(); + user = client.getUser(); + + transport = Transport.SSH; } - // set pushing user identity for reflog + if (!acceptPush(transport)) { + throw new ServiceNotAuthorizedException(); + } + + boolean allowAnonymousPushes = settings.getBoolean(Keys.git.allowAnonymousPushes, false); + if (!allowAnonymousPushes && UserModel.ANONYMOUS.equals(user)) { + // prohibit anonymous pushes + throw new ServiceNotEnabledException(); + } + + String url = settings.getString(Keys.web.canonicalUrl, null); + if (StringUtils.isEmpty(url)) { + url = gitblitUrl; + } + + final RepositoryModel repository = gitblit.getRepositoryModel(repositoryName); + + // Determine which receive pack to use for pushes + final GitblitReceivePack rp; + if (gitblit.getTicketService().isAcceptingNewPatchsets(repository)) { + rp = new PatchsetReceivePack(gitblit, db, repository, user); + } else { + rp = new GitblitReceivePack(gitblit, db, repository, user); + } + + rp.setGitblitUrl(url); rp.setRefLogIdent(new PersonIdent(user.username, user.username + "@" + origin)); rp.setTimeout(timeout); - - // set advanced ref permissions - RepositoryModel repository = GitBlit.self().getRepositoryModel(repositoryName); - rp.setAllowCreates(user.canCreateRef(repository)); - rp.setAllowDeletes(user.canDeleteRef(repository)); - rp.setAllowNonFastForwards(user.canRewindRef(repository)); - - // setup the receive hook - ReceiveHook hook = new ReceiveHook(); - hook.user = user; - hook.repository = repository; - hook.gitblitUrl = gitblitUrl; - - rp.setPreReceiveHook(hook); - rp.setPostReceiveHook(hook); return rp; } -} + + protected boolean acceptPush(Transport byTransport) { + if (byTransport == null) { + logger.info("Unknown transport, push rejected!"); + return false; + } + + Set<Transport> transports = new HashSet<Transport>(); + for (String value : gitblit.getSettings().getStrings(Keys.git.acceptedPushTransports)) { + Transport transport = Transport.fromString(value); + if (transport == null) { + logger.info(String.format("Ignoring unknown registered transport %s", value)); + continue; + } + + transports.add(transport); + } + + if (transports.isEmpty()) { + // no transports are explicitly specified, all are acceptable + return true; + } + + // verify that the transport is permitted + return transports.contains(byTransport); + } +} \ No newline at end of file -- Gitblit v1.9.1