Cleanup for http protocol servlet changes

This commit is contained in:
René Pfeuffer
2018-09-11 10:50:53 +02:00
parent bf9de8ea8e
commit e90dc11bc7
27 changed files with 32 additions and 596 deletions

View File

@@ -33,8 +33,6 @@
package sonia.scm.repository.spi;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.collect.ImmutableSet;
import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.repository.Repository;
@@ -45,8 +43,6 @@ import java.io.IOException;
import java.util.Collections;
import java.util.Set;
//~--- JDK imports ------------------------------------------------------------
/**
*
* @author Sebastian Sdorra

View File

@@ -45,47 +45,27 @@ import sonia.scm.web.GitScmProtocolProviderWrapper;
* @author Sebastian Sdorra
*/
@Extension
public class GitRepositoryServiceResolver implements RepositoryServiceResolver
{
public class GitRepositoryServiceResolver implements RepositoryServiceResolver {
/** Field description */
public static final String TYPE = "git";
//~--- constructors ---------------------------------------------------------
@Inject
public GitRepositoryServiceResolver(GitRepositoryHandler handler, GitScmProtocolProviderWrapper providerWrapper)
{
public GitRepositoryServiceResolver(GitRepositoryHandler handler, GitScmProtocolProviderWrapper providerWrapper) {
this.handler = handler;
this.providerWrapper = providerWrapper;
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param repository
*
* @return
*/
@Override
public GitRepositoryServiceProvider resolve(Repository repository)
{
public GitRepositoryServiceProvider resolve(Repository repository) {
GitRepositoryServiceProvider provider = null;
if (TYPE.equalsIgnoreCase(repository.getType()))
{
if (TYPE.equalsIgnoreCase(repository.getType())) {
provider = new GitRepositoryServiceProvider(handler, repository, providerWrapper.get(repository));
}
return provider;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private final GitRepositoryHandler handler;
private final GitScmProtocolProviderWrapper providerWrapper;
}

View File

@@ -33,32 +33,24 @@
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Inject;
import org.eclipse.jgit.http.server.GitSmartHttpTools;
import sonia.scm.ClientMessages;
import sonia.scm.Priority;
import sonia.scm.config.ScmConfiguration;
import sonia.scm.filter.Filters;
import sonia.scm.repository.GitUtil;
import sonia.scm.web.filter.ProviderPermissionFilter;
import sonia.scm.web.filter.PermissionFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//~--- JDK imports ------------------------------------------------------------
/**
* GitPermissionFilter decides if a git request requires write or read privileges.
*
* @author Sebastian Sdorra
*/
@Priority(Filters.PRIORITY_AUTHORIZATION)
//@WebElement(value = GitServletModule.PATTERN_GIT)
public class GitPermissionFilter extends ProviderPermissionFilter
public class GitPermissionFilter extends PermissionFilter
{
private static final String PARAMETER_SERVICE = "service";

View File

@@ -51,18 +51,6 @@ import sonia.scm.web.lfs.LfsBlobStoreFactory;
public class GitServletModule extends ServletModule
{
public static final String GIT_PATH = "/repo";
/** Field description */
public static final String PATTERN_GIT = GIT_PATH + "/*";
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*/
@Override
protected void configureServlets()
{

View File

@@ -33,8 +33,6 @@
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -57,8 +55,6 @@ import java.util.regex.Pattern;
import static org.eclipse.jgit.lfs.lib.Constants.CONTENT_TYPE_GIT_LFS_JSON;
import static org.slf4j.LoggerFactory.getLogger;
//~--- JDK imports ------------------------------------------------------------
/**
*
* @author Sebastian Sdorra
@@ -67,7 +63,8 @@ import static org.slf4j.LoggerFactory.getLogger;
public class ScmGitServlet extends GitServlet implements ScmProviderHttpServlet
{
/** Field description */
public static final String REPO_PATH = "/repo";
public static final Pattern REGEX_GITHTTPBACKEND = Pattern.compile(
"(?x)^/repo/(.*/(HEAD|info/refs|objects/(info/[^/]+|[0-9a-f]{2}/[0-9a-f]{38}|pack/pack-[0-9a-f]{40}\\.(pack|idx))|git-(upload|receive)-pack))$"
);
@@ -172,7 +169,7 @@ public class ScmGitServlet extends GitServlet implements ScmProviderHttpServlet
* @throws IOException
* @throws ServletException
*/
private void handleBrowserRequest(HttpServletRequest request, HttpServletResponse response, Repository repository) throws ServletException, IOException {
private void handleBrowserRequest(HttpServletRequest request, HttpServletResponse response, Repository repository) throws ServletException {
try {
repositoryViewer.handleRequest(request, response, repository);
} catch (IOException ex) {
@@ -191,7 +188,7 @@ public class ScmGitServlet extends GitServlet implements ScmProviderHttpServlet
*/
private static boolean isLfsFileTransferRequest(HttpServletRequest request, String repository) {
String regex = String.format("^%s%s/%s(\\.git)?/info/lfs/objects/[a-z0-9]{64}$", request.getContextPath(), GitServletModule.GIT_PATH, repository);
String regex = String.format("^%s%s/%s(\\.git)?/info/lfs/objects/[a-z0-9]{64}$", request.getContextPath(), REPO_PATH, repository);
boolean pathMatches = request.getRequestURI().matches(regex);
boolean methodMatches = request.getMethod().equals("PUT") || request.getMethod().equals("GET");
@@ -210,7 +207,7 @@ public class ScmGitServlet extends GitServlet implements ScmProviderHttpServlet
*/
private static boolean isLfsBatchApiRequest(HttpServletRequest request, String repository) {
String regex = String.format("^%s%s/%s(\\.git)?/info/lfs/objects/batch$", request.getContextPath(), GitServletModule.GIT_PATH, repository);
String regex = String.format("^%s%s/%s(\\.git)?/info/lfs/objects/batch$", request.getContextPath(), REPO_PATH, repository);
boolean pathMatches = request.getRequestURI().matches(regex);
boolean methodMatches = "POST".equals(request.getMethod());

View File

@@ -33,8 +33,6 @@
package sonia.scm.repository.spi;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.io.Closeables;
import sonia.scm.repository.Feature;
import sonia.scm.repository.HgHookManager;
@@ -49,8 +47,6 @@ import java.util.Collections;
import java.util.EnumSet;
import java.util.Set;
//~--- JDK imports ------------------------------------------------------------
/**
*
* @author Sebastian Sdorra

View File

@@ -33,8 +33,6 @@
package sonia.scm.repository.spi;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Inject;
import sonia.scm.plugin.Extension;
import sonia.scm.repository.HgHookManager;

View File

@@ -1,102 +0,0 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Inject;
import sonia.scm.Priority;
import sonia.scm.config.ScmConfiguration;
import sonia.scm.filter.Filters;
import sonia.scm.filter.WebElement;
import sonia.scm.web.filter.AuthenticationFilter;
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author Sebastian Sdorra
*/
@Priority(Filters.PRIORITY_AUTHENTICATION)
@WebElement(value = HgServletModule.MAPPING_HG)
public class HgBasicAuthenticationFilter extends AuthenticationFilter
{
/**
* Constructs ...
*
*
* @param configuration
* @param webTokenGenerators
*/
@Inject
public HgBasicAuthenticationFilter(ScmConfiguration configuration,
Set<WebTokenGenerator> webTokenGenerators)
{
super(configuration, webTokenGenerators);
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param request
* @param response
*
* @throws IOException
*/
@Override
protected void sendFailedAuthenticationError(HttpServletRequest request,
HttpServletResponse response)
throws IOException
{
if (HgUtil.isHgClient(request)
&& (configuration.isLoginAttemptLimitEnabled()))
{
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
else
{
super.sendFailedAuthenticationError(request, response);
}
}
}

View File

@@ -33,8 +33,6 @@
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.base.Stopwatch;
import com.google.common.base.Strings;
import com.google.inject.Inject;
@@ -68,8 +66,6 @@ import java.io.IOException;
import java.util.Base64;
import java.util.Enumeration;
//~--- JDK imports ------------------------------------------------------------
/**
*
* @author Sebastian Sdorra

View File

@@ -33,43 +33,30 @@
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.collect.ImmutableSet;
import com.google.inject.Inject;
import sonia.scm.config.ScmConfiguration;
import sonia.scm.web.filter.ProviderPermissionFilter;
import sonia.scm.web.filter.PermissionFilter;
import javax.servlet.http.HttpServletRequest;
import java.util.Set;
//~--- JDK imports ------------------------------------------------------------
/**
* Permission filter for mercurial repositories.
*
* @author Sebastian Sdorra
*/
//@Priority(Filters.PRIORITY_AUTHORIZATION)
//@WebElement(value = HgServletModule.MAPPING_HG)
public class HgPermissionFilter extends ProviderPermissionFilter
public class HgPermissionFilter extends PermissionFilter
{
private static final Set<String> READ_METHODS = ImmutableSet.of("GET", "HEAD", "OPTIONS", "TRACE");
/**
* Constructs a new instance.
*
* @param configuration scm configuration
*/
@Inject
public HgPermissionFilter(ScmConfiguration configuration)
{
super(configuration);
}
//~--- get methods ----------------------------------------------------------
@Override
public boolean isWriteRequest(HttpServletRequest request)
{

View File

@@ -33,8 +33,6 @@
package sonia.scm.repository.spi;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.collect.ImmutableSet;
import com.google.common.io.Closeables;
import sonia.scm.repository.Repository;
@@ -46,8 +44,6 @@ import java.io.IOException;
import java.util.Collections;
import java.util.Set;
//~--- JDK imports ------------------------------------------------------------
/**
*
* @author Sebastian Sdorra

View File

@@ -32,67 +32,34 @@
package sonia.scm.repository.spi;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Inject;
import sonia.scm.plugin.Extension;
import sonia.scm.repository.Repository;
import sonia.scm.repository.SvnRepositoryHandler;
import sonia.scm.web.SvnScmProtocolProviderWrapper;
/**
*
* @author Sebastian Sdorra
*/
@Extension
public class SvnRepositoryServiceResolver implements RepositoryServiceResolver
{
public class SvnRepositoryServiceResolver implements RepositoryServiceResolver {
/** Field description */
public static final String TYPE = "svn";
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*
* @param handler
* @param protocolWrapper
*/
@Inject
public SvnRepositoryServiceResolver(SvnRepositoryHandler handler, SvnScmProtocolProviderWrapper protocolWrapper)
{
public SvnRepositoryServiceResolver(SvnRepositoryHandler handler, SvnScmProtocolProviderWrapper protocolWrapper) {
this.handler = handler;
this.protocolWrapper = protocolWrapper;
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param repository
*
* @return
*/
@Override
public SvnRepositoryServiceProvider resolve(Repository repository)
{
public SvnRepositoryServiceProvider resolve(Repository repository) {
SvnRepositoryServiceProvider provider = null;
if (TYPE.equalsIgnoreCase(repository.getType()))
{
if (TYPE.equalsIgnoreCase(repository.getType())) {
provider = new SvnRepositoryServiceProvider(handler, repository, protocolWrapper.get(repository));
}
return provider;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private SvnRepositoryHandler handler;
private final InitializingHttpScmProtocolWrapper protocolWrapper;

View File

@@ -1,96 +0,0 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Inject;
import sonia.scm.config.ScmConfiguration;
import sonia.scm.repository.SvnUtil;
import sonia.scm.util.HttpUtil;
import sonia.scm.web.filter.AuthenticationFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Set;
//~--- JDK imports ------------------------------------------------------------
/**
*
* @author Sebastian Sdorra
*/
//@Priority(Filters.PRIORITY_AUTHENTICATION)
//@WebElement(value = SvnServletModule.PATTERN_SVN)
public class SvnBasicAuthenticationFilter extends AuthenticationFilter
{
/**
* Constructs ...
*
*
* @param configuration
* @param webTokenGenerators
*/
@Inject
public SvnBasicAuthenticationFilter(ScmConfiguration configuration, Set<WebTokenGenerator> webTokenGenerators) {
super(configuration, webTokenGenerators);
}
//~--- methods --------------------------------------------------------------
/**
* Sends unauthorized instead of forbidden for svn clients, because the
* svn client prompts again for authentication.
*
*
* @param request http request
* @param response http response
*
* @throws IOException
*/
@Override
protected void sendFailedAuthenticationError(HttpServletRequest request,
HttpServletResponse response)
throws IOException
{
if (SvnUtil.isSvnClient(request))
{
HttpUtil.sendUnauthorized(response, configuration.getRealmDescription());
}
else
{
super.sendFailedAuthenticationError(request, response);
}
}
}

View File

@@ -33,8 +33,6 @@
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.slf4j.Logger;
@@ -55,8 +53,6 @@ import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//~--- JDK imports ------------------------------------------------------------
/**
*
* @author Sebastian Sdorra

View File

@@ -33,30 +33,24 @@
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.collect.ImmutableSet;
import com.google.inject.Inject;
import sonia.scm.ClientMessages;
import sonia.scm.config.ScmConfiguration;
import sonia.scm.repository.ScmSvnErrorCode;
import sonia.scm.repository.SvnUtil;
import sonia.scm.web.filter.ProviderPermissionFilter;
import sonia.scm.web.filter.PermissionFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Set;
//~--- JDK imports ------------------------------------------------------------
/**
*
* @author Sebastian Sdorra
*/
//@Priority(Filters.PRIORITY_AUTHORIZATION)
//@WebElement(value = SvnServletModule.PATTERN_SVN)
public class SvnPermissionFilter extends ProviderPermissionFilter
public class SvnPermissionFilter extends PermissionFilter
{
/** Field description */

View File

@@ -12,10 +12,11 @@ import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import java.util.Enumeration;
import static sonia.scm.web.SvnServletModule.PARAMETER_SVN_PARENTPATH;
@Singleton
public class SvnScmProtocolProviderWrapper extends InitializingHttpScmProtocolWrapper {
public static final String PARAMETER_SVN_PARENTPATH = "SVNParentPath";
@Inject
public SvnScmProtocolProviderWrapper(Provider<SvnDAVServlet> servletProvider, Provider<SvnPermissionFilter> permissionFilter, Provider<UriInfoStore> uriInfoStore) {
super(servletProvider, permissionFilter, uriInfoStore);
@@ -24,14 +25,14 @@ public class SvnScmProtocolProviderWrapper extends InitializingHttpScmProtocolWr
@Override
protected void initializeServlet(ServletConfig config, ScmProviderHttpServlet httpServlet) throws ServletException {
super.initializeServlet(new X(config), httpServlet);
super.initializeServlet(new SvnConfigEnhancer(config), httpServlet);
}
private static class X implements ServletConfig {
private static class SvnConfigEnhancer implements ServletConfig {
private final ServletConfig originalConfig;
private X(ServletConfig originalConfig) {
private SvnConfigEnhancer(ServletConfig originalConfig) {
this.originalConfig = originalConfig;
}

View File

@@ -33,43 +33,21 @@
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.servlet.ServletModule;
import org.mapstruct.factory.Mappers;
import sonia.scm.api.v2.resources.SvnConfigDtoToSvnConfigMapper;
import sonia.scm.api.v2.resources.SvnConfigToSvnConfigDtoMapper;
import sonia.scm.plugin.Extension;
//~--- JDK imports ------------------------------------------------------------
/**
*
* @author Sebastian Sdorra
*/
@Extension
public class SvnServletModule extends ServletModule
{
public class SvnServletModule extends ServletModule {
/** Field description */
public static final String PARAMETER_SVN_PARENTPATH = "SVNParentPath";
/** Field description */
public static final String PATTERN_SVN = "/svn/*";
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*/
@Override
protected void configureServlets()
{
filter(PATTERN_SVN).through(SvnGZipFilter.class);
// filter(PATTERN_SVN).through(SvnBasicAuthenticationFilter.class);
// filter(PATTERN_SVN).through(SvnPermissionFilter.class);
protected void configureServlets() {
bind(SvnConfigDtoToSvnConfigMapper.class).to(Mappers.getMapper(SvnConfigDtoToSvnConfigMapper.class).getClass());
bind(SvnConfigToSvnConfigDtoMapper.class).to(Mappers.getMapper(SvnConfigToSvnConfigDtoMapper.class).getClass());
}