mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-05-07 15:28:09 +02:00
Replace static mercurial permission handling
Replace our own hg permission handling with the default hg permission which is controlled by the `web` config
This commit is contained in:
committed by
SCM-Manager
parent
e679dac94d
commit
026ffa18fd
@@ -31,19 +31,19 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.SCMContext;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.repository.HgEnvironmentBuilder;
|
||||
import sonia.scm.repository.HgExtensions;
|
||||
import sonia.scm.repository.HgConfig;
|
||||
import sonia.scm.repository.HgConfigResolver;
|
||||
import sonia.scm.repository.HgEnvironmentBuilder;
|
||||
import sonia.scm.repository.HgExtensions;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryPermissions;
|
||||
import sonia.scm.repository.RepositoryRequestListenerUtil;
|
||||
import sonia.scm.repository.spi.ScmProviderHttpServlet;
|
||||
import sonia.scm.web.cgi.CGIExecutor;
|
||||
import sonia.scm.web.cgi.CGIExecutorFactory;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import sonia.scm.web.cgi.EnvList;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -147,12 +147,12 @@ public class HgCGIServlet extends HttpServlet implements ScmProviderHttpServlet
|
||||
HgConfig config = configResolver.resolve(repository);
|
||||
executor.setWorkDirectory(config.getDirectory());
|
||||
|
||||
executor.setArgs(createArgs(config));
|
||||
executor.setArgs(createArgs(repository, config));
|
||||
executor.execute(config.getHgBinary());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private List<String> createArgs(HgConfig config) {
|
||||
private List<String> createArgs(Repository repository, HgConfig config) {
|
||||
List<String> args = new ArrayList<>();
|
||||
config(args, "extensions.cgiserve", extension.getAbsolutePath());
|
||||
|
||||
@@ -160,9 +160,19 @@ public class HgCGIServlet extends HttpServlet implements ScmProviderHttpServlet
|
||||
config(args, "hooks.pretxnchangegroup.scm", String.format("python:%s:pre_hook", hooks));
|
||||
config(args, "hooks.changegroup.scm", String.format("python:%s:post_hook", hooks));
|
||||
|
||||
if (RepositoryPermissions.push(repository).isPermitted()) {
|
||||
config(args, "web.allow_push", "*");
|
||||
} else {
|
||||
config(args, "web.deny_push", "*");
|
||||
}
|
||||
|
||||
if(RepositoryPermissions.pull(repository).isPermitted()) {
|
||||
config(args, "web.allow_read", "*");
|
||||
} else {
|
||||
config(args, "web.deny_read", "*");
|
||||
}
|
||||
|
||||
config(args, "web.push_ssl", "false");
|
||||
config(args, "web.allow_read", "*");
|
||||
config(args, "web.allow_push", "*");
|
||||
|
||||
// enable experimental httppostargs protocol of mercurial
|
||||
// Issue 970: https://goo.gl/poascp
|
||||
|
||||
@@ -21,40 +21,34 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
package sonia.scm.web;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.repository.HgRepositoryHandler;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.spi.ScmProviderHttpServlet;
|
||||
import sonia.scm.web.filter.PermissionFilter;
|
||||
|
||||
import sonia.scm.repository.HgRepositoryHandler;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Set;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Permission filter for mercurial repositories.
|
||||
*
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class HgPermissionFilter extends PermissionFilter
|
||||
{
|
||||
|
||||
private static final Set<String> READ_METHODS = ImmutableSet.of("GET", "HEAD", "OPTIONS", "TRACE");
|
||||
public class HgPermissionFilter extends PermissionFilter {
|
||||
|
||||
private static final Set<String> READ_METHODS = Set.of("GET", "HEAD", "OPTIONS", "TRACE");
|
||||
|
||||
private final HgRepositoryHandler repositoryHandler;
|
||||
|
||||
public HgPermissionFilter(ScmConfiguration configuration, ScmProviderHttpServlet delegate, HgRepositoryHandler repositoryHandler)
|
||||
{
|
||||
public HgPermissionFilter(ScmConfiguration configuration, ScmProviderHttpServlet delegate, HgRepositoryHandler repositoryHandler) {
|
||||
super(configuration, delegate);
|
||||
this.repositoryHandler = repositoryHandler;
|
||||
}
|
||||
@@ -73,10 +67,9 @@ public class HgPermissionFilter extends PermissionFilter
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWriteRequest(HttpServletRequest request)
|
||||
{
|
||||
public boolean isWriteRequest(HttpServletRequest request) {
|
||||
if (isHttpPostArgsEnabled()) {
|
||||
return isHttpPostArgsWriteRequest(request);
|
||||
return true;
|
||||
}
|
||||
return isDefaultWriteRequest(request);
|
||||
}
|
||||
@@ -85,14 +78,7 @@ public class HgPermissionFilter extends PermissionFilter
|
||||
return repositoryHandler.getConfig().isEnableHttpPostArgs();
|
||||
}
|
||||
|
||||
private boolean isHttpPostArgsWriteRequest(HttpServletRequest request) {
|
||||
return WireProtocol.isWriteRequest(request);
|
||||
}
|
||||
|
||||
private boolean isDefaultWriteRequest(HttpServletRequest request) {
|
||||
if (READ_METHODS.contains(request.getMethod())) {
|
||||
return WireProtocol.isWriteRequest(request);
|
||||
}
|
||||
return true;
|
||||
return !READ_METHODS.contains(request.getMethod());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
package sonia.scm.web;
|
||||
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.plugin.Extension;
|
||||
import sonia.scm.repository.HgRepositoryHandler;
|
||||
import sonia.scm.repository.spi.ScmProviderHttpServlet;
|
||||
@@ -35,13 +34,9 @@ import javax.inject.Inject;
|
||||
@Extension
|
||||
public class HgPermissionFilterFactory implements ScmProviderHttpServletDecoratorFactory {
|
||||
|
||||
private final ScmConfiguration configuration;
|
||||
private final HgRepositoryHandler repositoryHandler;
|
||||
|
||||
@Inject
|
||||
public HgPermissionFilterFactory(ScmConfiguration configuration, HgRepositoryHandler repositoryHandler) {
|
||||
this.configuration = configuration;
|
||||
this.repositoryHandler = repositoryHandler;
|
||||
public HgPermissionFilterFactory() {
|
||||
// empty
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -51,6 +46,6 @@ public class HgPermissionFilterFactory implements ScmProviderHttpServletDecorato
|
||||
|
||||
@Override
|
||||
public ScmProviderHttpServlet createDecorator(ScmProviderHttpServlet delegate) {
|
||||
return new HgPermissionFilter(configuration, delegate,repositoryHandler);
|
||||
return delegate;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,14 +29,20 @@ import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import sonia.scm.util.HttpUtil;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* WireProtocol provides methods for handling the mercurial wire protocol.
|
||||
@@ -45,52 +51,9 @@ import java.util.*;
|
||||
*/
|
||||
public final class WireProtocol {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(WireProtocol.class);
|
||||
|
||||
private static final Set<String> READ_COMMANDS = ImmutableSet.of(
|
||||
"batch", "between", "branchmap", "branches", "capabilities", "changegroup", "changegroupsubset", "clonebundles",
|
||||
"getbundle", "heads", "hello", "listkeys", "lookup", "known", "stream_out",
|
||||
// could not find lheads in the wireprotocol description but mercurial 4.5.2 uses it for clone
|
||||
"lheads",
|
||||
// For HG Evolve Extension
|
||||
"evoext_obshashrange_v1"
|
||||
);
|
||||
|
||||
private static final Set<String> WRITE_COMMANDS = ImmutableSet.of(
|
||||
"pushkey", "unbundle"
|
||||
);
|
||||
|
||||
private WireProtocol() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the request is a write request. The method will always return {@code true}, expect for the
|
||||
* following cases:
|
||||
*
|
||||
* - no command was specified with the request (is required for the hgweb ui)
|
||||
* - the command in the query string was found in the list of read request
|
||||
* - if query string contains the batch command, then all commands specified in X-HgArg headers must be
|
||||
* in the list of read requests
|
||||
* - in case of enabled HttpPostArgs protocol and query string container the batch command, the header X-HgArgs-Post
|
||||
* is read and the commands which are specified in the body from 0 to the value of X-HgArgs-Post must be in the list
|
||||
* of read requests
|
||||
*
|
||||
* @param request http request
|
||||
*
|
||||
* @return {@code true} for write requests.
|
||||
*/
|
||||
public static boolean isWriteRequest(HttpServletRequest request) {
|
||||
List<String> commands = commandsOf(request);
|
||||
boolean write = isWriteRequest(commands);
|
||||
LOG.trace("mercurial request {} is write: {}", commands, write);
|
||||
return write;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static boolean isWriteRequest(List<String> commands) {
|
||||
return !READ_COMMANDS.containsAll(commands);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static List<String> commandsOf(HttpServletRequest request) {
|
||||
List<String> listOfCmds = Lists.newArrayList();
|
||||
@@ -126,7 +89,7 @@ public final class WireProtocol {
|
||||
byte[] bytes = hgRequest.getInputStream().readAndCapture(hgArgsPostSize);
|
||||
// we use iso-8859-1 for encoding, because the post args are normally http headers which are using iso-8859-1
|
||||
// see https://tools.ietf.org/html/rfc7230#section-3.2.4
|
||||
String hgArgs = new String(bytes, Charsets.ISO_8859_1);
|
||||
String hgArgs = new String(bytes, StandardCharsets.ISO_8859_1);
|
||||
String decoded = decodeValue(hgArgs);
|
||||
parseHgCommandHeader(listOfCmds, decoded);
|
||||
} catch (IOException ex) {
|
||||
|
||||
Reference in New Issue
Block a user