reauthenticate user on mercurial hooks

This commit is contained in:
Sebastian Sdorra
2011-10-15 15:55:17 +02:00
parent 6328a14654
commit 84f63e94c0
4 changed files with 106 additions and 5 deletions

View File

@@ -47,12 +47,14 @@ import sonia.scm.repository.RepositoryManager;
import sonia.scm.util.AssertUtil;
import sonia.scm.web.cgi.CGIExecutor;
import sonia.scm.web.cgi.CGIExecutorFactory;
import sonia.scm.web.cgi.EnvList;
//~--- JDK imports ------------------------------------------------------------
import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -60,6 +62,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
*
@@ -78,6 +81,9 @@ public class HgCGIServlet extends HttpServlet
/** Field description */
public static final String ENV_REPOSITORY_PATH = "SCM_REPOSITORY_PATH";
/** Field description */
public static final String ENV_SESSION_PREFIX = "SCM_";
/** Field description */
private static final long serialVersionUID = -3492811300905099810L;
@@ -175,6 +181,13 @@ public class HgCGIServlet extends HttpServlet
directory.getAbsolutePath());
executor.getEnvironment().set(ENV_PYTHON_PATH, pythonPath);
HttpSession session = request.getSession();
if (session != null)
{
passSessionAttributes(executor.getEnvironment(), session);
}
String interpreter = getInterpreter();
if (interpreter != null)
@@ -185,6 +198,28 @@ public class HgCGIServlet extends HttpServlet
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 ----------------------------------------------------------
/**

View File

@@ -49,8 +49,10 @@ import sonia.scm.repository.HgRepositoryHookEvent;
import sonia.scm.repository.RepositoryHookType;
import sonia.scm.repository.RepositoryManager;
import sonia.scm.repository.RepositoryNotFoundException;
import sonia.scm.security.CipherUtil;
import sonia.scm.util.HttpUtil;
import sonia.scm.util.Util;
import sonia.scm.web.security.WebSecurityContext;
//~--- JDK imports ------------------------------------------------------------
@@ -81,6 +83,9 @@ public class HgHookCallbackServlet extends HttpServlet
/** Field description */
private static final String PARAM_CHALLENGE = "challenge";
/** Field description */
private static final String PARAM_CREDENTIALS = "credentials";
/** Field description */
private static final String PARAM_NODE = "node";
@@ -102,17 +107,19 @@ public class HgHookCallbackServlet extends HttpServlet
* @param handler
* @param hookManager
* @param contextProvider
* @param securityContextProvider
*/
@Inject
public HgHookCallbackServlet(RepositoryManager repositoryManager,
HgRepositoryHandler handler,
HgHookManager hookManager,
Provider<HgContext> contextProvider)
public HgHookCallbackServlet(
RepositoryManager repositoryManager, HgRepositoryHandler handler,
HgHookManager hookManager, Provider<HgContext> contextProvider,
Provider<WebSecurityContext> securityContextProvider)
{
this.repositoryManager = repositoryManager;
this.handler = handler;
this.hookManager = hookManager;
this.contextProvider = contextProvider;
this.securityContextProvider = securityContextProvider;
}
//~--- methods --------------------------------------------------------------
@@ -147,6 +154,13 @@ public class HgHookCallbackServlet extends HttpServlet
if (Util.isNotEmpty(node))
{
String credentials = request.getParameter(PARAM_CREDENTIALS);
if (Util.isNotEmpty(credentials))
{
authenticate(request, response, credentials);
}
hookCallback(response, repositoryId, type, challenge, node);
}
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
*
@@ -281,4 +329,7 @@ public class HgHookCallbackServlet extends HttpServlet
/** Field description */
private RepositoryManager repositoryManager;
/** Field description */
private Provider<WebSecurityContext> securityContextProvider;
}

View File

@@ -40,6 +40,7 @@ import os, urllib
baseUrl = "${url}"
challenge = "${challenge}"
credentials = os.environ['SCM_CREDENTIALS']
def callback(ui, repo, hooktype, node=None, source=None, **kwargs):
failure = True
@@ -47,7 +48,7 @@ def callback(ui, repo, hooktype, node=None, source=None, **kwargs):
try:
url = baseUrl + os.path.basename(repo.root) + "/" + hooktype
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);
if conn.code >= 200 and conn.code < 300:
ui.debug( "scm-hook " + hooktype + " success with status code " + str(conn.code) + "\n" )

View File

@@ -44,6 +44,7 @@ import org.slf4j.LoggerFactory;
import sonia.scm.config.ScmConfiguration;
import sonia.scm.group.Group;
import sonia.scm.group.GroupManager;
import sonia.scm.security.CipherUtil;
import sonia.scm.user.User;
import sonia.scm.user.UserManager;
import sonia.scm.util.Util;
@@ -67,6 +68,9 @@ import javax.servlet.http.HttpSession;
public class BasicSecurityContext implements WebSecurityContext
{
/** Field description */
public static final String SCM_CREDENTIALS = "SCM_CREDENTIALS";
/** Field description */
public static final String USER_ANONYMOUS = "anonymous";
@@ -154,6 +158,16 @@ public class BasicSecurityContext implements WebSecurityContext
{
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)
{