diff --git a/plugins/pom.xml b/plugins/pom.xml index 415e85032e..e91bbca70c 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -22,6 +22,7 @@ scm-graph-plugin scm-activedirectory-auth-plugin scm-pam-plugin + scm-bzr-plugin diff --git a/plugins/scm-bzr-plugin/pom.xml b/plugins/scm-bzr-plugin/pom.xml new file mode 100644 index 0000000000..81970def67 --- /dev/null +++ b/plugins/scm-bzr-plugin/pom.xml @@ -0,0 +1,31 @@ + + + + 4.0.0 + + + scm-plugins + sonia.scm.plugins + 1.0-M6-SNAPSHOT + + + sonia.scm.plugins + scm-bzr-plugin + 1.0-M6-SNAPSHOT + scm-bzr-plugin + https://bitbucket.org/sdorra/scm-manager + Plugin for the version control system Bazaar + + + + + javax.servlet + servlet-api + ${servlet.version} + provided + + + + + diff --git a/plugins/scm-bzr-plugin/src/main/java/sonia/scm/api/rest/resources/BzrConfigResource.java b/plugins/scm-bzr-plugin/src/main/java/sonia/scm/api/rest/resources/BzrConfigResource.java new file mode 100644 index 0000000000..f49a845879 --- /dev/null +++ b/plugins/scm-bzr-plugin/src/main/java/sonia/scm/api/rest/resources/BzrConfigResource.java @@ -0,0 +1,132 @@ +/** + * 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.api.rest.resources; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +import sonia.scm.repository.BzrConfig; +import sonia.scm.repository.BzrRepositoryHandler; +import sonia.scm.web.BzrScriptWriter; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +/** + * + * @author Sebastian Sdorra + */ +@Singleton +@Path("config/repositories/bzr") +public class BzrConfigResource +{ + + /** + * Constructs ... + * + * + * + * @param handler + */ + @Inject + public BzrConfigResource(BzrRepositoryHandler handler) + { + this.handler = handler; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @GET + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public BzrConfig getConfig() + { + BzrConfig config = handler.getConfig(); + + if (config == null) + { + config = new BzrConfig(); + } + + return config; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param uriInfo + * @param config + * + * @return + * + * @throws IOException + */ + @POST + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public Response setConfig(@Context UriInfo uriInfo, BzrConfig config) + throws IOException + { + handler.setConfig(config); + handler.storeConfig(); + new BzrScriptWriter(config).write(); + + return Response.created(uriInfo.getRequestUri()).build(); + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private BzrRepositoryHandler handler; +} diff --git a/plugins/scm-bzr-plugin/src/main/java/sonia/scm/repository/BzrConfig.java b/plugins/scm-bzr-plugin/src/main/java/sonia/scm/repository/BzrConfig.java new file mode 100644 index 0000000000..deffb169e3 --- /dev/null +++ b/plugins/scm-bzr-plugin/src/main/java/sonia/scm/repository/BzrConfig.java @@ -0,0 +1,134 @@ +/** + * 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; + +//~--- JDK imports ------------------------------------------------------------ + +import javax.xml.bind.annotation.XmlRootElement; + +/** + * + * @author Sebastian Sdorra + */ +@XmlRootElement(name = "config") +public class BzrConfig extends SimpleRepositoryConfig +{ + + /** + * Constructs ... + * + */ + public BzrConfig() {} + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + public String getBzrBinary() + { + return bzrBinary; + } + + /** + * Method description + * + * + * @return + */ + public String getPythonBinary() + { + return pythonBinary; + } + + /** + * Method description + * + * + * @return + */ + public String getPythonPath() + { + return pythonPath; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param bzrBinary + */ + public void setBzrBinary(String bzrBinary) + { + this.bzrBinary = bzrBinary; + } + + /** + * Method description + * + * + * @param pythonBinary + */ + public void setPythonBinary(String pythonBinary) + { + this.pythonBinary = pythonBinary; + } + + /** + * Method description + * + * + * @param pythonPath + */ + public void setPythonPath(String pythonPath) + { + this.pythonPath = pythonPath; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private String bzrBinary; + + /** Field description */ + private String pythonBinary; + + /** Field description */ + private String pythonPath = ""; +} diff --git a/plugins/scm-bzr-plugin/src/main/java/sonia/scm/repository/BzrRepositoryHandler.java b/plugins/scm-bzr-plugin/src/main/java/sonia/scm/repository/BzrRepositoryHandler.java new file mode 100644 index 0000000000..4a454d0ec0 --- /dev/null +++ b/plugins/scm-bzr-plugin/src/main/java/sonia/scm/repository/BzrRepositoryHandler.java @@ -0,0 +1,129 @@ +/** + * 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.Inject; +import com.google.inject.Singleton; + +import sonia.scm.Type; +import sonia.scm.io.ExtendedCommand; +import sonia.scm.plugin.ext.Extension; +import sonia.scm.store.StoreFactory; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; + +/** + * + * @author Sebastian Sdorra + */ +@Singleton +@Extension +public class BzrRepositoryHandler + extends AbstractSimpleRepositoryHandler +{ + + /** Field description */ + public static final String TYPE_DISPLAYNAME = "Bazaar"; + + /** Field description */ + public static final String TYPE_NAME = "bzr"; + + /** Field description */ + public static final Type TYPE = new Type(TYPE_NAME, TYPE_DISPLAYNAME); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param storeFactory + */ + @Inject + public BzrRepositoryHandler(StoreFactory storeFactory) + { + super(storeFactory); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public Type getType() + { + return TYPE; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param repository + * @param directory + * + * @return + */ + @Override + protected ExtendedCommand buildCreateCommand(Repository repository, + File directory) + { + return new ExtendedCommand(config.getBzrBinary(), "init-repo", + "--no-trees", directory.getPath()); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + protected Class getConfigClass() + { + return BzrConfig.class; + } +} diff --git a/plugins/scm-bzr-plugin/src/main/java/sonia/scm/web/BzrCGIServlet.java b/plugins/scm-bzr-plugin/src/main/java/sonia/scm/web/BzrCGIServlet.java new file mode 100644 index 0000000000..358b7bbcd2 --- /dev/null +++ b/plugins/scm-bzr-plugin/src/main/java/sonia/scm/web/BzrCGIServlet.java @@ -0,0 +1,253 @@ +/** + * 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.web; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +import sonia.scm.repository.BzrConfig; +import sonia.scm.repository.BzrRepositoryHandler; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryManager; +import sonia.scm.util.AssertUtil; +import sonia.scm.web.cgi.AbstractCGIServlet; +import sonia.scm.web.cgi.EnvList; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.IOException; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; + +/** + * + * @author Sebastian Sdorra + */ +@Singleton +public class BzrCGIServlet extends AbstractCGIServlet +{ + + /** Field description */ + public static final String ENV_PYTHON_PATH = "SCM_PYTHON_PATH"; + + /** 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 */ + private static final long serialVersionUID = 7674689744455227632L; + + /** Field description */ + public static final Pattern PATTERN_REPOSITORYNAME = + Pattern.compile("/[^/]+/([^/]+)(?:/.*)?"); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param repositoryManager + * @param handler + */ + @Inject + public BzrCGIServlet(RepositoryManager repositoryManager, + BzrRepositoryHandler handler) + { + this.repositoryManager = repositoryManager; + this.handler = handler; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @throws ServletException + */ + @Override + public void init() throws ServletException + { + command = BzrUtil.getCGI(); + super.init(); + } + + /** + * Method description + * + * + * @param request + * @param baseEnvironment + * + * @return + * + * @throws ServletException + */ + @Override + protected EnvList createRequestEnvironment(HttpServletRequest request, + EnvList baseEnvironment) + throws ServletException + { + EnvList list = new EnvList(baseEnvironment); + Repository repository = getRepository(request); + + if (repository == null) + { + throw new ServletException("repository not found"); + } + + String name = repository.getName(); + File directory = handler.getDirectory(repository); + + list.set(ENV_REPOSITORY_PATH, directory.getAbsolutePath()); + list.set(ENV_REPOSITORY_NAME, name); + + String pythonPath = ""; + BzrConfig config = handler.getConfig(); + + if (config != null) + { + pythonPath = config.getPythonPath(); + + if (pythonPath == null) + { + pythonPath = ""; + } + } + + list.set(ENV_PYTHON_PATH, pythonPath); + + return list; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * + * @return + * + */ + @Override + protected String getCmdPrefix() + { + BzrConfig config = handler.getConfig(); + + AssertUtil.assertIsNotNull(config); + + return config.getPythonBinary(); + } + + /** + * Method description + * + * + * @param request + * + * @return + * + * @throws IOException + * @throws ServletException + */ + @Override + protected File getCommand(HttpServletRequest request) + throws ServletException, IOException + { + return command; + } + + /** + * Method description + * + * + * @param request + * + * @return + */ + private Repository getRepository(HttpServletRequest request) + { + Repository repository = null; + String uri = request.getRequestURI(); + + uri = uri.substring(request.getContextPath().length()); + + Matcher m = PATTERN_REPOSITORYNAME.matcher(uri); + + if (m.matches()) + { + String repositoryname = m.group(1); + + repository = getRepository(repositoryname); + } + + return repository; + } + + /** + * Method description + * + * + * @param repositoryname + * + * @return + */ + private Repository getRepository(String repositoryname) + { + return repositoryManager.get(BzrRepositoryHandler.TYPE_NAME, + repositoryname); + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private File command; + + /** Field description */ + private BzrRepositoryHandler handler; + + /** Field description */ + private RepositoryManager repositoryManager; +} diff --git a/plugins/scm-bzr-plugin/src/main/java/sonia/scm/web/BzrPermissionFilter.java b/plugins/scm-bzr-plugin/src/main/java/sonia/scm/web/BzrPermissionFilter.java new file mode 100644 index 0000000000..65737a88be --- /dev/null +++ b/plugins/scm-bzr-plugin/src/main/java/sonia/scm/web/BzrPermissionFilter.java @@ -0,0 +1,101 @@ +/** + * 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.web; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.google.inject.Singleton; + +import sonia.scm.repository.BzrRepositoryHandler; +import sonia.scm.repository.RepositoryManager; +import sonia.scm.web.filter.RegexPermissionFilter; +import sonia.scm.web.security.WebSecurityContext; + +//~--- JDK imports ------------------------------------------------------------ + +import javax.servlet.http.HttpServletRequest; + +/** + * + * @author Sebastian Sdorra + */ +@Singleton +public class BzrPermissionFilter extends RegexPermissionFilter +{ + + /** + * Constructs ... + * + * + * @param securityContextProvider + * @param repositoryManager + */ + @Inject + public BzrPermissionFilter( + Provider securityContextProvider, + RepositoryManager repositoryManager) + { + super(securityContextProvider, repositoryManager); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + protected String getType() + { + return BzrRepositoryHandler.TYPE_NAME; + } + + /** + * Method description + * + * + * @param request + * + * @return + */ + @Override + protected boolean isWriteRequest(HttpServletRequest request) + { + return !request.getMethod().equalsIgnoreCase("GET"); + } +} diff --git a/plugins/scm-bzr-plugin/src/main/java/sonia/scm/web/BzrScriptWriter.java b/plugins/scm-bzr-plugin/src/main/java/sonia/scm/web/BzrScriptWriter.java new file mode 100644 index 0000000000..022dbf89ab --- /dev/null +++ b/plugins/scm-bzr-plugin/src/main/java/sonia/scm/web/BzrScriptWriter.java @@ -0,0 +1,125 @@ +/** + * 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.web; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.io.RegexResourceProcessor; +import sonia.scm.io.ResourceProcessor; +import sonia.scm.repository.BzrConfig; +import sonia.scm.util.IOUtil; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * + * @author Sebastian Sdorra + */ +public class BzrScriptWriter +{ + + /** Field description */ + public static final String CGI_TEMPLATE = "/sonia/scm/bzrweb.py"; + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param config + */ + public BzrScriptWriter(BzrConfig config) + { + this.config = config; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * + * @throws IOException + */ + public void write() throws IOException + { + File cgiFile = BzrUtil.getCGI(); + + writeCGIFile(cgiFile); + } + + /** + * Method description + * + * + * @param cgiFile + * + * @throws IOException + */ + private void writeCGIFile(File cgiFile) throws IOException + { + InputStream input = null; + OutputStream output = null; + + try + { + input = BzrScriptWriter.class.getResourceAsStream(CGI_TEMPLATE); + output = new FileOutputStream(cgiFile); + + ResourceProcessor rp = new RegexResourceProcessor(); + + rp.addVariable("python", config.getPythonBinary()); + rp.process(input, output); + cgiFile.setExecutable(true); + } + finally + { + IOUtil.close(input); + IOUtil.close(output); + } + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private BzrConfig config; +} diff --git a/plugins/scm-bzr-plugin/src/main/java/sonia/scm/web/BzrServletModule.java b/plugins/scm-bzr-plugin/src/main/java/sonia/scm/web/BzrServletModule.java new file mode 100644 index 0000000000..086a81cafc --- /dev/null +++ b/plugins/scm-bzr-plugin/src/main/java/sonia/scm/web/BzrServletModule.java @@ -0,0 +1,67 @@ +/** + * 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.web; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.inject.servlet.ServletModule; + +import sonia.scm.plugin.ext.Extension; +import sonia.scm.web.filter.BasicAuthenticationFilter; + +/** + * + * @author Sebastian Sdorra + */ +@Extension +public class BzrServletModule extends ServletModule +{ + + /** Field description */ + public static final String MAPPING_BZR = "/bzr/*"; + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + */ + @Override + protected void configureServlets() + { + filter(MAPPING_BZR).through(BasicAuthenticationFilter.class); + filter(MAPPING_BZR).through(BzrPermissionFilter.class); + serve(MAPPING_BZR).with(BzrCGIServlet.class); + } +} diff --git a/plugins/scm-bzr-plugin/src/main/java/sonia/scm/web/BzrUtil.java b/plugins/scm-bzr-plugin/src/main/java/sonia/scm/web/BzrUtil.java new file mode 100644 index 0000000000..7e956c3cba --- /dev/null +++ b/plugins/scm-bzr-plugin/src/main/java/sonia/scm/web/BzrUtil.java @@ -0,0 +1,78 @@ +/** + * 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.web; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.SCMContext; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; + +/** + * + * @author Sebastian Sdorra + */ +public class BzrUtil +{ + + /** Field description */ + public static final String CGI_DIRECTORY = "cgi-bin"; + + /** Field description */ + public static final String CGI_NAME = "bzrweb.py"; + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + public static File getCGI() + { + File cgiDirectory = new File(SCMContext.getContext().getBaseDirectory(), + CGI_DIRECTORY); + + if (!cgiDirectory.exists() &&!cgiDirectory.mkdirs()) + { + throw new RuntimeException( + "could not create directory".concat(cgiDirectory.getPath())); + } + + return new File(cgiDirectory, CGI_NAME); + } +} diff --git a/plugins/scm-bzr-plugin/src/main/resources/META-INF/scm/plugin.xml b/plugins/scm-bzr-plugin/src/main/resources/META-INF/scm/plugin.xml new file mode 100644 index 0000000000..451c4a6467 --- /dev/null +++ b/plugins/scm-bzr-plugin/src/main/resources/META-INF/scm/plugin.xml @@ -0,0 +1,59 @@ + + + + + + + + + ${project.groupId} + ${project.artifactId} + ${project.version} + ${project.name} + ${project.description} + Sebastian Sdorra + ${project.url} + + + + + + + diff --git a/plugins/scm-bzr-plugin/src/main/resources/sonia/scm/bzr.config.js b/plugins/scm-bzr-plugin/src/main/resources/sonia/scm/bzr.config.js new file mode 100644 index 0000000000..6212aa3cde --- /dev/null +++ b/plugins/scm-bzr-plugin/src/main/resources/sonia/scm/bzr.config.js @@ -0,0 +1,96 @@ +/* * + * 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 + * + */ + + + +registerConfigPanel({ + xtype : 'configForm', + title : 'Bazaar Settings', + items : [{ + xtype : 'textfield', + fieldLabel : 'Bzr Binary', + name : 'bzrBinary', + allowBlank : false + },{ + xtype : 'textfield', + fieldLabel : 'Python Binary', + name : 'pythonBinary', + allowBlank : false + },{ + xtype : 'textfield', + fieldLabel : 'Python Path', + name : 'pythonPath' + },{ + xtype: 'textfield', + name: 'repositoryDirectory', + fieldLabel: 'Repository directory', + allowBlank : false + }], + + onSubmit: function(values){ + this.el.mask('Submit ...'); + Ext.Ajax.request({ + url: restUrl + 'config/repositories/bzr.json', + method: 'POST', + jsonData: values, + scope: this, + disableCaching: true, + success: function(response){ + this.el.unmask(); + }, + failure: function(){ + this.el.unmask(); + } + }); + }, + + onLoad: function(el){ + var tid = setTimeout( function(){ el.mask('Loading ...'); }, 100); + Ext.Ajax.request({ + url: restUrl + 'config/repositories/bzr.json', + method: 'GET', + scope: this, + disableCaching: true, + success: function(response){ + var obj = Ext.decode(response.responseText); + this.load(obj); + clearTimeout(tid); + el.unmask(); + }, + failure: function(){ + el.unmask(); + clearTimeout(tid); + alert('failure'); + } + }); + } + +}); diff --git a/plugins/scm-bzr-plugin/src/main/resources/sonia/scm/bzrweb.py b/plugins/scm-bzr-plugin/src/main/resources/sonia/scm/bzrweb.py new file mode 100644 index 0000000000..ac07f87421 --- /dev/null +++ b/plugins/scm-bzr-plugin/src/main/resources/sonia/scm/bzrweb.py @@ -0,0 +1,83 @@ +#!/usr/bin/env ${python} + +import os, sys +pythonPath = os.environ['SCM_PYTHON_PATH'] + +if len(pythonPath) > 0: + pathParts = pythonPath.split(os.pathsep) + for i in range(len(pathParts)): + sys.path.insert(i, pathParts[i]) + +repositoryPath = os.environ['SCM_REPOSITORY_PATH'] +repositoryName = os.environ['REPO_NAME'] + +def run_with_cgi(application): + + environ = dict(os.environ.items()) + environ['wsgi.input'] = sys.stdin + environ['wsgi.errors'] = sys.stderr + environ['wsgi.version'] = (1, 0) + environ['wsgi.multithread'] = False + environ['wsgi.multiprocess'] = True + environ['wsgi.run_once'] = True + + if environ.get('HTTPS', 'off') in ('on', '1'): + environ['wsgi.url_scheme'] = 'https' + else: + environ['wsgi.url_scheme'] = 'http' + + headers_set = [] + headers_sent = [] + + def write(data): + if not headers_set: + raise AssertionError("write() before start_response()") + + elif not headers_sent: + # Before the first output, send the stored headers + status, response_headers = headers_sent[:] = headers_set + sys.stdout.write('Status: %s\r\n' % status) + for header in response_headers: + sys.stdout.write('%s: %s\r\n' % header) + sys.stdout.write('\r\n') + + sys.stdout.write(data) + sys.stdout.flush() + + def start_response(status, response_headers, exc_info=None): + if exc_info: + try: + if headers_sent: + # Re-raise original exception if headers sent + raise exc_info[0], exc_info[1], exc_info[2] + finally: + exc_info = None # avoid dangling circular ref + elif headers_set: + raise AssertionError("Headers already set!") + + headers_set[:] = [status, response_headers] + return write + + result = application(environ, start_response) + try: + for data in result: + if data: # don't send headers until body appears + write(data) + if not headers_sent: + write('') # send headers now if body was empty + finally: + if hasattr(result, 'close'): + result.close() + +from bzrlib.transport.http import wsgi + +def application(environ, start_response): + app = wsgi.make_app( + root=repositoryPath, + prefix="/"+repositoryName, + path_var='PATH_INFO', + readonly=False, + enable_logging=True) + return app(environ, start_response) + +run_with_cgi(application) \ No newline at end of file diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index d8df5e192a..d1038a6558 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -266,6 +266,12 @@ 1.0-M6-SNAPSHOT + + sonia.scm.plugins + scm-bzr-plugin + 1.0-M6-SNAPSHOT + +