diff --git a/pom.xml b/pom.xml index 821a7f02df..1650468606 100644 --- a/pom.xml +++ b/pom.xml @@ -277,6 +277,7 @@ true release,APIviz,doc @{project.version} + true diff --git a/scm-clients/scm-cli-client/pom.xml b/scm-clients/scm-cli-client/pom.xml index 65b9e1273e..44cb8e0d20 100644 --- a/scm-clients/scm-cli-client/pom.xml +++ b/scm-clients/scm-cli-client/pom.xml @@ -22,7 +22,6 @@ javax.servlet servlet-api ${servlet.version} - provided @@ -107,6 +106,124 @@ + + + + it + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.4 + + + package + + copy + + + + + sonia.scm + scm-webapp + ${project.version} + war + ${project.build.directory}/webapp + scm-webapp.war + + + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.12 + + + ${project.version} + + + + + integration-test + + integration-test + + + + verify + + verify + + + + + + + org.mortbay.jetty + jetty-maven-plugin + ${jetty.version} + + 8085 + STOP + + + scm.home + target/scm-it + + + file.encoding + UTF-8 + + + + + 8081 + 60000 + 16384 + + + + /scm + + ${project.build.directory}/webapp/scm-webapp.war + ${project.build.javaLevel} + ${project.build.javaLevel} + ${project.build.sourceEncoding} + 0 + true + + + + start-jetty + pre-integration-test + + deploy-war + + + + stop-jetty + post-integration-test + + stop + + + + + + + + + + + + diff --git a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/AbstractITCaseBase.java b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/AbstractITCaseBase.java new file mode 100644 index 0000000000..5184ea37ed --- /dev/null +++ b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/AbstractITCaseBase.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.cli; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.collect.Lists; +import com.google.common.io.Closeables; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import java.util.Arrays; +import java.util.List; + +/** + * + * @author Sebastian Sdorra + */ +public abstract class AbstractITCaseBase +{ + + /** + * Method description + * + * + * @param cmd + * + * @return + * + * @throws IOException + */ + protected String execute(String... cmd) throws IOException + { + String result = null; + ByteArrayInputStream inputStream = null; + ByteArrayOutputStream outputStream = null; + + try + { + inputStream = new ByteArrayInputStream(new byte[0]); + outputStream = new ByteArrayOutputStream(); + + App app = new App(inputStream, outputStream); + + app.run(cmd); + + outputStream.flush(); + result = outputStream.toString().trim(); + } + finally + { + Closeables.close(inputStream, true); + Closeables.close(outputStream, true); + } + + return result; + } + + /** + * Method description + * + * + * @param cmd + * + * @return + * + * @throws IOException + */ + protected String executeServer(String... cmd) throws IOException + { + List cmdList = Lists.newArrayList(); + + cmdList.add("--server"); + cmdList.add("http://localhost:8081/scm"); + cmdList.add("--user"); + cmdList.add("scmadmin"); + cmdList.add("--password"); + cmdList.add("scmadmin"); + cmdList.addAll(Arrays.asList(cmd)); + + return execute(cmdList.toArray(new String[cmdList.size()])); + } + + /** + * Method description + * + * + * @param values + * + * @return + */ + protected String prepareForTest(String values) + { + return values.replaceAll("\\n", ";").replaceAll("\\s+", ""); + } +} diff --git a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/RepositoriesITCase.java b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/RepositoriesITCase.java new file mode 100644 index 0000000000..d09e912157 --- /dev/null +++ b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/RepositoriesITCase.java @@ -0,0 +1,86 @@ +/** + * 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.cli; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +import static org.hamcrest.Matchers.*; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * + * @author Sebastian Sdorra + */ +public class RepositoriesITCase extends AbstractITCaseBase +{ + + /** + * Method description + * + * + * @throws IOException + */ + @Test + public void listRepositoriesTest() throws IOException + { + executeServer("create-repository", "--type", "git", "--name", "hobbo", + "--description", "Test Repo"); + + String repositories = prepareForTest(executeServer("list-repositories")); + + assertThat(repositories, containsString("Name:hobbo;")); + assertThat(repositories, containsString("Description:TestRepo;")); + assertThat(repositories, containsString("Type:git;")); + + Pattern pattern = Pattern.compile("ID:([^;]+);"); + Matcher matcher = pattern.matcher(repositories); + + if (!matcher.find()) + { + fail("could not extract id of repository"); + } + + String id = matcher.group(1); + + executeServer("delete-repository", id); + } +} diff --git a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/ServerVersionITCase.java b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/ServerVersionITCase.java new file mode 100644 index 0000000000..7e424587fb --- /dev/null +++ b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/ServerVersionITCase.java @@ -0,0 +1,70 @@ +/** + * 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.cli; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assume.assumeTrue; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + */ +public class ServerVersionITCase extends AbstractITCaseBase +{ + + /** + * Method description + * + * + * @throws IOException + */ + @Test + public void testServerVersion() throws IOException + { + String systemVersion = System.getProperty("scm.version"); + + assumeTrue("skip test, because system property scm.version is not set", + systemVersion != null); + + String version = executeServer("server-version"); + + assertEquals("scm-manager version: ".concat(systemVersion), version); + } +} diff --git a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/UsersITCase.java b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/UsersITCase.java new file mode 100644 index 0000000000..e5b29457a9 --- /dev/null +++ b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/UsersITCase.java @@ -0,0 +1,72 @@ +/** + * 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.cli; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +import static org.hamcrest.Matchers.*; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + */ +public class UsersITCase extends AbstractITCaseBase +{ + + /** + * Method description + * + * + * @throws IOException + */ + @Test + public void listUsersTest() throws IOException + { + String users = prepareForTest(executeServer("list-users")); + + assertThat(users, containsString("Name:scmadmin;")); + assertThat(users, containsString("DisplayName:SCMAdministrator;")); + assertThat(users, containsString("Type:xml;")); + assertThat(users, containsString("E-Mail:scm-admin@scm-manager.org;")); + assertThat(users, containsString("Active:true;")); + assertThat(users, containsString("Administrator:true;")); + System.out.println(users); + } +} diff --git a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/VersionITCase.java b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/VersionITCase.java new file mode 100644 index 0000000000..3d9563c34e --- /dev/null +++ b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/VersionITCase.java @@ -0,0 +1,65 @@ +/** + * 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.cli; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + */ +public class VersionITCase extends AbstractITCaseBase +{ + + /** + * Method description + * + * + * @throws IOException + */ + @Test + public void testVersion() throws IOException + { + // maven properties are not available during it tests + String version = execute("version"); + + assertEquals("scm-cli-client version: unknown", version); + } +} diff --git a/scm-core/src/main/java/sonia/scm/repository/DirectoryHealthCheck.java b/scm-core/src/main/java/sonia/scm/repository/DirectoryHealthCheck.java index 382857b30f..0f329d89b2 100644 --- a/scm-core/src/main/java/sonia/scm/repository/DirectoryHealthCheck.java +++ b/scm-core/src/main/java/sonia/scm/repository/DirectoryHealthCheck.java @@ -70,7 +70,7 @@ public abstract class DirectoryHealthCheck implements HealthCheck private static final HealthCheckFailure DIRECTORY_DOES_NOT_EXISTS = new HealthCheckFailure("1oOTx803F1", "repository directory does not exists", - "The repository does not exists. Perhaps it was deleted outside of scm-manafer."); + "The repository does not exists. Perhaps it was deleted outside of scm-manager."); /** * the logger for DirectoryHealthCheck diff --git a/scm-core/src/main/java/sonia/scm/security/DefaultCipherHandler.java b/scm-core/src/main/java/sonia/scm/security/DefaultCipherHandler.java index 64f81be6fd..4b82563687 100644 --- a/scm-core/src/main/java/sonia/scm/security/DefaultCipherHandler.java +++ b/scm-core/src/main/java/sonia/scm/security/DefaultCipherHandler.java @@ -35,6 +35,8 @@ package sonia.scm.security; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.annotations.VisibleForTesting; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -106,6 +108,21 @@ public class DefaultCipherHandler implements CipherHandler //~--- constructors --------------------------------------------------------- + /** + * Constructs a new DefaultCipherHandler. Note this constructor is only for + * unit tests. + * + * + * @param key + * + * @since 1.38 + */ + @VisibleForTesting + protected DefaultCipherHandler(String key) + { + this.key = key.toCharArray(); + } + /** * Constructs ... * @@ -116,7 +133,7 @@ public class DefaultCipherHandler implements CipherHandler * */ public DefaultCipherHandler(SCMContextProvider context, - KeyGenerator keyGenerator) + KeyGenerator keyGenerator) { File configDirectory = new File(context.getBaseDirectory(), "config"); @@ -178,7 +195,7 @@ public class DefaultCipherHandler implements CipherHandler System.arraycopy(encodedInput, 0, salt, 0, SALT_LENGTH); System.arraycopy(encodedInput, SALT_LENGTH, encoded, 0, - encodedInput.length - SALT_LENGTH); + encodedInput.length - SALT_LENGTH); IvParameterSpec iv = new IvParameterSpec(salt); SecretKey secretKey = buildSecretKey(plainKey); @@ -245,7 +262,7 @@ public class DefaultCipherHandler implements CipherHandler System.arraycopy(salt, 0, result, 0, SALT_LENGTH); System.arraycopy(encodedInput, 0, result, SALT_LENGTH, - result.length - SALT_LENGTH); + result.length - SALT_LENGTH); res = new String(Base64.encode(result), ENCODING); } catch (Exception ex) @@ -270,7 +287,7 @@ public class DefaultCipherHandler implements CipherHandler * @throws UnsupportedEncodingException */ private SecretKey buildSecretKey(char[] plainKey) - throws UnsupportedEncodingException, NoSuchAlgorithmException + throws UnsupportedEncodingException, NoSuchAlgorithmException { byte[] raw = new String(plainKey).getBytes(ENCODING); MessageDigest digest = MessageDigest.getInstance(DIGEST_TYPE); diff --git a/scm-core/src/main/java/sonia/scm/util/HttpUtil.java b/scm-core/src/main/java/sonia/scm/util/HttpUtil.java index 244ac98719..7e4c410aa4 100644 --- a/scm-core/src/main/java/sonia/scm/util/HttpUtil.java +++ b/scm-core/src/main/java/sonia/scm/util/HttpUtil.java @@ -37,7 +37,6 @@ package sonia.scm.util; import com.google.common.base.CharMatcher; import com.google.common.base.Strings; -import com.google.common.io.ByteStreams; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/scm-core/src/main/java/sonia/scm/xml/IndentXMLStreamWriter.java b/scm-core/src/main/java/sonia/scm/xml/IndentXMLStreamWriter.java index 55c6928d80..81e973f379 100644 --- a/scm-core/src/main/java/sonia/scm/xml/IndentXMLStreamWriter.java +++ b/scm-core/src/main/java/sonia/scm/xml/IndentXMLStreamWriter.java @@ -34,6 +34,7 @@ package sonia.scm.xml; //~--- JDK imports ------------------------------------------------------------ +import com.google.common.annotations.VisibleForTesting; import javax.xml.namespace.NamespaceContext; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; @@ -48,7 +49,8 @@ public final class IndentXMLStreamWriter implements XMLStreamWriter { /** line separator */ - private static final String LINE_SEPARATOR = + @VisibleForTesting + static final String LINE_SEPARATOR = System.getProperty("line.separator"); //~--- constructors --------------------------------------------------------- diff --git a/scm-core/src/test/java/sonia/scm/xml/IndentXMLStreamWriterTest.java b/scm-core/src/test/java/sonia/scm/xml/IndentXMLStreamWriterTest.java index 070a949ca4..ecfdd06a0f 100644 --- a/scm-core/src/test/java/sonia/scm/xml/IndentXMLStreamWriterTest.java +++ b/scm-core/src/test/java/sonia/scm/xml/IndentXMLStreamWriterTest.java @@ -86,15 +86,14 @@ public class IndentXMLStreamWriterTest String content = baos.toString(); - //J- - Assert.assertEquals( - "\n" + - "\n" + - " Hello\n" + - "\n", - content - ); - //J + StringBuilder buffer = new StringBuilder(""); + buffer.append(IndentXMLStreamWriter.LINE_SEPARATOR); + buffer.append("").append(IndentXMLStreamWriter.LINE_SEPARATOR); + buffer.append(" Hello"); + buffer.append(IndentXMLStreamWriter.LINE_SEPARATOR); + buffer.append("").append(IndentXMLStreamWriter.LINE_SEPARATOR); + + Assert.assertEquals(buffer.toString(), content); } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHealthCheck.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHealthCheck.java new file mode 100644 index 0000000000..66e33e8382 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHealthCheck.java @@ -0,0 +1,135 @@ +/** + * 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 sonia.scm.plugin.Extension; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; + +/** + * Simple {@link HealthCheck} for git repositories. + * + * @author Sebastian Sdorra + * @since 1.39 + */ +@Extension +public final class GitHealthCheck extends DirectoryHealthCheck +{ + + /** Field description */ + private static final HealthCheckFailure COULD_NOT_FIND_GIT_DIRECTORIES = + new HealthCheckFailure("AKOdhQ0pw1", + "Could not find .git or refs directory", + "The git repository does not contain a .git or a refs directory."); + + /** Field description */ + private static final String DIRECTORY_DOT_GIT = ".git"; + + /** Field description */ + private static final String DIRECTORY_REFS = "refs"; + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param repositoryManager + */ + @Inject + public GitHealthCheck(RepositoryManager repositoryManager) + { + super(repositoryManager); + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param repository + * @param directory + * + * @return + */ + @Override + protected HealthCheckResult check(Repository repository, File directory) + { + HealthCheckResult result = HealthCheckResult.healthy(); + + if (!isGitRepository(directory)) + { + result = HealthCheckResult.unhealthy(COULD_NOT_FIND_GIT_DIRECTORIES); + } + + return result; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Returns {@code true} if the repository is from type git. + * + * + * @param repository repository for the health check + * + * @return {@code true} for a mercurial git + */ + @Override + protected boolean isCheckResponsible(Repository repository) + { + return GitRepositoryHandler.TYPE_NAME.equalsIgnoreCase( + repository.getType()); + } + + /** + * Returns {@code true} if the directory contains a .git directory or a refs + * directory (bare git repository). + * + * + * @param directory git repository directory + * + * @return {@code true} if the directory contains a git repository + */ + private boolean isGitRepository(File directory) + { + return new File(directory, DIRECTORY_DOT_GIT).exists() + || new File(directory, DIRECTORY_REFS).exists(); + } +} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index 8bd530d5e9..6fe3211ca8 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -36,7 +36,6 @@ package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Strings; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; @@ -44,8 +43,6 @@ import org.eclipse.jgit.api.FetchCommand; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.diff.DiffFormatter; -import org.eclipse.jgit.errors.IncorrectObjectTypeException; -import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Ref; @@ -68,7 +65,6 @@ import sonia.scm.util.Util; import java.io.File; import java.io.IOException; -import java.util.Locale; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -471,9 +467,6 @@ public final class GitUtil * * @return * - * @throws IncorrectObjectTypeException - * @throws MissingObjectException - * * @throws IOException */ public static Ref getRefForCommit(org.eclipse.jgit.lib.Repository repository, diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitRepositoryViewer.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitRepositoryViewer.java index 62e334729a..bad6241ff8 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitRepositoryViewer.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitRepositoryViewer.java @@ -85,7 +85,7 @@ public class GitRepositoryViewer public static final String MIMETYPE_HTML = "text/html"; /** Field description */ - public static final String RESOURCE_GITINDEX = "sonia/scm/git.index.mustache"; + public static final String RESOURCE_GITINDEX = "/sonia/scm/git.index.mustache"; /** Field description */ private static final int CHANGESET_PER_BRANCH = 10; diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/installer/MacOSHgInstaller.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/installer/MacOSHgInstaller.java index 033a895067..3ceb1abb63 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/installer/MacOSHgInstaller.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/installer/MacOSHgInstaller.java @@ -35,7 +35,6 @@ package sonia.scm.installer; //~--- non-JDK imports -------------------------------------------------------- - import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgHealthCheck.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgHealthCheck.java new file mode 100644 index 0000000000..3aad7b511c --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgHealthCheck.java @@ -0,0 +1,116 @@ +/** + * 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 sonia.scm.plugin.Extension; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; + +/** + * Simple {@link HealthCheck} for mercurial repositories. + * + * @author Sebastian Sdorra + * @since 1.39 + */ +@Extension +public final class HgHealthCheck extends DirectoryHealthCheck +{ + + /** Field description */ + private static final HealthCheckFailure COULD_NOT_FIND_DOT_HG_DIRECTORY = + new HealthCheckFailure("6bOdhOXpB1", "Could not find .hg directory", + "The mercurial repository does not contain .hg directory."); + + /** Field description */ + private static final String DOT_HG = ".hg"; + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param repositoryManager + */ + @Inject + public HgHealthCheck(RepositoryManager repositoryManager) + { + super(repositoryManager); + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param repository + * @param directory + * + * @return + */ + @Override + protected HealthCheckResult check(Repository repository, File directory) + { + HealthCheckResult result = HealthCheckResult.healthy(); + File dotHgDirectory = new File(directory, DOT_HG); + + if (!dotHgDirectory.exists()) + { + result = HealthCheckResult.unhealthy(COULD_NOT_FIND_DOT_HG_DIRECTORY); + } + + return result; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Returns {@code true} if the repository is from type mercurial. + * + * + * @param repository repository for the health check + * + * @return {@code true} for a mercurial repository + */ + @Override + protected boolean isCheckResponsible(Repository repository) + { + return HgRepositoryHandler.TYPE_NAME.equalsIgnoreCase(repository.getType()); + } +} diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgServletModule.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgServletModule.java index dcdd4c4246..f595c2e8b7 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgServletModule.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgServletModule.java @@ -42,7 +42,6 @@ import sonia.scm.plugin.Extension; import sonia.scm.repository.HgContext; import sonia.scm.repository.HgContextProvider; import sonia.scm.repository.HgHookManager; -import sonia.scm.web.filter.BasicAuthenticationFilter; /** * diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceProvider.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceProvider.java index 7626bdd32a..5c1907da7b 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceProvider.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceProvider.java @@ -40,7 +40,6 @@ import com.google.common.io.Closeables; import sonia.scm.repository.Repository; import sonia.scm.repository.SvnRepositoryHandler; -import sonia.scm.repository.SvnUtil; import sonia.scm.repository.api.Command; //~--- JDK imports ------------------------------------------------------------ diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnCollectionRenderer.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnCollectionRenderer.java index 34f6a75cb8..7370dabadb 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnCollectionRenderer.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnCollectionRenderer.java @@ -78,7 +78,7 @@ public class SvnCollectionRenderer implements CollectionRenderer /** Field description */ private static final String RESOURCE_SVNINDEX = - "sonia/scm/svn.index.mustache"; + "/sonia/scm/svn.index.mustache"; /** * the logger for SvnCollectionRenderer diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnServletModule.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnServletModule.java index c7535ba9f0..dbf37b1d03 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnServletModule.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnServletModule.java @@ -75,7 +75,7 @@ public class SvnServletModule extends ServletModule Map parameters = new HashMap(); parameters.put(PARAMETER_SVN_PARENTPATH, - System.getProperty("java.io.tmpdir")); + System.getProperty("java.io.tmpdir")); serve(PATTERN_SVN).with(SvnDAVServlet.class, parameters); } } diff --git a/scm-server/pom.xml b/scm-server/pom.xml index bb903a2a0e..6f6275145a 100644 --- a/scm-server/pom.xml +++ b/scm-server/pom.xml @@ -20,7 +20,7 @@ commons-daemon commons-daemon - 1.0.10 + ${commons.daemon.version} @@ -56,7 +56,7 @@ sonia.maven appassembler-maven-plugin - 1.2.0.3 + 1.2.2.0 scm-app @@ -67,7 +67,7 @@ ${project.build.directory}/appassembler - ${project.build.directory}/appassembler/commons-daemon/scm-server + ${exploded.directory} lib flat true @@ -75,7 +75,7 @@ scm-server - 1.0.10 + ${commons.daemon.version} sonia.scm.server.ScmServerDaemon commons-daemon @@ -101,6 +101,10 @@ darwin.arch.enable false + + windows.service.dependencies + Tcpip + @@ -131,7 +135,7 @@ scm-webapp ${project.version} war - ${project.build.directory}/appassembler/commons-daemon/scm-server/var/webapp + ${exploded.directory}/var/webapp scm-webapp.war @@ -163,5 +167,138 @@ scm-server + + + + nativepkg + + + + + + com.github.sdorra + nativepkg-maven-plugin + 1.0.0-SNAPSHOT + + + + deb + rpm + + package + + + + true + all + ${maven.build.timestamp} +
devel
+ Development/Tools + SCM-Manager + BSD 3-Clause + www.scm-manager.org + ${project.description} + Sebastian Sdorra <s.sdorra@gmail.com> + + noarch + linux + + + ${project.basedir}/src/main/nativepkg/create-user + + + + + /opt/scm-server/bin/scm-server + ${exploded.directory}/bin/scm-server + 0744 + + + /opt/scm-server/conf/server-config.xml + ${project.basedir}/src/main/conf/server-config.xml + true + + + /opt/scm-server/conf/logging.xml + ${project.basedir}/src/main/nativepkg/logging.xml + true + + + /opt/scm-server/libexec/jsvc-linux-i686 + ${exploded.directory}/libexec/jsvc-linux-i686 + 0744 + + + /opt/scm-server/libexec/jsvc-linux-x86_64 + ${exploded.directory}/libexec/jsvc-linux-x86_64 + 0744 + + + /opt/scm-server/var/webapp/scm-webapp.war + ${exploded.directory}/var/webapp/scm-webapp.war + + + /opt/scm-server/var/webapp/docroot/index.html + ${basedir}/src/main/docroot/index.html + + + /etc/default/scm-server + ${project.basedir}/src/main/nativepkg/default + 0744 + true + + + /etc/init.d/scm-server + ${project.basedir}/src/main/nativepkg/init-script + 0744 + + + + + /opt/scm-server/var/log + /var/log/scm + + + /opt/scm-server/work + /var/cache/scm/work + + + + + /opt/scm-server/lib + ${exploded.directory}/lib + + + /var/cache/scm/work + scm + scm + 0700 + + + /var/log/scm + scm + scm + 0770 + + + /var/lib/scm + scm + scm + 0700 + + + +
+
+ +
+
+
+
+ + + 1.0.15 + ${project.build.directory}/appassembler/commons-daemon/scm-server + diff --git a/scm-server/src/main/java/sonia/scm/server/ScmServer.java b/scm-server/src/main/java/sonia/scm/server/ScmServer.java index 6cb36415a6..507e12a37f 100644 --- a/scm-server/src/main/java/sonia/scm/server/ScmServer.java +++ b/scm-server/src/main/java/sonia/scm/server/ScmServer.java @@ -92,12 +92,23 @@ public class ScmServer extends Thread { try { - server.start(); + if (!initialized) + { + init(); + } + server.join(); } catch (Exception ex) { - throw new RuntimeException(ex); + if (ex instanceof ScmServerException) + { + throw(ScmServerException) ex; + } + else + { + throw new ScmServerException("could not start scm-server", ex); + } } } @@ -110,6 +121,7 @@ public class ScmServer extends Thread try { server.setStopAtShutdown(true); + initialized = false; } catch (Exception ex) { @@ -117,8 +129,28 @@ public class ScmServer extends Thread } } + /** + * Method description + * + */ + void init() + { + try + { + server.start(); + initialized = true; + } + catch (Exception ex) + { + throw new ScmServerException("could not initialize server", ex); + } + } + //~--- fields --------------------------------------------------------------- + /** Field description */ + private boolean initialized = false; + /** Field description */ private Server server = new Server(); } diff --git a/scm-server/src/main/java/sonia/scm/server/ScmServerDaemon.java b/scm-server/src/main/java/sonia/scm/server/ScmServerDaemon.java index 93fd7d77bd..0799f7e69e 100644 --- a/scm-server/src/main/java/sonia/scm/server/ScmServerDaemon.java +++ b/scm-server/src/main/java/sonia/scm/server/ScmServerDaemon.java @@ -113,6 +113,9 @@ public class ScmServerDaemon implements Daemon public void init(DaemonContext context) throws DaemonInitException, Exception { daemonArgs = context.getArguments(); + // initialize web server and open port. We have to do this in the init + // method, because this method is started by jsvc with super user privileges. + webserver.init(); } /** diff --git a/scm-server/src/main/nativepkg/create-user b/scm-server/src/main/nativepkg/create-user new file mode 100644 index 0000000000..82398c513c --- /dev/null +++ b/scm-server/src/main/nativepkg/create-user @@ -0,0 +1,5 @@ +getent group scm >/dev/null || groupadd -r scm +getent passwd scm >/dev/null || \ + useradd -r -g scm -M -s /sbin/nologin \ + -c "user for the scm-server process" scm +exit 0 \ No newline at end of file diff --git a/scm-server/src/main/nativepkg/default b/scm-server/src/main/nativepkg/default new file mode 100644 index 0000000000..f2675e1673 --- /dev/null +++ b/scm-server/src/main/nativepkg/default @@ -0,0 +1,54 @@ +#!/bin/sh +# +# 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 +# + +# scm-server port +PORT=8080 + +# change user +USER=scm + +# home of scm-manager +export SCM_HOME=/var/lib/scm + +# force jvm path +# JAVA_HOME="/usr/lib/jvm/jre" + +# path to pid +PIDFILE=/var/run/scm.pid + +# path to log directory +LOGDIR=/var/log/scm + +# increase memory +# EXTRA_JVM_ARGUMENTS="$EXTRA_JVM_ARGUMENTS -Xms1g -Xmx1g" + +# pass extra jvm arguments +EXTRA_JVM_ARGUMENTS="$EXTRA_JVM_ARGUMENTS -Djetty.port=$PORT" diff --git a/scm-server/src/main/nativepkg/init-script b/scm-server/src/main/nativepkg/init-script new file mode 100644 index 0000000000..5e6cac53f3 --- /dev/null +++ b/scm-server/src/main/nativepkg/init-script @@ -0,0 +1,118 @@ +#!/bin/sh + +# +# SCM-Server start script +# + +# +# 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 +# + +# chkconfig: 35 35 65 +# description: SCM-Server +# +### BEGIN INIT INFO +# Provides: scm-server +# Required-Start: $local_fs $remote_fs $network $time $named +# Required-Stop: $local_fs $remote_fs $network $time $named +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Description: SCM-Server +### END INIT INFO + +# start script is based on the one posted from JavaNode to SCM-Manager mailing +# list: https://groups.google.com/d/msg/scmmanager/-wNjenUbl0Q/CkELJ6fLMHsJ + + +# Source function library. +if [ -x /etc/rc.d/init.d/functions ]; then +. /etc/rc.d/init.d/functions +fi + +# Check for and source configuration file otherwise set defaults +RETVAL=0 + +appname=ScmServerDaemon + +# See how we were called. +start() { + /opt/scm-server/bin/scm-server start +} + +stop() { + if [ ! status = 0 ] + then + /opt/scm-server/bin/scm-server stop + else + echo "SCM-Server is not running" + fi +} + +status() { + ps auxwww | grep java | grep ${appname} || echo "SCM-Server is not running" +} + +restart() { + stop + SECONDS=0 + STAT=$( ps auxwww | grep java | grep ${appname} | wc -l ) + while [ $STAT -ne 0 ] + do + sleep 3 + if [ $SECONDS -gt 300 ] + then + SCM_PID=$( ps auxwww | grep java | grep ${appname} | awk '{ print $2 }' ) + kill -9 $SCM_PID + fi + STAT=$( ps auxwww | grep java | grep ${appname} | wc -l ) + done + start +} + +# See how we were called. + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + restart + ;; + status) + status + ;; + *) + echo "Usage: $0 {start|stop|restart}" + exit 1 +esac + +exit $RETVAL \ No newline at end of file diff --git a/scm-server/src/main/nativepkg/logging.xml b/scm-server/src/main/nativepkg/logging.xml new file mode 100644 index 0000000000..c5ddb0f5f3 --- /dev/null +++ b/scm-server/src/main/nativepkg/logging.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + /var/log/scm/scm-manager.log + + + /var/log/scm/scm-manager-%i.log + 1 + 10 + + + + 10MB + + + true + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scm-test/src/main/java/sonia/scm/security/InMemoryCipherHandler.java b/scm-test/src/main/java/sonia/scm/security/InMemoryCipherHandler.java new file mode 100644 index 0000000000..18c965fc50 --- /dev/null +++ b/scm-test/src/main/java/sonia/scm/security/InMemoryCipherHandler.java @@ -0,0 +1,58 @@ +/** + * 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.security; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.UUID; + +/** + * @author Sebastian Sdorra + * @since 1.38 + */ +public class InMemoryCipherHandler extends DefaultCipherHandler +{ + + /** Field description */ + private static final String KEY = UUID.randomUUID().toString(); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + */ + public InMemoryCipherHandler() + { + super(KEY); + } +} diff --git a/scm-test/src/main/resources/META-INF/services/sonia.scm.security.CipherHandler b/scm-test/src/main/resources/META-INF/services/sonia.scm.security.CipherHandler new file mode 100644 index 0000000000..d480cb88a1 --- /dev/null +++ b/scm-test/src/main/resources/META-INF/services/sonia.scm.security.CipherHandler @@ -0,0 +1 @@ +sonia.scm.security.InMemoryCipherHandler \ No newline at end of file diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 818bab4c96..3c39cd377f 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -173,7 +173,7 @@ commons-beanutils commons-beanutils - 1.9.1 + 1.9.2 @@ -523,7 +523,7 @@ 1.13.1 1.0 3.0.5 - 0.8.14 + 0.8.15 Tomcat diff --git a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java index aceda6769e..dd0c3538a8 100644 --- a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java +++ b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java @@ -71,6 +71,7 @@ import sonia.scm.plugin.PluginManager; import sonia.scm.repository.DefaultRepositoryManager; import sonia.scm.repository.DefaultRepositoryProvider; import sonia.scm.repository.HealthCheckContextListener; +import sonia.scm.repository.LastModifiedUpdateListener; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryDAO; import sonia.scm.repository.RepositoryManager; @@ -141,6 +142,7 @@ import com.sun.jersey.spi.container.servlet.ServletContainer; import java.util.HashMap; import java.util.Map; +import java.util.Set; /** * @@ -356,10 +358,12 @@ public class ScmServletModule extends JerseyServletModule bind(TemplateEngine.class).annotatedWith(DefaultEngine.class).to( MustacheTemplateEngine.class); bind(TemplateEngineFactory.class); + + // bind events + bind(LastModifiedUpdateListener.class); // jersey Map params = new HashMap(); - /* * params.put("com.sun.jersey.spi.container.ContainerRequestFilters", * "com.sun.jersey.api.container.filter.LoggingFilter"); @@ -370,14 +374,14 @@ public class ScmServletModule extends JerseyServletModule */ params.put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE.toString()); params.put(ResourceConfig.FEATURE_REDIRECT, Boolean.TRUE.toString()); + params.put(ResourceConfig.FEATURE_DISABLE_WADL, Boolean.TRUE.toString()); /* * TODO remove UriExtensionsConfig and PackagesResourceConfig * to stop jersey classpath scanning */ - params.put(ServletContainer.RESOURCE_CONFIG_CLASS, - UriExtensionsConfig.class.getName()); + UriExtensionsConfig.class.getName()); params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "unbound"); serve(PATTERN_RESTAPI).with(GuiceContainer.class, params); } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/RestActionUploadResult.java b/scm-webapp/src/main/java/sonia/scm/api/rest/RestActionUploadResult.java index 4778e0ff1d..6428a7dffd 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/RestActionUploadResult.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/RestActionUploadResult.java @@ -30,18 +30,30 @@ */ + package sonia.scm.api.rest; +//~--- JDK imports ------------------------------------------------------------ + import javax.xml.bind.annotation.XmlRootElement; /** * * @author Sebastian Sdorra */ -@XmlRootElement(name="result") +@XmlRootElement(name = "result") public class RestActionUploadResult extends RestActionResult { + /** + * Constructs ... + * + */ + public RestActionUploadResult() + { + this(true); + } + /** * Constructs ... * diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractManagerResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractManagerResource.java index 599e1dcb30..dfee98f1f1 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractManagerResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractManagerResource.java @@ -196,7 +196,7 @@ public abstract class AbstractManagerResource classpathURLs = new LinkedList(); + List classpathURLs = Lists.newLinkedList(); for (String path : classpath) { @@ -224,32 +263,36 @@ public class BootstrapListener implements ServletContextListener } return BootstrapUtil.createClassLoader(classpathURLs, - getParentClassLoader()); + ClassLoaders.getContextClassLoader(BootstrapListener.class)); } - //~--- get methods ---------------------------------------------------------- - /** * Method description * * - * @return + * @param classLoader + * @param listener + * @param sce */ - private ClassLoader getParentClassLoader() + private void initializeContext(ClassLoader classLoader, + ServletContextListener listener, ServletContextEvent sce) { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); - if (classLoader == null) + try { - if (logger.isWarnEnabled()) + if (classLoader != null) { - logger.warn("could not use context classloader, try to use default"); + Thread.currentThread().setContextClassLoader(classLoader); } - classLoader = BootstrapListener.class.getClassLoader(); + logger.info("initialize scm context listener"); + listener.contextInitialized(sce); + } + finally + { + Thread.currentThread().setContextClassLoader(oldClassLoader); } - - return classLoader; } //~--- fields --------------------------------------------------------------- diff --git a/scm-webapp/src/main/java/sonia/scm/boot/BootstrapUtil.java b/scm-webapp/src/main/java/sonia/scm/boot/BootstrapUtil.java index 7ff693e64e..366d7971ef 100644 --- a/scm-webapp/src/main/java/sonia/scm/boot/BootstrapUtil.java +++ b/scm-webapp/src/main/java/sonia/scm/boot/BootstrapUtil.java @@ -40,12 +40,12 @@ import com.google.common.base.Strings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import sonia.scm.net.ChildFirstURLClassLoader; +import sonia.scm.plugin.ChildFirstPluginClassLoader; +import sonia.scm.plugin.DefaultPluginClassLoader; //~--- JDK imports ------------------------------------------------------------ import java.net.URL; -import java.net.URLClassLoader; import java.util.List; @@ -107,7 +107,7 @@ public final class BootstrapUtil { logger.info("using {} as plugin classloading strategy", STRATEGY_CHILDFIRST); - classLoader = new ChildFirstURLClassLoader(urls, parent); + classLoader = new ChildFirstPluginClassLoader(urls, parent); } else if (!STRATEGY_PARENTFIRST.equals(strategy)) { @@ -119,7 +119,7 @@ public final class BootstrapUtil { logger.info("using {} as plugin classloading strategy", STRATEGY_PARENTFIRST); - classLoader = new URLClassLoader(urls, parent); + classLoader = new DefaultPluginClassLoader(urls, parent); } return classLoader; @@ -238,4 +238,17 @@ public final class BootstrapUtil { context.setAttribute(CLASSLOADER, classLoader); } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param context + */ + public static void removeClassLoader(ServletContext context) + { + context.removeAttribute(CLASSLOADER); + } } diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/ChildFirstPluginClassLoader.java b/scm-webapp/src/main/java/sonia/scm/plugin/ChildFirstPluginClassLoader.java new file mode 100644 index 0000000000..5e57825401 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/plugin/ChildFirstPluginClassLoader.java @@ -0,0 +1,73 @@ +/** + * 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.plugin; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.net.ChildFirstURLClassLoader; + +//~--- JDK imports ------------------------------------------------------------ + +import java.net.URL; + +/** + * Child first {@link ClassLoader} for SCM-Manager plugins. + * + * @author Sebastian Sdorra + */ +public class ChildFirstPluginClassLoader extends ChildFirstURLClassLoader + implements PluginClassLoader +{ + + /** + * Constructs ... + * + * + * @param urls + */ + public ChildFirstPluginClassLoader(URL[] urls) + { + super(urls); + } + + /** + * Constructs ... + * + * + * @param urls + * @param parent + */ + public ChildFirstPluginClassLoader(URL[] urls, ClassLoader parent) + { + super(urls, parent); + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/DefaultPluginClassLoader.java b/scm-webapp/src/main/java/sonia/scm/plugin/DefaultPluginClassLoader.java new file mode 100644 index 0000000000..532fb1dbff --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/plugin/DefaultPluginClassLoader.java @@ -0,0 +1,71 @@ +/** + * 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.plugin; + +//~--- JDK imports ------------------------------------------------------------ + +import java.net.URL; +import java.net.URLClassLoader; + +/** + * Default {@link ClassLoader} for SCM-Manager plugins. This {@link ClassLoader} + * uses the default parent first strategy. + * + * @author Sebastian Sdorra + */ +public class DefaultPluginClassLoader extends URLClassLoader + implements PluginClassLoader +{ + + /** + * Constructs ... + * + * + * @param urls + */ + public DefaultPluginClassLoader(URL[] urls) + { + super(urls); + } + + /** + * Constructs ... + * + * + * @param urls + * @param parent + */ + public DefaultPluginClassLoader(URL[] urls, ClassLoader parent) + { + super(urls, parent); + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/PluginClassLoader.java b/scm-webapp/src/main/java/sonia/scm/plugin/PluginClassLoader.java new file mode 100644 index 0000000000..20a7a0bfb9 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/plugin/PluginClassLoader.java @@ -0,0 +1,40 @@ +/** + * 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.plugin; + +/** + * The PluginClassLoader interface is mainly a marker to find the class loader + * in a memory dump. This should make it easier to find class loader leaks. + * + * @author Sebastian Sdorra + */ +public interface PluginClassLoader {} diff --git a/scm-webapp/src/main/webapp/META-INF/context.xml b/scm-webapp/src/main/webapp/META-INF/context.xml index b1f2c9aba6..6572785af2 100644 --- a/scm-webapp/src/main/webapp/META-INF/context.xml +++ b/scm-webapp/src/main/webapp/META-INF/context.xml @@ -31,4 +31,4 @@ --> - + diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js index c6f469ead8..32a03dae2d 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js @@ -125,7 +125,11 @@ Sonia.repository.InfoPanel = Ext.extend(Ext.Panel, { var index = uri.indexOf("://"); if ( index > 0 ){ index += 3; - uri = uri.substring(0, index) + state.user.name + "@" + uri.substring(index); + var username = state.user.name; + // escape backslash for active directory users + // see https://bitbucket.org/sdorra/scm-manager/issue/570/incorrect-git-checkout-url-generated-for + username = username.replace('\\', '\\\\'); + uri = uri.substring(0, index) + username + "@" + uri.substring(index); } } return uri;