added a challenge for mercurial hooks

This commit is contained in:
Sebastian Sdorra
2011-07-22 13:08:12 +02:00
parent 21013a967f
commit 6b678b502a
5 changed files with 135 additions and 23 deletions

View File

@@ -40,6 +40,7 @@ import com.google.inject.Inject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import sonia.scm.repository.HgHookManager;
import sonia.scm.repository.HgRepositoryHandler; import sonia.scm.repository.HgRepositoryHandler;
import sonia.scm.repository.HgRepositoryHookEvent; import sonia.scm.repository.HgRepositoryHookEvent;
import sonia.scm.repository.RepositoryManager; import sonia.scm.repository.RepositoryManager;
@@ -47,10 +48,10 @@ import sonia.scm.repository.RepositoryNotFoundException;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
import javax.ws.rs.GET; import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
/** /**
@@ -73,13 +74,15 @@ public class HgHookCallback
* *
* @param repositoryManager * @param repositoryManager
* @param handler * @param handler
* @param hookManager
*/ */
@Inject @Inject
public HgHookCallback(RepositoryManager repositoryManager, public HgHookCallback(RepositoryManager repositoryManager,
HgRepositoryHandler handler) HgRepositoryHandler handler, HgHookManager hookManager)
{ {
this.repositoryManager = repositoryManager; this.repositoryManager = repositoryManager;
this.handler = handler; this.handler = handler;
this.hookManager = hookManager;
} }
//~--- methods -------------------------------------------------------------- //~--- methods --------------------------------------------------------------
@@ -91,38 +94,52 @@ public class HgHookCallback
* *
* @param repositoryName * @param repositoryName
* @param type * @param type
* @param challenge
* @param node * @param node
* *
* @return * @return
*/ */
@GET @POST
public Response hookCallback(@PathParam("repository") String repositoryName, public Response hookCallback(@PathParam("repository") String repositoryName,
@PathParam("type") String type, @PathParam("type") String type,
@QueryParam("node") String node) @FormParam("challenge") String challenge,
@FormParam("node") String node)
{ {
Response response = null; Response response = null;
try if (hookManager.isAcceptAble(challenge))
{ {
repositoryManager.fireHookEvent(HgRepositoryHandler.TYPE_NAME, try
repositoryName,
new HgRepositoryHookEvent(handler,
repositoryName, node));
response = Response.ok().build();
}
catch (RepositoryNotFoundException ex)
{
if (logger.isErrorEnabled())
{ {
logger.error("could not find repository {}", repositoryName); repositoryManager.fireHookEvent(HgRepositoryHandler.TYPE_NAME,
repositoryName,
if (logger.isTraceEnabled()) new HgRepositoryHookEvent(handler,
repositoryName, node));
response = Response.ok().build();
}
catch (RepositoryNotFoundException ex)
{
if (logger.isErrorEnabled())
{ {
logger.trace("repository not found", ex); logger.error("could not find repository {}", repositoryName);
if (logger.isTraceEnabled())
{
logger.trace("repository not found", ex);
}
} }
response = Response.status(Response.Status.NOT_FOUND).build();
}
}
else
{
if (logger.isWarnEnabled())
{
logger.warn("hg hook challenge is not accept able");
} }
response = Response.status(Response.Status.NOT_FOUND).build(); response = Response.status(Response.Status.BAD_REQUEST).build();
} }
return response; return response;
@@ -133,6 +150,9 @@ public class HgHookCallback
/** Field description */ /** Field description */
private HgRepositoryHandler handler; private HgRepositoryHandler handler;
/** Field description */
private HgHookManager hookManager;
/** Field description */ /** Field description */
private RepositoryManager repositoryManager; private RepositoryManager repositoryManager;
} }

View File

@@ -0,0 +1,80 @@
/**
* 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.repository;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Singleton;
//~--- JDK imports ------------------------------------------------------------
import java.util.UUID;
/**
*
* @author Sebastian Sdorra
*/
@Singleton
public class HgHookManager
{
/**
* Method description
*
*
* @return
*/
public String getChallenge()
{
return challenge;
}
/**
* Method description
*
*
* @param challenge
*
* @return
*/
public boolean isAcceptAble(String challenge)
{
return challenge.equals(challenge);
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private String challenge = UUID.randomUUID().toString();
}

View File

@@ -45,6 +45,7 @@ import sonia.scm.SCMContextProvider;
import sonia.scm.io.RegexResourceProcessor; import sonia.scm.io.RegexResourceProcessor;
import sonia.scm.io.ResourceProcessor; import sonia.scm.io.ResourceProcessor;
import sonia.scm.repository.HgConfig; import sonia.scm.repository.HgConfig;
import sonia.scm.repository.HgHookManager;
import sonia.scm.repository.HgRepositoryHandler; import sonia.scm.repository.HgRepositoryHandler;
import sonia.scm.util.IOUtil; import sonia.scm.util.IOUtil;
import sonia.scm.util.Util; import sonia.scm.util.Util;
@@ -86,13 +87,16 @@ public class HgHookScriptFilter extends HttpFilter
* *
* @param context * @param context
* @param handler * @param handler
* @param hookManager
*/ */
@Inject @Inject
public HgHookScriptFilter(SCMContextProvider context, public HgHookScriptFilter(SCMContextProvider context,
HgRepositoryHandler handler) HgRepositoryHandler handler,
HgHookManager hookManager)
{ {
this.context = context; this.context = context;
this.handler = handler; this.handler = handler;
this.hookManager = hookManager;
} }
//~--- methods -------------------------------------------------------------- //~--- methods --------------------------------------------------------------
@@ -183,6 +187,7 @@ public class HgHookScriptFilter extends HttpFilter
rp.addVariable("python", config.getPythonBinary()); rp.addVariable("python", config.getPythonBinary());
rp.addVariable("path", Util.nonNull(config.getPythonPath())); rp.addVariable("path", Util.nonNull(config.getPythonPath()));
rp.addVariable("url", url); rp.addVariable("url", url);
rp.addVariable("challenge", hookManager.getChallenge());
rp.process(input, output); rp.process(input, output);
script.setExecutable(true); script.setExecutable(true);
} }
@@ -201,6 +206,9 @@ public class HgHookScriptFilter extends HttpFilter
/** Field description */ /** Field description */
private HgRepositoryHandler handler; private HgRepositoryHandler handler;
/** Field description */
private HgHookManager hookManager;
/** Field description */ /** Field description */
private volatile boolean written = false; private volatile boolean written = false;
} }

View File

@@ -38,6 +38,7 @@ package sonia.scm.web;
import com.google.inject.servlet.ServletModule; import com.google.inject.servlet.ServletModule;
import sonia.scm.plugin.ext.Extension; import sonia.scm.plugin.ext.Extension;
import sonia.scm.repository.HgHookManager;
import sonia.scm.web.filter.BasicAuthenticationFilter; import sonia.scm.web.filter.BasicAuthenticationFilter;
/** /**
@@ -63,6 +64,7 @@ public class HgServletModule extends ServletModule
@Override @Override
protected void configureServlets() protected void configureServlets()
{ {
bind(HgHookManager.class);
// write hook script // write hook script
filter(MAPPING_ALL).through(HgHookScriptFilter.class); filter(MAPPING_ALL).through(HgHookScriptFilter.class);

View File

@@ -17,11 +17,13 @@ if len(pythonPath) > 0:
sys.path.insert(i, pathParts[i]) sys.path.insert(i, pathParts[i])
baseUrl = "${url}" baseUrl = "${url}"
challenge = "${challenge}"
def callback(ui, repo, hooktype, node=None, source=None, **kwargs): def callback(ui, repo, hooktype, node=None, source=None, **kwargs):
if node != None: if node != None:
url = baseUrl + os.path.basename(repo.root) + "/" + hooktype + "?node=" + node url = baseUrl + os.path.basename(repo.root) + "/" + hooktype
conn = urllib.urlopen(url); data = urllib.urlencode({'node': node, 'challenge': challenge})
conn = urllib.urlopen(url, data);
if conn.code == 200: if conn.code == 200:
print( "scm-hook executed successfully" ) print( "scm-hook executed successfully" )
else: else: