mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-09 15:05:44 +01:00
reauthenticate user on mercurial hooks
This commit is contained in:
@@ -47,12 +47,14 @@ import sonia.scm.repository.RepositoryManager;
|
|||||||
import sonia.scm.util.AssertUtil;
|
import sonia.scm.util.AssertUtil;
|
||||||
import sonia.scm.web.cgi.CGIExecutor;
|
import sonia.scm.web.cgi.CGIExecutor;
|
||||||
import sonia.scm.web.cgi.CGIExecutorFactory;
|
import sonia.scm.web.cgi.CGIExecutorFactory;
|
||||||
|
import sonia.scm.web.cgi.EnvList;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import java.util.Enumeration;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@@ -60,6 +62,7 @@ import javax.servlet.ServletException;
|
|||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -78,6 +81,9 @@ public class HgCGIServlet extends HttpServlet
|
|||||||
/** Field description */
|
/** Field description */
|
||||||
public static final String ENV_REPOSITORY_PATH = "SCM_REPOSITORY_PATH";
|
public static final String ENV_REPOSITORY_PATH = "SCM_REPOSITORY_PATH";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String ENV_SESSION_PREFIX = "SCM_";
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
private static final long serialVersionUID = -3492811300905099810L;
|
private static final long serialVersionUID = -3492811300905099810L;
|
||||||
|
|
||||||
@@ -175,6 +181,13 @@ public class HgCGIServlet extends HttpServlet
|
|||||||
directory.getAbsolutePath());
|
directory.getAbsolutePath());
|
||||||
executor.getEnvironment().set(ENV_PYTHON_PATH, pythonPath);
|
executor.getEnvironment().set(ENV_PYTHON_PATH, pythonPath);
|
||||||
|
|
||||||
|
HttpSession session = request.getSession();
|
||||||
|
|
||||||
|
if (session != null)
|
||||||
|
{
|
||||||
|
passSessionAttributes(executor.getEnvironment(), session);
|
||||||
|
}
|
||||||
|
|
||||||
String interpreter = getInterpreter();
|
String interpreter = getInterpreter();
|
||||||
|
|
||||||
if (interpreter != null)
|
if (interpreter != null)
|
||||||
@@ -185,6 +198,28 @@ public class HgCGIServlet extends HttpServlet
|
|||||||
executor.execute(command.getAbsolutePath());
|
executor.execute(command.getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param env
|
||||||
|
* @param session
|
||||||
|
*/
|
||||||
|
private void passSessionAttributes(EnvList env, HttpSession session)
|
||||||
|
{
|
||||||
|
Enumeration<String> enm = session.getAttributeNames();
|
||||||
|
|
||||||
|
while (enm.hasMoreElements())
|
||||||
|
{
|
||||||
|
String key = enm.nextElement();
|
||||||
|
|
||||||
|
if (key.startsWith(ENV_SESSION_PREFIX))
|
||||||
|
{
|
||||||
|
env.set(key, session.getAttribute(key).toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -49,8 +49,10 @@ import sonia.scm.repository.HgRepositoryHookEvent;
|
|||||||
import sonia.scm.repository.RepositoryHookType;
|
import sonia.scm.repository.RepositoryHookType;
|
||||||
import sonia.scm.repository.RepositoryManager;
|
import sonia.scm.repository.RepositoryManager;
|
||||||
import sonia.scm.repository.RepositoryNotFoundException;
|
import sonia.scm.repository.RepositoryNotFoundException;
|
||||||
|
import sonia.scm.security.CipherUtil;
|
||||||
import sonia.scm.util.HttpUtil;
|
import sonia.scm.util.HttpUtil;
|
||||||
import sonia.scm.util.Util;
|
import sonia.scm.util.Util;
|
||||||
|
import sonia.scm.web.security.WebSecurityContext;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
@@ -81,6 +83,9 @@ public class HgHookCallbackServlet extends HttpServlet
|
|||||||
/** Field description */
|
/** Field description */
|
||||||
private static final String PARAM_CHALLENGE = "challenge";
|
private static final String PARAM_CHALLENGE = "challenge";
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private static final String PARAM_CREDENTIALS = "credentials";
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
private static final String PARAM_NODE = "node";
|
private static final String PARAM_NODE = "node";
|
||||||
|
|
||||||
@@ -102,17 +107,19 @@ public class HgHookCallbackServlet extends HttpServlet
|
|||||||
* @param handler
|
* @param handler
|
||||||
* @param hookManager
|
* @param hookManager
|
||||||
* @param contextProvider
|
* @param contextProvider
|
||||||
|
* @param securityContextProvider
|
||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
public HgHookCallbackServlet(RepositoryManager repositoryManager,
|
public HgHookCallbackServlet(
|
||||||
HgRepositoryHandler handler,
|
RepositoryManager repositoryManager, HgRepositoryHandler handler,
|
||||||
HgHookManager hookManager,
|
HgHookManager hookManager, Provider<HgContext> contextProvider,
|
||||||
Provider<HgContext> contextProvider)
|
Provider<WebSecurityContext> securityContextProvider)
|
||||||
{
|
{
|
||||||
this.repositoryManager = repositoryManager;
|
this.repositoryManager = repositoryManager;
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
this.hookManager = hookManager;
|
this.hookManager = hookManager;
|
||||||
this.contextProvider = contextProvider;
|
this.contextProvider = contextProvider;
|
||||||
|
this.securityContextProvider = securityContextProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
//~--- methods --------------------------------------------------------------
|
||||||
@@ -147,6 +154,13 @@ public class HgHookCallbackServlet extends HttpServlet
|
|||||||
|
|
||||||
if (Util.isNotEmpty(node))
|
if (Util.isNotEmpty(node))
|
||||||
{
|
{
|
||||||
|
String credentials = request.getParameter(PARAM_CREDENTIALS);
|
||||||
|
|
||||||
|
if (Util.isNotEmpty(credentials))
|
||||||
|
{
|
||||||
|
authenticate(request, response, credentials);
|
||||||
|
}
|
||||||
|
|
||||||
hookCallback(response, repositoryId, type, challenge, node);
|
hookCallback(response, repositoryId, type, challenge, node);
|
||||||
}
|
}
|
||||||
else if (logger.isDebugEnabled())
|
else if (logger.isDebugEnabled())
|
||||||
@@ -170,6 +184,40 @@ public class HgHookCallbackServlet extends HttpServlet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @param credentials
|
||||||
|
*/
|
||||||
|
private void authenticate(HttpServletRequest request,
|
||||||
|
HttpServletResponse response, String credentials)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
credentials = CipherUtil.getInstance().decode(credentials);
|
||||||
|
|
||||||
|
if (Util.isNotEmpty(credentials))
|
||||||
|
{
|
||||||
|
String[] credentialsArray = credentials.split(":");
|
||||||
|
|
||||||
|
if (credentialsArray.length >= 2)
|
||||||
|
{
|
||||||
|
WebSecurityContext context = securityContextProvider.get();
|
||||||
|
|
||||||
|
context.authenticate(request, response, credentialsArray[0],
|
||||||
|
credentialsArray[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.error("could not authenticate user", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
@@ -281,4 +329,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
|||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
private RepositoryManager repositoryManager;
|
private RepositoryManager repositoryManager;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private Provider<WebSecurityContext> securityContextProvider;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import os, urllib
|
|||||||
|
|
||||||
baseUrl = "${url}"
|
baseUrl = "${url}"
|
||||||
challenge = "${challenge}"
|
challenge = "${challenge}"
|
||||||
|
credentials = os.environ['SCM_CREDENTIALS']
|
||||||
|
|
||||||
def callback(ui, repo, hooktype, node=None, source=None, **kwargs):
|
def callback(ui, repo, hooktype, node=None, source=None, **kwargs):
|
||||||
failure = True
|
failure = True
|
||||||
@@ -47,7 +48,7 @@ def callback(ui, repo, hooktype, node=None, source=None, **kwargs):
|
|||||||
try:
|
try:
|
||||||
url = baseUrl + os.path.basename(repo.root) + "/" + hooktype
|
url = baseUrl + os.path.basename(repo.root) + "/" + hooktype
|
||||||
ui.debug( "send scm-hook to " + url + " and " + node + "\n" )
|
ui.debug( "send scm-hook to " + url + " and " + node + "\n" )
|
||||||
data = urllib.urlencode({'node': node, 'challenge': challenge})
|
data = urllib.urlencode({'node': node, 'challenge': challenge, 'credentials': credentials})
|
||||||
conn = urllib.urlopen(url, data);
|
conn = urllib.urlopen(url, data);
|
||||||
if conn.code >= 200 and conn.code < 300:
|
if conn.code >= 200 and conn.code < 300:
|
||||||
ui.debug( "scm-hook " + hooktype + " success with status code " + str(conn.code) + "\n" )
|
ui.debug( "scm-hook " + hooktype + " success with status code " + str(conn.code) + "\n" )
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import sonia.scm.config.ScmConfiguration;
|
import sonia.scm.config.ScmConfiguration;
|
||||||
import sonia.scm.group.Group;
|
import sonia.scm.group.Group;
|
||||||
import sonia.scm.group.GroupManager;
|
import sonia.scm.group.GroupManager;
|
||||||
|
import sonia.scm.security.CipherUtil;
|
||||||
import sonia.scm.user.User;
|
import sonia.scm.user.User;
|
||||||
import sonia.scm.user.UserManager;
|
import sonia.scm.user.UserManager;
|
||||||
import sonia.scm.util.Util;
|
import sonia.scm.util.Util;
|
||||||
@@ -67,6 +68,9 @@ import javax.servlet.http.HttpSession;
|
|||||||
public class BasicSecurityContext implements WebSecurityContext
|
public class BasicSecurityContext implements WebSecurityContext
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
public static final String SCM_CREDENTIALS = "SCM_CREDENTIALS";
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
public static final String USER_ANONYMOUS = "anonymous";
|
public static final String USER_ANONYMOUS = "anonymous";
|
||||||
|
|
||||||
@@ -154,6 +158,16 @@ public class BasicSecurityContext implements WebSecurityContext
|
|||||||
{
|
{
|
||||||
logGroups();
|
logGroups();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String credentials = dbUser.getName();
|
||||||
|
|
||||||
|
if (Util.isNotEmpty(password))
|
||||||
|
{
|
||||||
|
credentials = credentials.concat(":").concat(password);
|
||||||
|
}
|
||||||
|
|
||||||
|
credentials = CipherUtil.getInstance().encode(credentials);
|
||||||
|
request.getSession(true).setAttribute(SCM_CREDENTIALS, credentials);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user