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.LoggerFactory;
import sonia.scm.repository.HgHookManager;
import sonia.scm.repository.HgRepositoryHandler;
import sonia.scm.repository.HgRepositoryHookEvent;
import sonia.scm.repository.RepositoryManager;
@@ -47,10 +48,10 @@ import sonia.scm.repository.RepositoryNotFoundException;
//~--- 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.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
/**
@@ -73,13 +74,15 @@ public class HgHookCallback
*
* @param repositoryManager
* @param handler
* @param hookManager
*/
@Inject
public HgHookCallback(RepositoryManager repositoryManager,
HgRepositoryHandler handler)
HgRepositoryHandler handler, HgHookManager hookManager)
{
this.repositoryManager = repositoryManager;
this.handler = handler;
this.hookManager = hookManager;
}
//~--- methods --------------------------------------------------------------
@@ -91,38 +94,52 @@ public class HgHookCallback
*
* @param repositoryName
* @param type
* @param challenge
* @param node
*
* @return
*/
@GET
@POST
public Response hookCallback(@PathParam("repository") String repositoryName,
@PathParam("type") String type,
@QueryParam("node") String node)
@FormParam("challenge") String challenge,
@FormParam("node") String node)
{
Response response = null;
try
if (hookManager.isAcceptAble(challenge))
{
repositoryManager.fireHookEvent(HgRepositoryHandler.TYPE_NAME,
repositoryName,
new HgRepositoryHookEvent(handler,
repositoryName, node));
response = Response.ok().build();
}
catch (RepositoryNotFoundException ex)
{
if (logger.isErrorEnabled())
try
{
logger.error("could not find repository {}", repositoryName);
if (logger.isTraceEnabled())
repositoryManager.fireHookEvent(HgRepositoryHandler.TYPE_NAME,
repositoryName,
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;
@@ -133,6 +150,9 @@ public class HgHookCallback
/** Field description */
private HgRepositoryHandler handler;
/** Field description */
private HgHookManager hookManager;
/** Field description */
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.ResourceProcessor;
import sonia.scm.repository.HgConfig;
import sonia.scm.repository.HgHookManager;
import sonia.scm.repository.HgRepositoryHandler;
import sonia.scm.util.IOUtil;
import sonia.scm.util.Util;
@@ -86,13 +87,16 @@ public class HgHookScriptFilter extends HttpFilter
*
* @param context
* @param handler
* @param hookManager
*/
@Inject
public HgHookScriptFilter(SCMContextProvider context,
HgRepositoryHandler handler)
HgRepositoryHandler handler,
HgHookManager hookManager)
{
this.context = context;
this.handler = handler;
this.hookManager = hookManager;
}
//~--- methods --------------------------------------------------------------
@@ -183,6 +187,7 @@ public class HgHookScriptFilter extends HttpFilter
rp.addVariable("python", config.getPythonBinary());
rp.addVariable("path", Util.nonNull(config.getPythonPath()));
rp.addVariable("url", url);
rp.addVariable("challenge", hookManager.getChallenge());
rp.process(input, output);
script.setExecutable(true);
}
@@ -201,6 +206,9 @@ public class HgHookScriptFilter extends HttpFilter
/** Field description */
private HgRepositoryHandler handler;
/** Field description */
private HgHookManager hookManager;
/** Field description */
private volatile boolean written = false;
}

View File

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

View File

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