diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java index 45eba94442..5084e4d38b 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java @@ -34,7 +34,6 @@ package sonia.scm.web; import com.google.common.base.Stopwatch; -import com.google.common.base.Strings; import com.google.inject.Inject; import com.google.inject.Singleton; import org.slf4j.Logger; @@ -42,16 +41,12 @@ import org.slf4j.LoggerFactory; import sonia.scm.SCMContext; import sonia.scm.config.ScmConfiguration; import sonia.scm.repository.HgConfig; -import sonia.scm.repository.HgEnvironment; -import sonia.scm.repository.HgHookManager; import sonia.scm.repository.HgPythonScript; import sonia.scm.repository.HgRepositoryHandler; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryRequestListenerUtil; import sonia.scm.repository.spi.ScmProviderHttpServlet; -import sonia.scm.security.CipherUtil; import sonia.scm.util.AssertUtil; -import sonia.scm.util.HttpUtil; import sonia.scm.web.cgi.CGIExecutor; import sonia.scm.web.cgi.CGIExecutorFactory; import sonia.scm.web.cgi.EnvList; @@ -62,14 +57,12 @@ import java.io.File; import java.io.IOException; import java.util.Enumeration; -import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import java.util.Base64; /** * @@ -79,25 +72,9 @@ import java.util.Base64; public class HgCGIServlet extends HttpServlet implements ScmProviderHttpServlet { - private static final String ENV_PYTHON_HTTPS_VERIFY = "PYTHONHTTPSVERIFY"; - - /** Field description */ - public static final String ENV_REPOSITORY_NAME = "REPO_NAME"; - - /** Field description */ - public static final String ENV_REPOSITORY_PATH = "SCM_REPOSITORY_PATH"; - - /** Field description */ - public static final String ENV_REPOSITORY_ID = "SCM_REPOSITORY_ID"; - - private static final String ENV_HTTP_POST_ARGS = "SCM_HTTP_POST_ARGS"; - /** Field description */ public static final String ENV_SESSION_PREFIX = "SCM_"; - /** Field description */ - private static final String SCM_CREDENTIALS = "SCM_CREDENTIALS"; - /** Field description */ private static final long serialVersionUID = -3492811300905099810L; @@ -107,30 +84,18 @@ public class HgCGIServlet extends HttpServlet implements ScmProviderHttpServlet //~--- constructors --------------------------------------------------------- - /** - * Constructs ... - * - * - * - * - * - * @param cgiExecutorFactory - * @param configuration - * @param handler - * @param hookManager - * @param requestListenerUtil - */ @Inject public HgCGIServlet(CGIExecutorFactory cgiExecutorFactory, - ScmConfiguration configuration, - HgRepositoryHandler handler, HgHookManager hookManager, - RepositoryRequestListenerUtil requestListenerUtil) + ScmConfiguration configuration, + HgRepositoryHandler handler, + RepositoryRequestListenerUtil requestListenerUtil, + HgRepositoryEnvironmentBuilder hgRepositoryEnvironmentBuilder) { this.cgiExecutorFactory = cgiExecutorFactory; this.configuration = configuration; this.handler = handler; - this.hookManager = hookManager; this.requestListenerUtil = requestListenerUtil; + this.hgRepositoryEnvironmentBuilder = hgRepositoryEnvironmentBuilder; this.exceptionHandler = new HgCGIExceptionHandler(); this.command = HgPythonScript.HGWEB.getFile(SCMContext.getContext()); } @@ -163,40 +128,6 @@ public class HgCGIServlet extends HttpServlet implements ScmProviderHttpServlet } } - /** - * Method description - * - * - * @param env - * @param request - */ - private void addCredentials(EnvList env, HttpServletRequest request) - { - String authorization = request.getHeader(HttpUtil.HEADER_AUTHORIZATION); - - if (!Strings.isNullOrEmpty(authorization)) - { - if (authorization.startsWith(HttpUtil.AUTHORIZATION_SCHEME_BASIC)) - { - String encodedUserInfo = - authorization.substring( - HttpUtil.AUTHORIZATION_SCHEME_BASIC.length()).trim(); - // TODO check encoding of user-agent ? - String userInfo = new String(Base64.getDecoder().decode(encodedUserInfo)); - - env.set(SCM_CREDENTIALS, CipherUtil.getInstance().encode(userInfo)); - } - else - { - logger.warn("unknow authentication scheme used"); - } - } - else - { - logger.trace("no authorization header found"); - } - } - /** * Method description * @@ -262,7 +193,6 @@ public class HgCGIServlet extends HttpServlet implements ScmProviderHttpServlet HttpServletResponse response, Repository repository) throws IOException, ServletException { - File directory = handler.getDirectory(repository.getId()); CGIExecutor executor = cgiExecutorFactory.createExecutor(configuration, getServletContext(), request, response); @@ -271,33 +201,7 @@ public class HgCGIServlet extends HttpServlet implements ScmProviderHttpServlet executor.setExceptionHandler(exceptionHandler); executor.setStatusCodeHandler(exceptionHandler); executor.setContentLengthWorkaround(true); - executor.getEnvironment().set(ENV_REPOSITORY_NAME, repository.getNamespace() + "/" + repository.getName()); - executor.getEnvironment().set(ENV_REPOSITORY_ID, repository.getId()); - executor.getEnvironment().set(ENV_REPOSITORY_PATH, - directory.getAbsolutePath()); - - // add hook environment - Map environment = executor.getEnvironment().asMutableMap(); - if (handler.getConfig().isDisableHookSSLValidation()) { - // disable ssl validation - // Issue 959: https://goo.gl/zH5eY8 - environment.put(ENV_PYTHON_HTTPS_VERIFY, "0"); - } - - // enable experimental httppostargs protocol of mercurial - // Issue 970: https://goo.gl/poascp - environment.put(ENV_HTTP_POST_ARGS, String.valueOf(handler.getConfig().isEnableHttpPostArgs())); - - //J- - HgEnvironment.prepareEnvironment( - environment, - handler, - hookManager, - request - ); - //J+ - - addCredentials(executor.getEnvironment(), request); + hgRepositoryEnvironmentBuilder.buildFor(repository, request, executor.getEnvironment()); // unused ??? HttpSession session = request.getSession(false); @@ -358,9 +262,8 @@ public class HgCGIServlet extends HttpServlet implements ScmProviderHttpServlet /** Field description */ private final HgRepositoryHandler handler; - /** Field description */ - private final HgHookManager hookManager; - /** Field description */ private final RepositoryRequestListenerUtil requestListenerUtil; + + private final HgRepositoryEnvironmentBuilder hgRepositoryEnvironmentBuilder; } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgRepositoryEnvironmentBuilder.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgRepositoryEnvironmentBuilder.java new file mode 100644 index 0000000000..3e7e590270 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgRepositoryEnvironmentBuilder.java @@ -0,0 +1,96 @@ +package sonia.scm.web; + +import com.google.common.base.Strings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import sonia.scm.repository.HgEnvironment; +import sonia.scm.repository.HgHookManager; +import sonia.scm.repository.HgRepositoryHandler; +import sonia.scm.repository.Repository; +import sonia.scm.security.CipherUtil; +import sonia.scm.util.HttpUtil; +import sonia.scm.web.cgi.EnvList; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.util.Base64; +import java.util.Map; + +public class HgRepositoryEnvironmentBuilder { + + private static final Logger LOG = LoggerFactory.getLogger(HgRepositoryEnvironmentBuilder.class); + + private static final String ENV_REPOSITORY_NAME = "REPO_NAME"; + private static final String ENV_REPOSITORY_PATH = "SCM_REPOSITORY_PATH"; + private static final String ENV_REPOSITORY_ID = "SCM_REPOSITORY_ID"; + private static final String ENV_PYTHON_HTTPS_VERIFY = "PYTHONHTTPSVERIFY"; + private static final String ENV_HTTP_POST_ARGS = "SCM_HTTP_POST_ARGS"; + private static final String SCM_CREDENTIALS = "SCM_CREDENTIALS"; + + private final HgRepositoryHandler handler; + private final HgHookManager hookManager; + + @Inject + public HgRepositoryEnvironmentBuilder(HgRepositoryHandler handler, HgHookManager hookManager) { + this.handler = handler; + this.hookManager = hookManager; + } + + void buildFor(Repository repository, HttpServletRequest request, EnvList environment) { + File directory = handler.getDirectory(repository.getId()); + + environment.set(ENV_REPOSITORY_NAME, repository.getNamespace() + "/" + repository.getName()); + environment.set(ENV_REPOSITORY_ID, repository.getId()); + environment.set(ENV_REPOSITORY_PATH, + directory.getAbsolutePath()); + + // add hook environment + Map environmentMap = environment.asMutableMap(); + if (handler.getConfig().isDisableHookSSLValidation()) { + // disable ssl validation + // Issue 959: https://goo.gl/zH5eY8 + environmentMap.put(ENV_PYTHON_HTTPS_VERIFY, "0"); + } + + // enable experimental httppostargs protocol of mercurial + // Issue 970: https://goo.gl/poascp + environmentMap.put(ENV_HTTP_POST_ARGS, String.valueOf(handler.getConfig().isEnableHttpPostArgs())); + + HgEnvironment.prepareEnvironment( + environmentMap, + handler, + hookManager, + request + ); + + addCredentials(environment, request); + } + + private void addCredentials(EnvList env, HttpServletRequest request) + { + String authorization = request.getHeader(HttpUtil.HEADER_AUTHORIZATION); + + if (!Strings.isNullOrEmpty(authorization)) + { + if (authorization.startsWith(HttpUtil.AUTHORIZATION_SCHEME_BASIC)) + { + String encodedUserInfo = + authorization.substring( + HttpUtil.AUTHORIZATION_SCHEME_BASIC.length()).trim(); + // TODO check encoding of user-agent ? + String userInfo = new String(Base64.getDecoder().decode(encodedUserInfo)); + + env.set(SCM_CREDENTIALS, CipherUtil.getInstance().encode(userInfo)); + } + else + { + LOG.warn("unknown authentication scheme used"); + } + } + else + { + LOG.trace("no authorization header found"); + } + } +}