From b17a23ddc8b138670ce241307a3c92a4030ed33b Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 6 Jul 2017 10:13:11 +0200 Subject: [PATCH 01/78] added option to disallow non fast-forward git pushes --- .../java/sonia/scm/repository/GitConfig.java | 15 +- .../sonia/scm/web/GitReceivePackFactory.java | 76 +++--- .../main/resources/sonia/scm/git.config.js | 9 + .../scm/web/GitReceivePackFactoryTest.java | 117 +++++++++ .../sonia/scm/it/GitNonFastForwardITCase.java | 222 ++++++++++++++++++ 5 files changed, 390 insertions(+), 49 deletions(-) create mode 100644 scm-plugins/scm-git-plugin/src/test/java/sonia/scm/web/GitReceivePackFactoryTest.java create mode 100644 scm-webapp/src/test/java/sonia/scm/it/GitNonFastForwardITCase.java diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitConfig.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitConfig.java index 80fe8907ac..26e49735eb 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitConfig.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitConfig.java @@ -51,9 +51,18 @@ public class GitConfig extends SimpleRepositoryConfig { @XmlElement(name = "gc-expression") private String gcExpression; - public String getGcExpression() - { + @XmlElement(name = "disallow-non-fast-forward") + private boolean nonFastForwardDisallowed; + + public String getGcExpression() { return gcExpression; } - + + public boolean isNonFastForwardDisallowed() { + return nonFastForwardDisallowed; + } + + public void setNonFastForwardDisallowed(boolean nonFastForwardDisallowed) { + this.nonFastForwardDisallowed = nonFastForwardDisallowed; + } } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitReceivePackFactory.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitReceivePackFactory.java index 25bbe04cfc..5cb8007986 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitReceivePackFactory.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitReceivePackFactory.java @@ -35,79 +35,63 @@ package sonia.scm.web; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.annotations.VisibleForTesting; import com.google.inject.Inject; - import org.eclipse.jgit.http.server.resolver.DefaultReceivePackFactory; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.ReceivePack; import org.eclipse.jgit.transport.resolver.ReceivePackFactory; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; - import sonia.scm.repository.GitRepositoryHandler; import sonia.scm.repository.spi.HookEventFacade; -//~--- JDK imports ------------------------------------------------------------ - import javax.servlet.http.HttpServletRequest; +//~--- JDK imports ------------------------------------------------------------ + /** + * GitReceivePackFactory creates {@link ReceivePack} objects and assigns the required + * Hook components. * * @author Sebastian Sdorra */ -public class GitReceivePackFactory - implements ReceivePackFactory +public class GitReceivePackFactory implements ReceivePackFactory { - /** - * Constructs ... - * - * - * - * @param hookEventFacade - * @param handler - */ + private final GitRepositoryHandler handler; + + private ReceivePackFactory wrapped; + + private final GitReceiveHook hook; + @Inject - public GitReceivePackFactory(HookEventFacade hookEventFacade, - GitRepositoryHandler handler) - { - hook = new GitReceiveHook(hookEventFacade, handler); + public GitReceivePackFactory(GitRepositoryHandler handler, HookEventFacade hookEventFacade) { + this.handler = handler; + this.hook = new GitReceiveHook(hookEventFacade, handler); + this.wrapped = new DefaultReceivePackFactory(); } - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param request - * @param repository - * - * @return - * - * @throws ServiceNotAuthorizedException - * @throws ServiceNotEnabledException - */ @Override public ReceivePack create(HttpServletRequest request, Repository repository) - throws ServiceNotEnabledException, ServiceNotAuthorizedException - { - ReceivePack rpack = defaultFactory.create(request, repository); + throws ServiceNotEnabledException, ServiceNotAuthorizedException { + ReceivePack receivePack = wrapped.create(request, repository); + receivePack.setAllowNonFastForwards(isNonFastForwardAllowed()); - rpack.setPreReceiveHook(hook); - rpack.setPostReceiveHook(hook); + receivePack.setPreReceiveHook(hook); + receivePack.setPostReceiveHook(hook); // apply collecting listener, to be able to check which commits are new - CollectingPackParserListener.set(rpack); + CollectingPackParserListener.set(receivePack); - return rpack; + return receivePack; } - //~--- fields --------------------------------------------------------------- + private boolean isNonFastForwardAllowed() { + return ! handler.getConfig().isNonFastForwardDisallowed(); + } - /** Field description */ - private DefaultReceivePackFactory defaultFactory = - new DefaultReceivePackFactory(); - - /** Field description */ - private GitReceiveHook hook; + @VisibleForTesting + void setWrapped(ReceivePackFactory wrapped) { + this.wrapped = wrapped; + } } diff --git a/scm-plugins/scm-git-plugin/src/main/resources/sonia/scm/git.config.js b/scm-plugins/scm-git-plugin/src/main/resources/sonia/scm/git.config.js index 9e038e4dee..b4cf4fdfc3 100644 --- a/scm-plugins/scm-git-plugin/src/main/resources/sonia/scm/git.config.js +++ b/scm-plugins/scm-git-plugin/src/main/resources/sonia/scm/git.config.js @@ -37,6 +37,7 @@ Sonia.git.ConfigPanel = Ext.extend(Sonia.config.SimpleConfigForm, { titleText: 'Git Settings', repositoryDirectoryText: 'Repository directory', gcExpressionText: 'Git GC Cron Expression', + disallowNonFastForwardText: 'Disallow Non Fast-Forward', disabledText: 'Disabled', // helpTexts @@ -53,6 +54,8 @@ Sonia.git.ConfigPanel = Ext.extend(Sonia.config.SimpleConfigForm, { \n\

E.g.: To run the task on every sunday at two o\'clock in the morning: 0 0 2 ? * SUN

\n\

For more informations please have a look at Quartz CronTrigger

', + // TODO i18n + disallowNonFastForwardHelpText: 'Reject git pushes which are non fast-forward such as --force.', disabledHelpText: 'Enable or disable the Git plugin.\n\ Note you have to reload the page, after changing this value.', @@ -73,6 +76,12 @@ Sonia.git.ConfigPanel = Ext.extend(Sonia.config.SimpleConfigForm, { fieldLabel: this.gcExpressionText, helpText: this.gcExpressionHelpText, allowBlank : true + },{ + xtype: 'checkbox', + name: 'disallow-non-fast-forward', + fieldLabel: this.disallowNonFastForwardText, + inputValue: 'true', + helpText: this.disallowNonFastForwardHelpText },{ xtype: 'checkbox', name: 'disabled', diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/web/GitReceivePackFactoryTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/web/GitReceivePackFactoryTest.java new file mode 100644 index 0000000000..dc0822deba --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/web/GitReceivePackFactoryTest.java @@ -0,0 +1,117 @@ +/** + * 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; + +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.transport.ReceivePack; +import org.eclipse.jgit.transport.resolver.ReceivePackFactory; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import sonia.scm.repository.GitConfig; +import sonia.scm.repository.GitRepositoryHandler; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.io.IOException; + +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.Assert.*; +import static org.mockito.Mockito.when; + + +/** + * Unit tests for {@link GitReceivePackFactory}. + */ +@RunWith(MockitoJUnitRunner.class) +public class GitReceivePackFactoryTest { + + @Mock + private GitRepositoryHandler handler; + + private GitConfig config; + + @Mock + private ReceivePackFactory wrappedReceivePackFactory; + + private GitReceivePackFactory factory; + + @Mock + private HttpServletRequest request; + + private Repository repository; + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Before + public void setUpObjectUnderTest() throws Exception { + this.repository = createRepositoryForTesting(); + + config = new GitConfig(); + when(handler.getConfig()).thenReturn(config); + + ReceivePack receivePack = new ReceivePack(repository); + when(wrappedReceivePackFactory.create(request, repository)).thenReturn(receivePack); + + factory = new GitReceivePackFactory(handler, null); + factory.setWrapped(wrappedReceivePackFactory); + } + + private Repository createRepositoryForTesting() throws GitAPIException, IOException { + File directory = temporaryFolder.newFolder(); + return Git.init().setDirectory(directory).call().getRepository(); + } + + @Test + public void testCreate() throws Exception { + ReceivePack receivePack = factory.create(request, repository); + assertThat(receivePack.getPackParserListener(), instanceOf(CollectingPackParserListener.class)); + assertThat(receivePack.getPreReceiveHook(), instanceOf(GitReceiveHook.class)); + assertThat(receivePack.getPostReceiveHook(), instanceOf(GitReceiveHook.class)); + assertTrue(receivePack.isAllowNonFastForwards()); + } + + @Test + public void testCreateWithDisabledNonFastForward() throws Exception { + config.setNonFastForwardDisallowed(true); + ReceivePack receivePack = factory.create(request, repository); + assertFalse(receivePack.isAllowNonFastForwards()); + } + +} diff --git a/scm-webapp/src/test/java/sonia/scm/it/GitNonFastForwardITCase.java b/scm-webapp/src/test/java/sonia/scm/it/GitNonFastForwardITCase.java new file mode 100644 index 0000000000..351e9b7142 --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/it/GitNonFastForwardITCase.java @@ -0,0 +1,222 @@ +/** + * 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.it; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; +import org.eclipse.jgit.api.CommitCommand; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.transport.CredentialsProvider; +import org.eclipse.jgit.transport.PushResult; +import org.eclipse.jgit.transport.RemoteRefUpdate; +import org.eclipse.jgit.transport.RemoteRefUpdate.Status; +import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; +import org.junit.*; +import org.junit.rules.TemporaryFolder; +import sonia.scm.repository.GitConfig; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryTestData; +import sonia.scm.repository.client.api.RepositoryClientFactory; + +import java.io.File; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static sonia.scm.it.IntegrationTestUtil.*; +import static sonia.scm.it.RepositoryITUtil.createRepository; +import static sonia.scm.it.RepositoryITUtil.deleteRepository; + +/** + * Integration Tests for Git with non fast-forward pushes. + */ +public class GitNonFastForwardITCase { + + private static final RepositoryClientFactory REPOSITORY_CLIENT_FACTORY = new RepositoryClientFactory(); + + private Client apiClient; + private Repository repository; + private File workingCopy; + private Git git; + + @Rule + public TemporaryFolder tempFolder = new TemporaryFolder(); + + @Before + public void createAndCloneTestRepository() throws IOException, GitAPIException { + apiClient = createAdminClient(); + Repository testRepository = RepositoryTestData.createHeartOfGold("git"); + this.repository = createRepository(apiClient, testRepository); + this.workingCopy = tempFolder.newFolder(); + + String url = repository.createUrl(BASE_URL); + this.git = clone(url); + } + + @After + public void removeTestRepository() { + deleteRepository(apiClient, repository.getId()); + apiClient.destroy(); + } + + /** + * Ensures that the normal behaviour (non fast-forward is allowed), is restored after the tests are executed. + */ + @AfterClass + public static void allowNonFastForward() { + setNonFastForwardDisallowed(false); + } + + @Test + public void testGitPushAmendWithoutForce() throws IOException, GitAPIException { + setNonFastForwardDisallowed(false); + + addTestFileToWorkingCopyAndCommit("a"); + pushAndAssert(false, Status.OK); + + addTestFileToWorkingCopyAndCommitAmend("c"); + pushAndAssert(false, Status.REJECTED_NONFASTFORWARD); + } + + @Test + public void testGitPushAmendWithForce() throws IOException, GitAPIException { + setNonFastForwardDisallowed(false); + + addTestFileToWorkingCopyAndCommit("a"); + pushAndAssert(false, Status.OK); + + addTestFileToWorkingCopyAndCommitAmend("c"); + pushAndAssert(true, Status.OK); + } + + @Test + public void testGitPushAmendForceWithDisallowNonFastForward() throws GitAPIException, IOException { + setNonFastForwardDisallowed(true); + + addTestFileToWorkingCopyAndCommit("a"); + pushAndAssert(false, Status.OK); + + addTestFileToWorkingCopyAndCommitAmend("c"); + pushAndAssert(true, Status.REJECTED_OTHER_REASON); + + setNonFastForwardDisallowed(false); + } + + private CredentialsProvider createCredentialProvider() { + return new UsernamePasswordCredentialsProvider( + IntegrationTestUtil.ADMIN_USERNAME, IntegrationTestUtil.ADMIN_PASSWORD + ); + } + + private Git clone(String url) throws GitAPIException { + return Git.cloneRepository() + .setDirectory(workingCopy) + .setURI(url) + .setCredentialsProvider(createCredentialProvider()) + .call(); + } + + private void addTestFileToWorkingCopyAndCommit(String name) throws IOException, GitAPIException { + addTestFile(name); + prepareCommit() + .setMessage("added ".concat(name)) + .call(); + } + + private void addTestFile(String name) throws IOException, GitAPIException { + String filename = name.concat(".txt"); + Files.write(name, new File(workingCopy, filename), Charsets.UTF_8); + git.add().addFilepattern(filename).call(); + } + + private CommitCommand prepareCommit() { + return git.commit() + .setAuthor(IntegrationTestUtil.AUTHOR.getName(), IntegrationTestUtil.AUTHOR.getMail()); + } + + private void pushAndAssert(boolean force, Status expectedStatus) throws GitAPIException { + Iterable results = push(force); + assertStatus(results, expectedStatus); + } + + private Iterable push(boolean force) throws GitAPIException { + return git.push() + .setRemote("origin") + .add("master") + .setForce(force) + .setCredentialsProvider(createCredentialProvider()) + .call(); + } + + private void assertStatus(Iterable results, Status expectedStatus) { + for ( PushResult pushResult : results ) { + assertStatus(pushResult, expectedStatus); + } + } + + private void assertStatus(PushResult pushResult, Status expectedStatus) { + for ( RemoteRefUpdate remoteRefUpdate : pushResult.getRemoteUpdates() ) { + assertEquals(expectedStatus, remoteRefUpdate.getStatus()); + } + } + + private void addTestFileToWorkingCopyAndCommitAmend(String name) throws IOException, GitAPIException { + addTestFile(name); + prepareCommit() + .setMessage("amend commit, because of missing ".concat(name)) + .setAmend(true) + .call(); + } + + private static void setNonFastForwardDisallowed(boolean nonFastForwardDisallowed) { + Client adminClient = createAdminClient(); + try { + WebResource resource = createResource(adminClient, "config/repositories/git"); + GitConfig config = resource.get(GitConfig.class); + + assertNotNull(config); + config.setNonFastForwardDisallowed(nonFastForwardDisallowed); + + ClientResponse response = resource.post(ClientResponse.class, config); + assertNotNull(response); + assertEquals(201, response.getStatus()); + } finally { + adminClient.destroy(); + } + } + +} From 785e1b12a983e7bda627ca600268bf1fc69afa1a Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 7 Jul 2017 19:09:46 +0200 Subject: [PATCH 02/78] fixed update of git repositories with empty git default branch, see issue #903 --- .../scm-git-plugin/src/main/resources/sonia/scm/git.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm-plugins/scm-git-plugin/src/main/resources/sonia/scm/git.config.js b/scm-plugins/scm-git-plugin/src/main/resources/sonia/scm/git.config.js index b4cf4fdfc3..c15cef4444 100644 --- a/scm-plugins/scm-git-plugin/src/main/resources/sonia/scm/git.config.js +++ b/scm-plugins/scm-git-plugin/src/main/resources/sonia/scm/git.config.js @@ -176,9 +176,9 @@ Sonia.git.GitSettingsFormPanel = Ext.extend(Sonia.repository.SettingsFormPanel, prepareUpdate: function(item) { if (item.defaultBranch) { var defaultBranch = item.defaultBranch; - delete item.defaultBranch; this.setDefaultBranch(item, defaultBranch); } + delete item.defaultBranch; } }); From f72648f646fc0ca229e2d1916e1e16a5f086b0ad Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 14 Aug 2017 16:04:30 +0200 Subject: [PATCH 03/78] fixes usage of named cache configurations, see issue #943 --- .../sonia/scm/cache/GuavaCacheManager.java | 19 +++++++--- .../scm/cache/GuavaCacheManagerTest.java | 38 ++++++++++++++++++- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/scm-webapp/src/main/java/sonia/scm/cache/GuavaCacheManager.java b/scm-webapp/src/main/java/sonia/scm/cache/GuavaCacheManager.java index fb112c0107..eb9f6d4891 100644 --- a/scm-webapp/src/main/java/sonia/scm/cache/GuavaCacheManager.java +++ b/scm-webapp/src/main/java/sonia/scm/cache/GuavaCacheManager.java @@ -78,15 +78,22 @@ public class GuavaCacheManager implements CacheManager, org.apache.shiro.cache.C protected GuavaCacheManager(GuavaCacheManagerConfiguration config) { defaultConfiguration = config.getDefaultCache(); - for (GuavaNamedCacheConfiguration ncc : config.getCaches()) { - logger.debug("create cache {} from configured configuration {}", ncc.getName(), ncc); - cacheMap.put(ncc.getName(), new CacheWithConfiguration( - GuavaCaches.create(defaultConfiguration, ncc.getName()), - defaultConfiguration) + for (GuavaNamedCacheConfiguration namedCacheConfiguration : config.getCaches()) { + logger.debug("create cache {} from configured configuration {}", + namedCacheConfiguration.getName(), namedCacheConfiguration ); + cacheMap.put(namedCacheConfiguration.getName(), createCacheWithConfiguration(namedCacheConfiguration)); } } + private CacheWithConfiguration createCacheWithConfiguration(GuavaNamedCacheConfiguration namedCacheConfiguration) { + return createCacheWithConfiguration(namedCacheConfiguration, namedCacheConfiguration.getName()); + } + + private CacheWithConfiguration createCacheWithConfiguration(GuavaCacheConfiguration configuration, String name) { + return new CacheWithConfiguration(GuavaCaches.create(configuration, name), configuration); + } + @Override public void close() throws IOException { logger.info("close guava cache manager"); @@ -110,7 +117,7 @@ public class GuavaCacheManager implements CacheManager, org.apache.shiro.cache.C "cache {} does not exists, creating a new instance from default configuration: {}", name, defaultConfiguration ); - cache = new CacheWithConfiguration(GuavaCaches.create(defaultConfiguration, name), defaultConfiguration); + cache = createCacheWithConfiguration(defaultConfiguration, name); cacheMap.put(name, cache); } diff --git a/scm-webapp/src/test/java/sonia/scm/cache/GuavaCacheManagerTest.java b/scm-webapp/src/test/java/sonia/scm/cache/GuavaCacheManagerTest.java index 3d91a56f40..be1848b303 100644 --- a/scm-webapp/src/test/java/sonia/scm/cache/GuavaCacheManagerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/cache/GuavaCacheManagerTest.java @@ -32,15 +32,33 @@ package sonia.scm.cache; +import com.google.common.collect.Lists; import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; /** * * @author Sebastian Sdorra */ +@RunWith(MockitoJUnitRunner.class) public class GuavaCacheManagerTest extends CacheManagerTestBase { + @Mock(answer = Answers.CALLS_REAL_METHODS) + private GuavaCacheConfiguration defaultConfiguration; + + @Mock(answer = Answers.CALLS_REAL_METHODS) + private GuavaNamedCacheConfiguration configuration; + /** * Method description * @@ -60,6 +78,24 @@ public class GuavaCacheManagerTest extends CacheManagerTestBase ((GuavaCache)c2).getWrappedCache() ); } - + + @Test + public void configuration() { + when(configuration.getName()).thenReturn("my-crazy-cache"); + when(configuration.getCopyStrategy()).thenReturn(CopyStrategy.READWRITE); + when(defaultConfiguration.getCopyStrategy()).thenReturn(CopyStrategy.READ); + + List configurations = Lists.newArrayList(configuration); + GuavaCacheManagerConfiguration managerConfiguration = new GuavaCacheManagerConfiguration(defaultConfiguration, configurations); + GuavaCacheManager guavaCacheManager = new GuavaCacheManager(managerConfiguration); + + // default cache + GuavaSecurityCache sorbotCache = guavaCacheManager.getCache("sorbot-cache"); + assertEquals(CopyStrategy.READ, sorbotCache.copyStrategy); + + // configured cache + GuavaSecurityCache crazyCache = guavaCacheManager.getCache("my-crazy-cache"); + assertEquals(CopyStrategy.READWRITE, crazyCache.copyStrategy); + } } From 14ee6ef0d6531514e9dd06f7ffb6eeffa5804f96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Stefanik?= Date: Mon, 18 Sep 2017 12:30:20 +0000 Subject: [PATCH 04/78] prevent binary data in {extras} from interfering with UTF-8 decoding --- .../src/main/resources/sonia/scm/styles/changesets-eager.style | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/styles/changesets-eager.style b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/styles/changesets-eager.style index 5c462fc459..e911bce7b2 100644 --- a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/styles/changesets-eager.style +++ b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/styles/changesets-eager.style @@ -1,5 +1,5 @@ header = "%{pattern}" -changeset = "{rev}:{node}{author}\n{date|hgdate}\n{branch}\n{parents}{join(extras,',')}\n{tags}{file_adds}{file_mods}{file_dels}\n{desc}\0" +changeset = "{rev}:{node}{author}\n{date|hgdate}\n{branch}\n{parents}close={if(get(extras, 'close'),1,0)}\n{tags}{file_adds}{file_mods}{file_dels}\n{desc}\0" tag = "t {tag}\n" file_add = "a {file_add}\n" file_mod = "m {file_mod}\n" From 77eea15417b8cf957f479a0cc6482b158ebbec70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Stefanik?= Date: Mon, 18 Sep 2017 12:34:50 +0000 Subject: [PATCH 05/78] oops... don't interpret "close=junk" as "close=1" --- .../src/main/resources/sonia/scm/styles/changesets-eager.style | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/styles/changesets-eager.style b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/styles/changesets-eager.style index e911bce7b2..73b3ec694b 100644 --- a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/styles/changesets-eager.style +++ b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/styles/changesets-eager.style @@ -1,5 +1,5 @@ header = "%{pattern}" -changeset = "{rev}:{node}{author}\n{date|hgdate}\n{branch}\n{parents}close={if(get(extras, 'close'),1,0)}\n{tags}{file_adds}{file_mods}{file_dels}\n{desc}\0" +changeset = "{rev}:{node}{author}\n{date|hgdate}\n{branch}\n{parents}close={ifeq(get(extras, 'close'),1,1,0)}\n{tags}{file_adds}{file_mods}{file_dels}\n{desc}\0" tag = "t {tag}\n" file_add = "a {file_add}\n" file_mod = "m {file_mod}\n" From 241f41bb1c1bb63c7517f8b044f4b707d127b3ba Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 25 Oct 2017 14:21:38 +0200 Subject: [PATCH 06/78] update svnkit to version 1.9.0-scm1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e31fc9c77a..cbd36d28e0 100644 --- a/pom.xml +++ b/pom.xml @@ -425,7 +425,7 @@ v4.5.2.201704071617-r-scm1 - 1.8.15-scm1 + 1.9.0-scm1 15.0 From c75eb388d9fdd0db110238e1f2a2a6a91fc7df17 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 25 Oct 2017 15:02:28 +0200 Subject: [PATCH 07/78] update jgit to version v4.5.3.201708160445-r-scm1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cbd36d28e0..5f24b9c971 100644 --- a/pom.xml +++ b/pom.xml @@ -424,7 +424,7 @@ 1.3.0 - v4.5.2.201704071617-r-scm1 + v4.5.3.201708160445-r-scm1 1.9.0-scm1 From fd047c117094dd4114e6bfc2078536c4cb1d6719 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 2 Nov 2017 09:21:42 +0100 Subject: [PATCH 08/78] [maven-release-plugin] prepare release 1.55 --- maven/pom.xml | 4 ++-- maven/scm-maven-plugin/pom.xml | 4 ++-- maven/scm-plugin-archetype/pom.xml | 4 ++-- pom.xml | 4 ++-- scm-clients/pom.xml | 6 +++--- scm-clients/scm-cli-client/pom.xml | 6 +++--- scm-clients/scm-client-api/pom.xml | 4 ++-- scm-clients/scm-client-impl/pom.xml | 8 ++++---- scm-core/pom.xml | 4 ++-- scm-dao-orientdb/pom.xml | 8 ++++---- scm-dao-xml/pom.xml | 8 ++++---- scm-plugin-backend/pom.xml | 6 +++--- scm-plugins/pom.xml | 8 ++++---- scm-plugins/scm-git-plugin/pom.xml | 6 +++--- scm-plugins/scm-hg-plugin/pom.xml | 6 +++--- scm-plugins/scm-svn-plugin/pom.xml | 6 +++--- scm-samples/pom.xml | 4 ++-- scm-samples/scm-sample-auth/pom.xml | 6 +++--- scm-samples/scm-sample-hello/pom.xml | 6 +++--- scm-server/pom.xml | 4 ++-- scm-test/pom.xml | 6 +++--- scm-webapp/pom.xml | 24 ++++++++++++------------ support/pom.xml | 4 ++-- support/scm-support-btrace/pom.xml | 6 +++--- 24 files changed, 76 insertions(+), 76 deletions(-) diff --git a/maven/pom.xml b/maven/pom.xml index 86be4ebaed..ec44f15717 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.55-SNAPSHOT + 1.55 sonia.scm.maven scm-maven-plugins pom - 1.55-SNAPSHOT + 1.55 scm-maven-plugins diff --git a/maven/scm-maven-plugin/pom.xml b/maven/scm-maven-plugin/pom.xml index da0c4192f0..09eafb1d25 100644 --- a/maven/scm-maven-plugin/pom.xml +++ b/maven/scm-maven-plugin/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.55-SNAPSHOT + 1.55 sonia.scm.maven scm-maven-plugin - 1.55-SNAPSHOT + 1.55 maven-plugin scm-maven-plugin diff --git a/maven/scm-plugin-archetype/pom.xml b/maven/scm-plugin-archetype/pom.xml index 61cec4e20b..ff895ee8f2 100644 --- a/maven/scm-plugin-archetype/pom.xml +++ b/maven/scm-plugin-archetype/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.55-SNAPSHOT + 1.55 sonia.scm.maven scm-plugin-archetype - 1.55-SNAPSHOT + 1.55 scm-plugin-archetype diff --git a/pom.xml b/pom.xml index 5f24b9c971..29f0f4a2c8 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ sonia.scm scm pom - 1.55-SNAPSHOT + 1.55 The easiest way to share your Git, Mercurial and Subversion repositories over http. @@ -36,7 +36,7 @@ scm:hg:http://bitbucket.org/sdorra/scm-manager scm:hg:https://bitbucket.org/sdorra/scm-manager http://bitbucket.org/sdorra/scm-manager - HEAD + 1.55 diff --git a/scm-clients/pom.xml b/scm-clients/pom.xml index d5264575e7..2647df0785 100644 --- a/scm-clients/pom.xml +++ b/scm-clients/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.55-SNAPSHOT + 1.55 sonia.scm.clients scm-clients pom - 1.55-SNAPSHOT + 1.55 scm-clients @@ -32,7 +32,7 @@ scm-core sonia.scm jar - 1.55-SNAPSHOT + 1.55 shiro-core diff --git a/scm-clients/scm-cli-client/pom.xml b/scm-clients/scm-cli-client/pom.xml index 77a2be54a6..75d0bf4612 100644 --- a/scm-clients/scm-cli-client/pom.xml +++ b/scm-clients/scm-cli-client/pom.xml @@ -6,12 +6,12 @@ scm-clients sonia.scm.clients - 1.55-SNAPSHOT + 1.55 sonia.scm.clients scm-cli-client - 1.55-SNAPSHOT + 1.55 scm-cli-client @@ -34,7 +34,7 @@ sonia.scm.clients scm-client-impl - 1.55-SNAPSHOT + 1.55 diff --git a/scm-clients/scm-client-api/pom.xml b/scm-clients/scm-client-api/pom.xml index e002b8ff75..94c2458530 100644 --- a/scm-clients/scm-client-api/pom.xml +++ b/scm-clients/scm-client-api/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.55-SNAPSHOT + 1.55 sonia.scm.clients scm-client-api jar - 1.55-SNAPSHOT + 1.55 scm-client-api diff --git a/scm-clients/scm-client-impl/pom.xml b/scm-clients/scm-client-impl/pom.xml index 255232bc7b..73bbb7968a 100644 --- a/scm-clients/scm-client-impl/pom.xml +++ b/scm-clients/scm-client-impl/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.55-SNAPSHOT + 1.55 sonia.scm.clients scm-client-impl jar - 1.55-SNAPSHOT + 1.55 scm-client-impl @@ -36,7 +36,7 @@ sonia.scm.clients scm-client-api - 1.55-SNAPSHOT + 1.55 @@ -70,7 +70,7 @@ sonia.scm scm-test - 1.55-SNAPSHOT + 1.55 test diff --git a/scm-core/pom.xml b/scm-core/pom.xml index 3496d9ab01..9de00fdc3b 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.55-SNAPSHOT + 1.55 sonia.scm scm-core - 1.55-SNAPSHOT + 1.55 scm-core diff --git a/scm-dao-orientdb/pom.xml b/scm-dao-orientdb/pom.xml index e89bb78811..4bb668c270 100644 --- a/scm-dao-orientdb/pom.xml +++ b/scm-dao-orientdb/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.55-SNAPSHOT + 1.55 sonia.scm scm-dao-orientdb - 1.55-SNAPSHOT + 1.55 scm-dao-orientdb @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.55-SNAPSHOT + 1.55 @@ -52,7 +52,7 @@ sonia.scm scm-test - 1.55-SNAPSHOT + 1.55 test diff --git a/scm-dao-xml/pom.xml b/scm-dao-xml/pom.xml index 79716b8b28..5b89e02908 100644 --- a/scm-dao-xml/pom.xml +++ b/scm-dao-xml/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.55-SNAPSHOT + 1.55 sonia.scm scm-dao-xml - 1.55-SNAPSHOT + 1.55 scm-dao-xml @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.55-SNAPSHOT + 1.55 @@ -34,7 +34,7 @@ sonia.scm scm-test - 1.55-SNAPSHOT + 1.55 test diff --git a/scm-plugin-backend/pom.xml b/scm-plugin-backend/pom.xml index 1d3621b8ea..b3566a12ca 100644 --- a/scm-plugin-backend/pom.xml +++ b/scm-plugin-backend/pom.xml @@ -6,13 +6,13 @@ scm sonia.scm - 1.55-SNAPSHOT + 1.55 sonia.scm scm-plugin-backend war - 1.55-SNAPSHOT + 1.55 ${project.artifactId} @@ -62,7 +62,7 @@ sonia.scm scm-core - 1.55-SNAPSHOT + 1.55 diff --git a/scm-plugins/pom.xml b/scm-plugins/pom.xml index 4ef5f4bfbf..4ed96bb740 100644 --- a/scm-plugins/pom.xml +++ b/scm-plugins/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.55-SNAPSHOT + 1.55 sonia.scm.plugins scm-plugins pom - 1.55-SNAPSHOT + 1.55 scm-plugins @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.55-SNAPSHOT + 1.55 @@ -59,7 +59,7 @@ sonia.scm.maven scm-maven-plugin - 1.55-SNAPSHOT + 1.55 process-resources diff --git a/scm-plugins/scm-git-plugin/pom.xml b/scm-plugins/scm-git-plugin/pom.xml index 695bfba8fd..37e41bf951 100644 --- a/scm-plugins/scm-git-plugin/pom.xml +++ b/scm-plugins/scm-git-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.55-SNAPSHOT + 1.55 sonia.scm.plugins scm-git-plugin - 1.55-SNAPSHOT + 1.55 scm-git-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Git @@ -54,7 +54,7 @@ sonia.scm scm-test - 1.55-SNAPSHOT + 1.55 test diff --git a/scm-plugins/scm-hg-plugin/pom.xml b/scm-plugins/scm-hg-plugin/pom.xml index a9281ffb37..e5323432ea 100644 --- a/scm-plugins/scm-hg-plugin/pom.xml +++ b/scm-plugins/scm-hg-plugin/pom.xml @@ -6,12 +6,12 @@ sonia.scm.plugins scm-plugins - 1.55-SNAPSHOT + 1.55 sonia.scm.plugins scm-hg-plugin - 1.55-SNAPSHOT + 1.55 scm-hg-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Mercurial @@ -42,7 +42,7 @@ sonia.scm scm-test - 1.55-SNAPSHOT + 1.55 test diff --git a/scm-plugins/scm-svn-plugin/pom.xml b/scm-plugins/scm-svn-plugin/pom.xml index 555f50f3ed..ac05bf7aee 100644 --- a/scm-plugins/scm-svn-plugin/pom.xml +++ b/scm-plugins/scm-svn-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.55-SNAPSHOT + 1.55 sonia.scm.plugins scm-svn-plugin - 1.55-SNAPSHOT + 1.55 scm-svn-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Subversion @@ -48,7 +48,7 @@ sonia.scm scm-test - 1.55-SNAPSHOT + 1.55 test diff --git a/scm-samples/pom.xml b/scm-samples/pom.xml index fd83551108..3c61624952 100644 --- a/scm-samples/pom.xml +++ b/scm-samples/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.55-SNAPSHOT + 1.55 sonia.scm.samples scm-samples pom - 1.55-SNAPSHOT + 1.55 scm-samples diff --git a/scm-samples/scm-sample-auth/pom.xml b/scm-samples/scm-sample-auth/pom.xml index 71e7568e95..3a9fb18411 100644 --- a/scm-samples/scm-sample-auth/pom.xml +++ b/scm-samples/scm-sample-auth/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.55-SNAPSHOT + 1.55 sonia.scm.sample scm-sample-auth - 1.55-SNAPSHOT + 1.55 scm-sample-auth Sample Authentication Plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.55-SNAPSHOT + 1.55 diff --git a/scm-samples/scm-sample-hello/pom.xml b/scm-samples/scm-sample-hello/pom.xml index 8afc4c768e..ffc8eb1171 100644 --- a/scm-samples/scm-sample-hello/pom.xml +++ b/scm-samples/scm-sample-hello/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.55-SNAPSHOT + 1.55 sonia.scm.sample scm-sample-hello - 1.55-SNAPSHOT + 1.55 scm-sample-hello A simple hello world plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.55-SNAPSHOT + 1.55 diff --git a/scm-server/pom.xml b/scm-server/pom.xml index e2005c6fbe..365bddc038 100644 --- a/scm-server/pom.xml +++ b/scm-server/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.55-SNAPSHOT + 1.55 sonia.scm scm-server - 1.55-SNAPSHOT + 1.55 scm-server jar diff --git a/scm-test/pom.xml b/scm-test/pom.xml index 062e0f68f1..0a7c6f2047 100644 --- a/scm-test/pom.xml +++ b/scm-test/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.55-SNAPSHOT + 1.55 sonia.scm scm-test - 1.55-SNAPSHOT + 1.55 scm-test @@ -25,7 +25,7 @@ sonia.scm scm-core - 1.55-SNAPSHOT + 1.55 diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 0d5629671c..ae0d5dffc7 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.55-SNAPSHOT + 1.55 sonia.scm scm-webapp war - 1.55-SNAPSHOT + 1.55 scm-webapp @@ -38,31 +38,31 @@ sonia.scm scm-core - 1.55-SNAPSHOT + 1.55 sonia.scm scm-dao-xml - 1.55-SNAPSHOT + 1.55 sonia.scm.plugins scm-hg-plugin - 1.55-SNAPSHOT + 1.55 sonia.scm.plugins scm-svn-plugin - 1.55-SNAPSHOT + 1.55 sonia.scm.plugins scm-git-plugin - 1.55-SNAPSHOT + 1.55 @@ -285,7 +285,7 @@ sonia.scm scm-test - 1.55-SNAPSHOT + 1.55 test @@ -298,7 +298,7 @@ sonia.scm.plugins scm-git-plugin - 1.55-SNAPSHOT + 1.55 tests test @@ -306,7 +306,7 @@ sonia.scm.plugins scm-hg-plugin - 1.55-SNAPSHOT + 1.55 tests test @@ -314,7 +314,7 @@ sonia.scm.plugins scm-svn-plugin - 1.55-SNAPSHOT + 1.55 tests test @@ -558,7 +558,7 @@ sonia.scm scm-dao-orientdb - 1.55-SNAPSHOT + 1.55 diff --git a/support/pom.xml b/support/pom.xml index 3f770d8f3c..113345a8e4 100644 --- a/support/pom.xml +++ b/support/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.55-SNAPSHOT + 1.55 sonia.scm.support scm-support pom - 1.55-SNAPSHOT + 1.55 scm-support diff --git a/support/scm-support-btrace/pom.xml b/support/scm-support-btrace/pom.xml index 98eb9981c4..a2d0145870 100644 --- a/support/scm-support-btrace/pom.xml +++ b/support/scm-support-btrace/pom.xml @@ -4,12 +4,12 @@ sonia.scm.support scm-support - 1.55-SNAPSHOT + 1.55 sonia.scm scm-support-btrace - 1.55-SNAPSHOT + 1.55 jar scm-support-btrace @@ -18,7 +18,7 @@ sonia.scm scm-core - 1.55-SNAPSHOT + 1.55 From cd9e07421c7a6432c13388db1081dfe66e6c94a8 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 2 Nov 2017 09:21:42 +0100 Subject: [PATCH 09/78] [maven-release-plugin] copy for tag 1.55 From 712c14f9107859dae3172da22a0e59db1619452d Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 2 Nov 2017 09:21:42 +0100 Subject: [PATCH 10/78] [maven-release-plugin] prepare for next development iteration --- maven/pom.xml | 4 ++-- maven/scm-maven-plugin/pom.xml | 4 ++-- maven/scm-plugin-archetype/pom.xml | 4 ++-- pom.xml | 4 ++-- scm-clients/pom.xml | 6 +++--- scm-clients/scm-cli-client/pom.xml | 6 +++--- scm-clients/scm-client-api/pom.xml | 4 ++-- scm-clients/scm-client-impl/pom.xml | 8 ++++---- scm-core/pom.xml | 4 ++-- scm-dao-orientdb/pom.xml | 8 ++++---- scm-dao-xml/pom.xml | 8 ++++---- scm-plugin-backend/pom.xml | 6 +++--- scm-plugins/pom.xml | 8 ++++---- scm-plugins/scm-git-plugin/pom.xml | 6 +++--- scm-plugins/scm-hg-plugin/pom.xml | 6 +++--- scm-plugins/scm-svn-plugin/pom.xml | 6 +++--- scm-samples/pom.xml | 4 ++-- scm-samples/scm-sample-auth/pom.xml | 6 +++--- scm-samples/scm-sample-hello/pom.xml | 6 +++--- scm-server/pom.xml | 4 ++-- scm-test/pom.xml | 6 +++--- scm-webapp/pom.xml | 24 ++++++++++++------------ support/pom.xml | 4 ++-- support/scm-support-btrace/pom.xml | 6 +++--- 24 files changed, 76 insertions(+), 76 deletions(-) diff --git a/maven/pom.xml b/maven/pom.xml index ec44f15717..4a87db1f3f 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.55 + 1.56-SNAPSHOT sonia.scm.maven scm-maven-plugins pom - 1.55 + 1.56-SNAPSHOT scm-maven-plugins diff --git a/maven/scm-maven-plugin/pom.xml b/maven/scm-maven-plugin/pom.xml index 09eafb1d25..27cbcc990c 100644 --- a/maven/scm-maven-plugin/pom.xml +++ b/maven/scm-maven-plugin/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.55 + 1.56-SNAPSHOT sonia.scm.maven scm-maven-plugin - 1.55 + 1.56-SNAPSHOT maven-plugin scm-maven-plugin diff --git a/maven/scm-plugin-archetype/pom.xml b/maven/scm-plugin-archetype/pom.xml index ff895ee8f2..dae441ff10 100644 --- a/maven/scm-plugin-archetype/pom.xml +++ b/maven/scm-plugin-archetype/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.55 + 1.56-SNAPSHOT sonia.scm.maven scm-plugin-archetype - 1.55 + 1.56-SNAPSHOT scm-plugin-archetype diff --git a/pom.xml b/pom.xml index 29f0f4a2c8..87a3ee5d95 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ sonia.scm scm pom - 1.55 + 1.56-SNAPSHOT The easiest way to share your Git, Mercurial and Subversion repositories over http. @@ -36,7 +36,7 @@ scm:hg:http://bitbucket.org/sdorra/scm-manager scm:hg:https://bitbucket.org/sdorra/scm-manager http://bitbucket.org/sdorra/scm-manager - 1.55 + HEAD diff --git a/scm-clients/pom.xml b/scm-clients/pom.xml index 2647df0785..75f2ab16df 100644 --- a/scm-clients/pom.xml +++ b/scm-clients/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.55 + 1.56-SNAPSHOT sonia.scm.clients scm-clients pom - 1.55 + 1.56-SNAPSHOT scm-clients @@ -32,7 +32,7 @@ scm-core sonia.scm jar - 1.55 + 1.56-SNAPSHOT shiro-core diff --git a/scm-clients/scm-cli-client/pom.xml b/scm-clients/scm-cli-client/pom.xml index 75d0bf4612..86f932cfb7 100644 --- a/scm-clients/scm-cli-client/pom.xml +++ b/scm-clients/scm-cli-client/pom.xml @@ -6,12 +6,12 @@ scm-clients sonia.scm.clients - 1.55 + 1.56-SNAPSHOT sonia.scm.clients scm-cli-client - 1.55 + 1.56-SNAPSHOT scm-cli-client @@ -34,7 +34,7 @@ sonia.scm.clients scm-client-impl - 1.55 + 1.56-SNAPSHOT diff --git a/scm-clients/scm-client-api/pom.xml b/scm-clients/scm-client-api/pom.xml index 94c2458530..83e7d3cd56 100644 --- a/scm-clients/scm-client-api/pom.xml +++ b/scm-clients/scm-client-api/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.55 + 1.56-SNAPSHOT sonia.scm.clients scm-client-api jar - 1.55 + 1.56-SNAPSHOT scm-client-api diff --git a/scm-clients/scm-client-impl/pom.xml b/scm-clients/scm-client-impl/pom.xml index 73bbb7968a..cfd2976f5a 100644 --- a/scm-clients/scm-client-impl/pom.xml +++ b/scm-clients/scm-client-impl/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.55 + 1.56-SNAPSHOT sonia.scm.clients scm-client-impl jar - 1.55 + 1.56-SNAPSHOT scm-client-impl @@ -36,7 +36,7 @@ sonia.scm.clients scm-client-api - 1.55 + 1.56-SNAPSHOT @@ -70,7 +70,7 @@ sonia.scm scm-test - 1.55 + 1.56-SNAPSHOT test diff --git a/scm-core/pom.xml b/scm-core/pom.xml index 9de00fdc3b..943bc636ad 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.55 + 1.56-SNAPSHOT sonia.scm scm-core - 1.55 + 1.56-SNAPSHOT scm-core diff --git a/scm-dao-orientdb/pom.xml b/scm-dao-orientdb/pom.xml index 4bb668c270..a82df0638c 100644 --- a/scm-dao-orientdb/pom.xml +++ b/scm-dao-orientdb/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.55 + 1.56-SNAPSHOT sonia.scm scm-dao-orientdb - 1.55 + 1.56-SNAPSHOT scm-dao-orientdb @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.55 + 1.56-SNAPSHOT @@ -52,7 +52,7 @@ sonia.scm scm-test - 1.55 + 1.56-SNAPSHOT test diff --git a/scm-dao-xml/pom.xml b/scm-dao-xml/pom.xml index 5b89e02908..6199f7e630 100644 --- a/scm-dao-xml/pom.xml +++ b/scm-dao-xml/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.55 + 1.56-SNAPSHOT sonia.scm scm-dao-xml - 1.55 + 1.56-SNAPSHOT scm-dao-xml @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.55 + 1.56-SNAPSHOT @@ -34,7 +34,7 @@ sonia.scm scm-test - 1.55 + 1.56-SNAPSHOT test diff --git a/scm-plugin-backend/pom.xml b/scm-plugin-backend/pom.xml index b3566a12ca..a8ff5f1bd6 100644 --- a/scm-plugin-backend/pom.xml +++ b/scm-plugin-backend/pom.xml @@ -6,13 +6,13 @@ scm sonia.scm - 1.55 + 1.56-SNAPSHOT sonia.scm scm-plugin-backend war - 1.55 + 1.56-SNAPSHOT ${project.artifactId} @@ -62,7 +62,7 @@ sonia.scm scm-core - 1.55 + 1.56-SNAPSHOT diff --git a/scm-plugins/pom.xml b/scm-plugins/pom.xml index 4ed96bb740..e626158205 100644 --- a/scm-plugins/pom.xml +++ b/scm-plugins/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.55 + 1.56-SNAPSHOT sonia.scm.plugins scm-plugins pom - 1.55 + 1.56-SNAPSHOT scm-plugins @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.55 + 1.56-SNAPSHOT @@ -59,7 +59,7 @@ sonia.scm.maven scm-maven-plugin - 1.55 + 1.56-SNAPSHOT process-resources diff --git a/scm-plugins/scm-git-plugin/pom.xml b/scm-plugins/scm-git-plugin/pom.xml index 37e41bf951..f79480f195 100644 --- a/scm-plugins/scm-git-plugin/pom.xml +++ b/scm-plugins/scm-git-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.55 + 1.56-SNAPSHOT sonia.scm.plugins scm-git-plugin - 1.55 + 1.56-SNAPSHOT scm-git-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Git @@ -54,7 +54,7 @@ sonia.scm scm-test - 1.55 + 1.56-SNAPSHOT test diff --git a/scm-plugins/scm-hg-plugin/pom.xml b/scm-plugins/scm-hg-plugin/pom.xml index e5323432ea..8a0c4a2364 100644 --- a/scm-plugins/scm-hg-plugin/pom.xml +++ b/scm-plugins/scm-hg-plugin/pom.xml @@ -6,12 +6,12 @@ sonia.scm.plugins scm-plugins - 1.55 + 1.56-SNAPSHOT sonia.scm.plugins scm-hg-plugin - 1.55 + 1.56-SNAPSHOT scm-hg-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Mercurial @@ -42,7 +42,7 @@ sonia.scm scm-test - 1.55 + 1.56-SNAPSHOT test diff --git a/scm-plugins/scm-svn-plugin/pom.xml b/scm-plugins/scm-svn-plugin/pom.xml index ac05bf7aee..70358bd4e7 100644 --- a/scm-plugins/scm-svn-plugin/pom.xml +++ b/scm-plugins/scm-svn-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.55 + 1.56-SNAPSHOT sonia.scm.plugins scm-svn-plugin - 1.55 + 1.56-SNAPSHOT scm-svn-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Subversion @@ -48,7 +48,7 @@ sonia.scm scm-test - 1.55 + 1.56-SNAPSHOT test diff --git a/scm-samples/pom.xml b/scm-samples/pom.xml index 3c61624952..ddf81770e8 100644 --- a/scm-samples/pom.xml +++ b/scm-samples/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.55 + 1.56-SNAPSHOT sonia.scm.samples scm-samples pom - 1.55 + 1.56-SNAPSHOT scm-samples diff --git a/scm-samples/scm-sample-auth/pom.xml b/scm-samples/scm-sample-auth/pom.xml index 3a9fb18411..72ebfa3e80 100644 --- a/scm-samples/scm-sample-auth/pom.xml +++ b/scm-samples/scm-sample-auth/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.55 + 1.56-SNAPSHOT sonia.scm.sample scm-sample-auth - 1.55 + 1.56-SNAPSHOT scm-sample-auth Sample Authentication Plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.55 + 1.56-SNAPSHOT diff --git a/scm-samples/scm-sample-hello/pom.xml b/scm-samples/scm-sample-hello/pom.xml index ffc8eb1171..6c6720aec1 100644 --- a/scm-samples/scm-sample-hello/pom.xml +++ b/scm-samples/scm-sample-hello/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.55 + 1.56-SNAPSHOT sonia.scm.sample scm-sample-hello - 1.55 + 1.56-SNAPSHOT scm-sample-hello A simple hello world plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.55 + 1.56-SNAPSHOT diff --git a/scm-server/pom.xml b/scm-server/pom.xml index 365bddc038..69945271c7 100644 --- a/scm-server/pom.xml +++ b/scm-server/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.55 + 1.56-SNAPSHOT sonia.scm scm-server - 1.55 + 1.56-SNAPSHOT scm-server jar diff --git a/scm-test/pom.xml b/scm-test/pom.xml index 0a7c6f2047..989d3ef0b7 100644 --- a/scm-test/pom.xml +++ b/scm-test/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.55 + 1.56-SNAPSHOT sonia.scm scm-test - 1.55 + 1.56-SNAPSHOT scm-test @@ -25,7 +25,7 @@ sonia.scm scm-core - 1.55 + 1.56-SNAPSHOT diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index ae0d5dffc7..a62edce4e1 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.55 + 1.56-SNAPSHOT sonia.scm scm-webapp war - 1.55 + 1.56-SNAPSHOT scm-webapp @@ -38,31 +38,31 @@ sonia.scm scm-core - 1.55 + 1.56-SNAPSHOT sonia.scm scm-dao-xml - 1.55 + 1.56-SNAPSHOT sonia.scm.plugins scm-hg-plugin - 1.55 + 1.56-SNAPSHOT sonia.scm.plugins scm-svn-plugin - 1.55 + 1.56-SNAPSHOT sonia.scm.plugins scm-git-plugin - 1.55 + 1.56-SNAPSHOT @@ -285,7 +285,7 @@ sonia.scm scm-test - 1.55 + 1.56-SNAPSHOT test @@ -298,7 +298,7 @@ sonia.scm.plugins scm-git-plugin - 1.55 + 1.56-SNAPSHOT tests test @@ -306,7 +306,7 @@ sonia.scm.plugins scm-hg-plugin - 1.55 + 1.56-SNAPSHOT tests test @@ -314,7 +314,7 @@ sonia.scm.plugins scm-svn-plugin - 1.55 + 1.56-SNAPSHOT tests test @@ -558,7 +558,7 @@ sonia.scm scm-dao-orientdb - 1.55 + 1.56-SNAPSHOT diff --git a/support/pom.xml b/support/pom.xml index 113345a8e4..d2776bcb09 100644 --- a/support/pom.xml +++ b/support/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.55 + 1.56-SNAPSHOT sonia.scm.support scm-support pom - 1.55 + 1.56-SNAPSHOT scm-support diff --git a/support/scm-support-btrace/pom.xml b/support/scm-support-btrace/pom.xml index a2d0145870..9f20f878bf 100644 --- a/support/scm-support-btrace/pom.xml +++ b/support/scm-support-btrace/pom.xml @@ -4,12 +4,12 @@ sonia.scm.support scm-support - 1.55 + 1.56-SNAPSHOT sonia.scm scm-support-btrace - 1.55 + 1.56-SNAPSHOT jar scm-support-btrace @@ -18,7 +18,7 @@ sonia.scm scm-core - 1.55 + 1.56-SNAPSHOT From 5e6685260efd20b1c45b56d9205866fc37c090d9 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 19 Nov 2017 21:07:28 +0100 Subject: [PATCH 11/78] fix integer overflow of request with body larger than 4gb, see issue #953 --- .../sonia/scm/web/cgi/DefaultCGIExecutor.java | 58 +++++++++++-------- .../scm/web/cgi/DefaultCGIExecutorTest.java | 54 +++++++++++++++++ 2 files changed, 89 insertions(+), 23 deletions(-) create mode 100644 scm-webapp/src/test/java/sonia/scm/web/cgi/DefaultCGIExecutorTest.java diff --git a/scm-webapp/src/main/java/sonia/scm/web/cgi/DefaultCGIExecutor.java b/scm-webapp/src/main/java/sonia/scm/web/cgi/DefaultCGIExecutor.java index 3eaa684080..b442042480 100644 --- a/scm-webapp/src/main/java/sonia/scm/web/cgi/DefaultCGIExecutor.java +++ b/scm-webapp/src/main/java/sonia/scm/web/cgi/DefaultCGIExecutor.java @@ -35,6 +35,7 @@ package sonia.scm.web.cgi; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; import com.google.common.io.ByteStreams; @@ -139,12 +140,6 @@ public class DefaultCGIExecutor extends AbstractCGIExecutor apendOsEnvironment(env); } - // workaround for mercurial 2.1 - if (isContentLengthWorkaround()) - { - env.set(ENV_CONTENT_LENGTH, Integer.toString(request.getContentLength())); - } - if (workDirectory == null) { workDirectory = command.getParentFile(); @@ -304,26 +299,10 @@ public class DefaultCGIExecutor extends AbstractCGIExecutor String uri = HttpUtil.removeMatrixParameter(request.getRequestURI()); String scriptName = uri.substring(0, uri.length() - pathInfo.length()); String scriptPath = context.getRealPath(scriptName); - int len = request.getContentLength(); EnvList env = new EnvList(); env.set(ENV_AUTH_TYPE, request.getAuthType()); - - /** - * Note CGI spec says CONTENT_LENGTH must be NULL ("") or undefined - * if there is no content, so we cannot put 0 or -1 in as per the - * Servlet API spec. - * - * see org.apache.catalina.servlets.CGIServlet - */ - if (len <= 0) - { - env.set(ENV_CONTENT_LENGTH, ""); - } - else - { - env.set(ENV_CONTENT_LENGTH, Integer.toString(len)); - } + env.set(ENV_CONTENT_LENGTH, createCGIContentLength(request, contentLengthWorkaround)); /** * Decode PATH_INFO @@ -383,6 +362,39 @@ public class DefaultCGIExecutor extends AbstractCGIExecutor return env; } + /** + * Returns the content length as string in the cgi specific format. + * + * CGI spec says CONTENT_LENGTH must be NULL ("") or undefined + * if there is no content, so we cannot put 0 or -1 in as per the + * Servlet API spec. Some CGI applications require a content + * length environment variable, which is not null or empty + * (e.g. mercurial). For those application the disallowEmptyResults + * parameter should be used. + * + * @param disallowEmptyResults {@code true} to return -1 instead of an empty string + * + * @return content length as cgi specific string + */ + @VisibleForTesting + static String createCGIContentLength(HttpServletRequest request, boolean disallowEmptyResults) { + String cgiContentLength = disallowEmptyResults ? "-1" : ""; + + String contentLength = request.getHeader("Content-Length"); + if (!Strings.isNullOrEmpty(contentLength)) { + try { + long len = Long.parseLong(contentLength); + if (len > 0) { + cgiContentLength = String.valueOf(len); + } + } catch (NumberFormatException ex) { + logger.warn("received request with invalid content-length header value: {}", contentLength); + } + } + + return cgiContentLength; + } + /** * Method description * diff --git a/scm-webapp/src/test/java/sonia/scm/web/cgi/DefaultCGIExecutorTest.java b/scm-webapp/src/test/java/sonia/scm/web/cgi/DefaultCGIExecutorTest.java new file mode 100644 index 0000000000..29c7dea358 --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/web/cgi/DefaultCGIExecutorTest.java @@ -0,0 +1,54 @@ +package sonia.scm.web.cgi; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import javax.servlet.http.HttpServletRequest; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.when; + +/** + * Unit tests for {@link DefaultCGIExecutor}. + */ +@RunWith(MockitoJUnitRunner.class) +public class DefaultCGIExecutorTest { + + @Mock + private HttpServletRequest request; + + @Test + public void testCreateCGIContentLength() { + when(request.getHeader("Content-Length")).thenReturn("42"); + assertEquals("42", DefaultCGIExecutor.createCGIContentLength(request, false)); + assertEquals("42", DefaultCGIExecutor.createCGIContentLength(request, true)); + } + + @Test + public void testCreateCGIContentLengthWithZeroLength() { + when(request.getHeader("Content-Length")).thenReturn("0"); + assertEquals("", DefaultCGIExecutor.createCGIContentLength(request, false)); + assertEquals("-1", DefaultCGIExecutor.createCGIContentLength(request, true)); + } + + @Test + public void testCreateCGIContentLengthWithoutContentLengthHeader() { + assertEquals("", DefaultCGIExecutor.createCGIContentLength(request, false)); + assertEquals("-1", DefaultCGIExecutor.createCGIContentLength(request, true)); + } + + @Test + public void testCreateCGIContentLengthWithLengthThatExeedsInteger() { + when(request.getHeader("Content-Length")).thenReturn("6314297259"); + assertEquals("6314297259", DefaultCGIExecutor.createCGIContentLength(request, false)); + } + + @Test + public void testCreateCGIContentLengthWithNonNumberHeader() { + when(request.getHeader("Content-Length")).thenReturn("abc"); + assertEquals("", DefaultCGIExecutor.createCGIContentLength(request, false)); + } + +} From 1b3e76e80902e0a2f3ddc3b3c4931a308e612d97 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 20 Nov 2017 17:01:10 +0100 Subject: [PATCH 12/78] close branch issue-953 From 2c5cd634b395aa7a2d6f997f9c0278fb622e351c Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 15 Dec 2017 12:53:12 +0100 Subject: [PATCH 13/78] update svnkit to v1.9.0-scm2, to fix high cpu load after client connection abort. See Issue #939 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 87a3ee5d95..59be1739a0 100644 --- a/pom.xml +++ b/pom.xml @@ -423,9 +423,9 @@ 1.3.0 - + v4.5.3.201708160445-r-scm1 - 1.9.0-scm1 + 1.9.0-scm2 15.0 From 942cd5d190afcbb81fe86f0eff900530289ae33b Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 15 Jan 2018 14:35:31 +0100 Subject: [PATCH 14/78] close branch issue-939 From f66221e5666b6f78f7de126f3ee352ba8f050bf2 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 15 Jan 2018 14:51:10 +0100 Subject: [PATCH 15/78] [maven-release-plugin] prepare release 1.56 --- maven/pom.xml | 4 ++-- maven/scm-maven-plugin/pom.xml | 4 ++-- maven/scm-plugin-archetype/pom.xml | 4 ++-- pom.xml | 4 ++-- scm-clients/pom.xml | 6 +++--- scm-clients/scm-cli-client/pom.xml | 6 +++--- scm-clients/scm-client-api/pom.xml | 4 ++-- scm-clients/scm-client-impl/pom.xml | 8 ++++---- scm-core/pom.xml | 4 ++-- scm-dao-orientdb/pom.xml | 8 ++++---- scm-dao-xml/pom.xml | 8 ++++---- scm-plugin-backend/pom.xml | 6 +++--- scm-plugins/pom.xml | 8 ++++---- scm-plugins/scm-git-plugin/pom.xml | 6 +++--- scm-plugins/scm-hg-plugin/pom.xml | 6 +++--- scm-plugins/scm-svn-plugin/pom.xml | 6 +++--- scm-samples/pom.xml | 4 ++-- scm-samples/scm-sample-auth/pom.xml | 6 +++--- scm-samples/scm-sample-hello/pom.xml | 6 +++--- scm-server/pom.xml | 4 ++-- scm-test/pom.xml | 6 +++--- scm-webapp/pom.xml | 24 ++++++++++++------------ support/pom.xml | 4 ++-- support/scm-support-btrace/pom.xml | 6 +++--- 24 files changed, 76 insertions(+), 76 deletions(-) diff --git a/maven/pom.xml b/maven/pom.xml index 4a87db1f3f..3469483fb6 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.56-SNAPSHOT + 1.56 sonia.scm.maven scm-maven-plugins pom - 1.56-SNAPSHOT + 1.56 scm-maven-plugins diff --git a/maven/scm-maven-plugin/pom.xml b/maven/scm-maven-plugin/pom.xml index 27cbcc990c..0e1b1b14b3 100644 --- a/maven/scm-maven-plugin/pom.xml +++ b/maven/scm-maven-plugin/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.56-SNAPSHOT + 1.56 sonia.scm.maven scm-maven-plugin - 1.56-SNAPSHOT + 1.56 maven-plugin scm-maven-plugin diff --git a/maven/scm-plugin-archetype/pom.xml b/maven/scm-plugin-archetype/pom.xml index dae441ff10..5f42c29187 100644 --- a/maven/scm-plugin-archetype/pom.xml +++ b/maven/scm-plugin-archetype/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.56-SNAPSHOT + 1.56 sonia.scm.maven scm-plugin-archetype - 1.56-SNAPSHOT + 1.56 scm-plugin-archetype diff --git a/pom.xml b/pom.xml index 59be1739a0..46654071b7 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ sonia.scm scm pom - 1.56-SNAPSHOT + 1.56 The easiest way to share your Git, Mercurial and Subversion repositories over http. @@ -36,7 +36,7 @@ scm:hg:http://bitbucket.org/sdorra/scm-manager scm:hg:https://bitbucket.org/sdorra/scm-manager http://bitbucket.org/sdorra/scm-manager - HEAD + 1.56 diff --git a/scm-clients/pom.xml b/scm-clients/pom.xml index 75f2ab16df..e6bc32ce2a 100644 --- a/scm-clients/pom.xml +++ b/scm-clients/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.56-SNAPSHOT + 1.56 sonia.scm.clients scm-clients pom - 1.56-SNAPSHOT + 1.56 scm-clients @@ -32,7 +32,7 @@ scm-core sonia.scm jar - 1.56-SNAPSHOT + 1.56 shiro-core diff --git a/scm-clients/scm-cli-client/pom.xml b/scm-clients/scm-cli-client/pom.xml index 86f932cfb7..8622c2eb57 100644 --- a/scm-clients/scm-cli-client/pom.xml +++ b/scm-clients/scm-cli-client/pom.xml @@ -6,12 +6,12 @@ scm-clients sonia.scm.clients - 1.56-SNAPSHOT + 1.56 sonia.scm.clients scm-cli-client - 1.56-SNAPSHOT + 1.56 scm-cli-client @@ -34,7 +34,7 @@ sonia.scm.clients scm-client-impl - 1.56-SNAPSHOT + 1.56 diff --git a/scm-clients/scm-client-api/pom.xml b/scm-clients/scm-client-api/pom.xml index 83e7d3cd56..2258307116 100644 --- a/scm-clients/scm-client-api/pom.xml +++ b/scm-clients/scm-client-api/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.56-SNAPSHOT + 1.56 sonia.scm.clients scm-client-api jar - 1.56-SNAPSHOT + 1.56 scm-client-api diff --git a/scm-clients/scm-client-impl/pom.xml b/scm-clients/scm-client-impl/pom.xml index cfd2976f5a..8e6512d90b 100644 --- a/scm-clients/scm-client-impl/pom.xml +++ b/scm-clients/scm-client-impl/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.56-SNAPSHOT + 1.56 sonia.scm.clients scm-client-impl jar - 1.56-SNAPSHOT + 1.56 scm-client-impl @@ -36,7 +36,7 @@ sonia.scm.clients scm-client-api - 1.56-SNAPSHOT + 1.56 @@ -70,7 +70,7 @@ sonia.scm scm-test - 1.56-SNAPSHOT + 1.56 test diff --git a/scm-core/pom.xml b/scm-core/pom.xml index 943bc636ad..8b75576551 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.56-SNAPSHOT + 1.56 sonia.scm scm-core - 1.56-SNAPSHOT + 1.56 scm-core diff --git a/scm-dao-orientdb/pom.xml b/scm-dao-orientdb/pom.xml index a82df0638c..36bf7eb2d9 100644 --- a/scm-dao-orientdb/pom.xml +++ b/scm-dao-orientdb/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.56-SNAPSHOT + 1.56 sonia.scm scm-dao-orientdb - 1.56-SNAPSHOT + 1.56 scm-dao-orientdb @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.56-SNAPSHOT + 1.56 @@ -52,7 +52,7 @@ sonia.scm scm-test - 1.56-SNAPSHOT + 1.56 test diff --git a/scm-dao-xml/pom.xml b/scm-dao-xml/pom.xml index 6199f7e630..45a3c23557 100644 --- a/scm-dao-xml/pom.xml +++ b/scm-dao-xml/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.56-SNAPSHOT + 1.56 sonia.scm scm-dao-xml - 1.56-SNAPSHOT + 1.56 scm-dao-xml @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.56-SNAPSHOT + 1.56 @@ -34,7 +34,7 @@ sonia.scm scm-test - 1.56-SNAPSHOT + 1.56 test diff --git a/scm-plugin-backend/pom.xml b/scm-plugin-backend/pom.xml index a8ff5f1bd6..1d6cfc527f 100644 --- a/scm-plugin-backend/pom.xml +++ b/scm-plugin-backend/pom.xml @@ -6,13 +6,13 @@ scm sonia.scm - 1.56-SNAPSHOT + 1.56 sonia.scm scm-plugin-backend war - 1.56-SNAPSHOT + 1.56 ${project.artifactId} @@ -62,7 +62,7 @@ sonia.scm scm-core - 1.56-SNAPSHOT + 1.56 diff --git a/scm-plugins/pom.xml b/scm-plugins/pom.xml index e626158205..8922758bf1 100644 --- a/scm-plugins/pom.xml +++ b/scm-plugins/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.56-SNAPSHOT + 1.56 sonia.scm.plugins scm-plugins pom - 1.56-SNAPSHOT + 1.56 scm-plugins @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.56-SNAPSHOT + 1.56 @@ -59,7 +59,7 @@ sonia.scm.maven scm-maven-plugin - 1.56-SNAPSHOT + 1.56 process-resources diff --git a/scm-plugins/scm-git-plugin/pom.xml b/scm-plugins/scm-git-plugin/pom.xml index f79480f195..45b67593da 100644 --- a/scm-plugins/scm-git-plugin/pom.xml +++ b/scm-plugins/scm-git-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.56-SNAPSHOT + 1.56 sonia.scm.plugins scm-git-plugin - 1.56-SNAPSHOT + 1.56 scm-git-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Git @@ -54,7 +54,7 @@ sonia.scm scm-test - 1.56-SNAPSHOT + 1.56 test diff --git a/scm-plugins/scm-hg-plugin/pom.xml b/scm-plugins/scm-hg-plugin/pom.xml index 8a0c4a2364..1b3cea43e5 100644 --- a/scm-plugins/scm-hg-plugin/pom.xml +++ b/scm-plugins/scm-hg-plugin/pom.xml @@ -6,12 +6,12 @@ sonia.scm.plugins scm-plugins - 1.56-SNAPSHOT + 1.56 sonia.scm.plugins scm-hg-plugin - 1.56-SNAPSHOT + 1.56 scm-hg-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Mercurial @@ -42,7 +42,7 @@ sonia.scm scm-test - 1.56-SNAPSHOT + 1.56 test diff --git a/scm-plugins/scm-svn-plugin/pom.xml b/scm-plugins/scm-svn-plugin/pom.xml index 70358bd4e7..5a4512d3f0 100644 --- a/scm-plugins/scm-svn-plugin/pom.xml +++ b/scm-plugins/scm-svn-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.56-SNAPSHOT + 1.56 sonia.scm.plugins scm-svn-plugin - 1.56-SNAPSHOT + 1.56 scm-svn-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Subversion @@ -48,7 +48,7 @@ sonia.scm scm-test - 1.56-SNAPSHOT + 1.56 test diff --git a/scm-samples/pom.xml b/scm-samples/pom.xml index ddf81770e8..1fff9e55e8 100644 --- a/scm-samples/pom.xml +++ b/scm-samples/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.56-SNAPSHOT + 1.56 sonia.scm.samples scm-samples pom - 1.56-SNAPSHOT + 1.56 scm-samples diff --git a/scm-samples/scm-sample-auth/pom.xml b/scm-samples/scm-sample-auth/pom.xml index 72ebfa3e80..75aa38d045 100644 --- a/scm-samples/scm-sample-auth/pom.xml +++ b/scm-samples/scm-sample-auth/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.56-SNAPSHOT + 1.56 sonia.scm.sample scm-sample-auth - 1.56-SNAPSHOT + 1.56 scm-sample-auth Sample Authentication Plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.56-SNAPSHOT + 1.56 diff --git a/scm-samples/scm-sample-hello/pom.xml b/scm-samples/scm-sample-hello/pom.xml index 6c6720aec1..ce559b808c 100644 --- a/scm-samples/scm-sample-hello/pom.xml +++ b/scm-samples/scm-sample-hello/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.56-SNAPSHOT + 1.56 sonia.scm.sample scm-sample-hello - 1.56-SNAPSHOT + 1.56 scm-sample-hello A simple hello world plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.56-SNAPSHOT + 1.56 diff --git a/scm-server/pom.xml b/scm-server/pom.xml index 69945271c7..5c2eaeee2c 100644 --- a/scm-server/pom.xml +++ b/scm-server/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.56-SNAPSHOT + 1.56 sonia.scm scm-server - 1.56-SNAPSHOT + 1.56 scm-server jar diff --git a/scm-test/pom.xml b/scm-test/pom.xml index 989d3ef0b7..63ff7e8914 100644 --- a/scm-test/pom.xml +++ b/scm-test/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.56-SNAPSHOT + 1.56 sonia.scm scm-test - 1.56-SNAPSHOT + 1.56 scm-test @@ -25,7 +25,7 @@ sonia.scm scm-core - 1.56-SNAPSHOT + 1.56 diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index a62edce4e1..93c83d643b 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.56-SNAPSHOT + 1.56 sonia.scm scm-webapp war - 1.56-SNAPSHOT + 1.56 scm-webapp @@ -38,31 +38,31 @@ sonia.scm scm-core - 1.56-SNAPSHOT + 1.56 sonia.scm scm-dao-xml - 1.56-SNAPSHOT + 1.56 sonia.scm.plugins scm-hg-plugin - 1.56-SNAPSHOT + 1.56 sonia.scm.plugins scm-svn-plugin - 1.56-SNAPSHOT + 1.56 sonia.scm.plugins scm-git-plugin - 1.56-SNAPSHOT + 1.56 @@ -285,7 +285,7 @@ sonia.scm scm-test - 1.56-SNAPSHOT + 1.56 test @@ -298,7 +298,7 @@ sonia.scm.plugins scm-git-plugin - 1.56-SNAPSHOT + 1.56 tests test @@ -306,7 +306,7 @@ sonia.scm.plugins scm-hg-plugin - 1.56-SNAPSHOT + 1.56 tests test @@ -314,7 +314,7 @@ sonia.scm.plugins scm-svn-plugin - 1.56-SNAPSHOT + 1.56 tests test @@ -558,7 +558,7 @@ sonia.scm scm-dao-orientdb - 1.56-SNAPSHOT + 1.56 diff --git a/support/pom.xml b/support/pom.xml index d2776bcb09..fc7b4685ee 100644 --- a/support/pom.xml +++ b/support/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.56-SNAPSHOT + 1.56 sonia.scm.support scm-support pom - 1.56-SNAPSHOT + 1.56 scm-support diff --git a/support/scm-support-btrace/pom.xml b/support/scm-support-btrace/pom.xml index 9f20f878bf..cfe31439d8 100644 --- a/support/scm-support-btrace/pom.xml +++ b/support/scm-support-btrace/pom.xml @@ -4,12 +4,12 @@ sonia.scm.support scm-support - 1.56-SNAPSHOT + 1.56 sonia.scm scm-support-btrace - 1.56-SNAPSHOT + 1.56 jar scm-support-btrace @@ -18,7 +18,7 @@ sonia.scm scm-core - 1.56-SNAPSHOT + 1.56 From f9a90508881cd8c21d3bf19da69fd24eb2a721e8 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 15 Jan 2018 14:51:11 +0100 Subject: [PATCH 16/78] [maven-release-plugin] copy for tag 1.56 From 0ff9b255c3fe32a47860ba58ec2b8ab7c51d797f Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 15 Jan 2018 14:51:11 +0100 Subject: [PATCH 17/78] [maven-release-plugin] prepare for next development iteration --- maven/pom.xml | 4 ++-- maven/scm-maven-plugin/pom.xml | 4 ++-- maven/scm-plugin-archetype/pom.xml | 4 ++-- pom.xml | 4 ++-- scm-clients/pom.xml | 6 +++--- scm-clients/scm-cli-client/pom.xml | 6 +++--- scm-clients/scm-client-api/pom.xml | 4 ++-- scm-clients/scm-client-impl/pom.xml | 8 ++++---- scm-core/pom.xml | 4 ++-- scm-dao-orientdb/pom.xml | 8 ++++---- scm-dao-xml/pom.xml | 8 ++++---- scm-plugin-backend/pom.xml | 6 +++--- scm-plugins/pom.xml | 8 ++++---- scm-plugins/scm-git-plugin/pom.xml | 6 +++--- scm-plugins/scm-hg-plugin/pom.xml | 6 +++--- scm-plugins/scm-svn-plugin/pom.xml | 6 +++--- scm-samples/pom.xml | 4 ++-- scm-samples/scm-sample-auth/pom.xml | 6 +++--- scm-samples/scm-sample-hello/pom.xml | 6 +++--- scm-server/pom.xml | 4 ++-- scm-test/pom.xml | 6 +++--- scm-webapp/pom.xml | 24 ++++++++++++------------ support/pom.xml | 4 ++-- support/scm-support-btrace/pom.xml | 6 +++--- 24 files changed, 76 insertions(+), 76 deletions(-) diff --git a/maven/pom.xml b/maven/pom.xml index 3469483fb6..c57712f36c 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.56 + 1.57-SNAPSHOT sonia.scm.maven scm-maven-plugins pom - 1.56 + 1.57-SNAPSHOT scm-maven-plugins diff --git a/maven/scm-maven-plugin/pom.xml b/maven/scm-maven-plugin/pom.xml index 0e1b1b14b3..09b02b5ddc 100644 --- a/maven/scm-maven-plugin/pom.xml +++ b/maven/scm-maven-plugin/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.56 + 1.57-SNAPSHOT sonia.scm.maven scm-maven-plugin - 1.56 + 1.57-SNAPSHOT maven-plugin scm-maven-plugin diff --git a/maven/scm-plugin-archetype/pom.xml b/maven/scm-plugin-archetype/pom.xml index 5f42c29187..cfd9cb397a 100644 --- a/maven/scm-plugin-archetype/pom.xml +++ b/maven/scm-plugin-archetype/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.56 + 1.57-SNAPSHOT sonia.scm.maven scm-plugin-archetype - 1.56 + 1.57-SNAPSHOT scm-plugin-archetype diff --git a/pom.xml b/pom.xml index 46654071b7..9b604a9bed 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ sonia.scm scm pom - 1.56 + 1.57-SNAPSHOT The easiest way to share your Git, Mercurial and Subversion repositories over http. @@ -36,7 +36,7 @@ scm:hg:http://bitbucket.org/sdorra/scm-manager scm:hg:https://bitbucket.org/sdorra/scm-manager http://bitbucket.org/sdorra/scm-manager - 1.56 + HEAD diff --git a/scm-clients/pom.xml b/scm-clients/pom.xml index e6bc32ce2a..ac6bc4cf8d 100644 --- a/scm-clients/pom.xml +++ b/scm-clients/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.56 + 1.57-SNAPSHOT sonia.scm.clients scm-clients pom - 1.56 + 1.57-SNAPSHOT scm-clients @@ -32,7 +32,7 @@ scm-core sonia.scm jar - 1.56 + 1.57-SNAPSHOT shiro-core diff --git a/scm-clients/scm-cli-client/pom.xml b/scm-clients/scm-cli-client/pom.xml index 8622c2eb57..88f28abd34 100644 --- a/scm-clients/scm-cli-client/pom.xml +++ b/scm-clients/scm-cli-client/pom.xml @@ -6,12 +6,12 @@ scm-clients sonia.scm.clients - 1.56 + 1.57-SNAPSHOT sonia.scm.clients scm-cli-client - 1.56 + 1.57-SNAPSHOT scm-cli-client @@ -34,7 +34,7 @@ sonia.scm.clients scm-client-impl - 1.56 + 1.57-SNAPSHOT diff --git a/scm-clients/scm-client-api/pom.xml b/scm-clients/scm-client-api/pom.xml index 2258307116..fa15ca7f80 100644 --- a/scm-clients/scm-client-api/pom.xml +++ b/scm-clients/scm-client-api/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.56 + 1.57-SNAPSHOT sonia.scm.clients scm-client-api jar - 1.56 + 1.57-SNAPSHOT scm-client-api diff --git a/scm-clients/scm-client-impl/pom.xml b/scm-clients/scm-client-impl/pom.xml index 8e6512d90b..f64f8c4df3 100644 --- a/scm-clients/scm-client-impl/pom.xml +++ b/scm-clients/scm-client-impl/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.56 + 1.57-SNAPSHOT sonia.scm.clients scm-client-impl jar - 1.56 + 1.57-SNAPSHOT scm-client-impl @@ -36,7 +36,7 @@ sonia.scm.clients scm-client-api - 1.56 + 1.57-SNAPSHOT @@ -70,7 +70,7 @@ sonia.scm scm-test - 1.56 + 1.57-SNAPSHOT test diff --git a/scm-core/pom.xml b/scm-core/pom.xml index 8b75576551..84a0dfb909 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.56 + 1.57-SNAPSHOT sonia.scm scm-core - 1.56 + 1.57-SNAPSHOT scm-core diff --git a/scm-dao-orientdb/pom.xml b/scm-dao-orientdb/pom.xml index 36bf7eb2d9..0bd256b5a7 100644 --- a/scm-dao-orientdb/pom.xml +++ b/scm-dao-orientdb/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.56 + 1.57-SNAPSHOT sonia.scm scm-dao-orientdb - 1.56 + 1.57-SNAPSHOT scm-dao-orientdb @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.56 + 1.57-SNAPSHOT @@ -52,7 +52,7 @@ sonia.scm scm-test - 1.56 + 1.57-SNAPSHOT test diff --git a/scm-dao-xml/pom.xml b/scm-dao-xml/pom.xml index 45a3c23557..55f94377ec 100644 --- a/scm-dao-xml/pom.xml +++ b/scm-dao-xml/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.56 + 1.57-SNAPSHOT sonia.scm scm-dao-xml - 1.56 + 1.57-SNAPSHOT scm-dao-xml @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.56 + 1.57-SNAPSHOT @@ -34,7 +34,7 @@ sonia.scm scm-test - 1.56 + 1.57-SNAPSHOT test diff --git a/scm-plugin-backend/pom.xml b/scm-plugin-backend/pom.xml index 1d6cfc527f..d5dc4d16bc 100644 --- a/scm-plugin-backend/pom.xml +++ b/scm-plugin-backend/pom.xml @@ -6,13 +6,13 @@ scm sonia.scm - 1.56 + 1.57-SNAPSHOT sonia.scm scm-plugin-backend war - 1.56 + 1.57-SNAPSHOT ${project.artifactId} @@ -62,7 +62,7 @@ sonia.scm scm-core - 1.56 + 1.57-SNAPSHOT diff --git a/scm-plugins/pom.xml b/scm-plugins/pom.xml index 8922758bf1..af9d007ced 100644 --- a/scm-plugins/pom.xml +++ b/scm-plugins/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.56 + 1.57-SNAPSHOT sonia.scm.plugins scm-plugins pom - 1.56 + 1.57-SNAPSHOT scm-plugins @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.56 + 1.57-SNAPSHOT @@ -59,7 +59,7 @@ sonia.scm.maven scm-maven-plugin - 1.56 + 1.57-SNAPSHOT process-resources diff --git a/scm-plugins/scm-git-plugin/pom.xml b/scm-plugins/scm-git-plugin/pom.xml index 45b67593da..08411e9b61 100644 --- a/scm-plugins/scm-git-plugin/pom.xml +++ b/scm-plugins/scm-git-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.56 + 1.57-SNAPSHOT sonia.scm.plugins scm-git-plugin - 1.56 + 1.57-SNAPSHOT scm-git-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Git @@ -54,7 +54,7 @@ sonia.scm scm-test - 1.56 + 1.57-SNAPSHOT test diff --git a/scm-plugins/scm-hg-plugin/pom.xml b/scm-plugins/scm-hg-plugin/pom.xml index 1b3cea43e5..d78d7d7dca 100644 --- a/scm-plugins/scm-hg-plugin/pom.xml +++ b/scm-plugins/scm-hg-plugin/pom.xml @@ -6,12 +6,12 @@ sonia.scm.plugins scm-plugins - 1.56 + 1.57-SNAPSHOT sonia.scm.plugins scm-hg-plugin - 1.56 + 1.57-SNAPSHOT scm-hg-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Mercurial @@ -42,7 +42,7 @@ sonia.scm scm-test - 1.56 + 1.57-SNAPSHOT test diff --git a/scm-plugins/scm-svn-plugin/pom.xml b/scm-plugins/scm-svn-plugin/pom.xml index 5a4512d3f0..b2f5d180c7 100644 --- a/scm-plugins/scm-svn-plugin/pom.xml +++ b/scm-plugins/scm-svn-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.56 + 1.57-SNAPSHOT sonia.scm.plugins scm-svn-plugin - 1.56 + 1.57-SNAPSHOT scm-svn-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Subversion @@ -48,7 +48,7 @@ sonia.scm scm-test - 1.56 + 1.57-SNAPSHOT test diff --git a/scm-samples/pom.xml b/scm-samples/pom.xml index 1fff9e55e8..f25c5d1ab6 100644 --- a/scm-samples/pom.xml +++ b/scm-samples/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.56 + 1.57-SNAPSHOT sonia.scm.samples scm-samples pom - 1.56 + 1.57-SNAPSHOT scm-samples diff --git a/scm-samples/scm-sample-auth/pom.xml b/scm-samples/scm-sample-auth/pom.xml index 75aa38d045..c646497e3c 100644 --- a/scm-samples/scm-sample-auth/pom.xml +++ b/scm-samples/scm-sample-auth/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.56 + 1.57-SNAPSHOT sonia.scm.sample scm-sample-auth - 1.56 + 1.57-SNAPSHOT scm-sample-auth Sample Authentication Plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.56 + 1.57-SNAPSHOT diff --git a/scm-samples/scm-sample-hello/pom.xml b/scm-samples/scm-sample-hello/pom.xml index ce559b808c..1f18d2bfb2 100644 --- a/scm-samples/scm-sample-hello/pom.xml +++ b/scm-samples/scm-sample-hello/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.56 + 1.57-SNAPSHOT sonia.scm.sample scm-sample-hello - 1.56 + 1.57-SNAPSHOT scm-sample-hello A simple hello world plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.56 + 1.57-SNAPSHOT diff --git a/scm-server/pom.xml b/scm-server/pom.xml index 5c2eaeee2c..6c486f36c2 100644 --- a/scm-server/pom.xml +++ b/scm-server/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.56 + 1.57-SNAPSHOT sonia.scm scm-server - 1.56 + 1.57-SNAPSHOT scm-server jar diff --git a/scm-test/pom.xml b/scm-test/pom.xml index 63ff7e8914..07f54c0249 100644 --- a/scm-test/pom.xml +++ b/scm-test/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.56 + 1.57-SNAPSHOT sonia.scm scm-test - 1.56 + 1.57-SNAPSHOT scm-test @@ -25,7 +25,7 @@ sonia.scm scm-core - 1.56 + 1.57-SNAPSHOT diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 93c83d643b..524720b0ae 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.56 + 1.57-SNAPSHOT sonia.scm scm-webapp war - 1.56 + 1.57-SNAPSHOT scm-webapp @@ -38,31 +38,31 @@ sonia.scm scm-core - 1.56 + 1.57-SNAPSHOT sonia.scm scm-dao-xml - 1.56 + 1.57-SNAPSHOT sonia.scm.plugins scm-hg-plugin - 1.56 + 1.57-SNAPSHOT sonia.scm.plugins scm-svn-plugin - 1.56 + 1.57-SNAPSHOT sonia.scm.plugins scm-git-plugin - 1.56 + 1.57-SNAPSHOT @@ -285,7 +285,7 @@ sonia.scm scm-test - 1.56 + 1.57-SNAPSHOT test @@ -298,7 +298,7 @@ sonia.scm.plugins scm-git-plugin - 1.56 + 1.57-SNAPSHOT tests test @@ -306,7 +306,7 @@ sonia.scm.plugins scm-hg-plugin - 1.56 + 1.57-SNAPSHOT tests test @@ -314,7 +314,7 @@ sonia.scm.plugins scm-svn-plugin - 1.56 + 1.57-SNAPSHOT tests test @@ -558,7 +558,7 @@ sonia.scm scm-dao-orientdb - 1.56 + 1.57-SNAPSHOT diff --git a/support/pom.xml b/support/pom.xml index fc7b4685ee..b531eb63f7 100644 --- a/support/pom.xml +++ b/support/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.56 + 1.57-SNAPSHOT sonia.scm.support scm-support pom - 1.56 + 1.57-SNAPSHOT scm-support diff --git a/support/scm-support-btrace/pom.xml b/support/scm-support-btrace/pom.xml index cfe31439d8..26ca7cc43e 100644 --- a/support/scm-support-btrace/pom.xml +++ b/support/scm-support-btrace/pom.xml @@ -4,12 +4,12 @@ sonia.scm.support scm-support - 1.56 + 1.57-SNAPSHOT sonia.scm scm-support-btrace - 1.56 + 1.57-SNAPSHOT jar scm-support-btrace @@ -18,7 +18,7 @@ sonia.scm scm-core - 1.56 + 1.57-SNAPSHOT From 9dd25b334a8059339eb30bdb46ad141fc9fe3e03 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 7 Feb 2018 11:24:53 +0100 Subject: [PATCH 18/78] treat update of a git tag as delete and create for hooks --- .../repository/api/GitHookTagProvider.java | 33 ++++++++++-- .../api/GitHookTagProviderTest.java | 54 ++++++++++++------- 2 files changed, 62 insertions(+), 25 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/api/GitHookTagProvider.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/api/GitHookTagProvider.java index e7a75a0ff4..bcc2dc8a18 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/api/GitHookTagProvider.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/api/GitHookTagProvider.java @@ -68,17 +68,40 @@ public class GitHookTagProvider implements HookTagProvider { if (Strings.isNullOrEmpty(tag)){ logger.debug("received ref name {} is not a tag", refName); - } else if (rc.getType() == ReceiveCommand.Type.CREATE) { - createdTagBuilder.add(new Tag(tag, GitUtil.getId(rc.getNewId()))); - } else if (rc.getType() == ReceiveCommand.Type.DELETE){ - deletedTagBuilder.add(new Tag(tag, GitUtil.getId(rc.getOldId()))); + } else if (isCreate(rc)) { + createdTagBuilder.add(createTagFromNewId(rc, tag)); + } else if (isDelete(rc)){ + deletedTagBuilder.add(createTagFromOldId(rc, tag)); + } else if (isUpdate(rc)) { + createdTagBuilder.add(createTagFromNewId(rc, tag)); + deletedTagBuilder.add(createTagFromOldId(rc, tag)); } } createdTags = createdTagBuilder.build(); deletedTags = deletedTagBuilder.build(); } - + + private Tag createTagFromNewId(ReceiveCommand rc, String tag) { + return new Tag(tag, GitUtil.getId(rc.getNewId())); + } + + private Tag createTagFromOldId(ReceiveCommand rc, String tag) { + return new Tag(tag, GitUtil.getId(rc.getOldId())); + } + + private boolean isUpdate(ReceiveCommand rc) { + return rc.getType() == ReceiveCommand.Type.UPDATE || rc.getType() == ReceiveCommand.Type.UPDATE_NONFASTFORWARD; + } + + private boolean isDelete(ReceiveCommand rc) { + return rc.getType() == ReceiveCommand.Type.DELETE; + } + + private boolean isCreate(ReceiveCommand rc) { + return rc.getType() == ReceiveCommand.Type.CREATE; + } + @Override public List getCreatedTags() { return createdTags; diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/api/GitHookTagProviderTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/api/GitHookTagProviderTest.java index 87e277b633..d18677885b 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/api/GitHookTagProviderTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/api/GitHookTagProviderTest.java @@ -32,20 +32,23 @@ package sonia.scm.repository.api; import com.google.common.collect.Lists; -import java.util.List; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.transport.ReceiveCommand; -import org.junit.Test; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; -import static org.hamcrest.Matchers.*; import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import org.mockito.stubbing.OngoingStubbing; import sonia.scm.repository.Tag; +import java.util.List; + +import static org.hamcrest.Matchers.empty; +import static org.junit.Assert.*; +import static org.mockito.Mockito.when; + /** * Unit tests for {@link GitHookTagProvider}. * @@ -54,6 +57,11 @@ import sonia.scm.repository.Tag; @RunWith(MockitoJUnitRunner.class) public class GitHookTagProviderTest { + private static final String ZERO = ObjectId.zeroId().getName(); + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + @Mock private ReceiveCommand command; @@ -73,7 +81,7 @@ public class GitHookTagProviderTest { @Test public void testGetCreatedTags() { String revision = "b2002b64013e54b78eac251df0672bd5d6a83aa7"; - GitHookTagProvider provider = createProvider(ReceiveCommand.Type.CREATE, "refs/tags/1.0.0", revision); + GitHookTagProvider provider = createProvider(ReceiveCommand.Type.CREATE, "refs/tags/1.0.0", revision, ZERO); assertTag("1.0.0", revision, provider.getCreatedTags()); assertThat(provider.getDeletedTags(), empty()); @@ -85,7 +93,7 @@ public class GitHookTagProviderTest { @Test public void testGetDeletedTags() { String revision = "b2002b64013e54b78eac251df0672bd5d6a83aa7"; - GitHookTagProvider provider = createProvider(ReceiveCommand.Type.DELETE, "refs/tags/1.0.0", revision); + GitHookTagProvider provider = createProvider(ReceiveCommand.Type.DELETE, "refs/tags/1.0.0", ZERO, revision); assertThat(provider.getCreatedTags(), empty()); assertTag("1.0.0", revision, provider.getDeletedTags()); @@ -97,11 +105,24 @@ public class GitHookTagProviderTest { @Test public void testWithBranch(){ String revision = "b2002b64013e54b78eac251df0672bd5d6a83aa7"; - GitHookTagProvider provider = createProvider(ReceiveCommand.Type.CREATE, "refs/heads/1.0.0", revision); + GitHookTagProvider provider = createProvider(ReceiveCommand.Type.CREATE, "refs/heads/1.0.0", revision, revision); assertThat(provider.getCreatedTags(), empty()); assertThat(provider.getDeletedTags(), empty()); } + + /** + * Tests {@link GitHookTagProvider} with update command. + */ + @Test + public void testUpdateTags() { + String newId = "b2002b64013e54b78eac251df0672bd5d6a83aa7"; + String oldId = "e0f2be968b147ff7043684a7715d2fe852553db4"; + + GitHookTagProvider provider = createProvider(ReceiveCommand.Type.UPDATE, "refs/tags/1.0.0", newId, oldId); + assertTag("1.0.0", newId, provider.getCreatedTags()); + assertTag("1.0.0", oldId, provider.getDeletedTags()); + } private void assertTag(String name, String revision, List tags){ assertNotNull(tags); @@ -112,19 +133,12 @@ public class GitHookTagProviderTest { assertEquals(revision, tag.getRevision()); } - private GitHookTagProvider createProvider(ReceiveCommand.Type type, String ref, String id){ - OngoingStubbing ongoing; - if (type == ReceiveCommand.Type.CREATE){ - ongoing = when(command.getNewId()); - } else { - ongoing = when(command.getOldId()); - } - ongoing.thenReturn(ObjectId.fromString(id)); - + private GitHookTagProvider createProvider(ReceiveCommand.Type type, String ref, String newId, String oldId){ + when(command.getNewId()).thenReturn(ObjectId.fromString(newId)); + when(command.getOldId()).thenReturn(ObjectId.fromString(oldId)); when(command.getType()).thenReturn(type); when(command.getRefName()).thenReturn(ref); - return new GitHookTagProvider(commands); } -} \ No newline at end of file +} From a8186a24926447807b4a75ef2f16c9cc9f701978 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 7 Feb 2018 15:19:20 +0100 Subject: [PATCH 19/78] update svnkit to version 1.9.0-scm3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9b604a9bed..d8ec7d24e5 100644 --- a/pom.xml +++ b/pom.xml @@ -425,7 +425,7 @@ v4.5.3.201708160445-r-scm1 - 1.9.0-scm2 + 1.9.0-scm3 15.0 From c216692eab43fa5fb32bc5a9c26b13e554648018 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 8 Feb 2018 22:36:54 +0100 Subject: [PATCH 20/78] #965 fixed handling of resources with spaces in its id --- .../it/JerseyGroupClientHandlerITCase.java | 25 ++++++- .../sonia/scm/url/RestModelUrlProvider.java | 4 +- .../scm/url/ModelUrlProviderTestBase.java | 4 +- .../scm/url/RestModelUrlProviderTestBase.java | 15 ++++ .../resources/AbstractManagerResource.java | 32 ++++----- .../AbstractManagerResourceTest.java | 71 +++++++++++++++++++ 6 files changed, 129 insertions(+), 22 deletions(-) create mode 100644 scm-webapp/src/test/java/sonia/scm/api/rest/resources/AbstractManagerResourceTest.java diff --git a/scm-clients/scm-client-impl/src/test/java/sonia/scm/client/it/JerseyGroupClientHandlerITCase.java b/scm-clients/scm-client-impl/src/test/java/sonia/scm/client/it/JerseyGroupClientHandlerITCase.java index 0650564741..08899945ad 100644 --- a/scm-clients/scm-client-impl/src/test/java/sonia/scm/client/it/JerseyGroupClientHandlerITCase.java +++ b/scm-clients/scm-client-impl/src/test/java/sonia/scm/client/it/JerseyGroupClientHandlerITCase.java @@ -35,11 +35,14 @@ package sonia.scm.client.it; //~--- non-JDK imports -------------------------------------------------------- +import org.junit.Test; import sonia.scm.client.ClientHandler; +import sonia.scm.client.GroupClientHandler; import sonia.scm.client.JerseyClientSession; -import sonia.scm.client.it.AbstractClientHandlerTestBase.ModifyTest; import sonia.scm.group.Group; +import static sonia.scm.client.it.ClientTestUtil.createAdminSession; + /** * * @author Sebastian Sdorra @@ -99,4 +102,24 @@ public class JerseyGroupClientHandlerITCase { return new Group("xml", "group-" + number); } + + /** + * Tests crud operations with a group which name contains spaces. + * + * @see manager; + + @Test + public void testLocation() throws URISyntaxException { + URI base = new URI("https://scm.scm-manager.org/"); + + TestManagerResource resource = new TestManagerResource(manager); + when(uriInfo.getAbsolutePath()).thenReturn(base); + + URI uri = resource.location(uriInfo, "special-group"); + assertEquals(new URI("https://scm.scm-manager.org/groups/special-group"), uri); + } + + @Test + public void testLocationWithSpaces() throws URISyntaxException { + URI base = new URI("https://scm.scm-manager.org/"); + + TestManagerResource resource = new TestManagerResource(manager); + when(uriInfo.getAbsolutePath()).thenReturn(base); + + URI uri = resource.location(uriInfo, "Scm Special Group"); + assertEquals(new URI("https://scm.scm-manager.org/groups/Scm%20Special%20Group"), uri); + } + + private static class TestManagerResource extends AbstractManagerResource { + + private TestManagerResource(Manager manager) { + super(manager); + } + + @Override + protected GenericEntity> createGenericEntity(Collection items) { + return null; + } + + @Override + protected String getId(Group group) { + return group.getId(); + } + + @Override + protected String getPathPart() { + return "groups"; + } + } +} From 184b802992fe6791c3eea109fe37187f82be2db2 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 9 Feb 2018 07:59:17 +0100 Subject: [PATCH 21/78] close branch issue-965 From b64d41f3c95fcc0dba6d7e30d2b9bd06d90eac1a Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 9 Feb 2018 08:14:34 +0100 Subject: [PATCH 22/78] [maven-release-plugin] prepare release 1.57 --- maven/pom.xml | 4 ++-- maven/scm-maven-plugin/pom.xml | 4 ++-- maven/scm-plugin-archetype/pom.xml | 4 ++-- pom.xml | 4 ++-- scm-clients/pom.xml | 6 +++--- scm-clients/scm-cli-client/pom.xml | 6 +++--- scm-clients/scm-client-api/pom.xml | 4 ++-- scm-clients/scm-client-impl/pom.xml | 8 ++++---- scm-core/pom.xml | 4 ++-- scm-dao-orientdb/pom.xml | 8 ++++---- scm-dao-xml/pom.xml | 8 ++++---- scm-plugin-backend/pom.xml | 6 +++--- scm-plugins/pom.xml | 8 ++++---- scm-plugins/scm-git-plugin/pom.xml | 6 +++--- scm-plugins/scm-hg-plugin/pom.xml | 6 +++--- scm-plugins/scm-svn-plugin/pom.xml | 6 +++--- scm-samples/pom.xml | 4 ++-- scm-samples/scm-sample-auth/pom.xml | 6 +++--- scm-samples/scm-sample-hello/pom.xml | 6 +++--- scm-server/pom.xml | 4 ++-- scm-test/pom.xml | 6 +++--- scm-webapp/pom.xml | 24 ++++++++++++------------ support/pom.xml | 4 ++-- support/scm-support-btrace/pom.xml | 6 +++--- 24 files changed, 76 insertions(+), 76 deletions(-) diff --git a/maven/pom.xml b/maven/pom.xml index c57712f36c..e0222c1e3b 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.57-SNAPSHOT + 1.57 sonia.scm.maven scm-maven-plugins pom - 1.57-SNAPSHOT + 1.57 scm-maven-plugins diff --git a/maven/scm-maven-plugin/pom.xml b/maven/scm-maven-plugin/pom.xml index 09b02b5ddc..1b82cc2d25 100644 --- a/maven/scm-maven-plugin/pom.xml +++ b/maven/scm-maven-plugin/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.57-SNAPSHOT + 1.57 sonia.scm.maven scm-maven-plugin - 1.57-SNAPSHOT + 1.57 maven-plugin scm-maven-plugin diff --git a/maven/scm-plugin-archetype/pom.xml b/maven/scm-plugin-archetype/pom.xml index cfd9cb397a..e499a5670c 100644 --- a/maven/scm-plugin-archetype/pom.xml +++ b/maven/scm-plugin-archetype/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.57-SNAPSHOT + 1.57 sonia.scm.maven scm-plugin-archetype - 1.57-SNAPSHOT + 1.57 scm-plugin-archetype diff --git a/pom.xml b/pom.xml index d8ec7d24e5..ec21f52813 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ sonia.scm scm pom - 1.57-SNAPSHOT + 1.57 The easiest way to share your Git, Mercurial and Subversion repositories over http. @@ -36,7 +36,7 @@ scm:hg:http://bitbucket.org/sdorra/scm-manager scm:hg:https://bitbucket.org/sdorra/scm-manager http://bitbucket.org/sdorra/scm-manager - HEAD + 1.57 diff --git a/scm-clients/pom.xml b/scm-clients/pom.xml index ac6bc4cf8d..835186be15 100644 --- a/scm-clients/pom.xml +++ b/scm-clients/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.57-SNAPSHOT + 1.57 sonia.scm.clients scm-clients pom - 1.57-SNAPSHOT + 1.57 scm-clients @@ -32,7 +32,7 @@ scm-core sonia.scm jar - 1.57-SNAPSHOT + 1.57 shiro-core diff --git a/scm-clients/scm-cli-client/pom.xml b/scm-clients/scm-cli-client/pom.xml index 88f28abd34..4a1d75c75d 100644 --- a/scm-clients/scm-cli-client/pom.xml +++ b/scm-clients/scm-cli-client/pom.xml @@ -6,12 +6,12 @@ scm-clients sonia.scm.clients - 1.57-SNAPSHOT + 1.57 sonia.scm.clients scm-cli-client - 1.57-SNAPSHOT + 1.57 scm-cli-client @@ -34,7 +34,7 @@ sonia.scm.clients scm-client-impl - 1.57-SNAPSHOT + 1.57 diff --git a/scm-clients/scm-client-api/pom.xml b/scm-clients/scm-client-api/pom.xml index fa15ca7f80..f3a091fc84 100644 --- a/scm-clients/scm-client-api/pom.xml +++ b/scm-clients/scm-client-api/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.57-SNAPSHOT + 1.57 sonia.scm.clients scm-client-api jar - 1.57-SNAPSHOT + 1.57 scm-client-api diff --git a/scm-clients/scm-client-impl/pom.xml b/scm-clients/scm-client-impl/pom.xml index f64f8c4df3..222b1375ef 100644 --- a/scm-clients/scm-client-impl/pom.xml +++ b/scm-clients/scm-client-impl/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.57-SNAPSHOT + 1.57 sonia.scm.clients scm-client-impl jar - 1.57-SNAPSHOT + 1.57 scm-client-impl @@ -36,7 +36,7 @@ sonia.scm.clients scm-client-api - 1.57-SNAPSHOT + 1.57 @@ -70,7 +70,7 @@ sonia.scm scm-test - 1.57-SNAPSHOT + 1.57 test diff --git a/scm-core/pom.xml b/scm-core/pom.xml index 84a0dfb909..24a2897f31 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.57-SNAPSHOT + 1.57 sonia.scm scm-core - 1.57-SNAPSHOT + 1.57 scm-core diff --git a/scm-dao-orientdb/pom.xml b/scm-dao-orientdb/pom.xml index 0bd256b5a7..b0c5cd275c 100644 --- a/scm-dao-orientdb/pom.xml +++ b/scm-dao-orientdb/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.57-SNAPSHOT + 1.57 sonia.scm scm-dao-orientdb - 1.57-SNAPSHOT + 1.57 scm-dao-orientdb @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.57-SNAPSHOT + 1.57 @@ -52,7 +52,7 @@ sonia.scm scm-test - 1.57-SNAPSHOT + 1.57 test diff --git a/scm-dao-xml/pom.xml b/scm-dao-xml/pom.xml index 55f94377ec..f7b223cfd8 100644 --- a/scm-dao-xml/pom.xml +++ b/scm-dao-xml/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.57-SNAPSHOT + 1.57 sonia.scm scm-dao-xml - 1.57-SNAPSHOT + 1.57 scm-dao-xml @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.57-SNAPSHOT + 1.57 @@ -34,7 +34,7 @@ sonia.scm scm-test - 1.57-SNAPSHOT + 1.57 test diff --git a/scm-plugin-backend/pom.xml b/scm-plugin-backend/pom.xml index d5dc4d16bc..c287f16eec 100644 --- a/scm-plugin-backend/pom.xml +++ b/scm-plugin-backend/pom.xml @@ -6,13 +6,13 @@ scm sonia.scm - 1.57-SNAPSHOT + 1.57 sonia.scm scm-plugin-backend war - 1.57-SNAPSHOT + 1.57 ${project.artifactId} @@ -62,7 +62,7 @@ sonia.scm scm-core - 1.57-SNAPSHOT + 1.57 diff --git a/scm-plugins/pom.xml b/scm-plugins/pom.xml index af9d007ced..5d4a8fd1ea 100644 --- a/scm-plugins/pom.xml +++ b/scm-plugins/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.57-SNAPSHOT + 1.57 sonia.scm.plugins scm-plugins pom - 1.57-SNAPSHOT + 1.57 scm-plugins @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.57-SNAPSHOT + 1.57 @@ -59,7 +59,7 @@ sonia.scm.maven scm-maven-plugin - 1.57-SNAPSHOT + 1.57 process-resources diff --git a/scm-plugins/scm-git-plugin/pom.xml b/scm-plugins/scm-git-plugin/pom.xml index 08411e9b61..6d47bfca08 100644 --- a/scm-plugins/scm-git-plugin/pom.xml +++ b/scm-plugins/scm-git-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.57-SNAPSHOT + 1.57 sonia.scm.plugins scm-git-plugin - 1.57-SNAPSHOT + 1.57 scm-git-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Git @@ -54,7 +54,7 @@ sonia.scm scm-test - 1.57-SNAPSHOT + 1.57 test diff --git a/scm-plugins/scm-hg-plugin/pom.xml b/scm-plugins/scm-hg-plugin/pom.xml index d78d7d7dca..dcd2dc5009 100644 --- a/scm-plugins/scm-hg-plugin/pom.xml +++ b/scm-plugins/scm-hg-plugin/pom.xml @@ -6,12 +6,12 @@ sonia.scm.plugins scm-plugins - 1.57-SNAPSHOT + 1.57 sonia.scm.plugins scm-hg-plugin - 1.57-SNAPSHOT + 1.57 scm-hg-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Mercurial @@ -42,7 +42,7 @@ sonia.scm scm-test - 1.57-SNAPSHOT + 1.57 test diff --git a/scm-plugins/scm-svn-plugin/pom.xml b/scm-plugins/scm-svn-plugin/pom.xml index b2f5d180c7..363a7f223b 100644 --- a/scm-plugins/scm-svn-plugin/pom.xml +++ b/scm-plugins/scm-svn-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.57-SNAPSHOT + 1.57 sonia.scm.plugins scm-svn-plugin - 1.57-SNAPSHOT + 1.57 scm-svn-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Subversion @@ -48,7 +48,7 @@ sonia.scm scm-test - 1.57-SNAPSHOT + 1.57 test diff --git a/scm-samples/pom.xml b/scm-samples/pom.xml index f25c5d1ab6..7c4017bfc8 100644 --- a/scm-samples/pom.xml +++ b/scm-samples/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.57-SNAPSHOT + 1.57 sonia.scm.samples scm-samples pom - 1.57-SNAPSHOT + 1.57 scm-samples diff --git a/scm-samples/scm-sample-auth/pom.xml b/scm-samples/scm-sample-auth/pom.xml index c646497e3c..40724f8d95 100644 --- a/scm-samples/scm-sample-auth/pom.xml +++ b/scm-samples/scm-sample-auth/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.57-SNAPSHOT + 1.57 sonia.scm.sample scm-sample-auth - 1.57-SNAPSHOT + 1.57 scm-sample-auth Sample Authentication Plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.57-SNAPSHOT + 1.57 diff --git a/scm-samples/scm-sample-hello/pom.xml b/scm-samples/scm-sample-hello/pom.xml index 1f18d2bfb2..49c63d9653 100644 --- a/scm-samples/scm-sample-hello/pom.xml +++ b/scm-samples/scm-sample-hello/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.57-SNAPSHOT + 1.57 sonia.scm.sample scm-sample-hello - 1.57-SNAPSHOT + 1.57 scm-sample-hello A simple hello world plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.57-SNAPSHOT + 1.57 diff --git a/scm-server/pom.xml b/scm-server/pom.xml index 6c486f36c2..7e5536b991 100644 --- a/scm-server/pom.xml +++ b/scm-server/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.57-SNAPSHOT + 1.57 sonia.scm scm-server - 1.57-SNAPSHOT + 1.57 scm-server jar diff --git a/scm-test/pom.xml b/scm-test/pom.xml index 07f54c0249..53d1ee0a6b 100644 --- a/scm-test/pom.xml +++ b/scm-test/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.57-SNAPSHOT + 1.57 sonia.scm scm-test - 1.57-SNAPSHOT + 1.57 scm-test @@ -25,7 +25,7 @@ sonia.scm scm-core - 1.57-SNAPSHOT + 1.57 diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 524720b0ae..a58f8c3c3a 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.57-SNAPSHOT + 1.57 sonia.scm scm-webapp war - 1.57-SNAPSHOT + 1.57 scm-webapp @@ -38,31 +38,31 @@ sonia.scm scm-core - 1.57-SNAPSHOT + 1.57 sonia.scm scm-dao-xml - 1.57-SNAPSHOT + 1.57 sonia.scm.plugins scm-hg-plugin - 1.57-SNAPSHOT + 1.57 sonia.scm.plugins scm-svn-plugin - 1.57-SNAPSHOT + 1.57 sonia.scm.plugins scm-git-plugin - 1.57-SNAPSHOT + 1.57 @@ -285,7 +285,7 @@ sonia.scm scm-test - 1.57-SNAPSHOT + 1.57 test @@ -298,7 +298,7 @@ sonia.scm.plugins scm-git-plugin - 1.57-SNAPSHOT + 1.57 tests test @@ -306,7 +306,7 @@ sonia.scm.plugins scm-hg-plugin - 1.57-SNAPSHOT + 1.57 tests test @@ -314,7 +314,7 @@ sonia.scm.plugins scm-svn-plugin - 1.57-SNAPSHOT + 1.57 tests test @@ -558,7 +558,7 @@ sonia.scm scm-dao-orientdb - 1.57-SNAPSHOT + 1.57 diff --git a/support/pom.xml b/support/pom.xml index b531eb63f7..6eecce15ee 100644 --- a/support/pom.xml +++ b/support/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.57-SNAPSHOT + 1.57 sonia.scm.support scm-support pom - 1.57-SNAPSHOT + 1.57 scm-support diff --git a/support/scm-support-btrace/pom.xml b/support/scm-support-btrace/pom.xml index 26ca7cc43e..d5ac090c27 100644 --- a/support/scm-support-btrace/pom.xml +++ b/support/scm-support-btrace/pom.xml @@ -4,12 +4,12 @@ sonia.scm.support scm-support - 1.57-SNAPSHOT + 1.57 sonia.scm scm-support-btrace - 1.57-SNAPSHOT + 1.57 jar scm-support-btrace @@ -18,7 +18,7 @@ sonia.scm scm-core - 1.57-SNAPSHOT + 1.57 From c28824319762c7c818c4f09b37e73cfe688d38db Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 9 Feb 2018 08:14:34 +0100 Subject: [PATCH 23/78] [maven-release-plugin] copy for tag 1.57 From d21a28fa0b86506616438089dbf7525e52ccc7c2 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 9 Feb 2018 08:14:35 +0100 Subject: [PATCH 24/78] [maven-release-plugin] prepare for next development iteration --- maven/pom.xml | 4 ++-- maven/scm-maven-plugin/pom.xml | 4 ++-- maven/scm-plugin-archetype/pom.xml | 4 ++-- pom.xml | 4 ++-- scm-clients/pom.xml | 6 +++--- scm-clients/scm-cli-client/pom.xml | 6 +++--- scm-clients/scm-client-api/pom.xml | 4 ++-- scm-clients/scm-client-impl/pom.xml | 8 ++++---- scm-core/pom.xml | 4 ++-- scm-dao-orientdb/pom.xml | 8 ++++---- scm-dao-xml/pom.xml | 8 ++++---- scm-plugin-backend/pom.xml | 6 +++--- scm-plugins/pom.xml | 8 ++++---- scm-plugins/scm-git-plugin/pom.xml | 6 +++--- scm-plugins/scm-hg-plugin/pom.xml | 6 +++--- scm-plugins/scm-svn-plugin/pom.xml | 6 +++--- scm-samples/pom.xml | 4 ++-- scm-samples/scm-sample-auth/pom.xml | 6 +++--- scm-samples/scm-sample-hello/pom.xml | 6 +++--- scm-server/pom.xml | 4 ++-- scm-test/pom.xml | 6 +++--- scm-webapp/pom.xml | 24 ++++++++++++------------ support/pom.xml | 4 ++-- support/scm-support-btrace/pom.xml | 6 +++--- 24 files changed, 76 insertions(+), 76 deletions(-) diff --git a/maven/pom.xml b/maven/pom.xml index e0222c1e3b..d371d05c94 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.57 + 1.58-SNAPSHOT sonia.scm.maven scm-maven-plugins pom - 1.57 + 1.58-SNAPSHOT scm-maven-plugins diff --git a/maven/scm-maven-plugin/pom.xml b/maven/scm-maven-plugin/pom.xml index 1b82cc2d25..f6d85bf8cb 100644 --- a/maven/scm-maven-plugin/pom.xml +++ b/maven/scm-maven-plugin/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.57 + 1.58-SNAPSHOT sonia.scm.maven scm-maven-plugin - 1.57 + 1.58-SNAPSHOT maven-plugin scm-maven-plugin diff --git a/maven/scm-plugin-archetype/pom.xml b/maven/scm-plugin-archetype/pom.xml index e499a5670c..201664de81 100644 --- a/maven/scm-plugin-archetype/pom.xml +++ b/maven/scm-plugin-archetype/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.57 + 1.58-SNAPSHOT sonia.scm.maven scm-plugin-archetype - 1.57 + 1.58-SNAPSHOT scm-plugin-archetype diff --git a/pom.xml b/pom.xml index ec21f52813..c888ababe8 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ sonia.scm scm pom - 1.57 + 1.58-SNAPSHOT The easiest way to share your Git, Mercurial and Subversion repositories over http. @@ -36,7 +36,7 @@ scm:hg:http://bitbucket.org/sdorra/scm-manager scm:hg:https://bitbucket.org/sdorra/scm-manager http://bitbucket.org/sdorra/scm-manager - 1.57 + HEAD diff --git a/scm-clients/pom.xml b/scm-clients/pom.xml index 835186be15..0e18675860 100644 --- a/scm-clients/pom.xml +++ b/scm-clients/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.57 + 1.58-SNAPSHOT sonia.scm.clients scm-clients pom - 1.57 + 1.58-SNAPSHOT scm-clients @@ -32,7 +32,7 @@ scm-core sonia.scm jar - 1.57 + 1.58-SNAPSHOT shiro-core diff --git a/scm-clients/scm-cli-client/pom.xml b/scm-clients/scm-cli-client/pom.xml index 4a1d75c75d..1d26cee2b4 100644 --- a/scm-clients/scm-cli-client/pom.xml +++ b/scm-clients/scm-cli-client/pom.xml @@ -6,12 +6,12 @@ scm-clients sonia.scm.clients - 1.57 + 1.58-SNAPSHOT sonia.scm.clients scm-cli-client - 1.57 + 1.58-SNAPSHOT scm-cli-client @@ -34,7 +34,7 @@ sonia.scm.clients scm-client-impl - 1.57 + 1.58-SNAPSHOT diff --git a/scm-clients/scm-client-api/pom.xml b/scm-clients/scm-client-api/pom.xml index f3a091fc84..75ac3d81d7 100644 --- a/scm-clients/scm-client-api/pom.xml +++ b/scm-clients/scm-client-api/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.57 + 1.58-SNAPSHOT sonia.scm.clients scm-client-api jar - 1.57 + 1.58-SNAPSHOT scm-client-api diff --git a/scm-clients/scm-client-impl/pom.xml b/scm-clients/scm-client-impl/pom.xml index 222b1375ef..e97a96e380 100644 --- a/scm-clients/scm-client-impl/pom.xml +++ b/scm-clients/scm-client-impl/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.57 + 1.58-SNAPSHOT sonia.scm.clients scm-client-impl jar - 1.57 + 1.58-SNAPSHOT scm-client-impl @@ -36,7 +36,7 @@ sonia.scm.clients scm-client-api - 1.57 + 1.58-SNAPSHOT @@ -70,7 +70,7 @@ sonia.scm scm-test - 1.57 + 1.58-SNAPSHOT test diff --git a/scm-core/pom.xml b/scm-core/pom.xml index 24a2897f31..732c0fa4d6 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.57 + 1.58-SNAPSHOT sonia.scm scm-core - 1.57 + 1.58-SNAPSHOT scm-core diff --git a/scm-dao-orientdb/pom.xml b/scm-dao-orientdb/pom.xml index b0c5cd275c..c708a12cba 100644 --- a/scm-dao-orientdb/pom.xml +++ b/scm-dao-orientdb/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.57 + 1.58-SNAPSHOT sonia.scm scm-dao-orientdb - 1.57 + 1.58-SNAPSHOT scm-dao-orientdb @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.57 + 1.58-SNAPSHOT @@ -52,7 +52,7 @@ sonia.scm scm-test - 1.57 + 1.58-SNAPSHOT test diff --git a/scm-dao-xml/pom.xml b/scm-dao-xml/pom.xml index f7b223cfd8..a6f7898246 100644 --- a/scm-dao-xml/pom.xml +++ b/scm-dao-xml/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.57 + 1.58-SNAPSHOT sonia.scm scm-dao-xml - 1.57 + 1.58-SNAPSHOT scm-dao-xml @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.57 + 1.58-SNAPSHOT @@ -34,7 +34,7 @@ sonia.scm scm-test - 1.57 + 1.58-SNAPSHOT test diff --git a/scm-plugin-backend/pom.xml b/scm-plugin-backend/pom.xml index c287f16eec..bc59a101a8 100644 --- a/scm-plugin-backend/pom.xml +++ b/scm-plugin-backend/pom.xml @@ -6,13 +6,13 @@ scm sonia.scm - 1.57 + 1.58-SNAPSHOT sonia.scm scm-plugin-backend war - 1.57 + 1.58-SNAPSHOT ${project.artifactId} @@ -62,7 +62,7 @@ sonia.scm scm-core - 1.57 + 1.58-SNAPSHOT diff --git a/scm-plugins/pom.xml b/scm-plugins/pom.xml index 5d4a8fd1ea..e11e11ebde 100644 --- a/scm-plugins/pom.xml +++ b/scm-plugins/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.57 + 1.58-SNAPSHOT sonia.scm.plugins scm-plugins pom - 1.57 + 1.58-SNAPSHOT scm-plugins @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.57 + 1.58-SNAPSHOT @@ -59,7 +59,7 @@ sonia.scm.maven scm-maven-plugin - 1.57 + 1.58-SNAPSHOT process-resources diff --git a/scm-plugins/scm-git-plugin/pom.xml b/scm-plugins/scm-git-plugin/pom.xml index 6d47bfca08..60c617cfd1 100644 --- a/scm-plugins/scm-git-plugin/pom.xml +++ b/scm-plugins/scm-git-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.57 + 1.58-SNAPSHOT sonia.scm.plugins scm-git-plugin - 1.57 + 1.58-SNAPSHOT scm-git-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Git @@ -54,7 +54,7 @@ sonia.scm scm-test - 1.57 + 1.58-SNAPSHOT test diff --git a/scm-plugins/scm-hg-plugin/pom.xml b/scm-plugins/scm-hg-plugin/pom.xml index dcd2dc5009..e4cfa7d6f2 100644 --- a/scm-plugins/scm-hg-plugin/pom.xml +++ b/scm-plugins/scm-hg-plugin/pom.xml @@ -6,12 +6,12 @@ sonia.scm.plugins scm-plugins - 1.57 + 1.58-SNAPSHOT sonia.scm.plugins scm-hg-plugin - 1.57 + 1.58-SNAPSHOT scm-hg-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Mercurial @@ -42,7 +42,7 @@ sonia.scm scm-test - 1.57 + 1.58-SNAPSHOT test diff --git a/scm-plugins/scm-svn-plugin/pom.xml b/scm-plugins/scm-svn-plugin/pom.xml index 363a7f223b..0be176d42c 100644 --- a/scm-plugins/scm-svn-plugin/pom.xml +++ b/scm-plugins/scm-svn-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.57 + 1.58-SNAPSHOT sonia.scm.plugins scm-svn-plugin - 1.57 + 1.58-SNAPSHOT scm-svn-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Subversion @@ -48,7 +48,7 @@ sonia.scm scm-test - 1.57 + 1.58-SNAPSHOT test diff --git a/scm-samples/pom.xml b/scm-samples/pom.xml index 7c4017bfc8..22e4b9cc04 100644 --- a/scm-samples/pom.xml +++ b/scm-samples/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.57 + 1.58-SNAPSHOT sonia.scm.samples scm-samples pom - 1.57 + 1.58-SNAPSHOT scm-samples diff --git a/scm-samples/scm-sample-auth/pom.xml b/scm-samples/scm-sample-auth/pom.xml index 40724f8d95..05ec3fddd9 100644 --- a/scm-samples/scm-sample-auth/pom.xml +++ b/scm-samples/scm-sample-auth/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.57 + 1.58-SNAPSHOT sonia.scm.sample scm-sample-auth - 1.57 + 1.58-SNAPSHOT scm-sample-auth Sample Authentication Plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.57 + 1.58-SNAPSHOT diff --git a/scm-samples/scm-sample-hello/pom.xml b/scm-samples/scm-sample-hello/pom.xml index 49c63d9653..f896257930 100644 --- a/scm-samples/scm-sample-hello/pom.xml +++ b/scm-samples/scm-sample-hello/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.57 + 1.58-SNAPSHOT sonia.scm.sample scm-sample-hello - 1.57 + 1.58-SNAPSHOT scm-sample-hello A simple hello world plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.57 + 1.58-SNAPSHOT diff --git a/scm-server/pom.xml b/scm-server/pom.xml index 7e5536b991..50c77d05fd 100644 --- a/scm-server/pom.xml +++ b/scm-server/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.57 + 1.58-SNAPSHOT sonia.scm scm-server - 1.57 + 1.58-SNAPSHOT scm-server jar diff --git a/scm-test/pom.xml b/scm-test/pom.xml index 53d1ee0a6b..3f769f3367 100644 --- a/scm-test/pom.xml +++ b/scm-test/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.57 + 1.58-SNAPSHOT sonia.scm scm-test - 1.57 + 1.58-SNAPSHOT scm-test @@ -25,7 +25,7 @@ sonia.scm scm-core - 1.57 + 1.58-SNAPSHOT diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index a58f8c3c3a..775b75525a 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.57 + 1.58-SNAPSHOT sonia.scm scm-webapp war - 1.57 + 1.58-SNAPSHOT scm-webapp @@ -38,31 +38,31 @@ sonia.scm scm-core - 1.57 + 1.58-SNAPSHOT sonia.scm scm-dao-xml - 1.57 + 1.58-SNAPSHOT sonia.scm.plugins scm-hg-plugin - 1.57 + 1.58-SNAPSHOT sonia.scm.plugins scm-svn-plugin - 1.57 + 1.58-SNAPSHOT sonia.scm.plugins scm-git-plugin - 1.57 + 1.58-SNAPSHOT @@ -285,7 +285,7 @@ sonia.scm scm-test - 1.57 + 1.58-SNAPSHOT test @@ -298,7 +298,7 @@ sonia.scm.plugins scm-git-plugin - 1.57 + 1.58-SNAPSHOT tests test @@ -306,7 +306,7 @@ sonia.scm.plugins scm-hg-plugin - 1.57 + 1.58-SNAPSHOT tests test @@ -314,7 +314,7 @@ sonia.scm.plugins scm-svn-plugin - 1.57 + 1.58-SNAPSHOT tests test @@ -558,7 +558,7 @@ sonia.scm scm-dao-orientdb - 1.57 + 1.58-SNAPSHOT diff --git a/support/pom.xml b/support/pom.xml index 6eecce15ee..9db5842b99 100644 --- a/support/pom.xml +++ b/support/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.57 + 1.58-SNAPSHOT sonia.scm.support scm-support pom - 1.57 + 1.58-SNAPSHOT scm-support diff --git a/support/scm-support-btrace/pom.xml b/support/scm-support-btrace/pom.xml index d5ac090c27..28b1febe75 100644 --- a/support/scm-support-btrace/pom.xml +++ b/support/scm-support-btrace/pom.xml @@ -4,12 +4,12 @@ sonia.scm.support scm-support - 1.57 + 1.58-SNAPSHOT sonia.scm scm-support-btrace - 1.57 + 1.58-SNAPSHOT jar scm-support-btrace @@ -18,7 +18,7 @@ sonia.scm scm-core - 1.57 + 1.58-SNAPSHOT From 7d94b03a0430e98933b1bb9d6f82863adb1fa1f7 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 23 Feb 2018 08:44:22 +0100 Subject: [PATCH 25/78] #959 added option to disable ssl validation for scm mercurial hook --- .../main/java/sonia/scm/repository/HgConfig.java | 14 ++++++++++++++ .../src/main/java/sonia/scm/web/HgCGIServlet.java | 12 +++++++++++- .../src/main/resources/sonia/scm/hg.config.js | 13 ++++++++++++- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgConfig.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgConfig.java index b9bd650925..ed336ff203 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgConfig.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgConfig.java @@ -123,6 +123,10 @@ public class HgConfig extends SimpleRepositoryConfig return useOptimizedBytecode; } + public boolean isDisableHookSSLValidation() { + return disableHookSSLValidation; + } + /** * Method description * @@ -204,6 +208,10 @@ public class HgConfig extends SimpleRepositoryConfig this.useOptimizedBytecode = useOptimizedBytecode; } + public void setDisableHookSSLValidation(boolean disableHookSSLValidation) { + this.disableHookSSLValidation = disableHookSSLValidation; + } + //~--- fields --------------------------------------------------------------- /** Field description */ @@ -223,4 +231,10 @@ public class HgConfig extends SimpleRepositoryConfig /** Field description */ private boolean showRevisionInId = false; + + /** + * disable validation of ssl certificates for mercurial hook + * @see Issue 959 + */ + private boolean disableHookSSLValidation = false; } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java index 4ba165c630..f6023dd0ae 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java @@ -63,6 +63,7 @@ import java.io.File; import java.io.IOException; import java.util.Enumeration; +import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -78,6 +79,8 @@ import javax.servlet.http.HttpSession; public class HgCGIServlet extends HttpServlet { + private static final String ENV_PYTHON_HTTPS_VERIFY = "PYTHONHTTPSVERIFY"; + /** Field description */ public static final String ENV_REPOSITORY_NAME = "REPO_NAME"; @@ -268,9 +271,16 @@ public class HgCGIServlet extends HttpServlet directory.getAbsolutePath()); // add hook environment + Map environment = executor.getEnvironment().asMutableMap(); + if (handler.getConfig().isDisableHookSSLValidation()) { + // disable ssl validation + // Issue 959: https://goo.gl/zH5eY8 + environment.put(ENV_PYTHON_HTTPS_VERIFY, "0"); + } + //J- HgEnvironment.prepareEnvironment( - executor.getEnvironment().asMutableMap(), + environment, handler, hookManager, request diff --git a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg.config.js b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg.config.js index f8aa46e0a8..58a73ea8e9 100644 --- a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg.config.js +++ b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg.config.js @@ -46,6 +46,8 @@ Sonia.hg.ConfigPanel = Ext.extend(Sonia.config.ConfigForm, { encodingText: 'Encoding', disabledText: 'Disabled', showRevisionInIdText: 'Show Revision', + // TODO: i18n + disableHookSSLValidationText: 'Disable SSL Validation on Hooks', // helpText hgBinaryHelpText: 'Location of Mercurial binary.', @@ -58,6 +60,9 @@ Sonia.hg.ConfigPanel = Ext.extend(Sonia.config.ConfigForm, { Note you have to reload the page, after changing this value.', showRevisionInIdHelpText: 'Show revision as part of the node id. Note: \n\ You have to restart the ApplicationServer to affect cached changesets.', + // TODO: i18n + disableHookSSLValidationHelpText: 'Disables the validation of ssl certificates for the mercurial hook, which forwards the repository changes back to scm-manager. \n\ + This option should only be used, if SCM-Manager uses a self signed certificate.', initComponent: function(){ @@ -104,6 +109,12 @@ Sonia.hg.ConfigPanel = Ext.extend(Sonia.config.ConfigForm, { fieldLabel: this.showRevisionInIdText, inputValue: 'true', helpText: this.showRevisionInIdHelpText + },{ + xtype: 'checkbox', + name: 'disableHookSSLValidation', + fieldLabel: this.disableHookSSLValidationText, + inputValue: 'true', + helpText: this.disableHookSSLValidationHelpText },{ xtype: 'checkbox', name: 'disabled', @@ -284,4 +295,4 @@ Ext.override(Sonia.repository.ChangesetViewerGrid, { return parents; } -}); \ No newline at end of file +}); From d8889298135e6f78b99204a89e585da63ea4fb48 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 9 Mar 2018 08:34:24 +0100 Subject: [PATCH 26/78] close branch issue-959 From e7dd54c1336a44c146e98c40585c6a2d469e82cc Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 29 Mar 2018 10:21:34 +0200 Subject: [PATCH 27/78] #970 added ngrep dumps for mercurial wire protocol and more realistic tests for isWriteRequest --- docs/mercurial/clone-empty.md | 74 +++++++ docs/mercurial/push-bookmark.md | 115 +++++++++++ .../push-multiple-branches-to-new.md | 165 ++++++++++++++++ docs/mercurial/push-multiple-branches.md | 181 ++++++++++++++++++ docs/mercurial/push-single-changeset.md | 146 ++++++++++++++ .../sonia/scm/web/HgPermissionFilterTest.java | 95 ++++++++- .../web/WireProtocolRequestMockFactory.java | 101 ++++++++++ 7 files changed, 872 insertions(+), 5 deletions(-) create mode 100644 docs/mercurial/clone-empty.md create mode 100644 docs/mercurial/push-bookmark.md create mode 100644 docs/mercurial/push-multiple-branches-to-new.md create mode 100644 docs/mercurial/push-multiple-branches.md create mode 100644 docs/mercurial/push-single-changeset.md create mode 100644 scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/WireProtocolRequestMockFactory.java diff --git a/docs/mercurial/clone-empty.md b/docs/mercurial/clone-empty.md new file mode 100644 index 0000000000..810a297806 --- /dev/null +++ b/docs/mercurial/clone-empty.md @@ -0,0 +1,74 @@ +# Clone empty repository + +GET /scm/hg/hgtest?cmd=capabilities HTTP/1.1. +Accept-Encoding: identity. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=1efk0qxy1dj5v133hev91zwsf4;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 05:57:18 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 130. +Server: Jetty(7.6.21.v20160908). +. +lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch stream unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 + +GET /scm/hg/hgtest?cmd=listkeys HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: namespace=bookmarks. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=1rsxj8u1rq9wizawhyyxok2p5;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 05:57:18 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 0. +Server: Jetty(7.6.21.v20160908). + +GET /scm/hg/hgtest?cmd=batch HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: cmds=heads+%3Bknown+nodes%3D. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=ewyx4m53d8dajjsob6gxobne;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 05:57:18 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 42. +Server: Jetty(7.6.21.v20160908). + +0000000000000000000000000000000000000000 +; + +GET /scm/hg/hgtest?cmd=listkeys HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: namespace=phases. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=1o0hou15jtiywsywutf30qwm8;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 05:57:18 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 15. +Server: Jetty(7.6.21.v20160908). +. +publishing.True diff --git a/docs/mercurial/push-bookmark.md b/docs/mercurial/push-bookmark.md new file mode 100644 index 0000000000..110bd40cd5 --- /dev/null +++ b/docs/mercurial/push-bookmark.md @@ -0,0 +1,115 @@ +# Push bookmark + +GET /scm/hg/hgtest?cmd=capabilities HTTP/1.1. +Accept-Encoding: identity. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=7rq9vpp9svfm1sicq7h9vetmv;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 08:08:35 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 130. +Server: Jetty(7.6.21.v20160908). + +lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch stream unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 + +GET /scm/hg/hgtest?cmd=batch HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: cmds=heads+%3Bknown+nodes%3Def5993bb4abb32a0565c347844c6d939fc4f4b98. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +T 172.17.0.2:8080 -> 172.17.0.1:36576 [AP] +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=1553csz4sf7scyvw8mqnqfirn;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 08:08:35 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 43. +Server: Jetty(7.6.21.v20160908). + +ef5993bb4abb32a0565c347844c6d939fc4f4b98 +;1 + +GET /scm/hg/hgtest?cmd=listkeys HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: namespace=phases. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=11xa5u3nrmx8k1nar3sazg6jzh;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 08:08:35 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 15. +Server: Jetty(7.6.21.v20160908). + +publishing.True + +GET /scm/hg/hgtest?cmd=listkeys HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: namespace=bookmarks. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=1p1uzcvfe1pvzh2buzo658rxw;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 08:08:35 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 0. +Server: Jetty(7.6.21.v20160908). + +GET /scm/hg/hgtest?cmd=listkeys HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: namespace=phases. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=1mhlj3ucfzdp6ifmzoua4zwit;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 08:08:35 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 15. +Server: Jetty(7.6.21.v20160908). + +publishing.True + +POST /scm/hg/hgtest?cmd=pushkey HTTP/1.1. +Accept-Encoding: identity. +content-type: application/mercurial-0.1. +vary: X-HgArg-1. +x-hgarg-1: key=markone&namespace=bookmarks&new=ef5993bb4abb32a0565c347844c6d939fc4f4b98&old=. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +content-length: 0. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=s4vtagb303dv1xg809wnp7e8z;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 08:08:35 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 2. +Server: Jetty(7.6.21.v20160908). +. +1 diff --git a/docs/mercurial/push-multiple-branches-to-new.md b/docs/mercurial/push-multiple-branches-to-new.md new file mode 100644 index 0000000000..56c3a4504a --- /dev/null +++ b/docs/mercurial/push-multiple-branches-to-new.md @@ -0,0 +1,165 @@ +# Push multiple branches to new repository + +GET /scm/hg/hgtest?cmd=capabilities HTTP/1.1. +Accept-Encoding: identity. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=1wu06ykfd4bcv1uv731y4hss2m;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 07:55:14 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 130. +Server: Jetty(7.6.21.v20160908). + +lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch stream unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 + +GET /scm/hg/hgtest?cmd=batch HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: cmds=heads+%3Bknown+nodes%3Def5993bb4abb32a0565c347844c6d939fc4f4b98. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=1rajglvqx222g5nppcq3jdfk0;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 07:55:14 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 43. +Server: Jetty(7.6.21.v20160908). + +0000000000000000000000000000000000000000 +;0 + +GET /scm/hg/hgtest?cmd=known HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: nodes=c0ceccb3b2f0f5c977ff32b9337519e5f37942c2+187ddf37e237c370514487a0bb1a226f11a780b3+b5914611f84eae14543684b2721eec88b0edac12+8b63a323606f10c86b30465570c2574eb7a3a989. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=a5vykp1f0ga2186l8v3gu6lid;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 07:55:14 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 4. +Server: Jetty(7.6.21.v20160908). + +0000 + +GET /scm/hg/hgtest?cmd=listkeys HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: namespace=phases. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=s8lpwqm4c2nqs9kwcg2ca6vm;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 07:55:14 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 15. +Server: Jetty(7.6.21.v20160908). + +publishing.True + +GET /scm/hg/hgtest?cmd=listkeys HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: namespace=bookmarks. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=1d2qj3kynxlhvk31oli4kk7vf;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 07:55:14 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 0. +Server: Jetty(7.6.21.v20160908). + +POST /scm/hg/hgtest?cmd=unbundle HTTP/1.1. +Accept-Encoding: identity. +content-type: application/mercurial-0.1. +vary: X-HgArg-1. +x-hgarg-1: heads=686173686564+6768033e216468247bd031a0a2d9876d79818f8f. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +content-length: 913. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HG10GZx...oh.U......E.1.....2q.<...s.1.YK*e#..b..{....{..%A..... +,\.....Y.XV....Q/J......`Q/.z.{...<.7....r.s.~?.?..5.~`..?..........O.j.0.....Ih.....!@.P... ..a +;!y..cT...]q.8Zg=...<..,.tq.*.........l........';..w^...w...-......Co..Fs.HYg... +9.F#.P......1..;......D.H.9$@.^....r:E..18...H....3..h...-.=.6l......=q .)."Yg..p\...s@.#.H.*....c8&96..2.GjJ.`.J....r...=Q1..@R.3.o{q...|.......yq.k..,cY..:[... ...S.2...VYp..c5..&.SFR.............V.d..o..........,.. A..M....k...0_.LO1..1"4.;...B....5.9.".U.m.e......]\../p..;?C..W9.........n.~o..gW...Q;..$....S..X.CN.5I].H..!.@...U..J...L.lY.../.-...6.:.Q.'...>.e'..<#3........OL}.52ra[..g*Y:Y....w...=..Z\...S.......tz..;..mf...W......&yUN.r.......4...........`..F...nT..U9................_.~..?...BwzUN.r....B. + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=163487i0ayf9s1k2ng9e1azadj;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 07:55:14 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 102. +Server: Jetty(7.6.21.v20160908). + +1 +adding changesets +adding manifests +adding file changes +added 5 changesets with 3 changes to 3 files + +GET /scm/hg/hgtest?cmd=listkeys HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: namespace=phases. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=a3i712yjss6t1xsxltnssq0tl;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 07:55:14 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 58. +Server: Jetty(7.6.21.v20160908). + +c0ceccb3b2f0f5c977ff32b9337519e5f37942c2.1 +publishing.True + +POST /scm/hg/hgtest?cmd=pushkey HTTP/1.1. +Accept-Encoding: identity. +content-type: application/mercurial-0.1. +vary: X-HgArg-1. +x-hgarg-1: key=ef5993bb4abb32a0565c347844c6d939fc4f4b98&namespace=phases&new=0&old=1. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +content-length: 0. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=g8cavdze42d83knmuasrlg10;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 07:55:14 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 2. +Server: Jetty(7.6.21.v20160908). +. +1 diff --git a/docs/mercurial/push-multiple-branches.md b/docs/mercurial/push-multiple-branches.md new file mode 100644 index 0000000000..7d38542fde --- /dev/null +++ b/docs/mercurial/push-multiple-branches.md @@ -0,0 +1,181 @@ +# Push multiple branches + +GET /scm/hg/hgtest?cmd=capabilities HTTP/1.1. +Accept-Encoding: identity. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=1mvm1rxg8333iib7754ksusxc;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 06:16:50 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 130. +Server: Jetty(7.6.21.v20160908). + +lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch stream unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 + +GET /scm/hg/hgtest?cmd=batch HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: cmds=heads+%3Bknown+nodes%3Def5993bb4abb32a0565c347844c6d939fc4f4b98. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=58p9y9vcnz5cjs22dtw8mpwk;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 06:16:50 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 43. +Server: Jetty(7.6.21.v20160908). + +c0ceccb3b2f0f5c977ff32b9337519e5f37942c2 +;0 + +GET /scm/hg/hgtest?cmd=listkeys HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: namespace=phases. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=v5wfwj8k4t261dp6808cdouoa;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 06:16:50 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 15. +Server: Jetty(7.6.21.v20160908). + +publishing.True + +GET /scm/hg/hgtest?cmd=listkeys HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: namespace=bookmarks. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=3pgqytfhm4za1dco9p41j9yz5;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 06:16:50 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 0. +Server: Jetty(7.6.21.v20160908). + +GET /scm/hg/hgtest?cmd=branchmap HTTP/1.1. +Accept-Encoding: identity. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). +. + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=1tiz6zf7ui54e1j3d4vouxig5m;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 06:16:50 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 48. +Server: Jetty(7.6.21.v20160908). + +default c0ceccb3b2f0f5c977ff32b9337519e5f37942c2 + +GET /scm/hg/hgtest?cmd=listkeys HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: namespace=bookmarks. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=1augu4tc71xax1dit20dtxzkez;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 06:16:50 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 0. +Server: Jetty(7.6.21.v20160908). + +POST /scm/hg/hgtest?cmd=unbundle HTTP/1.1. +Accept-Encoding: identity. +content-type: application/mercurial-0.1. +vary: X-HgArg-1. +x-hgarg-1: heads=686173686564+95373ca7cd5371cb6c49bb755ee451d9ec585845. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +content-length: 746. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HG10GZx...]H.Q...z..r.,.Y..Bw.~..c.Z&...hf.:......e.XK.X,... +,2.E1.B+...(.B"."*..z1.*......M...........93..k|..I..<...h..J_.L.9>.h..@.....op..^.....#....;.*..W....T@....!..dY....jT..A0O6.}..S.2..JPU.O6...aa...rY.VOf9.....7Ukj.&..<...z...j......%}..Jc.8c....k.."9.&".I.P.\..$.At......0..1..g.2.)<..$.. E..dn#....#.Y$3...n...5....J.e.......SNHN.q.MD..4..."I..`PF..?GH1..F..uES..Rl$47.....a........D.1...87.k.t..D..O_.3..6'cN.w.M..|@E.).X!.h*....U.B.X.....h..$.`4... +-..O.:./..oWN.....3...x.L......_[..../..k.R$.x.2..kkv.\2R....4...@.2...1Q..T +..(..m....s.Uo.......{.d.....Y....TYO...S.Pl`a5. ."N$.@...b...qJ.l.).n...1..F.Zy.....&>v;.q.....Jy..X.?.;....>U..|.....d.Y.*.q...NR.3...h.T..x..,.]...p{.^S.S...~..`..q.\j{.oCI.............K.....l9n.s...... + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=1e4fnqpncil9z1f7a2pya26nt7;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 06:16:50 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 102. +Server: Jetty(7.6.21.v20160908). + +1 +adding changesets +adding manifests +adding file changes +added 4 changesets with 2 changes to 2 files + +GET /scm/hg/hgtest?cmd=listkeys HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: namespace=phases. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=f9hvrjssniym1qe33q0u8r2m8;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 06:16:50 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 101. +Server: Jetty(7.6.21.v20160908). + +b5914611f84eae14543684b2721eec88b0edac12.1 +187ddf37e237c370514487a0bb1a226f11a780b3.1 +publishing.True + +POST /scm/hg/hgtest?cmd=pushkey HTTP/1.1. +Accept-Encoding: identity. +content-type: application/mercurial-0.1. +vary: X-HgArg-1. +x-hgarg-1: key=ef5993bb4abb32a0565c347844c6d939fc4f4b98&namespace=phases&new=0&old=1. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +content-length: 0. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=z5lrut6940a650sw6x9bls8a;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 06:16:50 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 2. +Server: Jetty(7.6.21.v20160908). + +1 diff --git a/docs/mercurial/push-single-changeset.md b/docs/mercurial/push-single-changeset.md new file mode 100644 index 0000000000..19b13c1dcd --- /dev/null +++ b/docs/mercurial/push-single-changeset.md @@ -0,0 +1,146 @@ +# Push single changeset + +GET /scm/hg/hgtest?cmd=capabilities HTTP/1.1. +Accept-Encoding: identity. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=18r2i2jsba46d14ncsmcjdhaem;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 06:03:35 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 130. +Server: Jetty(7.6.21.v20160908). + +lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch stream unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 + +GET /scm/hg/hgtest?cmd=batch HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: cmds=heads+%3Bknown+nodes%3Dc0ceccb3b2f0f5c977ff32b9337519e5f37942c2. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=1fw0i0c5zpy281gfgha0f26git;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 06:03:35 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 43. +Server: Jetty(7.6.21.v20160908). + +0000000000000000000000000000000000000000 +;0 + +GET /scm/hg/hgtest?cmd=listkeys HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: namespace=phases. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=dfa46uaqgf39w3jhk857oymu;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 06:03:35 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 15. +Server: Jetty(7.6.21.v20160908). + +publishing.True + +GET /scm/hg/hgtest?cmd=listkeys HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: namespace=bookmarks. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=2sk1llvrsagg33xgmwyirfpi;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 06:03:35 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 0. +Server: Jetty(7.6.21.v20160908). + +POST /scm/hg/hgtest?cmd=unbundle HTTP/1.1. +Accept-Encoding: identity. +content-type: application/mercurial-0.1. +vary: X-HgArg-1. +x-hgarg-1: heads=686173686564+6768033e216468247bd031a0a2d9876d79818f8f. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +content-length: 261. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HG10GZx.c``8w.....>|=Y..h.q.....N.......%......Z....&&&.&...YZ.&.&[$.........$.%q..&%..d&.).....%*.....Y.....9z...v\..FF...... +..F..\.z%.%\\.)).) +.P[....D..[un..L).nc..q.m*.H.l#C...eZJ..YJ.Q.qR...e.aJ.EjjJ.AZ..A.Q..E.1.T.'D..C....7s.}..4G........3.S.mL.0.....zk + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=hlucs5utn1ifnpehqmjpt593;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 06:03:35 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 102. +Server: Jetty(7.6.21.v20160908). + +1 +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files + +T 172.17.0.1:33206 -> 172.17.0.2:8080 [AP] +GET /scm/hg/hgtest?cmd=listkeys HTTP/1.1. +Accept-Encoding: identity. +vary: X-HgArg-1. +x-hgarg-1: namespace=phases. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=15xomlrxl8qja1cj47rjpqda0y;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 06:03:35 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 58. +Server: Jetty(7.6.21.v20160908). + +c0ceccb3b2f0f5c977ff32b9337519e5f37942c2.1 +publishing.True + +POST /scm/hg/hgtest?cmd=pushkey HTTP/1.1. +Accept-Encoding: identity. +content-type: application/mercurial-0.1. +vary: X-HgArg-1. +x-hgarg-1: key=c0ceccb3b2f0f5c977ff32b9337519e5f37942c2&namespace=phases&new=0&old=1. +accept: application/mercurial-0.1. +authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=. +content-length: 0. +host: localhost:8080. +user-agent: mercurial/proto-1.0 (Mercurial 4.3.1). + +HTTP/1.1 200 OK. +Set-Cookie: JSESSIONID=5zrop5v8e661ipk12tvru525;Path=/scm. +Expires: Thu, 01 Jan 1970 00:00:00 GMT. +Set-Cookie: rememberMe=deleteMe; Path=/scm; Max-Age=0; Expires=Wed, 28-Mar-2018 06:03:35 GMT. +Content-Type: application/mercurial-0.1. +Content-Length: 2. +Server: Jetty(7.6.21.v20160908). + +1 + diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgPermissionFilterTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgPermissionFilterTest.java index 01e01cf302..05250c8cf9 100644 --- a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgPermissionFilterTest.java +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgPermissionFilterTest.java @@ -39,6 +39,9 @@ import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import static org.mockito.Mockito.*; +import static sonia.scm.web.WireProtocolRequestMockFactory.CMDS_HEADS_KNOWN_NODES; +import static sonia.scm.web.WireProtocolRequestMockFactory.Namespace.*; + import org.mockito.runners.MockitoJUnitRunner; import sonia.scm.config.ScmConfiguration; import sonia.scm.repository.RepositoryProvider; @@ -51,15 +54,14 @@ import sonia.scm.repository.RepositoryProvider; @RunWith(MockitoJUnitRunner.class) public class HgPermissionFilterTest { - @Mock - private HttpServletRequest request; - @Mock private ScmConfiguration configuration; @Mock private RepositoryProvider repositoryProvider; - + + private WireProtocolRequestMockFactory wireProtocol = new WireProtocolRequestMockFactory("/scm/hg/repo"); + @InjectMocks private HgPermissionFilter filter; @@ -82,7 +84,90 @@ public class HgPermissionFilterTest { } private boolean isWriteRequest(String method) { + HttpServletRequest request = mock(HttpServletRequest.class); when(request.getMethod()).thenReturn(method); return filter.isWriteRequest(request); } -} \ No newline at end of file + + /** + * Tests {@link HgPermissionFilter#isWriteRequest(HttpServletRequest)} with a set of requests, which are used for a + * fresh clone of a repository. + */ + @Test + public void testIsWriteRequestWithClone() { + assertIsReadRequest(wireProtocol.capabilities()); + assertIsReadRequest(wireProtocol.listkeys(BOOKMARKS)); + assertIsReadRequest(wireProtocol.batch(CMDS_HEADS_KNOWN_NODES)); + assertIsReadRequest(wireProtocol.listkeys(PHASES)); + } + + /** + * Tests {@link HgPermissionFilter#isWriteRequest(HttpServletRequest)} with a set of requests, which are used for a + * push of a single changeset. + */ + @Test + public void testIsWriteRequestWithSingleChangesetPush() { + assertIsReadRequest(wireProtocol.capabilities()); + assertIsReadRequest(wireProtocol.batch(CMDS_HEADS_KNOWN_NODES.concat("c0ceccb3b2f0f5c977ff32b9337519e5f37942c2"))); + assertIsReadRequest(wireProtocol.listkeys(PHASES)); + assertIsReadRequest(wireProtocol.listkeys(BOOKMARKS)); + assertIsWriteRequest(wireProtocol.unbundle(261L, "686173686564+6768033e216468247bd031a0a2d9876d79818f8f")); + assertIsReadRequest(wireProtocol.listkeys(PHASES)); + assertIsWriteRequest(wireProtocol.pushkey("c0ceccb3b2f0f5c977ff32b9337519e5f37942c2&namespace=phases&new=0&old=1")); + } + + /** + * Tests {@link HgPermissionFilter#isWriteRequest(HttpServletRequest)} with a set of requests, which are used for a + * push to a single changeset. + */ + @Test + public void testIsWriteRequestWithMultipleChangesetsPush() { + assertIsReadRequest(wireProtocol.capabilities()); + assertIsReadRequest(wireProtocol.batch(CMDS_HEADS_KNOWN_NODES.concat("ef5993bb4abb32a0565c347844c6d939fc4f4b98"))); + assertIsReadRequest(wireProtocol.listkeys(PHASES)); + assertIsReadRequest(wireProtocol.listkeys(BOOKMARKS)); + assertIsReadRequest(wireProtocol.branchmap()); + assertIsReadRequest(wireProtocol.listkeys(BOOKMARKS)); + assertIsWriteRequest(wireProtocol.unbundle(746L, "686173686564+95373ca7cd5371cb6c49bb755ee451d9ec585845")); + assertIsReadRequest(wireProtocol.listkeys(PHASES)); + assertIsWriteRequest(wireProtocol.pushkey("ef5993bb4abb32a0565c347844c6d939fc4f4b98&namespace=phases&new=0&old=1")); + } + + /** + * Tests {@link HgPermissionFilter#isWriteRequest(HttpServletRequest)} with a set of requests, which are used for a + * push of multiple branches to a new repository. + */ + @Test + public void testIsWriteRequestWithMutlipleBranchesToNewRepositoryPush() { + assertIsReadRequest(wireProtocol.capabilities()); + assertIsReadRequest(wireProtocol.batch(CMDS_HEADS_KNOWN_NODES.concat("ef5993bb4abb32a0565c347844c6d939fc4f4b98"))); + assertIsReadRequest(wireProtocol.known("c0ceccb3b2f0f5c977ff32b9337519e5f37942c2+187ddf37e237c370514487a0bb1a226f11a780b3+b5914611f84eae14543684b2721eec88b0edac12+8b63a323606f10c86b30465570c2574eb7a3a989")); + assertIsReadRequest(wireProtocol.listkeys(PHASES)); + assertIsReadRequest(wireProtocol.listkeys(BOOKMARKS)); + assertIsWriteRequest(wireProtocol.unbundle(913L, "686173686564+6768033e216468247bd031a0a2d9876d79818f8f")); + assertIsReadRequest(wireProtocol.listkeys(PHASES)); + assertIsWriteRequest(wireProtocol.pushkey("ef5993bb4abb32a0565c347844c6d939fc4f4b98&namespace=phases&new=0&old=1")); + } + + /** + * Tests {@link HgPermissionFilter#isWriteRequest(HttpServletRequest)} with a set of requests, which are used for a + * push of a bookmark. + */ + @Test + public void testIsWriteRequestWithBookmarkPush() { + assertIsReadRequest(wireProtocol.capabilities()); + assertIsReadRequest(wireProtocol.batch(CMDS_HEADS_KNOWN_NODES.concat("ef5993bb4abb32a0565c347844c6d939fc4f4b98"))); + assertIsReadRequest(wireProtocol.listkeys(PHASES)); + assertIsReadRequest(wireProtocol.listkeys(BOOKMARKS)); + assertIsReadRequest(wireProtocol.listkeys(PHASES)); + assertIsWriteRequest(wireProtocol.pushkey("markone&namespace=bookmarks&new=ef5993bb4abb32a0565c347844c6d939fc4f4b98&old=")); + } + + private void assertIsReadRequest(HttpServletRequest request) { + assertFalse(filter.isWriteRequest(request)); + } + + private void assertIsWriteRequest(HttpServletRequest request) { + assertTrue(filter.isWriteRequest(request)); + } +} diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/WireProtocolRequestMockFactory.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/WireProtocolRequestMockFactory.java new file mode 100644 index 0000000000..3d2b6fab92 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/WireProtocolRequestMockFactory.java @@ -0,0 +1,101 @@ +package sonia.scm.web; + +import javax.servlet.http.HttpServletRequest; + +import java.util.Locale; + +import static org.mockito.Mockito.*; + +public class WireProtocolRequestMockFactory { + + public enum Namespace { + PHASES, BOOKMARKS; + } + + public static final String CMDS_HEADS_KNOWN_NODES = "heads+%3Bknown+nodes%3D"; + + private String repositoryPath; + + public WireProtocolRequestMockFactory(String repositoryPath) { + this.repositoryPath = repositoryPath; + } + + public HttpServletRequest capabilities() { + return base("GET", "?cmd=capabilities"); + } + + public HttpServletRequest listkeys(Namespace namespace) { + HttpServletRequest request = base("GET", "?cmd=capabilities"); + header(request, "vary", "X-HgArg-1"); + header(request, "x-hgarg-1", namespaceValue(namespace)); + return request; + } + + public HttpServletRequest branchmap() { + return base("GET", "?cmd=branchmap"); + } + + public HttpServletRequest batch(String... args) { + HttpServletRequest request = base("GET", "?cmd=batch"); + args(request, "cmds", args); + return request; + } + + public HttpServletRequest unbundle(long contentLength, String... heads) { + HttpServletRequest request = base("POST", "?cmd=unbundle"); + header(request, "Content-Length", String.valueOf(contentLength)); + args(request, "heads", heads); + return request; + } + + public HttpServletRequest pushkey(String... keys) { + HttpServletRequest request = base("POST", "?cmd=pushkey"); + args(request, "key", keys); + return request; + } + + public HttpServletRequest known(String... nodes) { + HttpServletRequest request = base("POST", "?cmd=pushkey"); + args(request, "nodes", nodes); + return request; + } + + private void args(HttpServletRequest request, String prefix, String[] values) { + StringBuilder vary = new StringBuilder(); + for ( int i=0; i0) { + vary.append(","); + } + vary.append("X-HgArg-" + (i+1)); + header(request, "X-HgArg-" + (i+1), prefix + "=" + values[i]); + } + header(request, "Vary", vary.toString()); + } + + private HttpServletRequest base(String method, String queryStringValue) { + HttpServletRequest request = mock(HttpServletRequest.class); + + when(request.getRequestURI()).thenReturn(repositoryPath); + when(request.getMethod()).thenReturn(method); + + queryString(request, queryStringValue); + + header(request, "Accept", "application/mercurial-0.1"); + header(request, "Accept-Encoding", "identity"); + header(request, "User-Agent", "mercurial/proto-1.0 (Mercurial 4.3.1)"); + return request; + } + + private void queryString(HttpServletRequest request, String queryString) { + when(request.getQueryString()).thenReturn(queryString); + } + + private void header(HttpServletRequest request, String header, String value) { + when(request.getHeader(header)).thenReturn(value); + } + + private String namespaceValue(Namespace namespace) { + return "namespace=" + namespace.toString().toLowerCase(Locale.ENGLISH); + } + +} From 3a9bc6828da2fd8ba30787cc1f10234350062e76 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 29 Mar 2018 19:58:52 +0200 Subject: [PATCH 28/78] use code blocks for request and response --- docs/mercurial/clone-empty.md | 2 ++ docs/mercurial/push-bookmark.md | 2 ++ docs/mercurial/push-multiple-branches-to-new.md | 2 ++ docs/mercurial/push-multiple-branches.md | 2 ++ docs/mercurial/push-single-changeset.md | 3 ++- 5 files changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/mercurial/clone-empty.md b/docs/mercurial/clone-empty.md index 810a297806..44a81de20c 100644 --- a/docs/mercurial/clone-empty.md +++ b/docs/mercurial/clone-empty.md @@ -1,5 +1,6 @@ # Clone empty repository +```http GET /scm/hg/hgtest?cmd=capabilities HTTP/1.1. Accept-Encoding: identity. accept: application/mercurial-0.1. @@ -72,3 +73,4 @@ Content-Length: 15. Server: Jetty(7.6.21.v20160908). . publishing.True +``` diff --git a/docs/mercurial/push-bookmark.md b/docs/mercurial/push-bookmark.md index 110bd40cd5..9ed591f9f4 100644 --- a/docs/mercurial/push-bookmark.md +++ b/docs/mercurial/push-bookmark.md @@ -1,5 +1,6 @@ # Push bookmark +```http GET /scm/hg/hgtest?cmd=capabilities HTTP/1.1. Accept-Encoding: identity. accept: application/mercurial-0.1. @@ -113,3 +114,4 @@ Content-Length: 2. Server: Jetty(7.6.21.v20160908). . 1 +``` diff --git a/docs/mercurial/push-multiple-branches-to-new.md b/docs/mercurial/push-multiple-branches-to-new.md index 56c3a4504a..734c479fef 100644 --- a/docs/mercurial/push-multiple-branches-to-new.md +++ b/docs/mercurial/push-multiple-branches-to-new.md @@ -1,5 +1,6 @@ # Push multiple branches to new repository +```http GET /scm/hg/hgtest?cmd=capabilities HTTP/1.1. Accept-Encoding: identity. accept: application/mercurial-0.1. @@ -163,3 +164,4 @@ Content-Length: 2. Server: Jetty(7.6.21.v20160908). . 1 +``` diff --git a/docs/mercurial/push-multiple-branches.md b/docs/mercurial/push-multiple-branches.md index 7d38542fde..5827cb0ceb 100644 --- a/docs/mercurial/push-multiple-branches.md +++ b/docs/mercurial/push-multiple-branches.md @@ -1,5 +1,6 @@ # Push multiple branches +```http GET /scm/hg/hgtest?cmd=capabilities HTTP/1.1. Accept-Encoding: identity. accept: application/mercurial-0.1. @@ -179,3 +180,4 @@ Content-Length: 2. Server: Jetty(7.6.21.v20160908). 1 +``` diff --git a/docs/mercurial/push-single-changeset.md b/docs/mercurial/push-single-changeset.md index 19b13c1dcd..499b4c21c3 100644 --- a/docs/mercurial/push-single-changeset.md +++ b/docs/mercurial/push-single-changeset.md @@ -1,5 +1,6 @@ # Push single changeset +```http GET /scm/hg/hgtest?cmd=capabilities HTTP/1.1. Accept-Encoding: identity. accept: application/mercurial-0.1. @@ -143,4 +144,4 @@ Content-Length: 2. Server: Jetty(7.6.21.v20160908). 1 - +``` From 8aaa67cd6aff0d1f57fbafae316f5c8bf7ec7be3 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 29 Mar 2018 20:26:56 +0200 Subject: [PATCH 29/78] #970 inspect mercurial commands in order to detect write requests The HgPermissionFilter will now inspect the used mercurial command, of all requests which are using a read method like GET, HEAD, OPTIONS or TRACE and tread every one as write request, expect: - no command was specified with the request (this is required for the hgweb ui) - the command in the query string was found in the list of read commands - if query string contains the batch command, then all commands specified in X-HgArg headers must be in the list of read commands This change is required, in order to fix CVE-2018-1000132 for SCM-Manager. --- .../sonia/scm/web/HgPermissionFilter.java | 9 +- .../main/java/sonia/scm/web/WireProtocol.java | 192 ++++++++++++++++++ .../sonia/scm/web/HgPermissionFilterTest.java | 30 ++- .../web/WireProtocolRequestMockFactory.java | 31 ++- .../java/sonia/scm/web/WireProtocolTest.java | 162 +++++++++++++++ 5 files changed, 403 insertions(+), 21 deletions(-) create mode 100644 scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/WireProtocol.java create mode 100644 scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/WireProtocolTest.java diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java index 6700ae3b8d..01fb21885e 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java @@ -51,13 +51,13 @@ import javax.servlet.http.HttpServletRequest; /** * Permission filter for mercurial repositories. - * + * * @author Sebastian Sdorra */ @Singleton public class HgPermissionFilter extends ProviderPermissionFilter { - + private static final Set READ_METHODS = ImmutableSet.of("GET", "HEAD", "OPTIONS", "TRACE"); /** @@ -78,6 +78,9 @@ public class HgPermissionFilter extends ProviderPermissionFilter @Override protected boolean isWriteRequest(HttpServletRequest request) { - return !READ_METHODS.contains(request.getMethod()); + if (READ_METHODS.contains(request.getMethod())) { + return WireProtocol.isWriteRequest(request); + } + return true; } } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/WireProtocol.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/WireProtocol.java new file mode 100644 index 0000000000..bab3083445 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/WireProtocol.java @@ -0,0 +1,192 @@ +/** + * Copyright (c) 2018, 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; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import com.google.common.collect.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import sonia.scm.util.HttpUtil; + +import javax.servlet.http.HttpServletRequest; +import java.util.*; + +/** + * WireProtocol provides methods for handling the mercurial wire protocol. + * + * @see Mercurial Wire Protocol + */ +public final class WireProtocol { + + private static final Logger LOG = LoggerFactory.getLogger(WireProtocol.class); + + private static final Set READ_COMMANDS = ImmutableSet.of( + "batch", "between", "branchmap", "branches", "capabilities", "changegroup", "changegroupsubset", "clonebundles", + "getbundle", "heads", "hello", "listkeys", "lookup", "known", "stream_out", + // could not find lheads in the wireprotocol description but mercurial 4.5.2 uses it for clone + "lheads" + ); + + private static final Set WRITE_COMMANDS = ImmutableSet.of( + "pushkey", "unbundle" + ); + + private WireProtocol() { + } + + /** + * Returns {@code true} if the request is a write request. The method will always return {@code true}, expect for the + * following cases: + * + * - no command was specified with the request (is required for the hgweb ui) + * - the command in the query string was found in the list of read request + * - if query string contains the batch command, then all commands specified in X-HgArg headers must be + * in the list of read request + * + * @param request http request + * + * @return {@code true} for write requests. + */ + public static boolean isWriteRequest(HttpServletRequest request) { + List commands = commandsOf(request); + boolean write = isWriteRequest(commands); + LOG.trace("mercurial request {} is write: {}", commands, write); + return write; + } + + @VisibleForTesting + static boolean isWriteRequest(List commands) { + return !READ_COMMANDS.containsAll(commands); + } + + @VisibleForTesting + static List commandsOf(HttpServletRequest request) { + List listOfCmds = Lists.newArrayList(); + String cmd = getCommandFromQueryString(request); + if (cmd != null) { + listOfCmds.add(cmd); + if (isBatchCommand(cmd)) { + parseHgArgHeaders(request, listOfCmds); + } + } + return Collections.unmodifiableList(listOfCmds); + } + + private static void parseHgArgHeaders(HttpServletRequest request, List listOfCmds) { + Enumeration headerNames = request.getHeaderNames(); + while (headerNames.hasMoreElements()) { + String header = (String) headerNames.nextElement(); + parseHgArgHeader(request, listOfCmds, header); + } + } + + private static void parseHgArgHeader(HttpServletRequest request, List listOfCmds, String header) { + if (isHgArgHeader(header)) { + String value = getHeaderDecoded(request, header); + if (isHgArgCommandHeader(value)) { + parseHgCommandHeader(listOfCmds, value); + } + } + } + + private static void parseHgCommandHeader(List listOfCmds, String value) { + String[] cmds = value.substring(5).split(";"); + for (String cmd : cmds ) { + String normalizedCmd = normalize(cmd); + int index = normalizedCmd.indexOf(' '); + if (index > 0) { + listOfCmds.add(normalizedCmd.substring(0, index)); + } else { + listOfCmds.add(normalizedCmd); + } + } + } + + private static String normalize(String cmd) { + return cmd.trim().toLowerCase(Locale.ENGLISH); + } + + private static boolean isHgArgCommandHeader(String value) { + return value.startsWith("cmds="); + } + + private static String getHeaderDecoded(HttpServletRequest request, String header) { + return HttpUtil.decode(Strings.nullToEmpty(request.getHeader(header))); + } + + private static boolean isHgArgHeader(String header) { + return header.toLowerCase(Locale.ENGLISH).startsWith("x-hgarg-"); + } + + private static boolean isBatchCommand(String cmd) { + return "batch".equalsIgnoreCase(cmd); + } + + private static String getCommandFromQueryString(HttpServletRequest request) { + // we can't use getParameter, because this would inspect the body for form parameters as well + Multimap queryParameterMap = createQueryParameterMap(request); + + Collection cmd = queryParameterMap.get("cmd"); + Preconditions.checkArgument(cmd.size() <= 1, "found more than one cmd query parameter"); + Iterator iterator = cmd.iterator(); + + String command = null; + if (iterator.hasNext()) { + command = iterator.next(); + } + return command; + } + + private static Multimap createQueryParameterMap(HttpServletRequest request) { + Multimap parameterMap = HashMultimap.create(); + + String queryString = request.getQueryString(); + if (!Strings.isNullOrEmpty(queryString)) { + + String[] parameters = queryString.split("&"); + for (String parameter : parameters) { + int index = parameter.indexOf('='); + if (index > 0) { + parameterMap.put(parameter.substring(0, index), parameter.substring(index + 1)); + } else { + parameterMap.put(parameter, "true"); + } + } + + } + + return parameterMap; + } +} diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgPermissionFilterTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgPermissionFilterTest.java index 05250c8cf9..8319134078 100644 --- a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgPermissionFilterTest.java +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgPermissionFilterTest.java @@ -1,10 +1,10 @@ /** * Copyright (c) 2014, 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, @@ -13,7 +13,7 @@ * 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 @@ -24,9 +24,9 @@ * 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; @@ -48,7 +48,7 @@ import sonia.scm.repository.RepositoryProvider; /** * Unit tests for {@link HgPermissionFilter}. - * + * * @author Sebastian Sdorra */ @RunWith(MockitoJUnitRunner.class) @@ -56,7 +56,7 @@ public class HgPermissionFilterTest { @Mock private ScmConfiguration configuration; - + @Mock private RepositoryProvider repositoryProvider; @@ -64,7 +64,7 @@ public class HgPermissionFilterTest { @InjectMocks private HgPermissionFilter filter; - + /** * Tests {@link HgPermissionFilter#isWriteRequest(HttpServletRequest)}. */ @@ -75,7 +75,7 @@ public class HgPermissionFilterTest { assertFalse(isWriteRequest("HEAD")); assertFalse(isWriteRequest("TRACE")); assertFalse(isWriteRequest("OPTIONS")); - + // write methods assertTrue(isWriteRequest("POST")); assertTrue(isWriteRequest("PUT")); @@ -85,6 +85,7 @@ public class HgPermissionFilterTest { private boolean isWriteRequest(String method) { HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getQueryString()).thenReturn("cmd=capabilities"); when(request.getMethod()).thenReturn(method); return filter.isWriteRequest(request); } @@ -163,6 +164,17 @@ public class HgPermissionFilterTest { assertIsWriteRequest(wireProtocol.pushkey("markone&namespace=bookmarks&new=ef5993bb4abb32a0565c347844c6d939fc4f4b98&old=")); } + /** + * Tests {@link HgPermissionFilter#isWriteRequest(HttpServletRequest)} with a write request hidden in a batch GET + * request. + * + * @see Issue #970 + */ + @Test + public void testIsWriteRequestWithBookmarkPushInABatch() { + assertIsWriteRequest(wireProtocol.batch("pushkey key=markthree,namespace=bookmarks,new=187ddf37e237c370514487a0bb1a226f11a780b3,old=")); + } + private void assertIsReadRequest(HttpServletRequest request) { assertFalse(filter.isWriteRequest(request)); } diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/WireProtocolRequestMockFactory.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/WireProtocolRequestMockFactory.java index 3d2b6fab92..d1f5124b3a 100644 --- a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/WireProtocolRequestMockFactory.java +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/WireProtocolRequestMockFactory.java @@ -1,7 +1,11 @@ package sonia.scm.web; +import com.google.common.collect.Lists; + import javax.servlet.http.HttpServletRequest; +import java.util.Collections; +import java.util.List; import java.util.Locale; import static org.mockito.Mockito.*; @@ -21,55 +25,64 @@ public class WireProtocolRequestMockFactory { } public HttpServletRequest capabilities() { - return base("GET", "?cmd=capabilities"); + return base("GET", "cmd=capabilities"); } public HttpServletRequest listkeys(Namespace namespace) { - HttpServletRequest request = base("GET", "?cmd=capabilities"); + HttpServletRequest request = base("GET", "cmd=capabilities"); header(request, "vary", "X-HgArg-1"); header(request, "x-hgarg-1", namespaceValue(namespace)); return request; } public HttpServletRequest branchmap() { - return base("GET", "?cmd=branchmap"); + return base("GET", "cmd=branchmap"); } public HttpServletRequest batch(String... args) { - HttpServletRequest request = base("GET", "?cmd=batch"); + HttpServletRequest request = base("GET", "cmd=batch"); args(request, "cmds", args); return request; } public HttpServletRequest unbundle(long contentLength, String... heads) { - HttpServletRequest request = base("POST", "?cmd=unbundle"); + HttpServletRequest request = base("POST", "cmd=unbundle"); header(request, "Content-Length", String.valueOf(contentLength)); args(request, "heads", heads); return request; } public HttpServletRequest pushkey(String... keys) { - HttpServletRequest request = base("POST", "?cmd=pushkey"); + HttpServletRequest request = base("POST", "cmd=pushkey"); args(request, "key", keys); return request; } public HttpServletRequest known(String... nodes) { - HttpServletRequest request = base("POST", "?cmd=pushkey"); + HttpServletRequest request = base("GET", "cmd=known"); args(request, "nodes", nodes); return request; } private void args(HttpServletRequest request, String prefix, String[] values) { + List headers = Lists.newArrayList(); + StringBuilder vary = new StringBuilder(); for ( int i=0; i0) { vary.append(","); } - vary.append("X-HgArg-" + (i+1)); - header(request, "X-HgArg-" + (i+1), prefix + "=" + values[i]); + + vary.append(header); + headers.add(header); + + header(request, header, prefix + "=" + values[i]); } header(request, "Vary", vary.toString()); + + when(request.getHeaderNames()).thenReturn(Collections.enumeration(headers)); } private HttpServletRequest base(String method, String queryStringValue) { diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/WireProtocolTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/WireProtocolTest.java new file mode 100644 index 0000000000..860b6a6392 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/WireProtocolTest.java @@ -0,0 +1,162 @@ +/** + * Copyright (c) 2018, 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; + +import com.google.common.collect.Lists; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import javax.servlet.http.HttpServletRequest; + +import java.util.Collections; +import java.util.List; + +import static org.hamcrest.Matchers.contains; +import static org.junit.Assert.*; +import static org.mockito.Mockito.when; + +/** + * Unit tests for {@link WireProtocol}. + */ +@RunWith(MockitoJUnitRunner.class) +public class WireProtocolTest { + + @Mock + private HttpServletRequest request; + + @Test + public void testIsWriteRequestOnPost() { + assertIsWriteRequest("capabilities", "unbundle"); + } + + @Test + public void testIsWriteRequest() { + assertIsWriteRequest("unbundle"); + assertIsWriteRequest("capabilities", "unbundle"); + assertIsWriteRequest("capabilities", "postkeys"); + assertIsReadRequest(); + assertIsReadRequest("capabilities"); + assertIsReadRequest("capabilities", "branches", "branchmap"); + } + + private void assertIsWriteRequest(String... commands) { + List cmdList = Lists.newArrayList(commands); + assertTrue(WireProtocol.isWriteRequest(cmdList)); + } + + private void assertIsReadRequest(String... commands) { + List cmdList = Lists.newArrayList(commands); + assertFalse(WireProtocol.isWriteRequest(cmdList)); + } + + @Test + public void testGetCommandsOf() { + expectQueryCommand("capabilities", "cmd=capabilities"); + expectQueryCommand("unbundle", "cmd=unbundle"); + expectQueryCommand("unbundle", "prefix=stuff&cmd=unbundle"); + expectQueryCommand("unbundle", "cmd=unbundle&suffix=stuff"); + expectQueryCommand("unbundle", "prefix=stuff&cmd=unbundle&suffix=stuff"); + expectQueryCommand("unbundle", "bool=&cmd=unbundle"); + expectQueryCommand("unbundle", "bool&cmd=unbundle"); + expectQueryCommand("unbundle", "prefix=stu==ff&cmd=unbundle"); + } + + @Test + public void testGetCommandsOfWithBatch() { + prepareBatch("cmds=heads ;known nodes,ef5993bb4abb32a0565c347844c6d939fc4f4b98"); + List commands = WireProtocol.commandsOf(request); + assertThat(commands, contains("batch", "heads", "known")); + } + + @Test + public void testGetCommandsOfWithBatchEncoded() { + prepareBatch("cmds=heads+%3Bknown+nodes%3Def5993bb4abb32a0565c347844c6d939fc4f4b98"); + List commands = WireProtocol.commandsOf(request); + assertThat(commands, contains("batch", "heads", "known")); + } + + @Test + public void testGetCommandsOfWithBatchAndMutlipleLines() { + prepareBatch( + "cmds=heads+%3Bknown+nodes%3Def5993bb4abb32a0565c347844c6d939fc4f4b98", + "cmds=unbundle; postkeys", + "cmds= branchmap p1=r2,p2=r4; listkeys" + ); + List commands = WireProtocol.commandsOf(request); + assertThat(commands, contains("batch", "heads", "known", "unbundle", "postkeys", "branchmap", "listkeys")); + } + + private void prepareBatch(String... args) { + when(request.getQueryString()).thenReturn("cmd=batch"); + List headers = Lists.newArrayList(); + for (int i=0; i commands = WireProtocol.commandsOf(request); + assertEquals(1, commands.size()); + assertTrue(commands.contains(expected)); + } + +} From a34acd8ed469f2977615139874e7fa2f029ff226 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 29 Mar 2018 22:14:28 +0200 Subject: [PATCH 30/78] #970 added option to enable the experimental httppostargs protocol of mercurial --- .../java/sonia/scm/repository/HgConfig.java | 10 +++++++++ .../main/java/sonia/scm/web/HgCGIServlet.java | 8 ++++++- .../src/main/resources/sonia/scm/hg.config.js | 21 +++++++++++++------ .../main/resources/sonia/scm/python/hgweb.py | 17 +++++++++++---- 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgConfig.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgConfig.java index ed336ff203..2eb060cb66 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgConfig.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgConfig.java @@ -127,6 +127,10 @@ public class HgConfig extends SimpleRepositoryConfig return disableHookSSLValidation; } + public boolean isEnableHttpPostArgs() { + return enableHttpPostArgs; + } + /** * Method description * @@ -197,6 +201,10 @@ public class HgConfig extends SimpleRepositoryConfig this.showRevisionInId = showRevisionInId; } + public void setEnableHttpPostArgs(boolean enableHttpPostArgs) { + this.enableHttpPostArgs = enableHttpPostArgs; + } + /** * Method description * @@ -232,6 +240,8 @@ public class HgConfig extends SimpleRepositoryConfig /** Field description */ private boolean showRevisionInId = false; + private boolean enableHttpPostArgs = false; + /** * disable validation of ssl certificates for mercurial hook * @see Issue 959 diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java index f6023dd0ae..1fb78161e0 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java @@ -87,6 +87,8 @@ public class HgCGIServlet extends HttpServlet /** Field description */ public static final String ENV_REPOSITORY_PATH = "SCM_REPOSITORY_PATH"; + private static final String ENV_HTTP_POST_ARGS = "SCM_HTTP_POST_ARGS"; + /** Field description */ public static final String ENV_SESSION_PREFIX = "SCM_"; @@ -278,11 +280,15 @@ public class HgCGIServlet extends HttpServlet environment.put(ENV_PYTHON_HTTPS_VERIFY, "0"); } + // enable experimental httppostargs protocol of mercurial + // Issue 970: https://goo.gl/poascp + environment.put(ENV_HTTP_POST_ARGS, String.valueOf(handler.getConfig().isEnableHttpPostArgs())); + //J- HgEnvironment.prepareEnvironment( environment, handler, - hookManager, + hookManager, request ); //J+ diff --git a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg.config.js b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg.config.js index 58a73ea8e9..f7b4f33240 100644 --- a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg.config.js +++ b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg.config.js @@ -48,6 +48,7 @@ Sonia.hg.ConfigPanel = Ext.extend(Sonia.config.ConfigForm, { showRevisionInIdText: 'Show Revision', // TODO: i18n disableHookSSLValidationText: 'Disable SSL Validation on Hooks', + enableHttpPostArgsText: 'Enable HttpPostArgs Protocol', // helpText hgBinaryHelpText: 'Location of Mercurial binary.', @@ -63,6 +64,8 @@ Sonia.hg.ConfigPanel = Ext.extend(Sonia.config.ConfigForm, { // TODO: i18n disableHookSSLValidationHelpText: 'Disables the validation of ssl certificates for the mercurial hook, which forwards the repository changes back to scm-manager. \n\ This option should only be used, if SCM-Manager uses a self signed certificate.', + // TODO explain it + enableHttpPostArgsHelpText: 'Enables the experimental HttpPostArgs Protocol.', initComponent: function(){ @@ -115,12 +118,18 @@ Sonia.hg.ConfigPanel = Ext.extend(Sonia.config.ConfigForm, { fieldLabel: this.disableHookSSLValidationText, inputValue: 'true', helpText: this.disableHookSSLValidationHelpText + },{ + xtype: 'checkbox', + name: 'enableHttpPostArgs', + fieldLabel: this.enableHttpPostArgsText, + inputValue: 'true', + helpText: this.enableHttpPostArgsHelpText },{ xtype: 'checkbox', name: 'disabled', fieldLabel: this.disabledText, inputValue: 'true', - helpText: this.disabledHelpText + helpText: this.disabledHelpText },{ xtype: 'button', text: this.configWizardText, @@ -260,11 +269,11 @@ Sonia.repository.typeIcons['hg'] = 'resources/images/icons/16x16/mercurial.png'; // override ChangesetViewerGrid to render changeset id's with revisions Ext.override(Sonia.repository.ChangesetViewerGrid, { - + isMercurialRepository: function(){ return this.repository.type === 'hg'; }, - + getChangesetId: function(id, record){ if ( this.isMercurialRepository() ){ var rev = Sonia.util.getProperty(record.get('properties'), 'hg.rev'); @@ -274,7 +283,7 @@ Ext.override(Sonia.repository.ChangesetViewerGrid, { } return id; }, - + getParentIds: function(id, record){ var parents = record.get('parents'); if ( this.isMercurialRepository() ){ @@ -285,7 +294,7 @@ Ext.override(Sonia.repository.ChangesetViewerGrid, { parents[0] = rev + ':' + parents[0]; } if ( parents.length > 1 ){ - rev = Sonia.util.getProperty(properties, 'hg.p2.rev'); + rev = Sonia.util.getProperty(properties, 'hg.p2.rev'); if (rev){ parents[1] = rev + ':' + parents[1]; } @@ -294,5 +303,5 @@ Ext.override(Sonia.repository.ChangesetViewerGrid, { } return parents; } - + }); diff --git a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/hgweb.py b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/hgweb.py index 66d5fadc3c..ff2869044d 100644 --- a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/hgweb.py +++ b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/hgweb.py @@ -31,12 +31,21 @@ import os -from mercurial import demandimport +from mercurial import demandimport, ui as uimod, hg from mercurial.hgweb import hgweb, wsgicgi -repositoryPath = os.environ['SCM_REPOSITORY_PATH'] - demandimport.enable() -application = hgweb(repositoryPath) +u = uimod.ui.load() + +# pass SCM_HTTP_POST_ARGS to enable experimental httppostargs protocol of mercurial +# SCM_HTTP_POST_ARGS is set by HgCGIServlet +# Issue 970: https://goo.gl/poascp +u.setconfig('experimental', 'httppostargs', os.environ['SCM_HTTP_POST_ARGS']) + +# open repository +# SCM_REPOSITORY_PATH contains the repository path and is set by HgCGIServlet +r = hg.repository(u, os.environ['SCM_REPOSITORY_PATH']) + +application = hgweb(r) wsgicgi.launch(application) From b43e406b765f6e67d828da608c8dad59e1a14f18 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 30 Mar 2018 11:20:22 +0200 Subject: [PATCH 31/78] #970 initial support of mercurials httppostargs protocol --- .../sonia/scm/web/HgPermissionFilter.java | 36 +++++++++--- .../sonia/scm/web/HgServletInputStream.java | 55 +++++++++++++++++++ .../java/sonia/scm/web/HgServletRequest.java | 31 +++++++++++ .../main/java/sonia/scm/web/WireProtocol.java | 48 ++++++++++++++-- .../sonia/scm/web/HgPermissionFilterTest.java | 48 +++++++++++++--- .../scm/web/HgServletInputStreamTest.java | 50 +++++++++++++++++ .../java/sonia/scm/web/WireProtocolTest.java | 32 ++++++++++- 7 files changed, 279 insertions(+), 21 deletions(-) create mode 100644 scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgServletInputStream.java create mode 100644 scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgServletRequest.java create mode 100644 scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgServletInputStreamTest.java diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java index 01fb21885e..dde048a746 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java @@ -38,16 +38,17 @@ package sonia.scm.web; import com.google.common.collect.ImmutableSet; import com.google.inject.Inject; import com.google.inject.Singleton; - import sonia.scm.config.ScmConfiguration; +import sonia.scm.repository.HgRepositoryHandler; import sonia.scm.repository.RepositoryProvider; import sonia.scm.web.filter.ProviderPermissionFilter; -//~--- JDK imports ------------------------------------------------------------ - -import java.util.Set; - +import javax.servlet.FilterChain; +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Set; /** * Permission filter for mercurial repositories. @@ -60,6 +61,8 @@ public class HgPermissionFilter extends ProviderPermissionFilter private static final Set READ_METHODS = ImmutableSet.of("GET", "HEAD", "OPTIONS", "TRACE"); + private final HgRepositoryHandler repositoryHandler; + /** * Constructs a new instance. * @@ -67,17 +70,36 @@ public class HgPermissionFilter extends ProviderPermissionFilter * @param repositoryProvider repository provider */ @Inject - public HgPermissionFilter(ScmConfiguration configuration, - RepositoryProvider repositoryProvider) + public HgPermissionFilter(ScmConfiguration configuration, RepositoryProvider repositoryProvider, HgRepositoryHandler repositoryHandler) { super(configuration, repositoryProvider); + this.repositoryHandler = repositoryHandler; } //~--- get methods ---------------------------------------------------------- + + @Override + protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { + HgServletRequest hgRequest = new HgServletRequest(request); + super.doFilter(hgRequest, response, chain); + // TODO closing stream in case of fire? + } + @Override protected boolean isWriteRequest(HttpServletRequest request) { + if (repositoryHandler.getConfig().isEnableHttpPostArgs()) { + return isHttpPostArgsWriteRequest(request); + } + return isDefaultWriteRequest(request); + } + + private boolean isHttpPostArgsWriteRequest(HttpServletRequest request) { + return WireProtocol.isWriteRequest(request); + } + + private boolean isDefaultWriteRequest(HttpServletRequest request) { if (READ_METHODS.contains(request.getMethod())) { return WireProtocol.isWriteRequest(request); } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgServletInputStream.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgServletInputStream.java new file mode 100644 index 0000000000..b0b2f8ef0d --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgServletInputStream.java @@ -0,0 +1,55 @@ +package sonia.scm.web; + +import com.google.common.base.Preconditions; + +import javax.servlet.ServletInputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; + +/** + * HgServletInputStream is a wrapper around the original {@link ServletInputStream} and provides some extra + * functionality to support the mercurial client. + */ +public class HgServletInputStream extends ServletInputStream { + + private final ServletInputStream original; + private ByteArrayInputStream captured; + + HgServletInputStream(ServletInputStream original) { + this.original = original; + } + + /** + * Reads the given amount of bytes from the stream and captures them, if the {@link #read()} methods is called the + * captured bytes are returned before the rest of the stream. + * + * @param size amount of bytes to read + * + * @return byte array + * + * @throws IOException if the method is called twice + */ + public byte[] readAndCapture(int size) throws IOException { + Preconditions.checkState(captured == null, "readAndCapture can only be called once per request"); + + // TODO should we enforce a limit? to prevent OOM? + byte[] bytes = new byte[size]; + original.read(bytes); + captured = new ByteArrayInputStream(bytes); + + return bytes; + } + + @Override + public int read() throws IOException { + if (captured != null && captured.available() > 0) { + return captured.read(); + } + return original.read(); + } + + @Override + public void close() throws IOException { + original.close(); + } +} diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgServletRequest.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgServletRequest.java new file mode 100644 index 0000000000..80251c140a --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgServletRequest.java @@ -0,0 +1,31 @@ +package sonia.scm.web; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.IOException; + +/** + * {@link HttpServletRequestWrapper} which adds some functionality in order to support the mercurial client. + */ +public final class HgServletRequest extends HttpServletRequestWrapper { + + private HgServletInputStream hgServletInputStream; + + /** + * Constructs a request object wrapping the given request. + * + * @param request + * @throws IllegalArgumentException if the request is null + */ + public HgServletRequest(HttpServletRequest request) { + super(request); + } + + @Override + public HgServletInputStream getInputStream() throws IOException { + if (hgServletInputStream == null) { + hgServletInputStream = new HgServletInputStream(super.getInputStream()); + } + return hgServletInputStream; + } +} diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/WireProtocol.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/WireProtocol.java index bab3083445..8a411ead64 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/WireProtocol.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/WireProtocol.java @@ -33,14 +33,17 @@ package sonia.scm.web; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Charsets; import com.google.common.base.Preconditions; import com.google.common.base.Strings; +import com.google.common.base.Throwables; import com.google.common.collect.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.util.HttpUtil; import javax.servlet.http.HttpServletRequest; +import java.io.IOException; import java.util.*; /** @@ -73,7 +76,10 @@ public final class WireProtocol { * - no command was specified with the request (is required for the hgweb ui) * - the command in the query string was found in the list of read request * - if query string contains the batch command, then all commands specified in X-HgArg headers must be - * in the list of read request + * in the list of read requests + * - in case of enabled HttpPostArgs protocol and query string container the batch command, the header X-HgArgs-Post + * is read and the commands which are specified in the body from 0 to the value of X-HgArgs-Post must be in the list + * of read requests * * @param request http request * @@ -94,16 +100,40 @@ public final class WireProtocol { @VisibleForTesting static List commandsOf(HttpServletRequest request) { List listOfCmds = Lists.newArrayList(); + String cmd = getCommandFromQueryString(request); if (cmd != null) { listOfCmds.add(cmd); if (isBatchCommand(cmd)) { parseHgArgHeaders(request, listOfCmds); + handleHttpPostArgs(request, listOfCmds); } } return Collections.unmodifiableList(listOfCmds); } + private static void handleHttpPostArgs(HttpServletRequest request, List listOfCmds) { + int hgArgsPostSize = request.getIntHeader("X-HgArgs-Post"); + if (hgArgsPostSize > 0) { + + if (request instanceof HgServletRequest) { + HgServletRequest hgRequest = (HgServletRequest) request; + + try { + byte[] bytes = hgRequest.getInputStream().readAndCapture(hgArgsPostSize); + String hgArgs = new String(bytes, Charsets.US_ASCII); + String decoded = decodeValue(hgArgs); + parseHgCommandHeader(listOfCmds, decoded); + } catch (IOException ex) { + throw Throwables.propagate(ex); + } + } else { + throw new IllegalArgumentException("could not process the httppostargs protocol without HgServletRequest"); + } + + } + } + private static void parseHgArgHeaders(HttpServletRequest request, List listOfCmds) { Enumeration headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { @@ -115,9 +145,13 @@ public final class WireProtocol { private static void parseHgArgHeader(HttpServletRequest request, List listOfCmds, String header) { if (isHgArgHeader(header)) { String value = getHeaderDecoded(request, header); - if (isHgArgCommandHeader(value)) { - parseHgCommandHeader(listOfCmds, value); - } + parseHgArgValue(listOfCmds, value); + } + } + + private static void parseHgArgValue(List listOfCmds, String value) { + if (isHgArgCommandHeader(value)) { + parseHgCommandHeader(listOfCmds, value); } } @@ -143,7 +177,11 @@ public final class WireProtocol { } private static String getHeaderDecoded(HttpServletRequest request, String header) { - return HttpUtil.decode(Strings.nullToEmpty(request.getHeader(header))); + return decodeValue(request.getHeader(header)); + } + + private static String decodeValue(String value) { + return HttpUtil.decode(Strings.nullToEmpty(value)); } private static boolean isHgArgHeader(String header) { diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgPermissionFilterTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgPermissionFilterTest.java index 8319134078..f8aefb95d1 100644 --- a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgPermissionFilterTest.java +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgPermissionFilterTest.java @@ -31,21 +31,27 @@ package sonia.scm.web; -import javax.servlet.http.HttpServletRequest; +import org.junit.Before; import org.junit.Test; -import static org.junit.Assert.*; - import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import static org.mockito.Mockito.*; -import static sonia.scm.web.WireProtocolRequestMockFactory.CMDS_HEADS_KNOWN_NODES; -import static sonia.scm.web.WireProtocolRequestMockFactory.Namespace.*; - import org.mockito.runners.MockitoJUnitRunner; import sonia.scm.config.ScmConfiguration; +import sonia.scm.repository.HgConfig; +import sonia.scm.repository.HgRepositoryHandler; import sonia.scm.repository.RepositoryProvider; +import javax.servlet.http.HttpServletRequest; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static sonia.scm.web.WireProtocolRequestMockFactory.CMDS_HEADS_KNOWN_NODES; +import static sonia.scm.web.WireProtocolRequestMockFactory.Namespace.BOOKMARKS; +import static sonia.scm.web.WireProtocolRequestMockFactory.Namespace.PHASES; + /** * Unit tests for {@link HgPermissionFilter}. * @@ -60,11 +66,19 @@ public class HgPermissionFilterTest { @Mock private RepositoryProvider repositoryProvider; + @Mock + private HgRepositoryHandler hgRepositoryHandler; + private WireProtocolRequestMockFactory wireProtocol = new WireProtocolRequestMockFactory("/scm/hg/repo"); @InjectMocks private HgPermissionFilter filter; + @Before + public void setUp() { + when(hgRepositoryHandler.getConfig()).thenReturn(new HgConfig()); + } + /** * Tests {@link HgPermissionFilter#isWriteRequest(HttpServletRequest)}. */ @@ -83,9 +97,27 @@ public class HgPermissionFilterTest { assertTrue(isWriteRequest("KA")); } + /** + * Tests {@link HgPermissionFilter#isWriteRequest(HttpServletRequest)} with enabled httppostargs option. + */ + @Test + public void testIsWriteRequestWithEnabledHttpPostArgs() { + HgConfig config = new HgConfig(); + config.setEnableHttpPostArgs(true); + when(hgRepositoryHandler.getConfig()).thenReturn(config); + + assertFalse(isWriteRequest("POST")); + assertFalse(isWriteRequest("POST", "heads")); + assertTrue(isWriteRequest("POST", "unbundle")); + } + private boolean isWriteRequest(String method) { + return isWriteRequest(method, "capabilities"); + } + + private boolean isWriteRequest(String method, String command) { HttpServletRequest request = mock(HttpServletRequest.class); - when(request.getQueryString()).thenReturn("cmd=capabilities"); + when(request.getQueryString()).thenReturn("cmd=" + command); when(request.getMethod()).thenReturn(method); return filter.isWriteRequest(request); } diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgServletInputStreamTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgServletInputStreamTest.java new file mode 100644 index 0000000000..51b0a050fc --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgServletInputStreamTest.java @@ -0,0 +1,50 @@ +package sonia.scm.web; + +import com.google.common.base.Charsets; +import com.google.common.io.ByteStreams; +import org.junit.Test; + +import javax.servlet.ServletInputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + +public class HgServletInputStreamTest { + + @Test + public void testReadAndCapture() throws IOException { + SampleServletInputStream original = new SampleServletInputStream("trillian.mcmillian@hitchhiker.com"); + HgServletInputStream hgServletInputStream = new HgServletInputStream(original); + + byte[] prefix = hgServletInputStream.readAndCapture(8); + assertEquals("trillian", new String(prefix, Charsets.US_ASCII)); + + byte[] wholeBytes = ByteStreams.toByteArray(hgServletInputStream); + assertEquals("trillian.mcmillian@hitchhiker.com", new String(wholeBytes, Charsets.US_ASCII)); + } + + @Test(expected = IllegalStateException.class) + public void testReadAndCaptureCalledTwice() throws IOException { + SampleServletInputStream original = new SampleServletInputStream("trillian.mcmillian@hitchhiker.com"); + HgServletInputStream hgServletInputStream = new HgServletInputStream(original); + + hgServletInputStream.readAndCapture(1); + hgServletInputStream.readAndCapture(1); + } + + private static class SampleServletInputStream extends ServletInputStream { + + private ByteArrayInputStream input; + + private SampleServletInputStream(String data) { + input = new ByteArrayInputStream(data.getBytes()); + } + + @Override + public int read() { + return input.read(); + } + } + +} diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/WireProtocolTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/WireProtocolTest.java index 860b6a6392..519dadfd6c 100644 --- a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/WireProtocolTest.java +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/WireProtocolTest.java @@ -32,14 +32,17 @@ package sonia.scm.web; +import com.google.common.base.Charsets; import com.google.common.collect.Lists; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; - +import java.io.ByteArrayInputStream; +import java.io.IOException; import java.util.Collections; import java.util.List; @@ -93,6 +96,18 @@ public class WireProtocolTest { expectQueryCommand("unbundle", "prefix=stu==ff&cmd=unbundle"); } + @Test + public void testGetCommandsOfWithHgArgsPost() throws IOException { + when(request.getMethod()).thenReturn("POST"); + when(request.getQueryString()).thenReturn("cmd=batch"); + when(request.getIntHeader("X-HgArgs-Post")).thenReturn(29); + when(request.getHeaderNames()).thenReturn(Collections.enumeration(Lists.newArrayList("X-HgArgs-Post"))); + when(request.getInputStream()).thenReturn(new BufferedServletInputStream("cmds=lheads+%3Bknown+nodes%3D")); + + List commands = WireProtocol.commandsOf(new HgServletRequest(request)); + assertThat(commands, contains("batch", "lheads", "known")); + } + @Test public void testGetCommandsOfWithBatch() { prepareBatch("cmds=heads ;known nodes,ef5993bb4abb32a0565c347844c6d939fc4f4b98"); @@ -159,4 +174,19 @@ public class WireProtocolTest { assertTrue(commands.contains(expected)); } + private static class BufferedServletInputStream extends ServletInputStream { + + private ByteArrayInputStream input; + + BufferedServletInputStream(String content) { + this.input = new ByteArrayInputStream(content.getBytes(Charsets.US_ASCII)); + } + + @Override + public int read() { + return input.read(); + } + + } + } From 8047d360285248122cb8dbb5e13d19e617859b6d Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Tue, 3 Apr 2018 11:00:16 +0200 Subject: [PATCH 32/78] #970 use iso-8859-1 for http post args instead of us-ascii --- .../main/java/sonia/scm/web/WireProtocol.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/WireProtocol.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/WireProtocol.java index 8a411ead64..fb84692805 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/WireProtocol.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/WireProtocol.java @@ -119,14 +119,7 @@ public final class WireProtocol { if (request instanceof HgServletRequest) { HgServletRequest hgRequest = (HgServletRequest) request; - try { - byte[] bytes = hgRequest.getInputStream().readAndCapture(hgArgsPostSize); - String hgArgs = new String(bytes, Charsets.US_ASCII); - String decoded = decodeValue(hgArgs); - parseHgCommandHeader(listOfCmds, decoded); - } catch (IOException ex) { - throw Throwables.propagate(ex); - } + parseHttpPostArgs(listOfCmds, hgArgsPostSize, hgRequest); } else { throw new IllegalArgumentException("could not process the httppostargs protocol without HgServletRequest"); } @@ -134,6 +127,19 @@ public final class WireProtocol { } } + private static void parseHttpPostArgs(List listOfCmds, int hgArgsPostSize, HgServletRequest hgRequest) { + try { + byte[] bytes = hgRequest.getInputStream().readAndCapture(hgArgsPostSize); + // we use iso-8859-1 for encoding, because the post args are normally http headers which are using iso-8859-1 + // see https://tools.ietf.org/html/rfc7230#section-3.2.4 + String hgArgs = new String(bytes, Charsets.ISO_8859_1); + String decoded = decodeValue(hgArgs); + parseHgCommandHeader(listOfCmds, decoded); + } catch (IOException ex) { + throw Throwables.propagate(ex); + } + } + private static void parseHgArgHeaders(HttpServletRequest request, List listOfCmds) { Enumeration headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { From acebd0f25e28955141a671a087deba7dd05bbcff Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Tue, 3 Apr 2018 11:14:05 +0200 Subject: [PATCH 33/78] #970 wrap requests only if http postargs is enabled --- .../sonia/scm/web/HgPermissionFilter.java | 19 ++++++++++++---- .../sonia/scm/web/HgPermissionFilterTest.java | 22 +++++++++++++++++-- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java index dde048a746..955002928c 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java @@ -35,6 +35,7 @@ package sonia.scm.web; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableSet; import com.google.inject.Inject; import com.google.inject.Singleton; @@ -81,20 +82,30 @@ public class HgPermissionFilter extends ProviderPermissionFilter @Override protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { - HgServletRequest hgRequest = new HgServletRequest(request); - super.doFilter(hgRequest, response, chain); - // TODO closing stream in case of fire? + super.doFilter(wrapRequestIfRequired(request), response, chain); + } + + @VisibleForTesting + HttpServletRequest wrapRequestIfRequired(HttpServletRequest request) { + if (isHttpPostArgsEnabled()) { + return new HgServletRequest(request); + } + return request; } @Override protected boolean isWriteRequest(HttpServletRequest request) { - if (repositoryHandler.getConfig().isEnableHttpPostArgs()) { + if (isHttpPostArgsEnabled()) { return isHttpPostArgsWriteRequest(request); } return isDefaultWriteRequest(request); } + private boolean isHttpPostArgsEnabled() { + return repositoryHandler.getConfig().isEnableHttpPostArgs(); + } + private boolean isHttpPostArgsWriteRequest(HttpServletRequest request) { return WireProtocol.isWriteRequest(request); } diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgPermissionFilterTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgPermissionFilterTest.java index f8aefb95d1..bb6692ffce 100644 --- a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgPermissionFilterTest.java +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/web/HgPermissionFilterTest.java @@ -44,8 +44,9 @@ import sonia.scm.repository.RepositoryProvider; import javax.servlet.http.HttpServletRequest; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static sonia.scm.web.WireProtocolRequestMockFactory.CMDS_HEADS_KNOWN_NODES; @@ -60,6 +61,9 @@ import static sonia.scm.web.WireProtocolRequestMockFactory.Namespace.PHASES; @RunWith(MockitoJUnitRunner.class) public class HgPermissionFilterTest { + @Mock + private HttpServletRequest request; + @Mock private ScmConfiguration configuration; @@ -79,6 +83,20 @@ public class HgPermissionFilterTest { when(hgRepositoryHandler.getConfig()).thenReturn(new HgConfig()); } + /** + * Tests {@link HgPermissionFilter#wrapRequestIfRequired(HttpServletRequest)}. + */ + @Test + public void testWrapRequestIfRequired() { + assertSame(request, filter.wrapRequestIfRequired(request)); + + HgConfig hgConfig = new HgConfig(); + hgConfig.setEnableHttpPostArgs(true); + when(hgRepositoryHandler.getConfig()).thenReturn(hgConfig); + + assertThat(filter.wrapRequestIfRequired(request), is(instanceOf(HgServletRequest.class))); + } + /** * Tests {@link HgPermissionFilter#isWriteRequest(HttpServletRequest)}. */ From 3d401b93ea6fbed8d3bef13e6ad7e079ac3d993d Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Tue, 3 Apr 2018 11:56:51 +0200 Subject: [PATCH 34/78] #970 added help text for enable httppostargs --- .../scm-hg-plugin/src/main/resources/sonia/scm/hg.config.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg.config.js b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg.config.js index f7b4f33240..b10de4b422 100644 --- a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg.config.js +++ b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg.config.js @@ -65,7 +65,9 @@ Sonia.hg.ConfigPanel = Ext.extend(Sonia.config.ConfigForm, { disableHookSSLValidationHelpText: 'Disables the validation of ssl certificates for the mercurial hook, which forwards the repository changes back to scm-manager. \n\ This option should only be used, if SCM-Manager uses a self signed certificate.', // TODO explain it - enableHttpPostArgsHelpText: 'Enables the experimental HttpPostArgs Protocol.', + enableHttpPostArgsHelpText: 'Enables the experimental HttpPostArgs Protocol of mercurial.\n\ + The HttpPostArgs Protocol uses the body of post requests to send the meta information instead of http headers.\ + This helps to reduce the header size of mercurial requests. HttpPostArgs is supported since mercurial 3.8.', initComponent: function(){ From 473f3257a0c068ea5807f72a3e3b5306b82caa8b Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 5 Apr 2018 18:44:42 +0200 Subject: [PATCH 35/78] close branch issue-970 From ff2afceb55c4362dbae252279ba3b8b5d87a4577 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 5 Apr 2018 19:48:04 +0200 Subject: [PATCH 36/78] update javahg to version 0.13 --- scm-plugins/scm-hg-plugin/pom.xml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/scm-plugins/scm-hg-plugin/pom.xml b/scm-plugins/scm-hg-plugin/pom.xml index e4cfa7d6f2..0bced018e6 100644 --- a/scm-plugins/scm-hg-plugin/pom.xml +++ b/scm-plugins/scm-hg-plugin/pom.xml @@ -1,6 +1,6 @@ - + 4.0.0 @@ -24,11 +24,11 @@ ${servlet.version} provided - + com.aragost.javahg javahg - 0.8-scm1 + 0.13 com.google.guava @@ -47,12 +47,12 @@ - + - + - + com.mycila.maven-license-plugin maven-license-plugin @@ -71,7 +71,7 @@ true - + org.apache.maven.plugins maven-jar-plugin @@ -84,18 +84,18 @@ - + - + - + maven.scm-manager.org scm-manager release repository http://maven.scm-manager.org/nexus/content/groups/public - + false @@ -108,7 +108,7 @@ default https://oss.sonatype.org/content/groups/public/ - + - + From 8af69c4e99fee97a29e6abe502769d5534327fec Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 5 Apr 2018 19:56:15 +0200 Subject: [PATCH 37/78] update vulnerable dependencies commons-beanutils to 1.9.3 commons-collections to 3.2.2 httpclient to 4.5.5 slf4j to 1.7.25 logback to 1.2.3 jackson to 1.9.13 --- pom.xml | 74 ++++++++++++++++++++++++++++++++++++++++++++-- scm-core/pom.xml | 1 - scm-webapp/pom.xml | 11 ------- 3 files changed, 72 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index c888ababe8..e06cf4698e 100644 --- a/pom.xml +++ b/pom.xml @@ -387,6 +387,75 @@ + + + + + + + commons-beanutils + commons-beanutils + 1.9.3 + + + + commons-collections + commons-collections + 3.2.2 + + + + + + org.apache.httpcomponents + httpclient + 4.5.5 + + + + + + slf4j-api + org.slf4j + ${slf4j.version} + + + + ch.qos.logback + logback-classic + ${logback.version} + + + + + + + org.codehaus.jackson + jackson-core-asl + ${jackson.version} + + + + org.codehaus.jackson + jackson-mapper-asl + ${jackson.version} + + + + org.codehaus.jackson + jackson-jaxrs + ${jackson.version} + + + + org.codehaus.jackson + jackson-xc + ${jackson.version} + + + + + @@ -410,8 +479,8 @@ 4.12 - 1.7.22 - 1.1.10 + 1.7.25 + 1.2.3 2.5 3.0 1.19.4 @@ -419,6 +488,7 @@ 2.3.20 7.6.21.v20160908 7.6.16.v20140903 + 1.9.13 1.3.0 diff --git a/scm-core/pom.xml b/scm-core/pom.xml index 732c0fa4d6..72c40c1f9a 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -30,7 +30,6 @@ slf4j-api org.slf4j - ${slf4j.version} diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 775b75525a..8c2d6379ae 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -136,7 +136,6 @@ ch.qos.logback logback-classic - ${logback.version} @@ -174,13 +173,11 @@ commons-beanutils commons-beanutils - 1.9.2 commons-collections commons-collections - 3.2.1 - - - org.apache.httpcomponents - httpclient - 4.2.6 - - From 528f7636341a40151f5b3701c59837db4e20ddbf Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 5 Apr 2018 20:35:48 +0200 Subject: [PATCH 38/78] removed never released scm-dao-orientdb module --- pom.xml | 1 - scm-dao-orientdb/pom.xml | 78 ---- .../scm/group/orientdb/GroupConverter.java | 180 --------- .../scm/group/orientdb/OrientDBGroupDAO.java | 112 ------ .../sonia/scm/orientdb/AbstractConverter.java | 198 ---------- .../orientdb/AbstractOrientDBModelDAO.java | 366 ------------------ .../scm/orientdb/ConnectionConfiguration.java | 282 -------------- .../scm/orientdb/ConnectionProvider.java | 296 -------------- .../java/sonia/scm/orientdb/Converter.java | 87 ----- .../sonia/scm/orientdb/OrientDBModule.java | 68 ---- .../OrientDBServletContextListener.java | 114 ------ .../java/sonia/scm/orientdb/OrientDBUtil.java | 295 -------------- .../orientdb/OrientDBRepositoryDAO.java | 182 --------- .../orientdb/PermissionConverter.java | 156 -------- .../orientdb/RepositoryConverter.java | 218 ----------- .../scm/store/orientdb/OrientDBStore.java | 222 ----------- .../store/orientdb/OrientDBStoreFactory.java | 162 -------- .../scm/user/orientdb/OrientDBUserDAO.java | 112 ------ .../scm/user/orientdb/UserConverter.java | 195 ---------- .../main/resources/META-INF/scm/override.xml | 58 --- .../scm/orientdb/server-configuration.xml | 52 --- 21 files changed, 3434 deletions(-) delete mode 100644 scm-dao-orientdb/pom.xml delete mode 100644 scm-dao-orientdb/src/main/java/sonia/scm/group/orientdb/GroupConverter.java delete mode 100644 scm-dao-orientdb/src/main/java/sonia/scm/group/orientdb/OrientDBGroupDAO.java delete mode 100644 scm-dao-orientdb/src/main/java/sonia/scm/orientdb/AbstractConverter.java delete mode 100644 scm-dao-orientdb/src/main/java/sonia/scm/orientdb/AbstractOrientDBModelDAO.java delete mode 100644 scm-dao-orientdb/src/main/java/sonia/scm/orientdb/ConnectionConfiguration.java delete mode 100644 scm-dao-orientdb/src/main/java/sonia/scm/orientdb/ConnectionProvider.java delete mode 100644 scm-dao-orientdb/src/main/java/sonia/scm/orientdb/Converter.java delete mode 100644 scm-dao-orientdb/src/main/java/sonia/scm/orientdb/OrientDBModule.java delete mode 100644 scm-dao-orientdb/src/main/java/sonia/scm/orientdb/OrientDBServletContextListener.java delete mode 100644 scm-dao-orientdb/src/main/java/sonia/scm/orientdb/OrientDBUtil.java delete mode 100644 scm-dao-orientdb/src/main/java/sonia/scm/repository/orientdb/OrientDBRepositoryDAO.java delete mode 100644 scm-dao-orientdb/src/main/java/sonia/scm/repository/orientdb/PermissionConverter.java delete mode 100644 scm-dao-orientdb/src/main/java/sonia/scm/repository/orientdb/RepositoryConverter.java delete mode 100644 scm-dao-orientdb/src/main/java/sonia/scm/store/orientdb/OrientDBStore.java delete mode 100644 scm-dao-orientdb/src/main/java/sonia/scm/store/orientdb/OrientDBStoreFactory.java delete mode 100644 scm-dao-orientdb/src/main/java/sonia/scm/user/orientdb/OrientDBUserDAO.java delete mode 100644 scm-dao-orientdb/src/main/java/sonia/scm/user/orientdb/UserConverter.java delete mode 100644 scm-dao-orientdb/src/main/resources/META-INF/scm/override.xml delete mode 100644 scm-dao-orientdb/src/main/resources/sonia/scm/orientdb/server-configuration.xml diff --git a/pom.xml b/pom.xml index e06cf4698e..6e4b76b847 100644 --- a/pom.xml +++ b/pom.xml @@ -70,7 +70,6 @@ scm-plugins scm-samples scm-dao-xml - scm-dao-orientdb scm-webapp scm-server scm-plugin-backend diff --git a/scm-dao-orientdb/pom.xml b/scm-dao-orientdb/pom.xml deleted file mode 100644 index c708a12cba..0000000000 --- a/scm-dao-orientdb/pom.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - - 4.0.0 - - - sonia.scm - scm - 1.58-SNAPSHOT - - - sonia.scm - scm-dao-orientdb - 1.58-SNAPSHOT - scm-dao-orientdb - - - - - javax.servlet - servlet-api - ${servlet.version} - provided - - - - sonia.scm - scm-core - 1.58-SNAPSHOT - - - - com.orientechnologies - orientdb-client - ${orientdb.version} - - - - com.orientechnologies - orientdb-server - ${orientdb.version} - - - com.orientechnologies - orientdb-client - - - - - - - - sonia.scm - scm-test - 1.58-SNAPSHOT - test - - - - - - 1.1.0 - - - - - - orientechnologies-repository - Orient Technologies Maven2 Repository - http://www.orientechnologies.com/listing/m2 - - true - - - - - - diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/group/orientdb/GroupConverter.java b/scm-dao-orientdb/src/main/java/sonia/scm/group/orientdb/GroupConverter.java deleted file mode 100644 index e25ce9a327..0000000000 --- a/scm-dao-orientdb/src/main/java/sonia/scm/group/orientdb/GroupConverter.java +++ /dev/null @@ -1,180 +0,0 @@ -/** - * 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.group.orientdb; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; -import com.orientechnologies.orient.core.metadata.schema.OClass; -import com.orientechnologies.orient.core.metadata.schema.OClass.INDEX_TYPE; -import com.orientechnologies.orient.core.metadata.schema.OSchema; -import com.orientechnologies.orient.core.metadata.schema.OType; -import com.orientechnologies.orient.core.record.impl.ODocument; - -import sonia.scm.group.Group; -import sonia.scm.orientdb.AbstractConverter; -import sonia.scm.orientdb.Converter; - -//~--- JDK imports ------------------------------------------------------------ - -import java.util.List; -import java.util.Map; - -/** - * - * @author Sebastian Sdorra - */ -public class GroupConverter extends AbstractConverter - implements Converter -{ - - /** Field description */ - public static final String DOCUMENT_CLASS = "Group"; - - /** Field description */ - public static final String FIELD_CREATIONDATE = "creationDate"; - - /** Field description */ - public static final String FIELD_DESCRIPTION = "description"; - - /** Field description */ - public static final String FIELD_MEMBERS = "members"; - - /** Field description */ - public static final String INDEX_ID = "groupId"; - - /** Field description */ - public static final GroupConverter INSTANCE = new GroupConverter(); - - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param group - * - * @return - */ - @Override - public ODocument convert(Group group) - { - ODocument doc = new ODocument(DOCUMENT_CLASS); - - return convert(doc, group); - } - - /** - * Method description - * - * - * @param doc - * @param group - * - * @return - */ - @Override - public ODocument convert(ODocument doc, Group group) - { - appendModelObjectFields(doc, group); - appendField(doc, FIELD_DESCRIPTION, group.getDescription()); - appendField(doc, FIELD_CREATIONDATE, group.getCreationDate(), OType.LONG); - appendField(doc, FIELD_MEMBERS, group.getMembers(), OType.EMBEDDEDLIST); - appendPropertiesField(doc, group); - - return doc; - } - - /** - * Method description - * - * - * @param doc - * - * @return - */ - @Override - public Group convert(ODocument doc) - { - Group group = new Group(); - - group.setName(getStringField(doc, FIELD_ID)); - group.setDescription(getStringField(doc, FIELD_DESCRIPTION)); - group.setType(getStringField(doc, FIELD_TYPE)); - group.setCreationDate(getLongField(doc, FIELD_CREATIONDATE)); - group.setLastModified(getLongField(doc, FIELD_LASTMODIFIED)); - - Map properties = doc.field(FIELD_PROPERTIES); - - group.setProperties(properties); - - List members = doc.field(FIELD_MEMBERS); - - group.setMembers(members); - - return group; - } - - /** - * Method description - * - * - * @param connection - */ - @Override - public void createShema(ODatabaseDocumentTx connection) - { - OSchema schema = connection.getMetadata().getSchema(); - OClass oclass = schema.getClass(DOCUMENT_CLASS); - - if (oclass == null) - { - oclass = schema.createClass(DOCUMENT_CLASS); - - // model properites - oclass.createProperty(FIELD_ID, OType.STRING); - oclass.createProperty(FIELD_TYPE, OType.STRING); - oclass.createProperty(FIELD_LASTMODIFIED, OType.LONG); - - // user properties - oclass.createProperty(FIELD_DESCRIPTION, OType.STRING); - oclass.createProperty(FIELD_CREATIONDATE, OType.LONG); - oclass.createProperty(FIELD_MEMBERS, OType.EMBEDDEDLIST); - oclass.createProperty(FIELD_PROPERTIES, OType.EMBEDDEDMAP); - - // indexes - oclass.createIndex(INDEX_ID, INDEX_TYPE.UNIQUE, FIELD_ID); - schema.save(); - } - } -} diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/group/orientdb/OrientDBGroupDAO.java b/scm-dao-orientdb/src/main/java/sonia/scm/group/orientdb/OrientDBGroupDAO.java deleted file mode 100644 index 56f2187537..0000000000 --- a/scm-dao-orientdb/src/main/java/sonia/scm/group/orientdb/OrientDBGroupDAO.java +++ /dev/null @@ -1,112 +0,0 @@ -/** - * 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.group.orientdb; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.google.inject.Inject; -import com.google.inject.Provider; - -import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; -import com.orientechnologies.orient.core.record.impl.ODocument; - -import sonia.scm.group.Group; -import sonia.scm.group.GroupDAO; -import sonia.scm.orientdb.AbstractOrientDBModelDAO; -import sonia.scm.orientdb.OrientDBUtil; - -//~--- JDK imports ------------------------------------------------------------ - -import java.util.List; - -/** - * - * @author Sebastian Sdorra - */ -public class OrientDBGroupDAO extends AbstractOrientDBModelDAO - implements GroupDAO -{ - - /** Field description */ - public static final String QUERY_ALL = "select from Group"; - - /** Field description */ - public static final String QUERY_SINGLE_BYID = - "select from Group where id = ?"; - - //~--- constructors --------------------------------------------------------- - - /** - * Constructs ... - * - * - * @param connectionProvider - */ - @Inject - public OrientDBGroupDAO(Provider connectionProvider) - { - super(connectionProvider, GroupConverter.INSTANCE); - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @param connection - * - * @return - */ - @Override - protected List getAllDocuments(ODatabaseDocumentTx connection) - { - return OrientDBUtil.executeListResultQuery(connection, QUERY_ALL); - } - - /** - * Method description - * - * - * @param connection - * @param id - * - * @return - */ - @Override - protected ODocument getDocument(ODatabaseDocumentTx connection, String id) - { - return OrientDBUtil.executeSingleResultQuery(connection, QUERY_SINGLE_BYID, - id); - } -} diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/AbstractConverter.java b/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/AbstractConverter.java deleted file mode 100644 index f811e56f20..0000000000 --- a/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/AbstractConverter.java +++ /dev/null @@ -1,198 +0,0 @@ -/** - * 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.orientdb; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.orientechnologies.orient.core.metadata.schema.OType; -import com.orientechnologies.orient.core.record.impl.ODocument; - -import sonia.scm.ModelObject; -import sonia.scm.PropertiesAware; - -//~--- JDK imports ------------------------------------------------------------ - -import java.util.List; - -/** - * - * @author Sebastian Sdorra - */ -public abstract class AbstractConverter -{ - - /** Field description */ - public static final String FIELD_ID = "id"; - - /** Field description */ - public static final String FIELD_LASTMODIFIED = "lastModified"; - - /** Field description */ - public static final String FIELD_PROPERTIES = "properties"; - - /** Field description */ - public static final String FIELD_TYPE = "type"; - - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param doc - * @param name - * @param value - */ - protected void appendField(ODocument doc, String name, Object value) - { - appendField(doc, name, value, null); - } - - /** - * Method description - * - * - * @param doc - * @param name - * @param value - * @param type - */ - protected void appendField(ODocument doc, String name, Object value, - OType type) - { - if (value != null) - { - if (type != null) - { - doc.field(name, value, type); - } - else - { - doc.field(name, value); - } - } - else if (doc.containsField(name)) - { - doc.removeField(name); - } - } - - /** - * Method description - * - * - * @param doc - * @param name - * @param converter - * @param list - * @param - */ - protected void appendListField(ODocument doc, String name, - Converter converter, List list) - { - List docs = OrientDBUtil.transformToDocuments(converter, list); - - appendField(doc, name, docs, OType.EMBEDDEDLIST); - } - - /** - * Method description - * - * - * @param doc - * @param model - */ - protected void appendModelObjectFields(ODocument doc, ModelObject model) - { - appendField(doc, FIELD_ID, model.getId()); - appendField(doc, FIELD_TYPE, model.getType()); - appendField(doc, FIELD_LASTMODIFIED, model.getLastModified(), OType.LONG); - } - - /** - * Method description - * - * - * @param doc - * @param object - */ - protected void appendPropertiesField(ODocument doc, PropertiesAware object) - { - appendField(doc, FIELD_PROPERTIES, object.getProperties(), - OType.EMBEDDEDMAP); - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @param doc - * @param name - * - * @return - */ - protected Boolean getBooleanField(ODocument doc, String name) - { - return doc.field(name); - } - - /** - * Method description - * - * - * @param doc - * @param name - * - * @return - */ - protected Long getLongField(ODocument doc, String name) - { - return doc.field(name); - } - - /** - * Method description - * - * - * @param doc - * @param name - * - * @return - */ - protected String getStringField(ODocument doc, String name) - { - return doc.field(name); - } -} diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/AbstractOrientDBModelDAO.java b/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/AbstractOrientDBModelDAO.java deleted file mode 100644 index 2b9585cb77..0000000000 --- a/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/AbstractOrientDBModelDAO.java +++ /dev/null @@ -1,366 +0,0 @@ -/** - * 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.orientdb; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.google.common.collect.Lists; -import com.google.inject.Provider; - -import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; -import com.orientechnologies.orient.core.record.impl.ODocument; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import sonia.scm.GenericDAO; -import sonia.scm.ModelObject; -import sonia.scm.util.Util; - -//~--- JDK imports ------------------------------------------------------------ - -import java.util.List; - -/** - * - * @author Sebastian Sdorra - * - * @param - */ -public abstract class AbstractOrientDBModelDAO - implements GenericDAO -{ - - /** Field description */ - public static final String TYPE = "orientdb"; - - /** - * the logger for AbstractOrientDBModelDAO - */ - private static final Logger logger = - LoggerFactory.getLogger(AbstractOrientDBModelDAO.class); - - //~--- constructors --------------------------------------------------------- - - /** - * Constructs ... - * - * - * @param connectionProvider - * @param converter - */ - public AbstractOrientDBModelDAO( - Provider connectionProvider, - Converter converter) - { - this.connectionProvider = connectionProvider; - this.converter = converter; - createShema(); - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @param connection - * - * @return - */ - protected abstract List getAllDocuments( - ODatabaseDocumentTx connection); - - /** - * Method description - * - * - * @param connection - * @param id - * - * @return - */ - protected abstract ODocument getDocument(ODatabaseDocumentTx connection, - String id); - - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * - * @param item - */ - @Override - public void add(T item) - { - ODatabaseDocumentTx connection = connectionProvider.get(); - - try - { - ODocument doc = converter.convert(item); - - doc.save(); - } - finally - { - OrientDBUtil.close(connection); - } - } - - /** - * Method description - * - * - * - * @param item - * - * @return - */ - @Override - public boolean contains(T item) - { - return contains(item.getId()); - } - - /** - * Method description - * - * - * @param id - * - * @return - */ - @Override - public boolean contains(String id) - { - return get(id) != null; - } - - /** - * Method description - * - * - * @param item - */ - @Override - public void delete(T item) - { - ODatabaseDocumentTx connection = connectionProvider.get(); - - try - { - ODocument doc = getDocument(connection, item.getId()); - - if (doc != null) - { - doc.delete(); - } - else if (logger.isErrorEnabled()) - { - logger.error("could not find document for delete"); - } - } - finally - { - OrientDBUtil.close(connection); - } - } - - /** - * Method description - * - * - * - * @param item - */ - @Override - public void modify(T item) - { - ODatabaseDocumentTx connection = connectionProvider.get(); - - try - { - ODocument doc = getDocument(connection, item.getId()); - - if (doc != null) - { - doc = converter.convert(doc, item); - doc.save(); - } - else if (logger.isErrorEnabled()) - { - logger.error("could not find document for modify"); - } - } - finally - { - OrientDBUtil.close(connection); - } - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @param id - * - * @return - */ - @Override - public T get(String id) - { - T item = null; - ODatabaseDocumentTx connection = connectionProvider.get(); - - try - { - ODocument doc = getDocument(connection, id); - - if (doc != null) - { - item = converter.convert(doc); - } - } - finally - { - OrientDBUtil.close(connection); - } - - return item; - } - - /** - * Method description - * - * - * @return - */ - @Override - public List getAll() - { - List items = null; - ODatabaseDocumentTx connection = connectionProvider.get(); - - try - { - List result = getAllDocuments(connection); - - if (Util.isNotEmpty(result)) - { - items = OrientDBUtil.transformToItems(converter, result); - } - else - { - items = Lists.newArrayList(); - } - } - finally - { - OrientDBUtil.close(connection); - } - - return items; - } - - /** - * Method description - * - * - * @return - */ - @Override - public Long getCreationTime() - { - - // TODO - return System.currentTimeMillis(); - } - - /** - * Method description - * - * - * @return - */ - @Override - public Long getLastModified() - { - - // TODO - return System.currentTimeMillis(); - } - - /** - * Method description - * - * - * @return - */ - @Override - public String getType() - { - return TYPE; - } - - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - */ - private void createShema() - { - ODatabaseDocumentTx connection = connectionProvider.get(); - - try - { - converter.createShema(connection); - } - finally - { - OrientDBUtil.close(connection); - } - } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - protected Provider connectionProvider; - - /** Field description */ - protected Converter converter; -} diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/ConnectionConfiguration.java b/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/ConnectionConfiguration.java deleted file mode 100644 index e6eae1af0d..0000000000 --- a/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/ConnectionConfiguration.java +++ /dev/null @@ -1,282 +0,0 @@ -/** - * 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.orientdb; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.google.common.base.Objects; - -//~--- JDK imports ------------------------------------------------------------ - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -/** - * - * @author Sebastian Sdorra - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlRootElement(name = "connection-configuration") -public class ConnectionConfiguration -{ - - /** - * Constructs ... - * - */ - public ConnectionConfiguration() {} - - /** - * Constructs ... - * - * - * @param url - * @param username - * @param password - */ - public ConnectionConfiguration(String url, String username, String password) - { - this.url = url; - this.username = username; - this.password = password; - } - - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param obj - * - * @return - */ - @Override - public boolean equals(Object obj) - { - if (obj == null) - { - return false; - } - - if (getClass() != obj.getClass()) - { - return false; - } - - final ConnectionConfiguration other = (ConnectionConfiguration) obj; - - //J- - return Objects.equal(url, other.url) - && Objects.equal(username, other.username) - && Objects.equal(password, other.password) - && Objects.equal(minPoolSize, other.minPoolSize) - && Objects.equal(maxPoolSize, other.maxPoolSize); - //J+ - } - - /** - * Method description - * - * - * @return - */ - @Override - public int hashCode() - { - return Objects.hashCode(url, username, password, minPoolSize, maxPoolSize); - } - - /** - * Method description - * - * - * @return - */ - @Override - @SuppressWarnings("squid:S2068") - public String toString() - { - String pwd = null; - - if (password != null) - { - pwd = "xxx"; - } - - //J- - return Objects.toStringHelper(this) - .add("url", url) - .add("username", username) - .add("password", pwd) - .add("minPoolSize", minPoolSize) - .add("maxPoolSize", maxPoolSize) - .toString(); - //J+ - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @return - */ - public int getMaxPoolSize() - { - return maxPoolSize; - } - - /** - * Method description - * - * - * @return - */ - public int getMinPoolSize() - { - return minPoolSize; - } - - /** - * Method description - * - * - * @return - */ - public String getPassword() - { - return password; - } - - /** - * Method description - * - * - * @return - */ - public String getUrl() - { - return url; - } - - /** - * Method description - * - * - * @return - */ - public String getUsername() - { - return username; - } - - //~--- set methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @param maxPoolSize - */ - public void setMaxPoolSize(int maxPoolSize) - { - this.maxPoolSize = maxPoolSize; - } - - /** - * Method description - * - * - * @param minPoolSize - */ - public void setMinPoolSize(int minPoolSize) - { - this.minPoolSize = minPoolSize; - } - - /** - * Method description - * - * - * @param password - */ - public void setPassword(String password) - { - this.password = password; - } - - /** - * Method description - * - * - * @param url - */ - public void setUrl(String url) - { - this.url = url; - } - - /** - * Method description - * - * - * @param username - */ - public void setUsername(String username) - { - this.username = username; - } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - @XmlElement(name = "max-pool-size") - private int maxPoolSize = 10; - - /** Field description */ - @XmlElement(name = "min-pool-size") - private int minPoolSize = 2; - - /** Field description */ - private String password; - - /** Field description */ - private String url; - - /** Field description */ - private String username; -} diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/ConnectionProvider.java b/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/ConnectionProvider.java deleted file mode 100644 index 65f8245f32..0000000000 --- a/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/ConnectionProvider.java +++ /dev/null @@ -1,296 +0,0 @@ -/** - * 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.orientdb; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.google.common.io.Resources; -import com.google.inject.Provider; -import com.google.inject.Singleton; - -import com.orientechnologies.orient.core.config.OGlobalConfiguration; -import com.orientechnologies.orient.core.db.document.ODatabaseDocumentPool; -import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; -import com.orientechnologies.orient.server.OServer; -import com.orientechnologies.orient.server.OServerMain; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import sonia.scm.ConfigurationException; -import sonia.scm.SCMContext; - -//~--- JDK imports ------------------------------------------------------------ - -import java.io.Closeable; -import java.io.File; - -import java.net.URL; - -import java.nio.charset.Charset; - -import javax.xml.bind.JAXB; - -/** - * - * @author Sebastian Sdorra - */ -@Singleton -public class ConnectionProvider - implements Provider, Closeable -{ - - /** Field description */ - public static final String DEFAULT_DB_DIRECTORY = "db"; - - /** Field description */ - public static final String DEFAULT_DB_SHEME = "local:"; - - /** Field description */ - @SuppressWarnings("squid:S2068") - public static final String DEFAULT_PASSWORD = "admin"; - - /** Field description */ - public static final String DEFAULT_USERNAME = "admin"; - - /** Field description */ - public static final String EMBEDDED_CONFIGURATION = - "sonia/scm/orientdb/server-configuration.xml"; - - /** Field description */ - public static final String CONFIG_PATH_SERVER = - "config".concat(File.separator).concat("orientdb-server.xml"); - - /** Field description */ - public static final String CONFIG_PATH_CLIENT = - "config".concat(File.separator).concat("orientdb-client.xml"); - - /** - * the logger for ConnectionProvider - */ - private static final Logger logger = - LoggerFactory.getLogger(ConnectionProvider.class); - - //~--- constructors --------------------------------------------------------- - - /** - * Constructs ... - * - */ - public ConnectionProvider() - { - File file = new File(SCMContext.getContext().getBaseDirectory(), - CONFIG_PATH_CLIENT); - - if (file.exists()) - { - if (logger.isInfoEnabled()) - { - logger.info("read database configuration from file {}", file); - } - - init(JAXB.unmarshal(file, ConnectionConfiguration.class)); - } - else - { - try - { - File baseDirectory = SCMContext.getContext().getBaseDirectory(); - - // create connection configuration for embedded server - File directory = new File(baseDirectory, DEFAULT_DB_DIRECTORY); - - if (logger.isInfoEnabled()) - { - logger.info("create configuration for embedded database at {}", - directory); - } - - /** - * set oritentdb tuning option - * https://groups.google.com/forum/#!msg/orient-database/DrJ3zPY3oao/RQQayirg4mYJ - */ - OGlobalConfiguration.STORAGE_KEEP_OPEN.setValue(Boolean.FALSE); - OGlobalConfiguration.MVRBTREE_LAZY_UPDATES.setValue(1); - server = OServerMain.create(); - - URL configUrl = null; - File serverConfiguration = new File(baseDirectory, CONFIG_PATH_SERVER); - - if (serverConfiguration.exists()) - { - configUrl = serverConfiguration.toURI().toURL(); - } - else - { - configUrl = Resources.getResource(EMBEDDED_CONFIGURATION); - } - - if (logger.isInfoEnabled()) - { - logger.info("load orientdb server configuration from {}", configUrl); - } - - String config = Resources.toString(configUrl, Charset.defaultCharset()); - - server.startup(config); - server.activate(); - - String url = DEFAULT_DB_SHEME.concat(directory.getAbsolutePath()); - - if (!directory.exists()) - { - if (logger.isInfoEnabled()) - { - logger.info("create new database at {}", directory); - } - - ODatabaseDocumentTx connection = null; - - try - { - connection = new ODatabaseDocumentTx(url); - connection.create(); - } - finally - { - OrientDBUtil.close(connection); - } - } - - init(new ConnectionConfiguration(url, DEFAULT_USERNAME, - DEFAULT_PASSWORD)); - } - catch (Exception ex) - { - throw new ConfigurationException("could not start embedded database", - ex); - } - } - } - - /** - * Constructs ... - * - * - * @param configuration - */ - public ConnectionProvider(ConnectionConfiguration configuration) - { - init(configuration); - } - - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - */ - @Override - public void close() - { - if (connectionPool != null) - { - try - { - connectionPool.close(); - } - catch (Exception ex) - { - logger.error("could not close connection pool", ex); - } - } - - if (server != null) - { - try - { - server.shutdown(); - } - catch (Exception ex) - { - logger.error("shutdown of orientdb server failed", ex); - } - } - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @return - */ - @Override - public ODatabaseDocumentTx get() - { - if (logger.isTraceEnabled()) - { - logger.trace("acquire new connection for database {}", - configuration.getUrl()); - } - - return connectionPool.acquire(configuration.getUrl(), - configuration.getUsername(), - configuration.getPassword()); - } - - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param configuration - */ - private void init(ConnectionConfiguration configuration) - { - this.configuration = configuration; - this.connectionPool = new ODatabaseDocumentPool(); - this.connectionPool.setup(configuration.getMinPoolSize(), - configuration.getMaxPoolSize()); - } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - private ConnectionConfiguration configuration; - - /** Field description */ - private ODatabaseDocumentPool connectionPool; - - /** Field description */ - private OServer server; -} diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/Converter.java b/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/Converter.java deleted file mode 100644 index 0575d47e5d..0000000000 --- a/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/Converter.java +++ /dev/null @@ -1,87 +0,0 @@ -/** - * 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.orientdb; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; -import com.orientechnologies.orient.core.record.impl.ODocument; - -/** - * - * @author Sebastian Sdorra - * - * @param - */ -public interface Converter -{ - - /** - * Method description - * - * - * @param item - * - * @return - */ - public ODocument convert(T item); - - /** - * Method description - * - * - * @param doc - * @param item - * - * @return - */ - public ODocument convert(ODocument doc, T item); - - /** - * Method description - * - * - * @param doc - * - * @return - */ - public T convert(ODocument doc); - - /** - * Method description - * - * - * @param connection - */ - public void createShema(ODatabaseDocumentTx connection); -} diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/OrientDBModule.java b/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/OrientDBModule.java deleted file mode 100644 index 57d4a14b9a..0000000000 --- a/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/OrientDBModule.java +++ /dev/null @@ -1,68 +0,0 @@ -/** - * 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.orientdb; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.google.inject.AbstractModule; -import com.google.inject.multibindings.Multibinder; - -import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; - -//~--- JDK imports ------------------------------------------------------------ - -import javax.servlet.ServletContextListener; - -/** - * - * @author Sebastian Sdorra - */ -public class OrientDBModule extends AbstractModule -{ - - /** - * Method description - * - */ - @Override - protected void configure() - { - bind(ODatabaseDocumentTx.class).toProvider(ConnectionProvider.class); - - Multibinder servletContextListenerBinder = - Multibinder.newSetBinder(binder(), ServletContextListener.class); - - servletContextListenerBinder.addBinding().to( - OrientDBServletContextListener.class); - } -} diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/OrientDBServletContextListener.java b/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/OrientDBServletContextListener.java deleted file mode 100644 index 7dc5468be6..0000000000 --- a/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/OrientDBServletContextListener.java +++ /dev/null @@ -1,114 +0,0 @@ -/** - * 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.orientdb; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.google.inject.Inject; -import com.google.inject.Singleton; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -//~--- JDK imports ------------------------------------------------------------ - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -/** - * - * @author Sebastian Sdorra - */ -@Singleton -public class OrientDBServletContextListener implements ServletContextListener -{ - - /** - * the logger for OrientDBServletContextListener - */ - private static final Logger logger = - LoggerFactory.getLogger(OrientDBServletContextListener.class); - - //~--- constructors --------------------------------------------------------- - - /** - * Constructs ... - * - * - * @param connectionProvider - */ - @Inject - public OrientDBServletContextListener(ConnectionProvider connectionProvider) - { - this.connectionProvider = connectionProvider; - } - - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param sce - */ - @Override - public void contextDestroyed(ServletContextEvent sce) - { - connectionProvider.close(); - - if (logger.isInfoEnabled()) - { - logger.info("orientdb context listener destroyed"); - } - } - - /** - * Method description - * - * - * @param sce - */ - @Override - public void contextInitialized(ServletContextEvent sce) - { - if (logger.isInfoEnabled()) - { - logger.info("orientdb context listener initialized"); - } - } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - private ConnectionProvider connectionProvider; -} diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/OrientDBUtil.java b/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/OrientDBUtil.java deleted file mode 100644 index 02ccb6066b..0000000000 --- a/scm-dao-orientdb/src/main/java/sonia/scm/orientdb/OrientDBUtil.java +++ /dev/null @@ -1,295 +0,0 @@ -/** - * 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.orientdb; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.google.common.base.Function; -import com.google.common.collect.Lists; - -import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; -import com.orientechnologies.orient.core.record.impl.ODocument; -import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import sonia.scm.util.Util; - -//~--- JDK imports ------------------------------------------------------------ - -import java.util.List; - -/** - * - * @author Sebastian Sdorra - */ -public final class OrientDBUtil -{ - - /** Field description */ - public static final String FETCH_PLAN = "*:-1"; - - /** - * the logger for OrientDBUtil - */ - private static final Logger logger = - LoggerFactory.getLogger(OrientDBUtil.class); - - //~--- constructors --------------------------------------------------------- - - /** - * Constructs ... - * - */ - private OrientDBUtil() {} - - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param connection - */ - public static void close(ODatabaseDocumentTx connection) - { - if (connection != null) - { - connection.close(); - } - } - - /** - * Method description - * - * - * @param connection - * @param query - * @param parameters - * - * @return - */ - public static List executeListResultQuery( - ODatabaseDocumentTx connection, String query, Object... parameters) - { - if (logger.isTraceEnabled()) - { - logger.trace("execute list result query '{}'", query); - } - - OSQLSynchQuery osqlQuery = new OSQLSynchQuery(query); - - osqlQuery.setFetchPlan(FETCH_PLAN); - - return connection.command(osqlQuery).execute(parameters); - } - - /** - * Method description - * - * - * @param connection - * @param query - * @param parameters - * - * @return - */ - public static ODocument executeSingleResultQuery( - ODatabaseDocumentTx connection, String query, Object... parameters) - { - if (logger.isTraceEnabled()) - { - logger.trace("execute single result query '{}'", query); - } - - ODocument result = null; - OSQLSynchQuery osqlQuery = new OSQLSynchQuery(query); - - osqlQuery.setFetchPlan(FETCH_PLAN); - - List resultList = - connection.command(osqlQuery).setLimit(1).execute(parameters); - - if (Util.isNotEmpty(resultList)) - { - result = resultList.get(0); - } - - return result; - } - - /** - * Method description - * - * - * @param converter - * @param items - * @param - * - * @return - */ - public static List transformToDocuments( - Converter converter, List items) - { - List docs = null; - - if (Util.isNotEmpty(items)) - { - docs = Lists.transform(items, new ItemConverterFunction(converter)); - } - - return docs; - } - - /** - * Method description - * - * - * @param converter - * @param docs - * @param - * - * @return - */ - public static List transformToItems(Converter converter, - List docs) - { - List items = null; - - if (Util.isNotEmpty(docs)) - { - items = Lists.transform(docs, - new DocumentConverterFunction(converter)); - } - - return items; - } - - //~--- inner classes -------------------------------------------------------- - - /** - * Class description - * - * - * @param - * - * @version Enter version here..., 12/03/12 - * @author Enter your name here... - */ - private static class DocumentConverterFunction - implements Function - { - - /** - * Constructs ... - * - * - * @param converter - */ - public DocumentConverterFunction(Converter converter) - { - this.converter = converter; - } - - //~--- methods ------------------------------------------------------------ - - /** - * Method description - * - * - * - * @param doc - * - * @return - */ - @Override - public T apply(ODocument doc) - { - return converter.convert(doc); - } - - //~--- fields ------------------------------------------------------------- - - /** Field description */ - private Converter converter; - } - - - /** - * Class description - * - * - * @param - * - * @version Enter version here..., 12/03/12 - * @author Enter your name here... - */ - private static class ItemConverterFunction - implements Function - { - - /** - * Constructs ... - * - * - * @param converter - */ - public ItemConverterFunction(Converter converter) - { - this.converter = converter; - } - - //~--- methods ------------------------------------------------------------ - - /** - * Method description - * - * - * @param f - * - * @return - */ - @Override - public ODocument apply(F f) - { - return converter.convert(f); - } - - //~--- fields ------------------------------------------------------------- - - /** Field description */ - private Converter converter; - } -} diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/repository/orientdb/OrientDBRepositoryDAO.java b/scm-dao-orientdb/src/main/java/sonia/scm/repository/orientdb/OrientDBRepositoryDAO.java deleted file mode 100644 index de013e8698..0000000000 --- a/scm-dao-orientdb/src/main/java/sonia/scm/repository/orientdb/OrientDBRepositoryDAO.java +++ /dev/null @@ -1,182 +0,0 @@ -/** - * 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.orientdb; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.google.inject.Inject; -import com.google.inject.Provider; - -import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; -import com.orientechnologies.orient.core.record.impl.ODocument; - -import sonia.scm.orientdb.AbstractOrientDBModelDAO; -import sonia.scm.orientdb.OrientDBUtil; -import sonia.scm.repository.Repository; -import sonia.scm.repository.RepositoryDAO; - -//~--- JDK imports ------------------------------------------------------------ - -import java.util.List; - -/** - * - * @author Sebastian Sdorra - */ -public class OrientDBRepositoryDAO extends AbstractOrientDBModelDAO - implements RepositoryDAO -{ - - /** Field description */ - public static final String QUERY_ALL = "select from Repository"; - - /** Field description */ - public static final String QUERY_SINGLE_BYID = - "select from Repository where id = ?"; - - /** Field description */ - public static final String QUERY_SINGLE_BYTYPEANDNAME = - "select from Repository where type = ? and name = ?"; - - //~--- constructors --------------------------------------------------------- - - /** - * Constructs ... - * - * - * @param connectionProvider - */ - @Inject - public OrientDBRepositoryDAO(Provider connectionProvider) - { - super(connectionProvider, RepositoryConverter.INSTANCE); - } - - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param type - * @param name - * - * @return - */ - @Override - public boolean contains(String type, String name) - { - return get(type, name) != null; - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @param type - * @param name - * - * @return - */ - @Override - public Repository get(String type, String name) - { - Repository repository = null; - ODatabaseDocumentTx connection = connectionProvider.get(); - - try - { - ODocument doc = getDocument(connection, type, name); - - if (doc != null) - { - repository = converter.convert(doc); - } - } - finally - { - OrientDBUtil.close(connection); - } - - return repository; - } - - /** - * Method description - * - * - * @param connection - * - * @return - */ - @Override - protected List getAllDocuments(ODatabaseDocumentTx connection) - { - return OrientDBUtil.executeListResultQuery(connection, QUERY_ALL); - } - - /** - * Method description - * - * - * @param connection - * @param id - * - * @return - */ - @Override - protected ODocument getDocument(ODatabaseDocumentTx connection, String id) - { - return OrientDBUtil.executeSingleResultQuery(connection, QUERY_SINGLE_BYID, - id); - } - - /** - * Method description - * - * - * @param connection - * @param type - * @param name - * - * @return - */ - private ODocument getDocument(ODatabaseDocumentTx connection, String type, - String name) - { - return OrientDBUtil.executeSingleResultQuery(connection, - QUERY_SINGLE_BYTYPEANDNAME, type, name); - } -} diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/repository/orientdb/PermissionConverter.java b/scm-dao-orientdb/src/main/java/sonia/scm/repository/orientdb/PermissionConverter.java deleted file mode 100644 index 6e152b4d87..0000000000 --- a/scm-dao-orientdb/src/main/java/sonia/scm/repository/orientdb/PermissionConverter.java +++ /dev/null @@ -1,156 +0,0 @@ -/** - * 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.orientdb; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; -import com.orientechnologies.orient.core.metadata.schema.OClass; -import com.orientechnologies.orient.core.metadata.schema.OSchema; -import com.orientechnologies.orient.core.metadata.schema.OType; -import com.orientechnologies.orient.core.record.impl.ODocument; - -import sonia.scm.orientdb.AbstractConverter; -import sonia.scm.orientdb.Converter; -import sonia.scm.repository.Permission; -import sonia.scm.repository.PermissionType; - -/** - * - * @author Sebastian Sdorra - */ -public class PermissionConverter extends AbstractConverter - implements Converter -{ - - /** Field description */ - public static final String DOCUMENT_CLASS = "Permission"; - - /** Field description */ - public static final String FIELD_GROUP = "group"; - - /** Field description */ - public static final String FIELD_NAME = "name"; - - /** Field description */ - public static final PermissionConverter INSTANCE = new PermissionConverter(); - - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param doc - * @param permission - * - * @return - */ - @Override - public ODocument convert(ODocument doc, Permission permission) - { - appendField(doc, FIELD_NAME, permission.getName()); - appendField(doc, FIELD_TYPE, permission.getType().toString()); - appendField(doc, FIELD_GROUP, permission.isGroupPermission(), - OType.BOOLEAN); - - return doc; - } - - /** - * Method description - * - * - * @param permission - * - * @return - */ - @Override - public ODocument convert(Permission permission) - { - ODocument doc = new ODocument(DOCUMENT_CLASS); - - convert(doc, permission); - - return doc; - } - - /** - * Method description - * - * - * @param doc - * - * @return - */ - @Override - public Permission convert(ODocument doc) - { - Permission permission = new Permission(); - - permission.setName(getStringField(doc, FIELD_NAME)); - - String typeString = doc.field(FIELD_TYPE); - - if (typeString != null) - { - permission.setType(PermissionType.valueOf(typeString)); - } - - permission.setGroupPermission(getBooleanField(doc, FIELD_GROUP)); - - return permission; - } - - /** - * Method description - * - * - * @param connection - */ - @Override - public void createShema(ODatabaseDocumentTx connection) - { - OSchema schema = connection.getMetadata().getSchema(); - OClass oclass = schema.getClass(DOCUMENT_CLASS); - - if (oclass == null) - { - oclass = schema.createClass(DOCUMENT_CLASS); - oclass.createProperty(FIELD_NAME, OType.STRING); - oclass.createProperty(FIELD_TYPE, OType.STRING); - oclass.createProperty(FIELD_GROUP, OType.BOOLEAN); - schema.save(); - } - } -} diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/repository/orientdb/RepositoryConverter.java b/scm-dao-orientdb/src/main/java/sonia/scm/repository/orientdb/RepositoryConverter.java deleted file mode 100644 index bd96ca3444..0000000000 --- a/scm-dao-orientdb/src/main/java/sonia/scm/repository/orientdb/RepositoryConverter.java +++ /dev/null @@ -1,218 +0,0 @@ -/** - * 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.orientdb; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; -import com.orientechnologies.orient.core.metadata.schema.OClass; -import com.orientechnologies.orient.core.metadata.schema.OClass.INDEX_TYPE; -import com.orientechnologies.orient.core.metadata.schema.OSchema; -import com.orientechnologies.orient.core.metadata.schema.OType; -import com.orientechnologies.orient.core.record.impl.ODocument; - -import sonia.scm.orientdb.AbstractConverter; -import sonia.scm.orientdb.Converter; -import sonia.scm.orientdb.OrientDBUtil; -import sonia.scm.repository.Repository; - -//~--- JDK imports ------------------------------------------------------------ - -import java.util.List; -import java.util.Map; - -/** - * - * @author Sebastian Sdorra - */ -public class RepositoryConverter extends AbstractConverter - implements Converter -{ - - /** Field description */ - public static final String DOCUMENT_CLASS = "Repository"; - - /** Field description */ - public static final String FIELD_ARCHIVED = "archived"; - - /** Field description */ - public static final String FIELD_CONTACT = "contact"; - - /** Field description */ - public static final String FIELD_CREATIONDATE = "creationDate"; - - /** Field description */ - public static final String FIELD_DESCRIPTION = "description"; - - /** Field description */ - public static final String FIELD_NAME = "name"; - - /** Field description */ - public static final String FIELD_PERMISSIONS = "permissions"; - - /** Field description */ - public static final String FIELD_PUBLIC = "public"; - - /** Field description */ - public static final String INDEX_ID = "RepositoryId"; - - /** Field description */ - public static final String INDEX_TYPEANDNAME = "RepositoryTypeAndName"; - - /** Field description */ - public static final RepositoryConverter INSTANCE = new RepositoryConverter(); - - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param doc - * @param repository - * - * @return - */ - @Override - public ODocument convert(ODocument doc, Repository repository) - { - appendModelObjectFields(doc, repository); - appendField(doc, FIELD_NAME, repository.getName()); - appendField(doc, FIELD_CONTACT, repository.getContact()); - appendField(doc, FIELD_DESCRIPTION, repository.getDescription()); - appendField(doc, FIELD_PUBLIC, repository.isPublicReadable(), - OType.BOOLEAN); - appendField(doc, FIELD_ARCHIVED, repository.isArchived(), OType.BOOLEAN); - appendField(doc, FIELD_CREATIONDATE, repository.getCreationDate(), - OType.LONG); - appendPropertiesField(doc, repository); - appendListField(doc, FIELD_PERMISSIONS, PermissionConverter.INSTANCE, - repository.getPermissions()); - - return doc; - } - - /** - * Method description - * - * - * @param repository - * - * @return - */ - @Override - public ODocument convert(Repository repository) - { - ODocument doc = new ODocument(DOCUMENT_CLASS); - - convert(doc, repository); - - return doc; - } - - /** - * Method description - * - * - * @param doc - * - * @return - */ - @Override - public Repository convert(ODocument doc) - { - Repository repository = new Repository(); - - repository.setId(getStringField(doc, FIELD_ID)); - repository.setType(getStringField(doc, FIELD_TYPE)); - repository.setName(getStringField(doc, FIELD_NAME)); - repository.setContact(getStringField(doc, FIELD_CONTACT)); - repository.setDescription(getStringField(doc, FIELD_DESCRIPTION)); - repository.setPublicReadable(getBooleanField(doc, FIELD_PUBLIC)); - repository.setArchived(getBooleanField(doc, FIELD_ARCHIVED)); - repository.setLastModified(getLongField(doc, FIELD_LASTMODIFIED)); - repository.setCreationDate(getLongField(doc, FIELD_CREATIONDATE)); - - Map properties = doc.field(FIELD_PROPERTIES); - - repository.setProperties(properties); - - List permissions = doc.field(FIELD_PERMISSIONS); - - repository.setPermissions( - OrientDBUtil.transformToItems( - PermissionConverter.INSTANCE, permissions)); - - return repository; - } - - /** - * Method description - * - * - * @param connection - */ - @Override - public void createShema(ODatabaseDocumentTx connection) - { - OSchema schema = connection.getMetadata().getSchema(); - OClass oclass = schema.getClass(DOCUMENT_CLASS); - - if (oclass == null) - { - oclass = schema.createClass(DOCUMENT_CLASS); - - // model properites - oclass.createProperty(FIELD_ID, OType.STRING); - oclass.createProperty(FIELD_TYPE, OType.STRING); - oclass.createProperty(FIELD_LASTMODIFIED, OType.LONG); - - // repository properties - oclass.createProperty(FIELD_CONTACT, OType.STRING); - oclass.createProperty(FIELD_CREATIONDATE, OType.LONG); - oclass.createProperty(FIELD_DESCRIPTION, OType.STRING); - oclass.createProperty(FIELD_NAME, OType.STRING); - oclass.createProperty(FIELD_PERMISSIONS, OType.EMBEDDEDLIST); - oclass.createProperty(FIELD_PROPERTIES, OType.EMBEDDEDMAP); - oclass.createProperty(FIELD_PUBLIC, OType.BOOLEAN); - - // indexes - oclass.createIndex(INDEX_ID, INDEX_TYPE.UNIQUE, FIELD_ID); - oclass.createIndex(INDEX_TYPEANDNAME, INDEX_TYPE.UNIQUE, FIELD_NAME, - FIELD_TYPE); - schema.save(); - } - - PermissionConverter.INSTANCE.createShema(connection); - } -} diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/store/orientdb/OrientDBStore.java b/scm-dao-orientdb/src/main/java/sonia/scm/store/orientdb/OrientDBStore.java deleted file mode 100644 index ff2d791114..0000000000 --- a/scm-dao-orientdb/src/main/java/sonia/scm/store/orientdb/OrientDBStore.java +++ /dev/null @@ -1,222 +0,0 @@ -/** - * 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.store.orientdb; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.google.inject.Provider; - -import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; -import com.orientechnologies.orient.core.record.impl.ODocument; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import sonia.scm.orientdb.OrientDBUtil; -import sonia.scm.store.AbstractListenableStore; -import sonia.scm.util.Util; - -//~--- JDK imports ------------------------------------------------------------ - -import java.io.StringReader; -import java.io.StringWriter; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; - -/** - * - * @author Sebastian Sdorra - * - * @param - */ -public class OrientDBStore extends AbstractListenableStore -{ - - /** Field description */ - public static final String DOCUMENT_CLASS = "StoreObject"; - - /** Field description */ - public static final String FIELD_DATA = "data"; - - /** Field description */ - public static final String FIELD_NAME = "name"; - - /** Field description */ - public static final String FIELD_TYPE = "type"; - - /** Field description */ - public static final String INDEX_NAME = "StoreTypeAndName"; - - /** Field description */ - public static final String QUERY_STORE = - "select from StoreObject where name = ? and type = ?"; - - /** - * the logger for OrientDBStore - */ - private static final Logger logger = - LoggerFactory.getLogger(OrientDBStore.class); - - //~--- constructors --------------------------------------------------------- - - /** - * Constructs ... - * - * - * @param connectionProvider - * @param context - * @param type - * @param name - */ - public OrientDBStore(Provider connectionProvider, - JAXBContext context, Class type, String name) - { - this.connectionProvider = connectionProvider; - this.context = context; - this.type = type; - this.name = name; - } - - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @return - */ - @Override - protected T readObject() - { - T result = null; - ODatabaseDocumentTx connection = connectionProvider.get(); - - try - { - ODocument doc = getStoreDocument(connection); - - if (doc != null) - { - String data = doc.field(FIELD_DATA); - - if (Util.isNotEmpty(data)) - { - StringReader reader = new StringReader(data); - - result = (T) context.createUnmarshaller().unmarshal(reader); - } - } - } - catch (JAXBException ex) - { - logger.error("could not unmarshall object", ex); - } - finally - { - OrientDBUtil.close(connection); - } - - return result; - } - - /** - * Method description - * - * - * @param t - */ - @Override - protected void writeObject(T t) - { - ODatabaseDocumentTx connection = connectionProvider.get(); - - try - { - ODocument doc = getStoreDocument(connection); - - if (doc == null) - { - doc = new ODocument(DOCUMENT_CLASS); - doc.field(FIELD_NAME, name); - doc.field(FIELD_TYPE, type.getName()); - } - - StringWriter buffer = new StringWriter(); - - context.createMarshaller().marshal(t, buffer); - doc.field(FIELD_DATA, buffer.toString()); - doc.save(); - fireEvent(t); - } - catch (JAXBException ex) - { - logger.error("could not marshall object", ex); - } - finally - { - OrientDBUtil.close(connection); - } - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @param connection - * - * @return - */ - private ODocument getStoreDocument(ODatabaseDocumentTx connection) - { - return OrientDBUtil.executeSingleResultQuery(connection, QUERY_STORE, name, - type.getName()); - } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - private Provider connectionProvider; - - /** Field description */ - private JAXBContext context; - - /** Field description */ - private String name; - - /** Field description */ - private Class type; -} diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/store/orientdb/OrientDBStoreFactory.java b/scm-dao-orientdb/src/main/java/sonia/scm/store/orientdb/OrientDBStoreFactory.java deleted file mode 100644 index 7e8c58b308..0000000000 --- a/scm-dao-orientdb/src/main/java/sonia/scm/store/orientdb/OrientDBStoreFactory.java +++ /dev/null @@ -1,162 +0,0 @@ -/** - * 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.store.orientdb; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.google.inject.Inject; -import com.google.inject.Provider; -import com.google.inject.Singleton; - -import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; -import com.orientechnologies.orient.core.metadata.schema.OClass; -import com.orientechnologies.orient.core.metadata.schema.OClass.INDEX_TYPE; -import com.orientechnologies.orient.core.metadata.schema.OSchema; -import com.orientechnologies.orient.core.metadata.schema.OType; - -import sonia.scm.SCMContextProvider; -import sonia.scm.orientdb.OrientDBUtil; -import sonia.scm.store.ListenableStoreFactory; -import sonia.scm.util.AssertUtil; - -//~--- JDK imports ------------------------------------------------------------ - -import java.io.IOException; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; - -/** - * - * @author Sebastian Sdorra - */ -@Singleton -public class OrientDBStoreFactory implements ListenableStoreFactory -{ - - /** - * Constructs ... - * - * - * @param connectionProvider - */ - @Inject - public OrientDBStoreFactory(Provider connectionProvider) - { - this.connectionProvider = connectionProvider; - } - - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @throws IOException - */ - @Override - public void close() throws IOException - { - - // do nothing - } - - /** - * Method description - * - * - * @param context - */ - @Override - public void init(SCMContextProvider context) - { - ODatabaseDocumentTx connection = connectionProvider.get(); - - try - { - OSchema schema = connection.getMetadata().getSchema(); - OClass oclass = schema.getClass(OrientDBStore.DOCUMENT_CLASS); - - if (oclass == null) - { - oclass = schema.createClass(OrientDBStore.DOCUMENT_CLASS); - oclass.createProperty(OrientDBStore.FIELD_NAME, OType.STRING); - oclass.createProperty(OrientDBStore.FIELD_TYPE, OType.STRING); - oclass.createProperty(OrientDBStore.FIELD_DATA, OType.STRING); - oclass.createIndex(OrientDBStore.INDEX_NAME, INDEX_TYPE.UNIQUE, - OrientDBStore.FIELD_NAME, OrientDBStore.FIELD_TYPE); - schema.save(); - } - } - finally - { - OrientDBUtil.close(connection); - } - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @param type - * @param name - * @param - * - * @return - */ - @Override - public OrientDBStore getStore(Class type, String name) - { - AssertUtil.assertIsNotNull(type); - AssertUtil.assertIsNotEmpty(name); - - try - { - return new OrientDBStore(connectionProvider, - JAXBContext.newInstance(type), type, name); - } - catch (JAXBException ex) - { - throw new RuntimeException( - "could not create jaxb context for ".concat(type.getName()), ex); - } - } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - private Provider connectionProvider; -} diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/user/orientdb/OrientDBUserDAO.java b/scm-dao-orientdb/src/main/java/sonia/scm/user/orientdb/OrientDBUserDAO.java deleted file mode 100644 index e2fdf0d59d..0000000000 --- a/scm-dao-orientdb/src/main/java/sonia/scm/user/orientdb/OrientDBUserDAO.java +++ /dev/null @@ -1,112 +0,0 @@ -/** - * 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.user.orientdb; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.google.inject.Inject; -import com.google.inject.Provider; - -import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; -import com.orientechnologies.orient.core.record.impl.ODocument; - -import sonia.scm.orientdb.AbstractOrientDBModelDAO; -import sonia.scm.orientdb.OrientDBUtil; -import sonia.scm.user.User; -import sonia.scm.user.UserDAO; - -//~--- JDK imports ------------------------------------------------------------ - -import java.util.List; - -/** - * - * @author Sebastian Sdorra - */ -public class OrientDBUserDAO extends AbstractOrientDBModelDAO - implements UserDAO -{ - - /** Field description */ - public static final String QUERY_ALL = "select from User"; - - /** Field description */ - public static final String QUERY_SINGLE_BYID = - "select from User where id = ?"; - - //~--- constructors --------------------------------------------------------- - - /** - * Constructs ... - * - * - * @param connectionProvider - */ - @Inject - public OrientDBUserDAO(Provider connectionProvider) - { - super(connectionProvider, UserConverter.INSTANCE); - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @param connection - * - * @return - */ - @Override - protected List getAllDocuments(ODatabaseDocumentTx connection) - { - return OrientDBUtil.executeListResultQuery(connection, QUERY_ALL); - } - - /** - * Method description - * - * - * @param connection - * @param id - * - * @return - */ - @Override - protected ODocument getDocument(ODatabaseDocumentTx connection, String id) - { - return OrientDBUtil.executeSingleResultQuery(connection, QUERY_SINGLE_BYID, - id); - } -} diff --git a/scm-dao-orientdb/src/main/java/sonia/scm/user/orientdb/UserConverter.java b/scm-dao-orientdb/src/main/java/sonia/scm/user/orientdb/UserConverter.java deleted file mode 100644 index 9753f21a19..0000000000 --- a/scm-dao-orientdb/src/main/java/sonia/scm/user/orientdb/UserConverter.java +++ /dev/null @@ -1,195 +0,0 @@ -/** - * 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.user.orientdb; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx; -import com.orientechnologies.orient.core.metadata.schema.OClass; -import com.orientechnologies.orient.core.metadata.schema.OClass.INDEX_TYPE; -import com.orientechnologies.orient.core.metadata.schema.OSchema; -import com.orientechnologies.orient.core.metadata.schema.OType; -import com.orientechnologies.orient.core.record.impl.ODocument; - -import sonia.scm.orientdb.AbstractConverter; -import sonia.scm.orientdb.Converter; -import sonia.scm.user.User; - -//~--- JDK imports ------------------------------------------------------------ - -import java.util.Map; - -/** - * - * @author Sebastian Sdorra - */ -public class UserConverter extends AbstractConverter implements Converter -{ - - /** Field description */ - public static final String DOCUMENT_CLASS = "User"; - - /** Field description */ - public static final String FIELD_ACTIVE = "active"; - - /** Field description */ - public static final String FIELD_ADMIN = "admin"; - - /** Field description */ - public static final String FIELD_CREATIONDATE = "creationDate"; - - /** Field description */ - public static final String FIELD_DISPLAYNAME = "displayName"; - - /** Field description */ - public static final String FIELD_MAIL = "mail"; - - /** Field description */ - @SuppressWarnings("squid:S2068") - public static final String FIELD_PASSWORD = "password"; - - /** Field description */ - public static final String INDEX_ID = "UserId"; - - /** Field description */ - public static final UserConverter INSTANCE = new UserConverter(); - - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param item - * - * @return - */ - @Override - public ODocument convert(User item) - { - ODocument doc = new ODocument(DOCUMENT_CLASS); - - return convert(doc, item); - } - - /** - * Method description - * - * - * @param doc - * @param user - * - * @return - */ - @Override - public ODocument convert(ODocument doc, User user) - { - appendModelObjectFields(doc, user); - appendField(doc, FIELD_DISPLAYNAME, user.getDisplayName()); - appendField(doc, FIELD_MAIL, user.getMail()); - appendField(doc, FIELD_PASSWORD, user.getPassword()); - appendField(doc, FIELD_ADMIN, user.isAdmin()); - appendField(doc, FIELD_ACTIVE, user.isActive()); - appendField(doc, FIELD_CREATIONDATE, user.getCreationDate(), OType.LONG); - appendPropertiesField(doc, user); - - return doc; - } - - /** - * Method description - * - * - * @param doc - * - * @return - */ - @Override - public User convert(ODocument doc) - { - User user = new User(); - - user.setName(getStringField(doc, FIELD_ID)); - user.setDisplayName(getStringField(doc, FIELD_DISPLAYNAME)); - user.setMail(getStringField(doc, FIELD_MAIL)); - user.setPassword(getStringField(doc, FIELD_PASSWORD)); - user.setType(getStringField(doc, FIELD_TYPE)); - user.setAdmin(getBooleanField(doc, FIELD_ADMIN)); - user.setAdmin(getBooleanField(doc, FIELD_ACTIVE)); - user.setLastModified(getLongField(doc, FIELD_LASTMODIFIED)); - user.setCreationDate(getLongField(doc, FIELD_CREATIONDATE)); - - Map properties = doc.field(FIELD_PROPERTIES); - - user.setProperties(properties); - - return user; - } - - /** - * Method description - * - * - * @param connection - */ - @Override - public void createShema(ODatabaseDocumentTx connection) - { - OSchema schema = connection.getMetadata().getSchema(); - OClass oclass = schema.getClass(DOCUMENT_CLASS); - - if (oclass == null) - { - oclass = schema.createClass(DOCUMENT_CLASS); - - // model properites - oclass.createProperty(FIELD_ID, OType.STRING); - oclass.createProperty(FIELD_TYPE, OType.STRING); - oclass.createProperty(FIELD_LASTMODIFIED, OType.LONG); - - // user properties - oclass.createProperty(FIELD_ADMIN, OType.BOOLEAN); - oclass.createProperty(FIELD_CREATIONDATE, OType.LONG); - oclass.createProperty(FIELD_DISPLAYNAME, OType.STRING); - oclass.createProperty(FIELD_MAIL, OType.STRING); - oclass.createProperty(FIELD_ACTIVE, OType.STRING); - oclass.createProperty(FIELD_PASSWORD, OType.STRING); - oclass.createProperty(FIELD_PROPERTIES, OType.EMBEDDEDMAP); - - // indexes - oclass.createIndex(INDEX_ID, INDEX_TYPE.UNIQUE, FIELD_ID); - schema.save(); - } - } -} diff --git a/scm-dao-orientdb/src/main/resources/META-INF/scm/override.xml b/scm-dao-orientdb/src/main/resources/META-INF/scm/override.xml deleted file mode 100644 index f15b1f30e8..0000000000 --- a/scm-dao-orientdb/src/main/resources/META-INF/scm/override.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - sonia.scm.user.UserDAO - sonia.scm.user.orientdb.OrientDBUserDAO - - - - sonia.scm.group.GroupDAO - sonia.scm.group.orientdb.OrientDBGroupDAO - - - - sonia.scm.repository.RepositoryDAO - sonia.scm.repository.orientdb.OrientDBRepositoryDAO - - - - sonia.scm.store.StoreFactory - sonia.scm.store.orientdb.OrientDBStoreFactory - - - sonia.scm.orientdb.OrientDBModule - - \ No newline at end of file diff --git a/scm-dao-orientdb/src/main/resources/sonia/scm/orientdb/server-configuration.xml b/scm-dao-orientdb/src/main/resources/sonia/scm/orientdb/server-configuration.xml deleted file mode 100644 index 797270bbdb..0000000000 --- a/scm-dao-orientdb/src/main/resources/sonia/scm/orientdb/server-configuration.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 4e58b82373a8ae3a8359a3403f3cb424f55a1017 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 5 Apr 2018 21:58:00 +0200 Subject: [PATCH 39/78] update fron sonatype aether to eclipse aether 1.1.0 --- scm-webapp/pom.xml | 162 +++++++++--------- .../scm/plugin/AbstractDependencyFilter.java | 11 +- .../main/java/sonia/scm/plugin/Aether.java | 103 +++++------ .../plugin/AetherAuthenticationSelector.java | 20 +-- .../scm/plugin/AetherDependencyResolver.java | 33 ++-- .../sonia/scm/plugin/AetherPluginHandler.java | 11 +- .../scm/plugin/AetherServiceLocator.java | 63 ++++--- .../scm/plugin/DefaultProxySelector.java | 15 +- .../plugin/StringDependencyGraphDumper.java | 4 +- 9 files changed, 216 insertions(+), 206 deletions(-) diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 8c2d6379ae..43031a8cb1 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -25,22 +25,22 @@ - - + + javax.transaction jta 1.1 provided - + - + sonia.scm scm-core 1.58-SNAPSHOT - + sonia.scm scm-dao-xml @@ -64,7 +64,7 @@ scm-git-plugin 1.58-SNAPSHOT - + @@ -72,7 +72,7 @@ shiro-web ${shiro.version} - + org.apache.shiro shiro-guice @@ -116,13 +116,13 @@ provided - + com.sun.jersey.contribs jersey-multipart ${jersey.version} - + @@ -130,26 +130,26 @@ guice-multibindings ${guice.version} - + ch.qos.logback logback-classic - + org.slf4j jcl-over-slf4j ${slf4j.version} - + org.slf4j log4j-over-slf4j ${slf4j.version} - + @@ -157,46 +157,46 @@ ehcache-core ${ehcache.version} - + - + xml-apis xml-apis 1.4.01 - + - + commons-beanutils commons-beanutils - + commons-collections commons-collections - - - + commons-codec commons-codec 1.9 - + com.google.guava guava ${guava.version} - + org.quartz-scheduler quartz @@ -208,7 +208,7 @@ - + @@ -216,7 +216,7 @@ freemarker ${freemarker.version} - + com.github.spullara.mustache.java compiler @@ -226,13 +226,13 @@ - org.sonatype.aether + org.eclipse.aether aether-api ${aether.version} - org.sonatype.aether + org.eclipse.aether aether-impl ${aether.version} @@ -250,19 +250,25 @@ - org.sonatype.aether - aether-connector-asynchttpclient + org.eclipse.aether + aether-transport-http ${aether.version} - + - org.sonatype.aether - aether-connector-file + org.eclipse.aether + aether-transport-file ${aether.version} - + + + org.eclipse.aether + aether-connector-basic + ${aether.version} + + - + com.webcohesion.enunciate enunciate-core-annotations @@ -283,7 +289,7 @@ - + sonia.scm.plugins scm-git-plugin @@ -291,7 +297,7 @@ tests test - + sonia.scm.plugins scm-hg-plugin @@ -299,7 +305,7 @@ tests test - + sonia.scm.plugins scm-svn-plugin @@ -307,7 +313,7 @@ tests test - + org.seleniumhq.selenium selenium-java @@ -321,7 +327,7 @@ ${selenium.version} test - + org.seleniumhq.selenium htmlunit-driver @@ -342,23 +348,23 @@ ${jersey.version} test - + com.github.sdorra shiro-unit 1.0.0 test - + - + commons-logging commons-logging 1.1.3 provided - + log4j log4j @@ -371,7 +377,7 @@ - + com.mycila.maven-license-plugin maven-license-plugin @@ -393,7 +399,7 @@ true - + org.apache.maven.plugins @@ -412,7 +418,7 @@ - + org.apache.maven.plugins maven-antrun-plugin @@ -444,7 +450,7 @@ - + org.apache.maven.plugins maven-war-plugin @@ -513,8 +519,8 @@ ${project.build.sourceEncoding} 0 - - + + scm-webapp @@ -526,9 +532,9 @@ default 2.53.1 2.9.1 - 1.13.1 + 1.1.0 1.0 - 3.0.5 + 3.3.9 0.8.17 Tomcat e1 @@ -538,18 +544,18 @@ - + cluster - + - + sonia.scm scm-dao-orientdb 1.58-SNAPSHOT - + @@ -679,29 +685,29 @@ - + - + selenium - + - + org.apache.httpcomponents httpclient 4.3.2 test - + - + - + org.apache.maven.plugins maven-failsafe-plugin @@ -726,7 +732,7 @@ - + org.mortbay.jetty jetty-maven-plugin @@ -770,7 +776,7 @@ - + org.codehaus.mojo selenium-maven-plugin @@ -791,22 +797,22 @@ post-integration-test stop-server - + - + - + - + doc - + - + org.apache.maven.plugins maven-resources-plugin @@ -820,7 +826,7 @@ ${project.build.directory} - + src/main/doc true @@ -828,12 +834,12 @@ **/enunciate.xml - - + + - + com.webcohesion.enunciate enunciate-maven-plugin @@ -865,7 +871,7 @@ - + org.apache.maven.plugins maven-assembly-plugin @@ -884,12 +890,12 @@ - + - + diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/AbstractDependencyFilter.java b/scm-webapp/src/main/java/sonia/scm/plugin/AbstractDependencyFilter.java index d448358b64..8a17b1e50c 100644 --- a/scm-webapp/src/main/java/sonia/scm/plugin/AbstractDependencyFilter.java +++ b/scm-webapp/src/main/java/sonia/scm/plugin/AbstractDependencyFilter.java @@ -36,18 +36,13 @@ package sonia.scm.plugin; //~--- non-JDK imports -------------------------------------------------------- import com.google.common.base.Throwables; - +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.graph.DependencyFilter; +import org.eclipse.aether.graph.DependencyNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonatype.aether.artifact.Artifact; -import org.sonatype.aether.graph.DependencyFilter; -import org.sonatype.aether.graph.DependencyNode; - -//~--- JDK imports ------------------------------------------------------------ - import java.io.IOException; - import java.util.List; import java.util.Set; diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/Aether.java b/scm-webapp/src/main/java/sonia/scm/plugin/Aether.java index 0ad53e62c3..0657b167b5 100644 --- a/scm-webapp/src/main/java/sonia/scm/plugin/Aether.java +++ b/scm-webapp/src/main/java/sonia/scm/plugin/Aether.java @@ -35,41 +35,34 @@ package sonia.scm.plugin; //~--- non-JDK imports -------------------------------------------------------- -import org.apache.maven.repository.internal.MavenRepositorySystemSession; - +import com.google.common.base.Throwables; +import org.apache.maven.repository.internal.MavenRepositorySystemUtils; +import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.collection.DependencyCollectionException; +import org.eclipse.aether.collection.DependencyGraphTransformer; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.graph.DependencyFilter; +import org.eclipse.aether.graph.DependencyNode; +import org.eclipse.aether.repository.*; +import org.eclipse.aether.resolution.DependencyRequest; +import org.eclipse.aether.resolution.DependencyResolutionException; +import org.eclipse.aether.spi.locator.ServiceLocator; +import org.eclipse.aether.util.artifact.JavaScopes; +import org.eclipse.aether.util.filter.AndDependencyFilter; +import org.eclipse.aether.util.filter.DependencyFilterUtils; +import org.eclipse.aether.util.graph.transformer.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import org.sonatype.aether.RepositorySystem; -import org.sonatype.aether.RepositorySystemSession; -import org.sonatype.aether.collection.CollectRequest; -import org.sonatype.aether.collection.DependencyCollectionException; -import org.sonatype.aether.collection.DependencyGraphTransformer; -import org.sonatype.aether.graph.Dependency; -import org.sonatype.aether.graph.DependencyFilter; -import org.sonatype.aether.graph.DependencyNode; -import org.sonatype.aether.repository.LocalRepository; -import org.sonatype.aether.repository.LocalRepositoryManager; -import org.sonatype.aether.repository.Proxy; -import org.sonatype.aether.repository.RemoteRepository; -import org.sonatype.aether.repository.RepositoryPolicy; -import org.sonatype.aether.resolution.DependencyRequest; -import org.sonatype.aether.resolution.DependencyResolutionException; -import org.sonatype.aether.util.artifact.DefaultArtifact; -import org.sonatype.aether.util.artifact.JavaScopes; -import org.sonatype.aether.util.filter.AndDependencyFilter; -import org.sonatype.aether.util.filter.DependencyFilterUtils; -import org.sonatype.aether.util.graph.transformer - .ChainedDependencyGraphTransformer; -import org.sonatype.aether.util.graph.transformer.ConflictMarker; -import org.sonatype.aether.util.graph.transformer.JavaDependencyContextRefiner; -import org.sonatype.aether.util.graph.transformer.JavaEffectiveScopeCalculator; -import org.sonatype.aether.util.graph.transformer - .NearestVersionConflictResolver; - import sonia.scm.config.ScmConfiguration; import sonia.scm.net.Proxies; +import java.net.MalformedURLException; +import java.net.URL; + /** * * @author Sebastian Sdorra @@ -77,6 +70,8 @@ import sonia.scm.net.Proxies; public final class Aether { + private static final ServiceLocator serviceLocator = new AetherServiceLocator(); + /** Field description */ private static final DependencyFilter FILTER = new AndDependencyFilter(new CoreDependencyFilter(), @@ -134,11 +129,9 @@ public final class Aether public static RemoteRepository createRemoteRepository( ScmConfiguration configuration, PluginRepository pluginRepository) { - RemoteRepository remoteRepository = - new RemoteRepository(pluginRepository.getId(), "default", - pluginRepository.getUrl()); + RemoteRepository.Builder builder = new RemoteRepository.Builder(pluginRepository.getId(), "default", pluginRepository.getUrl()); - if (Proxies.isEnabled(configuration, remoteRepository.getHost())) + if (Proxies.isEnabled(configuration, hostFromUrl(pluginRepository.getUrl()))) { Proxy proxy = DefaultProxySelector.createProxy(configuration); @@ -148,10 +141,18 @@ public final class Aether pluginRepository.getUrl()); } - remoteRepository.setProxy(proxy); + builder.setProxy(proxy); } - return remoteRepository; + return builder.build(); + } + + private static String hostFromUrl(String url) { + try { + return new URL(url).getHost(); + } catch (MalformedURLException e) { + throw Throwables.propagate(e); + } } /** @@ -162,7 +163,7 @@ public final class Aether */ public static RepositorySystem createRepositorySystem() { - return new AetherServiceLocator().getService(RepositorySystem.class); + return serviceLocator.getService(RepositorySystem.class); } /** @@ -181,8 +182,7 @@ public final class Aether ScmConfiguration configuration, AdvancedPluginConfiguration advancedPluginConfiguration) { - MavenRepositorySystemSession session = new MavenRepositorySystemSession(); - + DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); session.setChecksumPolicy(RepositoryPolicy.CHECKSUM_POLICY_WARN); if (configuration.isEnableProxy()) @@ -191,23 +191,26 @@ public final class Aether session.setProxySelector(new DefaultProxySelector(configuration)); } - LocalRepositoryManager localRepositoryManager = - system.newLocalRepositoryManager(localRepository); + LocalRepositoryManager localRepositoryManager = system.newLocalRepositoryManager(session, localRepository); session.setLocalRepositoryManager(localRepositoryManager); session.setAuthenticationSelector( new AetherAuthenticationSelector(advancedPluginConfiguration) ); - // create graph transformer to resolve dependency conflicts - //J- - DependencyGraphTransformer dgt = new ChainedDependencyGraphTransformer( - new ConflictMarker(), - new JavaEffectiveScopeCalculator(), - new NearestVersionConflictResolver(), - new JavaDependencyContextRefiner() + // create graph transformer and conflictResolver to resolve dependency conflicts + ConflictResolver conflictResolver = new ConflictResolver( + new NearestVersionSelector(), + new JavaScopeSelector(), + new SimpleOptionalitySelector(), + new JavaScopeDeriver() + ); + + DependencyGraphTransformer dgt = new ChainedDependencyGraphTransformer( + new ConflictMarker(), + conflictResolver, + new JavaDependencyContextRefiner() ); - //J+ session.setDependencyGraphTransformer(dgt); @@ -228,7 +231,7 @@ public final class Aether * @throws DependencyResolutionException */ public static DependencyNode resolveDependencies(RepositorySystem system, - RepositorySystemSession session, CollectRequest request) + RepositorySystemSession session, CollectRequest request) throws DependencyCollectionException, DependencyResolutionException { DependencyNode node = system.collectDependencies(session, diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/AetherAuthenticationSelector.java b/scm-webapp/src/main/java/sonia/scm/plugin/AetherAuthenticationSelector.java index 1f264940f8..59e8eb481e 100644 --- a/scm-webapp/src/main/java/sonia/scm/plugin/AetherAuthenticationSelector.java +++ b/scm-webapp/src/main/java/sonia/scm/plugin/AetherAuthenticationSelector.java @@ -36,20 +36,18 @@ package sonia.scm.plugin; import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; - +import org.eclipse.aether.repository.Authentication; +import org.eclipse.aether.repository.AuthenticationSelector; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.util.repository.AuthenticationBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import org.sonatype.aether.repository.Authentication; -import org.sonatype.aether.repository.AuthenticationSelector; -import org.sonatype.aether.repository.RemoteRepository; - import sonia.scm.plugin.AdvancedPluginConfiguration.Server; -//~--- JDK imports ------------------------------------------------------------ - import java.util.Map; +//~--- JDK imports ------------------------------------------------------------ + /** * * @author Sebastian Sdorra @@ -115,8 +113,10 @@ public class AetherAuthenticationSelector implements AuthenticationSelector { logger.info("use user {} for repository wiht id {}", server.getUsername(), repository.getId()); - authentication = new Authentication(server.getUsername(), - server.getPassword()); + authentication = new AuthenticationBuilder() + .addUsername(server.getUsername()) + .addPassword(server.getPassword()) + .build(); } return authentication; diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/AetherDependencyResolver.java b/scm-webapp/src/main/java/sonia/scm/plugin/AetherDependencyResolver.java index ee0e9b586c..f4e26b9955 100644 --- a/scm-webapp/src/main/java/sonia/scm/plugin/AetherDependencyResolver.java +++ b/scm-webapp/src/main/java/sonia/scm/plugin/AetherDependencyResolver.java @@ -36,27 +36,24 @@ package sonia.scm.plugin; //~--- non-JDK imports -------------------------------------------------------- import com.google.common.collect.Lists; - +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.collection.DependencyCollectionException; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.graph.DependencyNode; +import org.eclipse.aether.repository.LocalRepository; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.resolution.DependencyResolutionException; +import org.eclipse.aether.util.graph.visitor.PreorderNodeListGenerator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import org.sonatype.aether.RepositorySystem; -import org.sonatype.aether.RepositorySystemSession; -import org.sonatype.aether.collection.CollectRequest; -import org.sonatype.aether.collection.DependencyCollectionException; -import org.sonatype.aether.graph.Dependency; -import org.sonatype.aether.graph.DependencyNode; -import org.sonatype.aether.repository.LocalRepository; -import org.sonatype.aether.repository.RemoteRepository; -import org.sonatype.aether.resolution.DependencyResolutionException; -import org.sonatype.aether.util.graph.PreorderNodeListGenerator; - import sonia.scm.config.ScmConfiguration; -//~--- JDK imports ------------------------------------------------------------ - import java.util.List; +//~--- JDK imports ------------------------------------------------------------ + /** * * @author Sebastian Sdorra @@ -83,9 +80,9 @@ public class AetherDependencyResolver * @param remoteRepositories */ public AetherDependencyResolver(ScmConfiguration configuration, - AdvancedPluginConfiguration advancedPluginConfiguration, - RepositorySystem system, LocalRepository localRepository, - List remoteRepositories) + AdvancedPluginConfiguration advancedPluginConfiguration, + RepositorySystem system, LocalRepository localRepository, + List remoteRepositories) { this.configuration = configuration; this.advancedPluginConfiguration = advancedPluginConfiguration; diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/AetherPluginHandler.java b/scm-webapp/src/main/java/sonia/scm/plugin/AetherPluginHandler.java index b122463a24..8668277f12 100644 --- a/scm-webapp/src/main/java/sonia/scm/plugin/AetherPluginHandler.java +++ b/scm-webapp/src/main/java/sonia/scm/plugin/AetherPluginHandler.java @@ -40,10 +40,10 @@ import com.google.common.collect.Lists; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonatype.aether.RepositorySystem; -import org.sonatype.aether.graph.Dependency; -import org.sonatype.aether.repository.LocalRepository; -import org.sonatype.aether.repository.RemoteRepository; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.repository.LocalRepository; +import org.eclipse.aether.repository.RemoteRepository; import sonia.scm.ConfigurationException; import sonia.scm.SCMContextProvider; @@ -190,7 +190,6 @@ public class AetherPluginHandler * * * @param dependency - * @param dependencies * @param localDependencies */ private void collectDependencies(Dependency dependency, @@ -200,7 +199,7 @@ public class AetherPluginHandler { //J- AetherDependencyResolver resolver = new AetherDependencyResolver( - configuration, advancedPluginConfiguration, repositorySystem, + configuration, advancedPluginConfiguration, repositorySystem, localRepository, remoteRepositories ); //J+ diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/AetherServiceLocator.java b/scm-webapp/src/main/java/sonia/scm/plugin/AetherServiceLocator.java index 79038a4102..4220064882 100644 --- a/scm-webapp/src/main/java/sonia/scm/plugin/AetherServiceLocator.java +++ b/scm-webapp/src/main/java/sonia/scm/plugin/AetherServiceLocator.java @@ -37,32 +37,30 @@ package sonia.scm.plugin; import org.apache.maven.repository.internal.DefaultArtifactDescriptorReader; import org.apache.maven.repository.internal.DefaultVersionRangeResolver; import org.apache.maven.repository.internal.DefaultVersionResolver; +import org.apache.maven.repository.internal.MavenRepositorySystemUtils; +import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; +import org.eclipse.aether.impl.ArtifactDescriptorReader; +import org.eclipse.aether.impl.DefaultServiceLocator; +import org.eclipse.aether.impl.VersionRangeResolver; +import org.eclipse.aether.impl.VersionResolver; +import org.eclipse.aether.internal.impl.slf4j.Slf4jLoggerFactory; +import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; +import org.eclipse.aether.spi.connector.transport.TransporterFactory; +import org.eclipse.aether.spi.locator.ServiceLocator; +import org.eclipse.aether.spi.log.LoggerFactory; +import org.eclipse.aether.transport.file.FileTransporterFactory; +import org.eclipse.aether.transport.http.HttpTransporterFactory; -import org.slf4j.LoggerFactory; - -import org.sonatype.aether.connector.async.AsyncRepositoryConnectorFactory; -import org.sonatype.aether.connector.file.FileRepositoryConnectorFactory; -import org.sonatype.aether.impl.ArtifactDescriptorReader; -import org.sonatype.aether.impl.VersionRangeResolver; -import org.sonatype.aether.impl.VersionResolver; -import org.sonatype.aether.impl.internal.DefaultServiceLocator; -import org.sonatype.aether.impl.internal.Slf4jLogger; -import org.sonatype.aether.spi.connector.RepositoryConnectorFactory; -import org.sonatype.aether.spi.log.Logger; +import java.util.List; /** * * @author Sebastian Sdorra */ -public class AetherServiceLocator extends DefaultServiceLocator +public class AetherServiceLocator implements ServiceLocator { - /** Field description */ - private static final String LOGGER_NAME = "org.sonatype.aether"; - - /** Field description */ - private static final Slf4jLogger logger = - new Slf4jLogger(LoggerFactory.getLogger(LOGGER_NAME)); + private DefaultServiceLocator delegate; //~--- constructors --------------------------------------------------------- @@ -70,16 +68,25 @@ public class AetherServiceLocator extends DefaultServiceLocator * Constructs ... * */ - public AetherServiceLocator() + AetherServiceLocator() { - setServices(Logger.class, logger); - addService(VersionResolver.class, DefaultVersionResolver.class); - addService(VersionRangeResolver.class, DefaultVersionRangeResolver.class); - addService(ArtifactDescriptorReader.class, - DefaultArtifactDescriptorReader.class); - addService(RepositoryConnectorFactory.class, - AsyncRepositoryConnectorFactory.class); - addService(RepositoryConnectorFactory.class, - FileRepositoryConnectorFactory.class); + delegate = MavenRepositorySystemUtils.newServiceLocator(); + delegate.setService(LoggerFactory.class, Slf4jLoggerFactory.class); + delegate.addService(VersionResolver.class, DefaultVersionResolver.class); + delegate.addService(VersionRangeResolver.class, DefaultVersionRangeResolver.class); + delegate.addService(ArtifactDescriptorReader.class, DefaultArtifactDescriptorReader.class); + delegate.addService(TransporterFactory.class, HttpTransporterFactory.class); + delegate.addService(TransporterFactory.class, FileTransporterFactory.class); + delegate.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class); + } + + @Override + public T getService(Class type) { + return delegate.getService(type); + } + + @Override + public List getServices(Class type) { + return delegate.getServices(type); } } diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/DefaultProxySelector.java b/scm-webapp/src/main/java/sonia/scm/plugin/DefaultProxySelector.java index fd3ad16507..ba694e01a8 100644 --- a/scm-webapp/src/main/java/sonia/scm/plugin/DefaultProxySelector.java +++ b/scm-webapp/src/main/java/sonia/scm/plugin/DefaultProxySelector.java @@ -34,13 +34,13 @@ package sonia.scm.plugin; //~--- non-JDK imports -------------------------------------------------------- +import org.eclipse.aether.repository.Authentication; +import org.eclipse.aether.repository.Proxy; +import org.eclipse.aether.repository.ProxySelector; +import org.eclipse.aether.repository.RemoteRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonatype.aether.repository.Authentication; -import org.sonatype.aether.repository.Proxy; -import org.sonatype.aether.repository.ProxySelector; -import org.sonatype.aether.repository.RemoteRepository; import sonia.scm.config.ScmConfiguration; import sonia.scm.util.Util; @@ -89,8 +89,11 @@ public class DefaultProxySelector implements ProxySelector if (Util.isNotEmpty(username) || Util.isNotEmpty(password)) { - authentication = new Authentication(Util.nonNull(username), - Util.nonNull(password)); + /* + TODO + authentication = new Authentication(Util.nonNull(username), Util.nonNull(password)); + */ + } return new Proxy(Proxy.TYPE_HTTP, configuration.getProxyServer(), diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/StringDependencyGraphDumper.java b/scm-webapp/src/main/java/sonia/scm/plugin/StringDependencyGraphDumper.java index 5bfcdebd23..126be9da6a 100644 --- a/scm-webapp/src/main/java/sonia/scm/plugin/StringDependencyGraphDumper.java +++ b/scm-webapp/src/main/java/sonia/scm/plugin/StringDependencyGraphDumper.java @@ -34,8 +34,8 @@ package sonia.scm.plugin; //~--- non-JDK imports -------------------------------------------------------- -import org.sonatype.aether.graph.DependencyNode; -import org.sonatype.aether.graph.DependencyVisitor; +import org.eclipse.aether.graph.DependencyNode; +import org.eclipse.aether.graph.DependencyVisitor; /** * From 49168b10a7dd38ee2678857e0fa7ff5c9a943857 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 5 Apr 2018 21:59:41 +0200 Subject: [PATCH 40/78] update apache shiro to version 1.3.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6e4b76b847..65d5b6e35a 100644 --- a/pom.xml +++ b/pom.xml @@ -490,7 +490,7 @@ 1.9.13 - 1.3.0 + 1.3.2 v4.5.3.201708160445-r-scm1 From 482589fc67881c7e15e0da66b307e54dc125624c Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 6 Apr 2018 08:28:50 +0200 Subject: [PATCH 41/78] [maven-release-plugin] prepare release 1.58 --- maven/pom.xml | 4 ++-- maven/scm-maven-plugin/pom.xml | 4 ++-- maven/scm-plugin-archetype/pom.xml | 4 ++-- pom.xml | 4 ++-- scm-clients/pom.xml | 6 +++--- scm-clients/scm-cli-client/pom.xml | 6 +++--- scm-clients/scm-client-api/pom.xml | 4 ++-- scm-clients/scm-client-impl/pom.xml | 8 ++++---- scm-core/pom.xml | 4 ++-- scm-dao-xml/pom.xml | 8 ++++---- scm-plugin-backend/pom.xml | 6 +++--- scm-plugins/pom.xml | 8 ++++---- scm-plugins/scm-git-plugin/pom.xml | 6 +++--- scm-plugins/scm-hg-plugin/pom.xml | 6 +++--- scm-plugins/scm-svn-plugin/pom.xml | 6 +++--- scm-samples/pom.xml | 4 ++-- scm-samples/scm-sample-auth/pom.xml | 6 +++--- scm-samples/scm-sample-hello/pom.xml | 6 +++--- scm-server/pom.xml | 4 ++-- scm-test/pom.xml | 6 +++--- scm-webapp/pom.xml | 22 +++++++++++----------- support/pom.xml | 4 ++-- support/scm-support-btrace/pom.xml | 6 +++--- 23 files changed, 71 insertions(+), 71 deletions(-) diff --git a/maven/pom.xml b/maven/pom.xml index d371d05c94..b035bf6ae1 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.58-SNAPSHOT + 1.58 sonia.scm.maven scm-maven-plugins pom - 1.58-SNAPSHOT + 1.58 scm-maven-plugins diff --git a/maven/scm-maven-plugin/pom.xml b/maven/scm-maven-plugin/pom.xml index f6d85bf8cb..df4251d610 100644 --- a/maven/scm-maven-plugin/pom.xml +++ b/maven/scm-maven-plugin/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.58-SNAPSHOT + 1.58 sonia.scm.maven scm-maven-plugin - 1.58-SNAPSHOT + 1.58 maven-plugin scm-maven-plugin diff --git a/maven/scm-plugin-archetype/pom.xml b/maven/scm-plugin-archetype/pom.xml index 201664de81..4914db4c6a 100644 --- a/maven/scm-plugin-archetype/pom.xml +++ b/maven/scm-plugin-archetype/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.58-SNAPSHOT + 1.58 sonia.scm.maven scm-plugin-archetype - 1.58-SNAPSHOT + 1.58 scm-plugin-archetype diff --git a/pom.xml b/pom.xml index 65d5b6e35a..7a8ece68b0 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ sonia.scm scm pom - 1.58-SNAPSHOT + 1.58 The easiest way to share your Git, Mercurial and Subversion repositories over http. @@ -36,7 +36,7 @@ scm:hg:http://bitbucket.org/sdorra/scm-manager scm:hg:https://bitbucket.org/sdorra/scm-manager http://bitbucket.org/sdorra/scm-manager - HEAD + 1.58 diff --git a/scm-clients/pom.xml b/scm-clients/pom.xml index 0e18675860..82ec11c4ed 100644 --- a/scm-clients/pom.xml +++ b/scm-clients/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.58-SNAPSHOT + 1.58 sonia.scm.clients scm-clients pom - 1.58-SNAPSHOT + 1.58 scm-clients @@ -32,7 +32,7 @@ scm-core sonia.scm jar - 1.58-SNAPSHOT + 1.58 shiro-core diff --git a/scm-clients/scm-cli-client/pom.xml b/scm-clients/scm-cli-client/pom.xml index 1d26cee2b4..8360abe06f 100644 --- a/scm-clients/scm-cli-client/pom.xml +++ b/scm-clients/scm-cli-client/pom.xml @@ -6,12 +6,12 @@ scm-clients sonia.scm.clients - 1.58-SNAPSHOT + 1.58 sonia.scm.clients scm-cli-client - 1.58-SNAPSHOT + 1.58 scm-cli-client @@ -34,7 +34,7 @@ sonia.scm.clients scm-client-impl - 1.58-SNAPSHOT + 1.58 diff --git a/scm-clients/scm-client-api/pom.xml b/scm-clients/scm-client-api/pom.xml index 75ac3d81d7..a6f2fdf3b7 100644 --- a/scm-clients/scm-client-api/pom.xml +++ b/scm-clients/scm-client-api/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.58-SNAPSHOT + 1.58 sonia.scm.clients scm-client-api jar - 1.58-SNAPSHOT + 1.58 scm-client-api diff --git a/scm-clients/scm-client-impl/pom.xml b/scm-clients/scm-client-impl/pom.xml index e97a96e380..1278c841e5 100644 --- a/scm-clients/scm-client-impl/pom.xml +++ b/scm-clients/scm-client-impl/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.58-SNAPSHOT + 1.58 sonia.scm.clients scm-client-impl jar - 1.58-SNAPSHOT + 1.58 scm-client-impl @@ -36,7 +36,7 @@ sonia.scm.clients scm-client-api - 1.58-SNAPSHOT + 1.58 @@ -70,7 +70,7 @@ sonia.scm scm-test - 1.58-SNAPSHOT + 1.58 test diff --git a/scm-core/pom.xml b/scm-core/pom.xml index 72c40c1f9a..67baea7f97 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.58-SNAPSHOT + 1.58 sonia.scm scm-core - 1.58-SNAPSHOT + 1.58 scm-core diff --git a/scm-dao-xml/pom.xml b/scm-dao-xml/pom.xml index a6f7898246..7694ccbb6f 100644 --- a/scm-dao-xml/pom.xml +++ b/scm-dao-xml/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.58-SNAPSHOT + 1.58 sonia.scm scm-dao-xml - 1.58-SNAPSHOT + 1.58 scm-dao-xml @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.58-SNAPSHOT + 1.58 @@ -34,7 +34,7 @@ sonia.scm scm-test - 1.58-SNAPSHOT + 1.58 test diff --git a/scm-plugin-backend/pom.xml b/scm-plugin-backend/pom.xml index bc59a101a8..aa99261ecb 100644 --- a/scm-plugin-backend/pom.xml +++ b/scm-plugin-backend/pom.xml @@ -6,13 +6,13 @@ scm sonia.scm - 1.58-SNAPSHOT + 1.58 sonia.scm scm-plugin-backend war - 1.58-SNAPSHOT + 1.58 ${project.artifactId} @@ -62,7 +62,7 @@ sonia.scm scm-core - 1.58-SNAPSHOT + 1.58 diff --git a/scm-plugins/pom.xml b/scm-plugins/pom.xml index e11e11ebde..f42a7a58dc 100644 --- a/scm-plugins/pom.xml +++ b/scm-plugins/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.58-SNAPSHOT + 1.58 sonia.scm.plugins scm-plugins pom - 1.58-SNAPSHOT + 1.58 scm-plugins @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.58-SNAPSHOT + 1.58 @@ -59,7 +59,7 @@ sonia.scm.maven scm-maven-plugin - 1.58-SNAPSHOT + 1.58 process-resources diff --git a/scm-plugins/scm-git-plugin/pom.xml b/scm-plugins/scm-git-plugin/pom.xml index 60c617cfd1..a3135bebea 100644 --- a/scm-plugins/scm-git-plugin/pom.xml +++ b/scm-plugins/scm-git-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.58-SNAPSHOT + 1.58 sonia.scm.plugins scm-git-plugin - 1.58-SNAPSHOT + 1.58 scm-git-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Git @@ -54,7 +54,7 @@ sonia.scm scm-test - 1.58-SNAPSHOT + 1.58 test diff --git a/scm-plugins/scm-hg-plugin/pom.xml b/scm-plugins/scm-hg-plugin/pom.xml index 0bced018e6..4e081d3766 100644 --- a/scm-plugins/scm-hg-plugin/pom.xml +++ b/scm-plugins/scm-hg-plugin/pom.xml @@ -6,12 +6,12 @@ sonia.scm.plugins scm-plugins - 1.58-SNAPSHOT + 1.58 sonia.scm.plugins scm-hg-plugin - 1.58-SNAPSHOT + 1.58 scm-hg-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Mercurial @@ -42,7 +42,7 @@ sonia.scm scm-test - 1.58-SNAPSHOT + 1.58 test diff --git a/scm-plugins/scm-svn-plugin/pom.xml b/scm-plugins/scm-svn-plugin/pom.xml index 0be176d42c..b3f5214239 100644 --- a/scm-plugins/scm-svn-plugin/pom.xml +++ b/scm-plugins/scm-svn-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.58-SNAPSHOT + 1.58 sonia.scm.plugins scm-svn-plugin - 1.58-SNAPSHOT + 1.58 scm-svn-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Subversion @@ -48,7 +48,7 @@ sonia.scm scm-test - 1.58-SNAPSHOT + 1.58 test diff --git a/scm-samples/pom.xml b/scm-samples/pom.xml index 22e4b9cc04..a5712aa81d 100644 --- a/scm-samples/pom.xml +++ b/scm-samples/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.58-SNAPSHOT + 1.58 sonia.scm.samples scm-samples pom - 1.58-SNAPSHOT + 1.58 scm-samples diff --git a/scm-samples/scm-sample-auth/pom.xml b/scm-samples/scm-sample-auth/pom.xml index 05ec3fddd9..13ec4d8266 100644 --- a/scm-samples/scm-sample-auth/pom.xml +++ b/scm-samples/scm-sample-auth/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.58-SNAPSHOT + 1.58 sonia.scm.sample scm-sample-auth - 1.58-SNAPSHOT + 1.58 scm-sample-auth Sample Authentication Plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.58-SNAPSHOT + 1.58 diff --git a/scm-samples/scm-sample-hello/pom.xml b/scm-samples/scm-sample-hello/pom.xml index f896257930..67b34814d1 100644 --- a/scm-samples/scm-sample-hello/pom.xml +++ b/scm-samples/scm-sample-hello/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.58-SNAPSHOT + 1.58 sonia.scm.sample scm-sample-hello - 1.58-SNAPSHOT + 1.58 scm-sample-hello A simple hello world plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.58-SNAPSHOT + 1.58 diff --git a/scm-server/pom.xml b/scm-server/pom.xml index 50c77d05fd..b5c1bbff15 100644 --- a/scm-server/pom.xml +++ b/scm-server/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.58-SNAPSHOT + 1.58 sonia.scm scm-server - 1.58-SNAPSHOT + 1.58 scm-server jar diff --git a/scm-test/pom.xml b/scm-test/pom.xml index 3f769f3367..6de92ac324 100644 --- a/scm-test/pom.xml +++ b/scm-test/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.58-SNAPSHOT + 1.58 sonia.scm scm-test - 1.58-SNAPSHOT + 1.58 scm-test @@ -25,7 +25,7 @@ sonia.scm scm-core - 1.58-SNAPSHOT + 1.58 diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 43031a8cb1..c4c0e54bee 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.58-SNAPSHOT + 1.58 sonia.scm scm-webapp war - 1.58-SNAPSHOT + 1.58 scm-webapp @@ -38,31 +38,31 @@ sonia.scm scm-core - 1.58-SNAPSHOT + 1.58 sonia.scm scm-dao-xml - 1.58-SNAPSHOT + 1.58 sonia.scm.plugins scm-hg-plugin - 1.58-SNAPSHOT + 1.58 sonia.scm.plugins scm-svn-plugin - 1.58-SNAPSHOT + 1.58 sonia.scm.plugins scm-git-plugin - 1.58-SNAPSHOT + 1.58 @@ -280,7 +280,7 @@ sonia.scm scm-test - 1.58-SNAPSHOT + 1.58 test @@ -293,7 +293,7 @@ sonia.scm.plugins scm-git-plugin - 1.58-SNAPSHOT + 1.58 tests test @@ -301,7 +301,7 @@ sonia.scm.plugins scm-hg-plugin - 1.58-SNAPSHOT + 1.58 tests test @@ -309,7 +309,7 @@ sonia.scm.plugins scm-svn-plugin - 1.58-SNAPSHOT + 1.58 tests test diff --git a/support/pom.xml b/support/pom.xml index 9db5842b99..768b99b4b6 100644 --- a/support/pom.xml +++ b/support/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.58-SNAPSHOT + 1.58 sonia.scm.support scm-support pom - 1.58-SNAPSHOT + 1.58 scm-support diff --git a/support/scm-support-btrace/pom.xml b/support/scm-support-btrace/pom.xml index 28b1febe75..fbc1f06fdc 100644 --- a/support/scm-support-btrace/pom.xml +++ b/support/scm-support-btrace/pom.xml @@ -4,12 +4,12 @@ sonia.scm.support scm-support - 1.58-SNAPSHOT + 1.58 sonia.scm scm-support-btrace - 1.58-SNAPSHOT + 1.58 jar scm-support-btrace @@ -18,7 +18,7 @@ sonia.scm scm-core - 1.58-SNAPSHOT + 1.58 From 5575b4cd11087649ca18dd38ec5987919e58638c Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 6 Apr 2018 08:28:51 +0200 Subject: [PATCH 42/78] [maven-release-plugin] copy for tag 1.58 From dd313036ffbb9a75ac71198a2c59fec3e5db3fc9 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 6 Apr 2018 08:28:51 +0200 Subject: [PATCH 43/78] [maven-release-plugin] prepare for next development iteration --- maven/pom.xml | 4 ++-- maven/scm-maven-plugin/pom.xml | 4 ++-- maven/scm-plugin-archetype/pom.xml | 4 ++-- pom.xml | 4 ++-- scm-clients/pom.xml | 6 +++--- scm-clients/scm-cli-client/pom.xml | 6 +++--- scm-clients/scm-client-api/pom.xml | 4 ++-- scm-clients/scm-client-impl/pom.xml | 8 ++++---- scm-core/pom.xml | 4 ++-- scm-dao-xml/pom.xml | 8 ++++---- scm-plugin-backend/pom.xml | 6 +++--- scm-plugins/pom.xml | 8 ++++---- scm-plugins/scm-git-plugin/pom.xml | 6 +++--- scm-plugins/scm-hg-plugin/pom.xml | 6 +++--- scm-plugins/scm-svn-plugin/pom.xml | 6 +++--- scm-samples/pom.xml | 4 ++-- scm-samples/scm-sample-auth/pom.xml | 6 +++--- scm-samples/scm-sample-hello/pom.xml | 6 +++--- scm-server/pom.xml | 4 ++-- scm-test/pom.xml | 6 +++--- scm-webapp/pom.xml | 22 +++++++++++----------- support/pom.xml | 4 ++-- support/scm-support-btrace/pom.xml | 6 +++--- 23 files changed, 71 insertions(+), 71 deletions(-) diff --git a/maven/pom.xml b/maven/pom.xml index b035bf6ae1..a1ed336d8c 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.58 + 1.59-SNAPSHOT sonia.scm.maven scm-maven-plugins pom - 1.58 + 1.59-SNAPSHOT scm-maven-plugins diff --git a/maven/scm-maven-plugin/pom.xml b/maven/scm-maven-plugin/pom.xml index df4251d610..c52e518a7d 100644 --- a/maven/scm-maven-plugin/pom.xml +++ b/maven/scm-maven-plugin/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.58 + 1.59-SNAPSHOT sonia.scm.maven scm-maven-plugin - 1.58 + 1.59-SNAPSHOT maven-plugin scm-maven-plugin diff --git a/maven/scm-plugin-archetype/pom.xml b/maven/scm-plugin-archetype/pom.xml index 4914db4c6a..4b74d47a7c 100644 --- a/maven/scm-plugin-archetype/pom.xml +++ b/maven/scm-plugin-archetype/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.58 + 1.59-SNAPSHOT sonia.scm.maven scm-plugin-archetype - 1.58 + 1.59-SNAPSHOT scm-plugin-archetype diff --git a/pom.xml b/pom.xml index 7a8ece68b0..eb5d09d1fe 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ sonia.scm scm pom - 1.58 + 1.59-SNAPSHOT The easiest way to share your Git, Mercurial and Subversion repositories over http. @@ -36,7 +36,7 @@ scm:hg:http://bitbucket.org/sdorra/scm-manager scm:hg:https://bitbucket.org/sdorra/scm-manager http://bitbucket.org/sdorra/scm-manager - 1.58 + HEAD diff --git a/scm-clients/pom.xml b/scm-clients/pom.xml index 82ec11c4ed..1903d4ea2a 100644 --- a/scm-clients/pom.xml +++ b/scm-clients/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.58 + 1.59-SNAPSHOT sonia.scm.clients scm-clients pom - 1.58 + 1.59-SNAPSHOT scm-clients @@ -32,7 +32,7 @@ scm-core sonia.scm jar - 1.58 + 1.59-SNAPSHOT shiro-core diff --git a/scm-clients/scm-cli-client/pom.xml b/scm-clients/scm-cli-client/pom.xml index 8360abe06f..7b3d7d9464 100644 --- a/scm-clients/scm-cli-client/pom.xml +++ b/scm-clients/scm-cli-client/pom.xml @@ -6,12 +6,12 @@ scm-clients sonia.scm.clients - 1.58 + 1.59-SNAPSHOT sonia.scm.clients scm-cli-client - 1.58 + 1.59-SNAPSHOT scm-cli-client @@ -34,7 +34,7 @@ sonia.scm.clients scm-client-impl - 1.58 + 1.59-SNAPSHOT diff --git a/scm-clients/scm-client-api/pom.xml b/scm-clients/scm-client-api/pom.xml index a6f2fdf3b7..74dcb8c861 100644 --- a/scm-clients/scm-client-api/pom.xml +++ b/scm-clients/scm-client-api/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.58 + 1.59-SNAPSHOT sonia.scm.clients scm-client-api jar - 1.58 + 1.59-SNAPSHOT scm-client-api diff --git a/scm-clients/scm-client-impl/pom.xml b/scm-clients/scm-client-impl/pom.xml index 1278c841e5..e6cae0bbaa 100644 --- a/scm-clients/scm-client-impl/pom.xml +++ b/scm-clients/scm-client-impl/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.58 + 1.59-SNAPSHOT sonia.scm.clients scm-client-impl jar - 1.58 + 1.59-SNAPSHOT scm-client-impl @@ -36,7 +36,7 @@ sonia.scm.clients scm-client-api - 1.58 + 1.59-SNAPSHOT @@ -70,7 +70,7 @@ sonia.scm scm-test - 1.58 + 1.59-SNAPSHOT test diff --git a/scm-core/pom.xml b/scm-core/pom.xml index 67baea7f97..8371073636 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.58 + 1.59-SNAPSHOT sonia.scm scm-core - 1.58 + 1.59-SNAPSHOT scm-core diff --git a/scm-dao-xml/pom.xml b/scm-dao-xml/pom.xml index 7694ccbb6f..1716dff787 100644 --- a/scm-dao-xml/pom.xml +++ b/scm-dao-xml/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.58 + 1.59-SNAPSHOT sonia.scm scm-dao-xml - 1.58 + 1.59-SNAPSHOT scm-dao-xml @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.58 + 1.59-SNAPSHOT @@ -34,7 +34,7 @@ sonia.scm scm-test - 1.58 + 1.59-SNAPSHOT test diff --git a/scm-plugin-backend/pom.xml b/scm-plugin-backend/pom.xml index aa99261ecb..070dc2955e 100644 --- a/scm-plugin-backend/pom.xml +++ b/scm-plugin-backend/pom.xml @@ -6,13 +6,13 @@ scm sonia.scm - 1.58 + 1.59-SNAPSHOT sonia.scm scm-plugin-backend war - 1.58 + 1.59-SNAPSHOT ${project.artifactId} @@ -62,7 +62,7 @@ sonia.scm scm-core - 1.58 + 1.59-SNAPSHOT diff --git a/scm-plugins/pom.xml b/scm-plugins/pom.xml index f42a7a58dc..b4214fab06 100644 --- a/scm-plugins/pom.xml +++ b/scm-plugins/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.58 + 1.59-SNAPSHOT sonia.scm.plugins scm-plugins pom - 1.58 + 1.59-SNAPSHOT scm-plugins @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.58 + 1.59-SNAPSHOT @@ -59,7 +59,7 @@ sonia.scm.maven scm-maven-plugin - 1.58 + 1.59-SNAPSHOT process-resources diff --git a/scm-plugins/scm-git-plugin/pom.xml b/scm-plugins/scm-git-plugin/pom.xml index a3135bebea..66590a19d6 100644 --- a/scm-plugins/scm-git-plugin/pom.xml +++ b/scm-plugins/scm-git-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.58 + 1.59-SNAPSHOT sonia.scm.plugins scm-git-plugin - 1.58 + 1.59-SNAPSHOT scm-git-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Git @@ -54,7 +54,7 @@ sonia.scm scm-test - 1.58 + 1.59-SNAPSHOT test diff --git a/scm-plugins/scm-hg-plugin/pom.xml b/scm-plugins/scm-hg-plugin/pom.xml index 4e081d3766..938936df13 100644 --- a/scm-plugins/scm-hg-plugin/pom.xml +++ b/scm-plugins/scm-hg-plugin/pom.xml @@ -6,12 +6,12 @@ sonia.scm.plugins scm-plugins - 1.58 + 1.59-SNAPSHOT sonia.scm.plugins scm-hg-plugin - 1.58 + 1.59-SNAPSHOT scm-hg-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Mercurial @@ -42,7 +42,7 @@ sonia.scm scm-test - 1.58 + 1.59-SNAPSHOT test diff --git a/scm-plugins/scm-svn-plugin/pom.xml b/scm-plugins/scm-svn-plugin/pom.xml index b3f5214239..26054696e7 100644 --- a/scm-plugins/scm-svn-plugin/pom.xml +++ b/scm-plugins/scm-svn-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.58 + 1.59-SNAPSHOT sonia.scm.plugins scm-svn-plugin - 1.58 + 1.59-SNAPSHOT scm-svn-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Subversion @@ -48,7 +48,7 @@ sonia.scm scm-test - 1.58 + 1.59-SNAPSHOT test diff --git a/scm-samples/pom.xml b/scm-samples/pom.xml index a5712aa81d..5d91b43022 100644 --- a/scm-samples/pom.xml +++ b/scm-samples/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.58 + 1.59-SNAPSHOT sonia.scm.samples scm-samples pom - 1.58 + 1.59-SNAPSHOT scm-samples diff --git a/scm-samples/scm-sample-auth/pom.xml b/scm-samples/scm-sample-auth/pom.xml index 13ec4d8266..f53b75e16e 100644 --- a/scm-samples/scm-sample-auth/pom.xml +++ b/scm-samples/scm-sample-auth/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.58 + 1.59-SNAPSHOT sonia.scm.sample scm-sample-auth - 1.58 + 1.59-SNAPSHOT scm-sample-auth Sample Authentication Plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.58 + 1.59-SNAPSHOT diff --git a/scm-samples/scm-sample-hello/pom.xml b/scm-samples/scm-sample-hello/pom.xml index 67b34814d1..2b1eb4302f 100644 --- a/scm-samples/scm-sample-hello/pom.xml +++ b/scm-samples/scm-sample-hello/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.58 + 1.59-SNAPSHOT sonia.scm.sample scm-sample-hello - 1.58 + 1.59-SNAPSHOT scm-sample-hello A simple hello world plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.58 + 1.59-SNAPSHOT diff --git a/scm-server/pom.xml b/scm-server/pom.xml index b5c1bbff15..857e0cf5be 100644 --- a/scm-server/pom.xml +++ b/scm-server/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.58 + 1.59-SNAPSHOT sonia.scm scm-server - 1.58 + 1.59-SNAPSHOT scm-server jar diff --git a/scm-test/pom.xml b/scm-test/pom.xml index 6de92ac324..003aa41c64 100644 --- a/scm-test/pom.xml +++ b/scm-test/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.58 + 1.59-SNAPSHOT sonia.scm scm-test - 1.58 + 1.59-SNAPSHOT scm-test @@ -25,7 +25,7 @@ sonia.scm scm-core - 1.58 + 1.59-SNAPSHOT diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index c4c0e54bee..5684b7ace1 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.58 + 1.59-SNAPSHOT sonia.scm scm-webapp war - 1.58 + 1.59-SNAPSHOT scm-webapp @@ -38,31 +38,31 @@ sonia.scm scm-core - 1.58 + 1.59-SNAPSHOT sonia.scm scm-dao-xml - 1.58 + 1.59-SNAPSHOT sonia.scm.plugins scm-hg-plugin - 1.58 + 1.59-SNAPSHOT sonia.scm.plugins scm-svn-plugin - 1.58 + 1.59-SNAPSHOT sonia.scm.plugins scm-git-plugin - 1.58 + 1.59-SNAPSHOT @@ -280,7 +280,7 @@ sonia.scm scm-test - 1.58 + 1.59-SNAPSHOT test @@ -293,7 +293,7 @@ sonia.scm.plugins scm-git-plugin - 1.58 + 1.59-SNAPSHOT tests test @@ -301,7 +301,7 @@ sonia.scm.plugins scm-hg-plugin - 1.58 + 1.59-SNAPSHOT tests test @@ -309,7 +309,7 @@ sonia.scm.plugins scm-svn-plugin - 1.58 + 1.59-SNAPSHOT tests test diff --git a/support/pom.xml b/support/pom.xml index 768b99b4b6..d099d6bf4e 100644 --- a/support/pom.xml +++ b/support/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.58 + 1.59-SNAPSHOT sonia.scm.support scm-support pom - 1.58 + 1.59-SNAPSHOT scm-support diff --git a/support/scm-support-btrace/pom.xml b/support/scm-support-btrace/pom.xml index fbc1f06fdc..9ced93263c 100644 --- a/support/scm-support-btrace/pom.xml +++ b/support/scm-support-btrace/pom.xml @@ -4,12 +4,12 @@ sonia.scm.support scm-support - 1.58 + 1.59-SNAPSHOT sonia.scm scm-support-btrace - 1.58 + 1.59-SNAPSHOT jar scm-support-btrace @@ -18,7 +18,7 @@ sonia.scm scm-core - 1.58 + 1.59-SNAPSHOT From 7ed4dbcf002016a922c95db5157b771c037dcbb4 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 6 Apr 2018 14:01:00 +0200 Subject: [PATCH 44/78] fix hgweb execution for mercurial versions prior 4.1 --- .../scm-hg-plugin/src/main/resources/sonia/scm/python/hgweb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/hgweb.py b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/hgweb.py index ff2869044d..e2e7d8e931 100644 --- a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/hgweb.py +++ b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/hgweb.py @@ -36,7 +36,7 @@ from mercurial.hgweb import hgweb, wsgicgi demandimport.enable() -u = uimod.ui.load() +u = uimod.ui() # pass SCM_HTTP_POST_ARGS to enable experimental httppostargs protocol of mercurial # SCM_HTTP_POST_ARGS is set by HgCGIServlet From e230c0f4cd2eaa4bf437ea4121d11d1b963f56da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Stefanik?= Date: Fri, 6 Apr 2018 20:30:15 +0000 Subject: [PATCH 45/78] make {extras} work on old versions of Hg --- .../src/main/resources/sonia/scm/styles/changesets-eager.style | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/styles/changesets-eager.style b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/styles/changesets-eager.style index 73b3ec694b..2185c47a05 100644 --- a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/styles/changesets-eager.style +++ b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/styles/changesets-eager.style @@ -1,7 +1,8 @@ header = "%{pattern}" -changeset = "{rev}:{node}{author}\n{date|hgdate}\n{branch}\n{parents}close={ifeq(get(extras, 'close'),1,1,0)}\n{tags}{file_adds}{file_mods}{file_dels}\n{desc}\0" +changeset = "{rev}:{node}{author}\n{date|hgdate}\n{branch}\n{parents}{extras}\n{tags}{file_adds}{file_mods}{file_dels}\n{desc}\0" tag = "t {tag}\n" file_add = "a {file_add}\n" file_mod = "m {file_mod}\n" file_del = "d {file_del}\n" +extra = "{key}={value|stringescape}," footer = "%{pattern}" \ No newline at end of file From 92a492f68b5751cb1a649323dc4307f711f32723 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 11 Apr 2018 10:09:11 +0200 Subject: [PATCH 46/78] [maven-release-plugin] prepare release 1.59 --- maven/pom.xml | 4 ++-- maven/scm-maven-plugin/pom.xml | 4 ++-- maven/scm-plugin-archetype/pom.xml | 4 ++-- pom.xml | 4 ++-- scm-clients/pom.xml | 6 +++--- scm-clients/scm-cli-client/pom.xml | 6 +++--- scm-clients/scm-client-api/pom.xml | 4 ++-- scm-clients/scm-client-impl/pom.xml | 8 ++++---- scm-core/pom.xml | 4 ++-- scm-dao-xml/pom.xml | 8 ++++---- scm-plugin-backend/pom.xml | 6 +++--- scm-plugins/pom.xml | 8 ++++---- scm-plugins/scm-git-plugin/pom.xml | 6 +++--- scm-plugins/scm-hg-plugin/pom.xml | 6 +++--- scm-plugins/scm-svn-plugin/pom.xml | 6 +++--- scm-samples/pom.xml | 4 ++-- scm-samples/scm-sample-auth/pom.xml | 6 +++--- scm-samples/scm-sample-hello/pom.xml | 6 +++--- scm-server/pom.xml | 4 ++-- scm-test/pom.xml | 6 +++--- scm-webapp/pom.xml | 22 +++++++++++----------- support/pom.xml | 4 ++-- support/scm-support-btrace/pom.xml | 6 +++--- 23 files changed, 71 insertions(+), 71 deletions(-) diff --git a/maven/pom.xml b/maven/pom.xml index a1ed336d8c..816f79db1c 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.59-SNAPSHOT + 1.59 sonia.scm.maven scm-maven-plugins pom - 1.59-SNAPSHOT + 1.59 scm-maven-plugins diff --git a/maven/scm-maven-plugin/pom.xml b/maven/scm-maven-plugin/pom.xml index c52e518a7d..281b256428 100644 --- a/maven/scm-maven-plugin/pom.xml +++ b/maven/scm-maven-plugin/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.59-SNAPSHOT + 1.59 sonia.scm.maven scm-maven-plugin - 1.59-SNAPSHOT + 1.59 maven-plugin scm-maven-plugin diff --git a/maven/scm-plugin-archetype/pom.xml b/maven/scm-plugin-archetype/pom.xml index 4b74d47a7c..6e80df4106 100644 --- a/maven/scm-plugin-archetype/pom.xml +++ b/maven/scm-plugin-archetype/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.59-SNAPSHOT + 1.59 sonia.scm.maven scm-plugin-archetype - 1.59-SNAPSHOT + 1.59 scm-plugin-archetype diff --git a/pom.xml b/pom.xml index eb5d09d1fe..ab43a93112 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ sonia.scm scm pom - 1.59-SNAPSHOT + 1.59 The easiest way to share your Git, Mercurial and Subversion repositories over http. @@ -36,7 +36,7 @@ scm:hg:http://bitbucket.org/sdorra/scm-manager scm:hg:https://bitbucket.org/sdorra/scm-manager http://bitbucket.org/sdorra/scm-manager - HEAD + 1.59 diff --git a/scm-clients/pom.xml b/scm-clients/pom.xml index 1903d4ea2a..39ad548338 100644 --- a/scm-clients/pom.xml +++ b/scm-clients/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.59-SNAPSHOT + 1.59 sonia.scm.clients scm-clients pom - 1.59-SNAPSHOT + 1.59 scm-clients @@ -32,7 +32,7 @@ scm-core sonia.scm jar - 1.59-SNAPSHOT + 1.59 shiro-core diff --git a/scm-clients/scm-cli-client/pom.xml b/scm-clients/scm-cli-client/pom.xml index 7b3d7d9464..53fb3636d2 100644 --- a/scm-clients/scm-cli-client/pom.xml +++ b/scm-clients/scm-cli-client/pom.xml @@ -6,12 +6,12 @@ scm-clients sonia.scm.clients - 1.59-SNAPSHOT + 1.59 sonia.scm.clients scm-cli-client - 1.59-SNAPSHOT + 1.59 scm-cli-client @@ -34,7 +34,7 @@ sonia.scm.clients scm-client-impl - 1.59-SNAPSHOT + 1.59 diff --git a/scm-clients/scm-client-api/pom.xml b/scm-clients/scm-client-api/pom.xml index 74dcb8c861..e79a729934 100644 --- a/scm-clients/scm-client-api/pom.xml +++ b/scm-clients/scm-client-api/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.59-SNAPSHOT + 1.59 sonia.scm.clients scm-client-api jar - 1.59-SNAPSHOT + 1.59 scm-client-api diff --git a/scm-clients/scm-client-impl/pom.xml b/scm-clients/scm-client-impl/pom.xml index e6cae0bbaa..2afc822d4f 100644 --- a/scm-clients/scm-client-impl/pom.xml +++ b/scm-clients/scm-client-impl/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.59-SNAPSHOT + 1.59 sonia.scm.clients scm-client-impl jar - 1.59-SNAPSHOT + 1.59 scm-client-impl @@ -36,7 +36,7 @@ sonia.scm.clients scm-client-api - 1.59-SNAPSHOT + 1.59 @@ -70,7 +70,7 @@ sonia.scm scm-test - 1.59-SNAPSHOT + 1.59 test diff --git a/scm-core/pom.xml b/scm-core/pom.xml index 8371073636..a69d19d9bf 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.59-SNAPSHOT + 1.59 sonia.scm scm-core - 1.59-SNAPSHOT + 1.59 scm-core diff --git a/scm-dao-xml/pom.xml b/scm-dao-xml/pom.xml index 1716dff787..0af6ee3117 100644 --- a/scm-dao-xml/pom.xml +++ b/scm-dao-xml/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.59-SNAPSHOT + 1.59 sonia.scm scm-dao-xml - 1.59-SNAPSHOT + 1.59 scm-dao-xml @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.59-SNAPSHOT + 1.59 @@ -34,7 +34,7 @@ sonia.scm scm-test - 1.59-SNAPSHOT + 1.59 test diff --git a/scm-plugin-backend/pom.xml b/scm-plugin-backend/pom.xml index 070dc2955e..8a08b7c48f 100644 --- a/scm-plugin-backend/pom.xml +++ b/scm-plugin-backend/pom.xml @@ -6,13 +6,13 @@ scm sonia.scm - 1.59-SNAPSHOT + 1.59 sonia.scm scm-plugin-backend war - 1.59-SNAPSHOT + 1.59 ${project.artifactId} @@ -62,7 +62,7 @@ sonia.scm scm-core - 1.59-SNAPSHOT + 1.59 diff --git a/scm-plugins/pom.xml b/scm-plugins/pom.xml index b4214fab06..031360efba 100644 --- a/scm-plugins/pom.xml +++ b/scm-plugins/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.59-SNAPSHOT + 1.59 sonia.scm.plugins scm-plugins pom - 1.59-SNAPSHOT + 1.59 scm-plugins @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.59-SNAPSHOT + 1.59 @@ -59,7 +59,7 @@ sonia.scm.maven scm-maven-plugin - 1.59-SNAPSHOT + 1.59 process-resources diff --git a/scm-plugins/scm-git-plugin/pom.xml b/scm-plugins/scm-git-plugin/pom.xml index 66590a19d6..9973c8856d 100644 --- a/scm-plugins/scm-git-plugin/pom.xml +++ b/scm-plugins/scm-git-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.59-SNAPSHOT + 1.59 sonia.scm.plugins scm-git-plugin - 1.59-SNAPSHOT + 1.59 scm-git-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Git @@ -54,7 +54,7 @@ sonia.scm scm-test - 1.59-SNAPSHOT + 1.59 test diff --git a/scm-plugins/scm-hg-plugin/pom.xml b/scm-plugins/scm-hg-plugin/pom.xml index 938936df13..e911c7a030 100644 --- a/scm-plugins/scm-hg-plugin/pom.xml +++ b/scm-plugins/scm-hg-plugin/pom.xml @@ -6,12 +6,12 @@ sonia.scm.plugins scm-plugins - 1.59-SNAPSHOT + 1.59 sonia.scm.plugins scm-hg-plugin - 1.59-SNAPSHOT + 1.59 scm-hg-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Mercurial @@ -42,7 +42,7 @@ sonia.scm scm-test - 1.59-SNAPSHOT + 1.59 test diff --git a/scm-plugins/scm-svn-plugin/pom.xml b/scm-plugins/scm-svn-plugin/pom.xml index 26054696e7..050ad7b2ef 100644 --- a/scm-plugins/scm-svn-plugin/pom.xml +++ b/scm-plugins/scm-svn-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.59-SNAPSHOT + 1.59 sonia.scm.plugins scm-svn-plugin - 1.59-SNAPSHOT + 1.59 scm-svn-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Subversion @@ -48,7 +48,7 @@ sonia.scm scm-test - 1.59-SNAPSHOT + 1.59 test diff --git a/scm-samples/pom.xml b/scm-samples/pom.xml index 5d91b43022..84324dd576 100644 --- a/scm-samples/pom.xml +++ b/scm-samples/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.59-SNAPSHOT + 1.59 sonia.scm.samples scm-samples pom - 1.59-SNAPSHOT + 1.59 scm-samples diff --git a/scm-samples/scm-sample-auth/pom.xml b/scm-samples/scm-sample-auth/pom.xml index f53b75e16e..898caddb9d 100644 --- a/scm-samples/scm-sample-auth/pom.xml +++ b/scm-samples/scm-sample-auth/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.59-SNAPSHOT + 1.59 sonia.scm.sample scm-sample-auth - 1.59-SNAPSHOT + 1.59 scm-sample-auth Sample Authentication Plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.59-SNAPSHOT + 1.59 diff --git a/scm-samples/scm-sample-hello/pom.xml b/scm-samples/scm-sample-hello/pom.xml index 2b1eb4302f..faaef48f8e 100644 --- a/scm-samples/scm-sample-hello/pom.xml +++ b/scm-samples/scm-sample-hello/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.59-SNAPSHOT + 1.59 sonia.scm.sample scm-sample-hello - 1.59-SNAPSHOT + 1.59 scm-sample-hello A simple hello world plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.59-SNAPSHOT + 1.59 diff --git a/scm-server/pom.xml b/scm-server/pom.xml index 857e0cf5be..5ad81d34cd 100644 --- a/scm-server/pom.xml +++ b/scm-server/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.59-SNAPSHOT + 1.59 sonia.scm scm-server - 1.59-SNAPSHOT + 1.59 scm-server jar diff --git a/scm-test/pom.xml b/scm-test/pom.xml index 003aa41c64..533f4c57be 100644 --- a/scm-test/pom.xml +++ b/scm-test/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.59-SNAPSHOT + 1.59 sonia.scm scm-test - 1.59-SNAPSHOT + 1.59 scm-test @@ -25,7 +25,7 @@ sonia.scm scm-core - 1.59-SNAPSHOT + 1.59 diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 5684b7ace1..22fcd213bb 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.59-SNAPSHOT + 1.59 sonia.scm scm-webapp war - 1.59-SNAPSHOT + 1.59 scm-webapp @@ -38,31 +38,31 @@ sonia.scm scm-core - 1.59-SNAPSHOT + 1.59 sonia.scm scm-dao-xml - 1.59-SNAPSHOT + 1.59 sonia.scm.plugins scm-hg-plugin - 1.59-SNAPSHOT + 1.59 sonia.scm.plugins scm-svn-plugin - 1.59-SNAPSHOT + 1.59 sonia.scm.plugins scm-git-plugin - 1.59-SNAPSHOT + 1.59 @@ -280,7 +280,7 @@ sonia.scm scm-test - 1.59-SNAPSHOT + 1.59 test @@ -293,7 +293,7 @@ sonia.scm.plugins scm-git-plugin - 1.59-SNAPSHOT + 1.59 tests test @@ -301,7 +301,7 @@ sonia.scm.plugins scm-hg-plugin - 1.59-SNAPSHOT + 1.59 tests test @@ -309,7 +309,7 @@ sonia.scm.plugins scm-svn-plugin - 1.59-SNAPSHOT + 1.59 tests test diff --git a/support/pom.xml b/support/pom.xml index d099d6bf4e..b1c51c9494 100644 --- a/support/pom.xml +++ b/support/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.59-SNAPSHOT + 1.59 sonia.scm.support scm-support pom - 1.59-SNAPSHOT + 1.59 scm-support diff --git a/support/scm-support-btrace/pom.xml b/support/scm-support-btrace/pom.xml index 9ced93263c..6b47cdb7b6 100644 --- a/support/scm-support-btrace/pom.xml +++ b/support/scm-support-btrace/pom.xml @@ -4,12 +4,12 @@ sonia.scm.support scm-support - 1.59-SNAPSHOT + 1.59 sonia.scm scm-support-btrace - 1.59-SNAPSHOT + 1.59 jar scm-support-btrace @@ -18,7 +18,7 @@ sonia.scm scm-core - 1.59-SNAPSHOT + 1.59 From 39ceb11e9b76ce27b1dec9253254ee5327ef91be Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 11 Apr 2018 10:09:11 +0200 Subject: [PATCH 47/78] [maven-release-plugin] copy for tag 1.59 From 247ee63a95a939484dce471337dda1d550947eec Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 11 Apr 2018 10:09:12 +0200 Subject: [PATCH 48/78] [maven-release-plugin] prepare for next development iteration --- maven/pom.xml | 4 ++-- maven/scm-maven-plugin/pom.xml | 4 ++-- maven/scm-plugin-archetype/pom.xml | 4 ++-- pom.xml | 4 ++-- scm-clients/pom.xml | 6 +++--- scm-clients/scm-cli-client/pom.xml | 6 +++--- scm-clients/scm-client-api/pom.xml | 4 ++-- scm-clients/scm-client-impl/pom.xml | 8 ++++---- scm-core/pom.xml | 4 ++-- scm-dao-xml/pom.xml | 8 ++++---- scm-plugin-backend/pom.xml | 6 +++--- scm-plugins/pom.xml | 8 ++++---- scm-plugins/scm-git-plugin/pom.xml | 6 +++--- scm-plugins/scm-hg-plugin/pom.xml | 6 +++--- scm-plugins/scm-svn-plugin/pom.xml | 6 +++--- scm-samples/pom.xml | 4 ++-- scm-samples/scm-sample-auth/pom.xml | 6 +++--- scm-samples/scm-sample-hello/pom.xml | 6 +++--- scm-server/pom.xml | 4 ++-- scm-test/pom.xml | 6 +++--- scm-webapp/pom.xml | 22 +++++++++++----------- support/pom.xml | 4 ++-- support/scm-support-btrace/pom.xml | 6 +++--- 23 files changed, 71 insertions(+), 71 deletions(-) diff --git a/maven/pom.xml b/maven/pom.xml index 816f79db1c..9215c0c526 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.59 + 1.60-SNAPSHOT sonia.scm.maven scm-maven-plugins pom - 1.59 + 1.60-SNAPSHOT scm-maven-plugins diff --git a/maven/scm-maven-plugin/pom.xml b/maven/scm-maven-plugin/pom.xml index 281b256428..956a8339a4 100644 --- a/maven/scm-maven-plugin/pom.xml +++ b/maven/scm-maven-plugin/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.59 + 1.60-SNAPSHOT sonia.scm.maven scm-maven-plugin - 1.59 + 1.60-SNAPSHOT maven-plugin scm-maven-plugin diff --git a/maven/scm-plugin-archetype/pom.xml b/maven/scm-plugin-archetype/pom.xml index 6e80df4106..8031c1e2a6 100644 --- a/maven/scm-plugin-archetype/pom.xml +++ b/maven/scm-plugin-archetype/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.59 + 1.60-SNAPSHOT sonia.scm.maven scm-plugin-archetype - 1.59 + 1.60-SNAPSHOT scm-plugin-archetype diff --git a/pom.xml b/pom.xml index ab43a93112..3f4cfda18a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ sonia.scm scm pom - 1.59 + 1.60-SNAPSHOT The easiest way to share your Git, Mercurial and Subversion repositories over http. @@ -36,7 +36,7 @@ scm:hg:http://bitbucket.org/sdorra/scm-manager scm:hg:https://bitbucket.org/sdorra/scm-manager http://bitbucket.org/sdorra/scm-manager - 1.59 + HEAD diff --git a/scm-clients/pom.xml b/scm-clients/pom.xml index 39ad548338..dbbf9abe99 100644 --- a/scm-clients/pom.xml +++ b/scm-clients/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.59 + 1.60-SNAPSHOT sonia.scm.clients scm-clients pom - 1.59 + 1.60-SNAPSHOT scm-clients @@ -32,7 +32,7 @@ scm-core sonia.scm jar - 1.59 + 1.60-SNAPSHOT shiro-core diff --git a/scm-clients/scm-cli-client/pom.xml b/scm-clients/scm-cli-client/pom.xml index 53fb3636d2..ee196d5c11 100644 --- a/scm-clients/scm-cli-client/pom.xml +++ b/scm-clients/scm-cli-client/pom.xml @@ -6,12 +6,12 @@ scm-clients sonia.scm.clients - 1.59 + 1.60-SNAPSHOT sonia.scm.clients scm-cli-client - 1.59 + 1.60-SNAPSHOT scm-cli-client @@ -34,7 +34,7 @@ sonia.scm.clients scm-client-impl - 1.59 + 1.60-SNAPSHOT diff --git a/scm-clients/scm-client-api/pom.xml b/scm-clients/scm-client-api/pom.xml index e79a729934..498c3dac3d 100644 --- a/scm-clients/scm-client-api/pom.xml +++ b/scm-clients/scm-client-api/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.59 + 1.60-SNAPSHOT sonia.scm.clients scm-client-api jar - 1.59 + 1.60-SNAPSHOT scm-client-api diff --git a/scm-clients/scm-client-impl/pom.xml b/scm-clients/scm-client-impl/pom.xml index 2afc822d4f..1150017db7 100644 --- a/scm-clients/scm-client-impl/pom.xml +++ b/scm-clients/scm-client-impl/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.59 + 1.60-SNAPSHOT sonia.scm.clients scm-client-impl jar - 1.59 + 1.60-SNAPSHOT scm-client-impl @@ -36,7 +36,7 @@ sonia.scm.clients scm-client-api - 1.59 + 1.60-SNAPSHOT @@ -70,7 +70,7 @@ sonia.scm scm-test - 1.59 + 1.60-SNAPSHOT test diff --git a/scm-core/pom.xml b/scm-core/pom.xml index a69d19d9bf..1547e778f4 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.59 + 1.60-SNAPSHOT sonia.scm scm-core - 1.59 + 1.60-SNAPSHOT scm-core diff --git a/scm-dao-xml/pom.xml b/scm-dao-xml/pom.xml index 0af6ee3117..d42307809e 100644 --- a/scm-dao-xml/pom.xml +++ b/scm-dao-xml/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.59 + 1.60-SNAPSHOT sonia.scm scm-dao-xml - 1.59 + 1.60-SNAPSHOT scm-dao-xml @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.59 + 1.60-SNAPSHOT @@ -34,7 +34,7 @@ sonia.scm scm-test - 1.59 + 1.60-SNAPSHOT test diff --git a/scm-plugin-backend/pom.xml b/scm-plugin-backend/pom.xml index 8a08b7c48f..921e9756dd 100644 --- a/scm-plugin-backend/pom.xml +++ b/scm-plugin-backend/pom.xml @@ -6,13 +6,13 @@ scm sonia.scm - 1.59 + 1.60-SNAPSHOT sonia.scm scm-plugin-backend war - 1.59 + 1.60-SNAPSHOT ${project.artifactId} @@ -62,7 +62,7 @@ sonia.scm scm-core - 1.59 + 1.60-SNAPSHOT diff --git a/scm-plugins/pom.xml b/scm-plugins/pom.xml index 031360efba..513dc0a6fe 100644 --- a/scm-plugins/pom.xml +++ b/scm-plugins/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.59 + 1.60-SNAPSHOT sonia.scm.plugins scm-plugins pom - 1.59 + 1.60-SNAPSHOT scm-plugins @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.59 + 1.60-SNAPSHOT @@ -59,7 +59,7 @@ sonia.scm.maven scm-maven-plugin - 1.59 + 1.60-SNAPSHOT process-resources diff --git a/scm-plugins/scm-git-plugin/pom.xml b/scm-plugins/scm-git-plugin/pom.xml index 9973c8856d..8b15ad31fa 100644 --- a/scm-plugins/scm-git-plugin/pom.xml +++ b/scm-plugins/scm-git-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.59 + 1.60-SNAPSHOT sonia.scm.plugins scm-git-plugin - 1.59 + 1.60-SNAPSHOT scm-git-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Git @@ -54,7 +54,7 @@ sonia.scm scm-test - 1.59 + 1.60-SNAPSHOT test diff --git a/scm-plugins/scm-hg-plugin/pom.xml b/scm-plugins/scm-hg-plugin/pom.xml index e911c7a030..cf4c42d1dc 100644 --- a/scm-plugins/scm-hg-plugin/pom.xml +++ b/scm-plugins/scm-hg-plugin/pom.xml @@ -6,12 +6,12 @@ sonia.scm.plugins scm-plugins - 1.59 + 1.60-SNAPSHOT sonia.scm.plugins scm-hg-plugin - 1.59 + 1.60-SNAPSHOT scm-hg-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Mercurial @@ -42,7 +42,7 @@ sonia.scm scm-test - 1.59 + 1.60-SNAPSHOT test diff --git a/scm-plugins/scm-svn-plugin/pom.xml b/scm-plugins/scm-svn-plugin/pom.xml index 050ad7b2ef..025193838d 100644 --- a/scm-plugins/scm-svn-plugin/pom.xml +++ b/scm-plugins/scm-svn-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.59 + 1.60-SNAPSHOT sonia.scm.plugins scm-svn-plugin - 1.59 + 1.60-SNAPSHOT scm-svn-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Subversion @@ -48,7 +48,7 @@ sonia.scm scm-test - 1.59 + 1.60-SNAPSHOT test diff --git a/scm-samples/pom.xml b/scm-samples/pom.xml index 84324dd576..1b25fb0b18 100644 --- a/scm-samples/pom.xml +++ b/scm-samples/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.59 + 1.60-SNAPSHOT sonia.scm.samples scm-samples pom - 1.59 + 1.60-SNAPSHOT scm-samples diff --git a/scm-samples/scm-sample-auth/pom.xml b/scm-samples/scm-sample-auth/pom.xml index 898caddb9d..f443d37763 100644 --- a/scm-samples/scm-sample-auth/pom.xml +++ b/scm-samples/scm-sample-auth/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.59 + 1.60-SNAPSHOT sonia.scm.sample scm-sample-auth - 1.59 + 1.60-SNAPSHOT scm-sample-auth Sample Authentication Plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.59 + 1.60-SNAPSHOT diff --git a/scm-samples/scm-sample-hello/pom.xml b/scm-samples/scm-sample-hello/pom.xml index faaef48f8e..21199294ba 100644 --- a/scm-samples/scm-sample-hello/pom.xml +++ b/scm-samples/scm-sample-hello/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.59 + 1.60-SNAPSHOT sonia.scm.sample scm-sample-hello - 1.59 + 1.60-SNAPSHOT scm-sample-hello A simple hello world plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.59 + 1.60-SNAPSHOT diff --git a/scm-server/pom.xml b/scm-server/pom.xml index 5ad81d34cd..ef1bac43c8 100644 --- a/scm-server/pom.xml +++ b/scm-server/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.59 + 1.60-SNAPSHOT sonia.scm scm-server - 1.59 + 1.60-SNAPSHOT scm-server jar diff --git a/scm-test/pom.xml b/scm-test/pom.xml index 533f4c57be..6401485329 100644 --- a/scm-test/pom.xml +++ b/scm-test/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.59 + 1.60-SNAPSHOT sonia.scm scm-test - 1.59 + 1.60-SNAPSHOT scm-test @@ -25,7 +25,7 @@ sonia.scm scm-core - 1.59 + 1.60-SNAPSHOT diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 22fcd213bb..d467061d1d 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.59 + 1.60-SNAPSHOT sonia.scm scm-webapp war - 1.59 + 1.60-SNAPSHOT scm-webapp @@ -38,31 +38,31 @@ sonia.scm scm-core - 1.59 + 1.60-SNAPSHOT sonia.scm scm-dao-xml - 1.59 + 1.60-SNAPSHOT sonia.scm.plugins scm-hg-plugin - 1.59 + 1.60-SNAPSHOT sonia.scm.plugins scm-svn-plugin - 1.59 + 1.60-SNAPSHOT sonia.scm.plugins scm-git-plugin - 1.59 + 1.60-SNAPSHOT @@ -280,7 +280,7 @@ sonia.scm scm-test - 1.59 + 1.60-SNAPSHOT test @@ -293,7 +293,7 @@ sonia.scm.plugins scm-git-plugin - 1.59 + 1.60-SNAPSHOT tests test @@ -301,7 +301,7 @@ sonia.scm.plugins scm-hg-plugin - 1.59 + 1.60-SNAPSHOT tests test @@ -309,7 +309,7 @@ sonia.scm.plugins scm-svn-plugin - 1.59 + 1.60-SNAPSHOT tests test diff --git a/support/pom.xml b/support/pom.xml index b1c51c9494..882727808b 100644 --- a/support/pom.xml +++ b/support/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.59 + 1.60-SNAPSHOT sonia.scm.support scm-support pom - 1.59 + 1.60-SNAPSHOT scm-support diff --git a/support/scm-support-btrace/pom.xml b/support/scm-support-btrace/pom.xml index 6b47cdb7b6..9dc37271b2 100644 --- a/support/scm-support-btrace/pom.xml +++ b/support/scm-support-btrace/pom.xml @@ -4,12 +4,12 @@ sonia.scm.support scm-support - 1.59 + 1.60-SNAPSHOT sonia.scm scm-support-btrace - 1.59 + 1.60-SNAPSHOT jar scm-support-btrace @@ -18,7 +18,7 @@ sonia.scm scm-core - 1.59 + 1.60-SNAPSHOT From c841e72dcbc2c4df7059527a418e51f5663c0504 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 12 Apr 2018 11:34:00 +0200 Subject: [PATCH 49/78] #972 encforce jdk 7 bytecode for dependencies --- pom.xml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/pom.xml b/pom.xml index 3f4cfda18a..fa324ac12e 100644 --- a/pom.xml +++ b/pom.xml @@ -159,6 +159,36 @@ + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M1 + + + enforce-java + compile + + enforce + + + + + 1.7 + + + true + + + + + + org.codehaus.mojo + extra-enforcer-rules + 1.0-beta-7 + + + + org.apache.maven.plugins maven-compiler-plugin From 7d6c65799e78ed2c94f02f4b525859f9c0bab96b Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 12 Apr 2018 11:57:00 +0200 Subject: [PATCH 50/78] #972 use javahg version which is compatible with java 7 --- scm-plugins/scm-hg-plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm-plugins/scm-hg-plugin/pom.xml b/scm-plugins/scm-hg-plugin/pom.xml index cf4c42d1dc..bb339bb983 100644 --- a/scm-plugins/scm-hg-plugin/pom.xml +++ b/scm-plugins/scm-hg-plugin/pom.xml @@ -28,7 +28,7 @@ com.aragost.javahg javahg - 0.13 + 0.13-java7 com.google.guava From b568b9ee9356e007092eee531c46d85f57126b13 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 12 Apr 2018 12:41:58 +0200 Subject: [PATCH 51/78] fix some maven warnings --- pom.xml | 86 +++++++++++++++++++++++++++------------------------------ 1 file changed, 41 insertions(+), 45 deletions(-) diff --git a/pom.xml b/pom.xml index 3f4cfda18a..8a63ae0c44 100644 --- a/pom.xml +++ b/pom.xml @@ -59,10 +59,6 @@ https://scm-manager.ci.cloudbees.com/ - - 3.0.0 - - scm-core scm-test @@ -274,53 +270,53 @@ org.apache.maven.plugins maven-site-plugin - 3.2 - - - - - org.apache.maven.plugins - maven-project-info-reports-plugin - 2.4 - - - - org.apache.maven.plugins - maven-jxr-plugin - 2.3 - - - - org.codehaus.mojo - findbugs-maven-plugin - 2.4.0 - - - - org.apache.maven.plugins - maven-surefire-report-plugin - 2.12 - - - - org.apache.maven.plugins - maven-pmd-plugin - 2.7.1 - - true - ${project.build.sourceEncoding} - ${project.build.javaLevel} - - - - - + 3.7 + + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 2.4 + + + + org.apache.maven.plugins + maven-jxr-plugin + 2.3 + + + + org.codehaus.mojo + findbugs-maven-plugin + 2.4.0 + + + + org.apache.maven.plugins + maven-surefire-report-plugin + 2.12 + + + + org.apache.maven.plugins + maven-pmd-plugin + 2.7.1 + + ${project.build.sourceEncoding} + ${project.build.javaLevel} + + + + + + From bfee6331e1fe2281ca87406154890d7fce24e374 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 12 Apr 2018 13:15:04 +0200 Subject: [PATCH 52/78] fix build on java 9 --- pom.xml | 31 +++++++++++++++++++++++++-- scm-core/pom.xml | 54 ++++++++++++++++++++++++++++++++++-------------- 2 files changed, 67 insertions(+), 18 deletions(-) diff --git a/pom.xml b/pom.xml index 8a63ae0c44..71cbb28e22 100644 --- a/pom.xml +++ b/pom.xml @@ -137,7 +137,7 @@ org.codehaus.mojo animal-sniffer-maven-plugin - 1.15 + 1.16 org.codehaus.mojo.signature @@ -360,7 +360,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.8.1 + 3.0.0 org.jboss.apiviz.APIviz @@ -448,6 +448,32 @@ ${jackson.version} + + + + javax.xml.bind + jaxb-api + ${jaxb.version} + + + + com.sun.xml.bind + jaxb-impl + ${jaxb.version} + + + + org.glassfish.jaxb + jaxb-runtime + ${jaxb.version} + + + + javax.activation + activation + 1.1.1 + + @@ -484,6 +510,7 @@ 7.6.21.v20160908 7.6.16.v20140903 1.9.13 + 2.3.0 1.3.2 diff --git a/scm-core/pom.xml b/scm-core/pom.xml index 1547e778f4..5ab21b553b 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -1,6 +1,6 @@ - + 4.0.0 @@ -15,7 +15,7 @@ scm-core - + @@ -24,22 +24,22 @@ ${servlet.version} provided - + slf4j-api org.slf4j - + - + org.apache.shiro shiro-core ${shiro.version} - + @@ -59,13 +59,13 @@ guice-servlet ${guice.version} - + com.google.inject.extensions guice-throwingproviders ${guice.version} - + @@ -73,15 +73,37 @@ jersey-core ${jersey.version} - + + + + + javax.xml.bind + jaxb-api + + + + com.sun.xml.bind + jaxb-impl + + + + org.glassfish.jaxb + jaxb-runtime + + + + javax.activation + activation + + - + com.google.guava guava ${guava.version} - + commons-lang commons-lang @@ -89,14 +111,14 @@ - + - + org.apache.maven.plugins maven-javadoc-plugin - 2.9 + 3.0.0 true ${project.build.sourceEncoding} @@ -122,8 +144,8 @@ - + - + From 68006b322d810ef356012fe5f2204b229ea6a265 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 12 Apr 2018 20:20:32 +0200 Subject: [PATCH 53/78] removed unused import from GroupCollectorTest --- .../scm/security/GroupCollectorTest.java | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/scm-webapp/src/test/java/sonia/scm/security/GroupCollectorTest.java b/scm-webapp/src/test/java/sonia/scm/security/GroupCollectorTest.java index 57f0362549..e366b15b50 100644 --- a/scm-webapp/src/test/java/sonia/scm/security/GroupCollectorTest.java +++ b/scm-webapp/src/test/java/sonia/scm/security/GroupCollectorTest.java @@ -1,10 +1,10 @@ /** * Copyright (c) 2014, 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, @@ -13,7 +13,7 @@ * 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 @@ -24,20 +24,15 @@ * 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; import com.google.common.collect.ImmutableSet; -import java.util.Set; -import jdk.nashorn.internal.ir.annotations.Immutable; import org.junit.Test; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; -import static org.hamcrest.Matchers.*; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; @@ -47,9 +42,15 @@ import sonia.scm.group.GroupManager; import sonia.scm.user.UserTestData; import sonia.scm.web.security.AuthenticationResult; +import java.util.Set; + +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.when; + /** * Unit tests for {@link GroupCollector}. - * + * * @author Sebastian Sdorra * @since 1.52 */ @@ -58,10 +59,10 @@ public class GroupCollectorTest { @Mock private GroupManager groupManager; - + @InjectMocks private GroupCollector collector; - + /** * Tests {@link GroupCollector#collectGroups(AuthenticationResult)} without groups from authenticator. */ @@ -70,7 +71,7 @@ public class GroupCollectorTest { Set groups = collector.collectGroups(new AuthenticationResult(UserTestData.createSlarti())); assertThat(groups, containsInAnyOrder("_authenticated")); } - + /** * Tests {@link GroupCollector#collectGroups(AuthenticationResult)} with groups from authenticator. */ @@ -80,7 +81,7 @@ public class GroupCollectorTest { Set groups = collector.collectGroups(new AuthenticationResult(UserTestData.createSlarti(), authGroups)); assertThat(groups, containsInAnyOrder("_authenticated", "puzzle42")); } - + /** * Tests {@link GroupCollector#collectGroups(AuthenticationResult)} with groups from db. */ @@ -91,7 +92,7 @@ public class GroupCollectorTest { Set groups = collector.collectGroups(new AuthenticationResult(UserTestData.createSlarti())); assertThat(groups, containsInAnyOrder("_authenticated", "puzzle42")); } - + /** * Tests {@link GroupCollector#collectGroups(AuthenticationResult)} with groups from db. */ @@ -104,4 +105,4 @@ public class GroupCollectorTest { assertThat(groups, containsInAnyOrder("_authenticated", "puzzle42", "heartOfGold")); } -} \ No newline at end of file +} From 0fc9f6d4856aab2cd1559e0bdb7148708deee65c Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 12 Apr 2018 20:21:22 +0200 Subject: [PATCH 54/78] use APIviz only for javadoc of scm-core --- pom.xml | 11 +---------- scm-core/pom.xml | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index 71cbb28e22..7553913789 100644 --- a/pom.xml +++ b/pom.xml @@ -362,16 +362,7 @@ maven-javadoc-plugin 3.0.0 - org.jboss.apiviz.APIviz - - org.jboss.apiviz - apiviz - 1.3.2.GA - - - -sourceclasspath ${project.build.outputDirectory} - -nopackagediagram - + false diff --git a/scm-core/pom.xml b/scm-core/pom.xml index 5ab21b553b..411a3c1d78 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -142,6 +142,20 @@ http://www.slf4j.org/api/ http://shiro.apache.org/static/current/apidocs/ + org.jboss.apiviz.APIviz + + org.jboss.apiviz + apiviz + 1.3.2.GA + + + + -sourceclasspath ${project.build.outputDirectory} + + + -nopackagediagram + + From 966c18eca17471393b462c509ef00b08b9c1aa0c Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 12 Apr 2018 20:22:40 +0200 Subject: [PATCH 55/78] close branch issue-972 From b8144b514e2b40eb9473cd453c375534c466a4a4 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 13 Apr 2018 16:23:33 +0200 Subject: [PATCH 56/78] ignore module-info for enforceBytecodeVersion rule --- pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pom.xml b/pom.xml index 180a95745a..b27cbf84ea 100644 --- a/pom.xml +++ b/pom.xml @@ -170,6 +170,13 @@ 1.7 + + + module-info + true From b8456d364cd5609cbac42f77bf9ec5338c89dc35 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 13 Apr 2018 23:32:50 +0200 Subject: [PATCH 57/78] update commons-daemon to version 1.1.0 --- scm-server/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scm-server/pom.xml b/scm-server/pom.xml index ef1bac43c8..7103b0a701 100644 --- a/scm-server/pom.xml +++ b/scm-server/pom.xml @@ -308,8 +308,8 @@ - 1.0.15 - 1.0.15.1 + 1.1.0 + 1.1.0 ${project.build.directory}/appassembler/commons-daemon/scm-server From a55dd9873bf5e79873a839f11d9fced303ca727b Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Tue, 17 Apr 2018 22:00:54 +0200 Subject: [PATCH 58/78] #979 split implementation of ScmClientConfigFileHandler in order to create new more secure implementation --- .../scm/cli/config/CipherStreamHandler.java | 60 +++++ .../java/sonia/scm/cli/config/KeyStore.java | 57 ++++ .../sonia/scm/cli/config/PrefsKeyStore.java | 64 +++++ .../sonia/scm/cli/config/ScmClientConfig.java | 2 +- .../config/ScmClientConfigFileHandler.java | 246 ++++-------------- .../cli/config/WeakCipherStreamHandler.java | 109 ++++++++ .../ScmClientConfigFileHandlerTest.java | 98 +++++++ 7 files changed, 439 insertions(+), 197 deletions(-) create mode 100644 scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/CipherStreamHandler.java create mode 100644 scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/KeyStore.java create mode 100644 scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/PrefsKeyStore.java create mode 100644 scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/WeakCipherStreamHandler.java create mode 100644 scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ScmClientConfigFileHandlerTest.java diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/CipherStreamHandler.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/CipherStreamHandler.java new file mode 100644 index 0000000000..e687988be3 --- /dev/null +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/CipherStreamHandler.java @@ -0,0 +1,60 @@ +/** + * 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.config; + +import java.io.InputStream; +import java.io.OutputStream; + +/** + * The CipherStreamHandler is able to encrypt and decrypt streams. + */ +public interface CipherStreamHandler { + + /** + * Decrypts the given input stream. + * + * @param inputStream encrypted input stream + * + * @return raw input stream + */ + InputStream decrypt(InputStream inputStream); + + /** + * Encrypts the given output stream. + * + * @param outputStream raw output stream + * + * @return encrypting output stream + */ + OutputStream encrypt(OutputStream outputStream); +} diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/KeyStore.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/KeyStore.java new file mode 100644 index 0000000000..39874b499c --- /dev/null +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/KeyStore.java @@ -0,0 +1,57 @@ +/** + * 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.config; + +/** + * KeyStore is able to read and write keys. + */ +public interface KeyStore { + + /** + * Writes the given secret key to the store. + * + * @param secretKey secret key to write + */ + void set(String secretKey); + + /** + * Reads the secret key from the store. The method returns {@code null} if no secret key was stored. + * + * @return secret key of {@code null} + */ + String get(); + + /** + * Removes the secret key from store. + */ + void remove(); +} diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/PrefsKeyStore.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/PrefsKeyStore.java new file mode 100644 index 0000000000..26a7e67b05 --- /dev/null +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/PrefsKeyStore.java @@ -0,0 +1,64 @@ +/** + * 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.config; + +import java.util.prefs.Preferences; + +/** + * KeyStore implementation with uses {@link Preferences}. + */ +public class PrefsKeyStore implements KeyStore { + + private static final String PREF_SECRET_KEY = "scm.client.key"; + + private final Preferences preferences; + + public PrefsKeyStore() { + // we use ScmClientConfigFileHandler as base for backward compatibility + preferences = Preferences.userNodeForPackage(ScmClientConfigFileHandler.class); + } + + @Override + public void set(String secretKey) { + preferences.put(PREF_SECRET_KEY, secretKey); + } + + @Override + public String get() { + return preferences.get(PREF_SECRET_KEY, null); + } + + @Override + public void remove() { + preferences.remove(PREF_SECRET_KEY); + } +} diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfig.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfig.java index 9edb2b382a..7bec710974 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfig.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfig.java @@ -66,7 +66,7 @@ public class ScmClientConfig * Constructs ... * */ - private ScmClientConfig() + ScmClientConfig() { this.serverConfigMap = new HashMap(); } diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfigFileHandler.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfigFileHandler.java index 5cc2c46978..bbb0fd85c1 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfigFileHandler.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfigFileHandler.java @@ -35,38 +35,17 @@ package sonia.scm.cli.config; //~--- non-JDK imports -------------------------------------------------------- -import sonia.scm.util.IOUtil; +import sonia.scm.security.KeyGenerator; +import sonia.scm.security.UUIDKeyGenerator; import sonia.scm.util.Util; -//~--- JDK imports ------------------------------------------------------------ - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.OutputStream; - -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.spec.InvalidKeySpecException; - -import java.util.UUID; -import java.util.prefs.Preferences; - -import javax.crypto.Cipher; -import javax.crypto.CipherInputStream; -import javax.crypto.CipherOutputStream; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.SecretKey; -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.PBEKeySpec; -import javax.crypto.spec.PBEParameterSpec; - import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; +import java.io.*; + +//~--- JDK imports ------------------------------------------------------------ /** * @@ -81,62 +60,66 @@ public class ScmClientConfigFileHandler /** Field description */ public static final String ENV_CONFIG_FILE = "SCM_CLI_CONFIG"; - /** Field description */ - public static final String PREF_SECRET_KEY = "scm.client.key"; - - /** Field description */ - public static final String SALT = "AE16347F"; - - /** Field description */ - public static final int SPEC_ITERATION = 12; - - /** Field description */ - private static final String CIPHER_NAME = "PBEWithMD5AndDES"; - //~--- constructors --------------------------------------------------------- + private final KeyStore keyStore; + private final KeyGenerator keyGenerator; + private final File file; + private final JAXBContext context; + + private final CipherStreamHandler cipherStreamHandler; + + /** * Constructs ... * */ - public ScmClientConfigFileHandler() - { - prefs = Preferences.userNodeForPackage(ScmClientConfigFileHandler.class); - key = prefs.get(PREF_SECRET_KEY, null); + public ScmClientConfigFileHandler() { + this(new PrefsKeyStore(), new UUIDKeyGenerator(), getDefaultConfigFile()); + } - if (Util.isEmpty(key)) - { - key = createNewKey(); - prefs.put(PREF_SECRET_KEY, key); + ScmClientConfigFileHandler(KeyStore keyStore, KeyGenerator keyGenerator, File file) { + this.keyStore = keyStore; + this.keyGenerator = keyGenerator; + this.file = file; + + String key = keyStore.get(); + + if (Util.isEmpty(key)) { + key = keyGenerator.createKey(); + keyStore.set(key); } - try - { + cipherStreamHandler = new WeakCipherStreamHandler(key.toCharArray()); + + try { context = JAXBContext.newInstance(ScmClientConfig.class); - } - catch (JAXBException ex) - { - throw new ScmConfigException( - "could not create JAXBContext for ScmClientConfig", ex); + } catch (JAXBException ex) { + throw new ScmConfigException("could not create JAXBContext for ScmClientConfig", ex); } } //~--- methods -------------------------------------------------------------- + private static File getDefaultConfigFile() { + String configPath = System.getenv(ENV_CONFIG_FILE); + + if (Util.isNotEmpty(configPath)){ + return new File(configPath); + } + return new File(System.getProperty("user.home"), DEFAULT_CONFIG_NAME); + } + /** * Method description * */ - public void delete() - { - File configFile = getConfigFile(); - - if (configFile.exists() &&!configFile.delete()) - { + public void delete() { + if (file.exists() &&!file.delete()) { throw new ScmConfigException("could not delete config file"); } - prefs.remove(PREF_SECRET_KEY); + keyStore.remove(); } /** @@ -145,33 +128,16 @@ public class ScmClientConfigFileHandler * * @return */ - public ScmClientConfig read() - { + public ScmClientConfig read() { ScmClientConfig config = null; - File configFile = getConfigFile(); - - if (configFile.exists()) - { - InputStream input = null; - - try - { - Cipher c = createCipher(Cipher.DECRYPT_MODE); - - input = new CipherInputStream(new FileInputStream(configFile), c); + if (file.exists()) { + try (InputStream input = cipherStreamHandler.decrypt(new FileInputStream(file))) { Unmarshaller um = context.createUnmarshaller(); - config = (ScmClientConfig) um.unmarshal(input); - } - catch (Exception ex) - { + } catch (IOException | JAXBException ex) { throw new ScmConfigException("could not read config file", ex); } - finally - { - IOUtil.close(input); - } } return config; @@ -183,124 +149,12 @@ public class ScmClientConfigFileHandler * * @param config */ - public void write(ScmClientConfig config) - { - File configFile = getConfigFile(); - OutputStream output = null; - - try - { - Cipher c = createCipher(Cipher.ENCRYPT_MODE); - - output = new CipherOutputStream(new FileOutputStream(configFile), c); - + public void write(ScmClientConfig config) { + try (OutputStream output = cipherStreamHandler.encrypt(new FileOutputStream(file))) { Marshaller m = context.createMarshaller(); - m.marshal(config, output); - } - catch (Exception ex) - { + } catch (IOException | JAXBException ex) { throw new ScmConfigException("could not write config file", ex); } - finally - { - IOUtil.close(output); - } } - - /** - * Method description - * - * - * @param mode - * - * @return - * - * - * @throws InvalidAlgorithmParameterException - * @throws InvalidKeyException - * @throws InvalidKeySpecException - * @throws NoSuchAlgorithmException - * @throws NoSuchPaddingException - */ - private Cipher createCipher(int mode) - throws NoSuchAlgorithmException, NoSuchPaddingException, - InvalidKeySpecException, InvalidKeyException, - InvalidAlgorithmParameterException - { - SecretKey sk = createSecretKey(); - Cipher cipher = Cipher.getInstance(CIPHER_NAME); - PBEParameterSpec spec = new PBEParameterSpec(SALT.getBytes(), - SPEC_ITERATION); - - cipher.init(mode, sk, spec); - - return cipher; - } - - /** - * Method description - * - * - * @return - */ - private String createNewKey() - { - return UUID.randomUUID().toString(); - } - - /** - * Method description - * - * - * @return - * - * @throws InvalidKeySpecException - * @throws NoSuchAlgorithmException - */ - private SecretKey createSecretKey() - throws NoSuchAlgorithmException, InvalidKeySpecException - { - PBEKeySpec keySpec = new PBEKeySpec(key.toCharArray()); - SecretKeyFactory factory = SecretKeyFactory.getInstance(CIPHER_NAME); - - return factory.generateSecret(keySpec); - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @return - */ - private File getConfigFile() - { - File configFile = null; - String configPath = System.getenv(ENV_CONFIG_FILE); - - if (Util.isEmpty(configPath)) - { - configFile = new File(System.getProperty("user.home"), - DEFAULT_CONFIG_NAME); - } - else - { - configFile = new File(configPath); - } - - return configFile; - } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - private JAXBContext context; - - /** Field description */ - private String key; - - /** Field description */ - private Preferences prefs; } diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/WeakCipherStreamHandler.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/WeakCipherStreamHandler.java new file mode 100644 index 0000000000..0a867d5b30 --- /dev/null +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/WeakCipherStreamHandler.java @@ -0,0 +1,109 @@ +/** + * 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.config; + +import javax.crypto.*; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.PBEParameterSpec; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; + +/** + * Weak implementation of {@link CipherStreamHandler}. + * + * @see Issue 978 + * @see Issue 979 + */ +public class WeakCipherStreamHandler implements CipherStreamHandler { + + private static final String SALT = "AE16347F"; + private static final int SPEC_ITERATION = 12; + private static final String CIPHER_NAME = "PBEWithMD5AndDES"; + + private final char[] secretKey; + + /** + * Creates a new handler with the given secret key. + * + * @param secretKey secret key + */ + public WeakCipherStreamHandler(char[] secretKey) { + this.secretKey = secretKey; + } + + @Override + public InputStream decrypt(InputStream inputStream) { + try { + Cipher c = createCipher(Cipher.DECRYPT_MODE); + return new CipherInputStream(inputStream, c); + } catch (Exception ex) { + throw new ScmConfigException("could not encrypt output stream", ex); + } + } + + @Override + public OutputStream encrypt(OutputStream outputStream) { + try { + Cipher c = createCipher(Cipher.ENCRYPT_MODE); + return new CipherOutputStream(outputStream, c); + } catch (Exception ex) { + throw new ScmConfigException("could not encrypt output stream", ex); + } + } + + private Cipher createCipher(int mode) + throws NoSuchAlgorithmException, NoSuchPaddingException, + InvalidKeySpecException, InvalidKeyException, + InvalidAlgorithmParameterException + { + SecretKey sk = createSecretKey(); + Cipher cipher = Cipher.getInstance(CIPHER_NAME); + PBEParameterSpec spec = new PBEParameterSpec(SALT.getBytes(), SPEC_ITERATION); + + cipher.init(mode, sk, spec); + + return cipher; + } + + private SecretKey createSecretKey() + throws NoSuchAlgorithmException, InvalidKeySpecException + { + PBEKeySpec keySpec = new PBEKeySpec(secretKey); + SecretKeyFactory factory = SecretKeyFactory.getInstance(CIPHER_NAME); + + return factory.generateSecret(keySpec); + } +} diff --git a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ScmClientConfigFileHandlerTest.java b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ScmClientConfigFileHandlerTest.java new file mode 100644 index 0000000000..ec598fd2d4 --- /dev/null +++ b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ScmClientConfigFileHandlerTest.java @@ -0,0 +1,98 @@ +/** + * 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.config; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import sonia.scm.security.UUIDKeyGenerator; + +import java.io.File; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class ScmClientConfigFileHandlerTest { + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Test + public void testClientConfigFileHandler() throws IOException { + File configFile = temporaryFolder.newFile(); + + ScmClientConfigFileHandler handler = new ScmClientConfigFileHandler( + new InMemoryKeyStore(), new UUIDKeyGenerator(), configFile + ); + + ScmClientConfig config = new ScmClientConfig(); + ServerConfig defaultConfig = config.getDefaultConfig(); + defaultConfig.setServerUrl("http://localhost:8080/scm"); + defaultConfig.setUsername("scmadmin"); + defaultConfig.setPassword("admin123"); + handler.write(config); + + assertTrue(configFile.exists()); + + config = handler.read(); + defaultConfig = config.getDefaultConfig(); + assertEquals("http://localhost:8080/scm", defaultConfig.getServerUrl()); + assertEquals("scmadmin", defaultConfig.getUsername()); + assertEquals("admin123", defaultConfig.getPassword()); + + handler.delete(); + + assertFalse(configFile.exists()); + } + + private static class InMemoryKeyStore implements KeyStore { + + private String secretKey; + + @Override + public void set(String secretKey) { + this.secretKey = secretKey; + } + + @Override + public String get() { + return secretKey; + } + + @Override + public void remove() { + this.secretKey = null; + } + } +} From d9e7de82022beb80c7812b435970f12357d3c7c9 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 18 Apr 2018 08:09:28 +0200 Subject: [PATCH 59/78] #979 improve javadoc --- .../src/main/java/sonia/scm/cli/config/KeyStore.java | 2 +- .../java/sonia/scm/cli/config/WeakCipherStreamHandler.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/KeyStore.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/KeyStore.java index 39874b499c..7ce64750ce 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/KeyStore.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/KeyStore.java @@ -46,7 +46,7 @@ public interface KeyStore { /** * Reads the secret key from the store. The method returns {@code null} if no secret key was stored. * - * @return secret key of {@code null} + * @return secret key or {@code null} */ String get(); diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/WeakCipherStreamHandler.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/WeakCipherStreamHandler.java index 0a867d5b30..a9e3e5ef42 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/WeakCipherStreamHandler.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/WeakCipherStreamHandler.java @@ -42,7 +42,8 @@ import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; /** - * Weak implementation of {@link CipherStreamHandler}. + * Weak implementation of {@link CipherStreamHandler}. This is the old implementation, which was used in versions prior + * 1.60. * * @see Issue 978 * @see Issue 979 From 3ee0bcedac4ce72cffb8f474ac33ae4d5c1b77a4 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 18 Apr 2018 14:41:38 +0200 Subject: [PATCH 60/78] #979 encrypt cli configuration with aes instead of pbe --- .../cli/config/AesCipherStreamHandler.java | 108 +++++++++++++ .../scm/cli/config/CipherStreamHandler.java | 8 +- .../sonia/scm/cli/config/ConfigFiles.java | 151 ++++++++++++++++++ .../config/ScmClientConfigFileHandler.java | 64 +++----- .../cli/config/SecureRandomKeyGenerator.java | 69 ++++++++ .../cli/config/WeakCipherStreamHandler.java | 7 +- .../config/AesCipherStreamHandlerTest.java | 68 ++++++++ .../cli/config/ClientConfigurationTests.java | 96 +++++++++++ .../sonia/scm/cli/config/ConfigFilesTest.java | 105 ++++++++++++ .../scm/cli/config/InMemoryKeyStore.java | 53 ++++++ .../ScmClientConfigFileHandlerTest.java | 76 ++++++--- .../config/SecureRandomKeyGeneratorTest.java | 47 ++++++ .../scm/cli/config/scm-cli-config.enc.xml | Bin 0 -> 296 bytes 13 files changed, 790 insertions(+), 62 deletions(-) create mode 100644 scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/AesCipherStreamHandler.java create mode 100644 scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ConfigFiles.java create mode 100644 scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/SecureRandomKeyGenerator.java create mode 100644 scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/AesCipherStreamHandlerTest.java create mode 100644 scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ClientConfigurationTests.java create mode 100644 scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ConfigFilesTest.java create mode 100644 scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/InMemoryKeyStore.java create mode 100644 scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/SecureRandomKeyGeneratorTest.java create mode 100644 scm-clients/scm-cli-client/src/test/resources/sonia/scm/cli/config/scm-cli-config.enc.xml diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/AesCipherStreamHandler.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/AesCipherStreamHandler.java new file mode 100644 index 0000000000..5955b8b762 --- /dev/null +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/AesCipherStreamHandler.java @@ -0,0 +1,108 @@ +/** + * 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.config; + +import com.google.common.base.Charsets; + +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; +import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.SecureRandom; + +/** + * Implementation of {@link CipherStreamHandler} which uses AES. This version is used since version 1.60 for the + * cli client encryption. + * + * @author Sebastian Sdorra + * @since 1.60 + */ +public class AesCipherStreamHandler implements CipherStreamHandler { + + private static final String ALGORITHM = "AES/GCM/NoPadding"; + + private final SecureRandom random = new SecureRandom(); + + private final byte[] secretKey; + + AesCipherStreamHandler(String secretKey) { + this.secretKey = secretKey.getBytes(Charsets.UTF_8); + } + + @Override + public OutputStream encrypt(OutputStream outputStream) throws IOException { + Cipher cipher = createCipherForEncryption(); + outputStream.write(cipher.getIV()); + return new CipherOutputStream(outputStream, cipher); + } + + @Override + public InputStream decrypt(InputStream inputStream) throws IOException { + Cipher cipher = createCipherForDecryption(inputStream); + return new CipherInputStream(inputStream, cipher); + } + + private Cipher createCipherForDecryption(InputStream inputStream) throws IOException { + byte[] iv =new byte[12]; + inputStream.read(iv); + return createCipher(Cipher.DECRYPT_MODE, iv); + } + + private Cipher createCipherForEncryption() { + byte[] iv = generateIV(); + return createCipher(Cipher.ENCRYPT_MODE, iv); + } + + private byte[] generateIV() { + // use 12 byte as described at nist + // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf + byte[] iv = new byte[12]; + random.nextBytes(iv); + return iv; + } + + private Cipher createCipher(int mode, byte[] iv) { + try { + Cipher cipher = Cipher.getInstance(ALGORITHM); + GCMParameterSpec parameterSpec = new GCMParameterSpec(128, iv); + cipher.init(mode, new SecretKeySpec(secretKey, "AES"), parameterSpec); + return cipher; + } catch (Exception ex) { + throw new ScmConfigException("failed to create cipher", ex); + } + } +} diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/CipherStreamHandler.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/CipherStreamHandler.java index e687988be3..2321b3d9d9 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/CipherStreamHandler.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/CipherStreamHandler.java @@ -32,11 +32,15 @@ package sonia.scm.cli.config; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * The CipherStreamHandler is able to encrypt and decrypt streams. + * + * @author Sebastian Sdorra + * @since 1.60 */ public interface CipherStreamHandler { @@ -47,7 +51,7 @@ public interface CipherStreamHandler { * * @return raw input stream */ - InputStream decrypt(InputStream inputStream); + InputStream decrypt(InputStream inputStream) throws IOException; /** * Encrypts the given output stream. @@ -56,5 +60,5 @@ public interface CipherStreamHandler { * * @return encrypting output stream */ - OutputStream encrypt(OutputStream outputStream); + OutputStream encrypt(OutputStream outputStream) throws IOException; } diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ConfigFiles.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ConfigFiles.java new file mode 100644 index 0000000000..5087c50746 --- /dev/null +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ConfigFiles.java @@ -0,0 +1,151 @@ +/** + * 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.config; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Charsets; +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import sonia.scm.security.KeyGenerator; + +import javax.xml.bind.JAXB; +import java.io.*; +import java.util.Arrays; + +/** + * Util methods for configuration files. + * + * @author Sebastian Sdorra + * @since 1.60 + */ +final class ConfigFiles { + + private static final KeyGenerator keyGenerator = new SecureRandomKeyGenerator(); + + // SCM Config Version 2 + @VisibleForTesting + static final byte[] VERSION_IDENTIFIER = "SCV2".getBytes(Charsets.US_ASCII); + + private ConfigFiles() { + } + + /** + * Returns {@code true} if the file is encrypted with the v2 format. + * + * @param file configuration file + * + * @return {@code true} for format v2 + * + * @throws IOException + */ + static boolean isFormatV2(File file) throws IOException { + try (InputStream input = new FileInputStream(file)) { + byte[] bytes = new byte[VERSION_IDENTIFIER.length]; + input.read(bytes); + return Arrays.equals(VERSION_IDENTIFIER, bytes); + } + } + + /** + * Decrypt and parse v1 configuration file. + * + * @param keyStore key store + * @param file configuration file + * + * @return client configuration + * + * @throws IOException + */ + static ScmClientConfig parseV1(KeyStore keyStore, File file) throws IOException { + String secretKey = secretKey(keyStore); + CipherStreamHandler cipherStreamHandler = new WeakCipherStreamHandler(secretKey); + return decrypt(cipherStreamHandler, new FileInputStream(file)); + } + + /** + * Decrypt and parse v12configuration file. + * + * @param keyStore key store + * @param file configuration file + * + * @return client configuration + * + * @throws IOException + */ + static ScmClientConfig parseV2(KeyStore keyStore, File file) throws IOException { + String secretKey = secretKey(keyStore); + CipherStreamHandler cipherStreamHandler = new AesCipherStreamHandler(secretKey); + try (InputStream input = new FileInputStream(file)) { + input.skip(VERSION_IDENTIFIER.length); + return decrypt(cipherStreamHandler, input); + } + } + + /** + * Store encrypt and write the configuration to the given file. + * Note the method uses always the latest available format. + * + * @param keyStore key store + * @param config configuration + * @param file configuration file + * + * @throws IOException + */ + static void store(KeyStore keyStore, ScmClientConfig config, File file) throws IOException { + String secretKey = keyGenerator.createKey(); + CipherStreamHandler cipherStreamHandler = new AesCipherStreamHandler(secretKey); + try (OutputStream output = new FileOutputStream(file)) { + output.write(VERSION_IDENTIFIER); + encrypt(cipherStreamHandler, output, config); + } + keyStore.set(secretKey); + } + + private static String secretKey(KeyStore keyStore) { + String secretKey = keyStore.get(); + Preconditions.checkState(!Strings.isNullOrEmpty(secretKey), "no stored secret key found"); + return secretKey; + } + + private static ScmClientConfig decrypt(CipherStreamHandler cipherStreamHandler, InputStream input) throws IOException { + try ( InputStream decryptedInputStream = cipherStreamHandler.decrypt(input) ) { + return JAXB.unmarshal(decryptedInputStream, ScmClientConfig.class); + } + } + + private static void encrypt(CipherStreamHandler cipherStreamHandler, OutputStream output, ScmClientConfig clientConfig) throws IOException { + try ( OutputStream encryptedOutputStream = cipherStreamHandler.encrypt(output) ) { + JAXB.marshal(clientConfig, encryptedOutputStream); + } + } + +} diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfigFileHandler.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfigFileHandler.java index bbb0fd85c1..00a0eb6cf6 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfigFileHandler.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfigFileHandler.java @@ -35,15 +35,10 @@ package sonia.scm.cli.config; //~--- non-JDK imports -------------------------------------------------------- -import sonia.scm.security.KeyGenerator; -import sonia.scm.security.UUIDKeyGenerator; import sonia.scm.util.Util; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import java.io.*; +import java.io.File; +import java.io.IOException; //~--- JDK imports ------------------------------------------------------------ @@ -63,40 +58,20 @@ public class ScmClientConfigFileHandler //~--- constructors --------------------------------------------------------- private final KeyStore keyStore; - private final KeyGenerator keyGenerator; private final File file; - private final JAXBContext context; - - private final CipherStreamHandler cipherStreamHandler; /** - * Constructs ... + * Constructs a new ScmClientConfigFileHandler * */ public ScmClientConfigFileHandler() { - this(new PrefsKeyStore(), new UUIDKeyGenerator(), getDefaultConfigFile()); + this(new PrefsKeyStore(), getDefaultConfigFile()); } - ScmClientConfigFileHandler(KeyStore keyStore, KeyGenerator keyGenerator, File file) { + ScmClientConfigFileHandler(KeyStore keyStore,File file) { this.keyStore = keyStore; - this.keyGenerator = keyGenerator; this.file = file; - - String key = keyStore.get(); - - if (Util.isEmpty(key)) { - key = keyGenerator.createKey(); - keyStore.set(key); - } - - cipherStreamHandler = new WeakCipherStreamHandler(key.toCharArray()); - - try { - context = JAXBContext.newInstance(ScmClientConfig.class); - } catch (JAXBException ex) { - throw new ScmConfigException("could not create JAXBContext for ScmClientConfig", ex); - } } //~--- methods -------------------------------------------------------------- @@ -132,17 +107,27 @@ public class ScmClientConfigFileHandler ScmClientConfig config = null; if (file.exists()) { - try (InputStream input = cipherStreamHandler.decrypt(new FileInputStream(file))) { - Unmarshaller um = context.createUnmarshaller(); - config = (ScmClientConfig) um.unmarshal(input); - } catch (IOException | JAXBException ex) { - throw new ScmConfigException("could not read config file", ex); - } + config = readFromFile(); } return config; } + private ScmClientConfig readFromFile() { + ScmClientConfig config; + try { + if (ConfigFiles.isFormatV2(file)) { + config = ConfigFiles.parseV2(keyStore, file); + } else { + config = ConfigFiles.parseV1(keyStore, file); + ConfigFiles.store(keyStore, config, file); + } + } catch (IOException ex) { + throw new ScmConfigException("could not read config file", ex); + } + return config; + } + /** * Method description * @@ -150,10 +135,9 @@ public class ScmClientConfigFileHandler * @param config */ public void write(ScmClientConfig config) { - try (OutputStream output = cipherStreamHandler.encrypt(new FileOutputStream(file))) { - Marshaller m = context.createMarshaller(); - m.marshal(config, output); - } catch (IOException | JAXBException ex) { + try { + ConfigFiles.store(keyStore, config, file); + } catch (IOException ex) { throw new ScmConfigException("could not write config file", ex); } } diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/SecureRandomKeyGenerator.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/SecureRandomKeyGenerator.java new file mode 100644 index 0000000000..19ae135461 --- /dev/null +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/SecureRandomKeyGenerator.java @@ -0,0 +1,69 @@ +/** + * 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.config; + +import com.google.common.annotations.VisibleForTesting; +import sonia.scm.security.KeyGenerator; + +import java.security.SecureRandom; +import java.util.Locale; + +/** + * Create keys by using {@link SecureRandom}. The SecureRandomKeyGenerator produces aes compatible keys. + * Warning the class is not thread safe. + * + * @author Sebastian Sdorra + * @since 1.60 + */ +public class SecureRandomKeyGenerator implements KeyGenerator { + + private SecureRandom random = new SecureRandom(); + + // key length 16 for aes128 + @VisibleForTesting + static final int KEY_LENGTH = 16; + + private static final String UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + private static final String LOWER = UPPER.toLowerCase(Locale.ENGLISH); + private static final String DIGITS = "0123456789"; + private static final char[] ALL = (UPPER + LOWER + DIGITS).toCharArray(); + + @Override + public String createKey() { + char[] key = new char[KEY_LENGTH]; + for (int idx = 0; idx < KEY_LENGTH; ++idx) { + key[idx] = ALL[random.nextInt(ALL.length)]; + } + return new String(key); + } +} diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/WeakCipherStreamHandler.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/WeakCipherStreamHandler.java index a9e3e5ef42..175d1986c6 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/WeakCipherStreamHandler.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/WeakCipherStreamHandler.java @@ -45,6 +45,9 @@ import java.security.spec.InvalidKeySpecException; * Weak implementation of {@link CipherStreamHandler}. This is the old implementation, which was used in versions prior * 1.60. * + * @author Sebastian Sdorra + * @since 1.60 + * * @see Issue 978 * @see Issue 979 */ @@ -61,8 +64,8 @@ public class WeakCipherStreamHandler implements CipherStreamHandler { * * @param secretKey secret key */ - public WeakCipherStreamHandler(char[] secretKey) { - this.secretKey = secretKey; + WeakCipherStreamHandler(String secretKey) { + this.secretKey = secretKey.toCharArray(); } @Override diff --git a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/AesCipherStreamHandlerTest.java b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/AesCipherStreamHandlerTest.java new file mode 100644 index 0000000000..14000faa33 --- /dev/null +++ b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/AesCipherStreamHandlerTest.java @@ -0,0 +1,68 @@ +/** + * 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.config; + +import com.google.common.base.Charsets; +import com.google.common.io.ByteStreams; +import org.junit.Test; +import sonia.scm.security.KeyGenerator; + +import java.io.*; + +import static org.junit.Assert.assertEquals; + +public class AesCipherStreamHandlerTest { + + private final KeyGenerator keyGenerator = new SecureRandomKeyGenerator(); + + @Test + public void testEncryptAndDecrypt() throws IOException { + AesCipherStreamHandler cipherStreamHandler = new AesCipherStreamHandler(keyGenerator.createKey()); + + // douglas adams + String content = "If you try and take a cat apart to see how it works, the first thing you have on your hands is a nonworking cat."; + + // encrypt + ByteArrayOutputStream output = new ByteArrayOutputStream(); + OutputStream encryptedOutput = cipherStreamHandler.encrypt(output); + encryptedOutput.write(content.getBytes(Charsets.UTF_8)); + encryptedOutput.close(); + + InputStream input = new ByteArrayInputStream(output.toByteArray()); + input = cipherStreamHandler.decrypt(input); + byte[] decrypted = ByteStreams.toByteArray(input); + + assertEquals(content, new String(decrypted, Charsets.UTF_8)); + } + +} diff --git a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ClientConfigurationTests.java b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ClientConfigurationTests.java new file mode 100644 index 0000000000..20422df7ed --- /dev/null +++ b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ClientConfigurationTests.java @@ -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 + * + */ + + +package sonia.scm.cli.config; + +import com.google.common.base.Charsets; +import com.google.common.io.ByteStreams; + +import javax.xml.bind.JAXB; +import java.io.*; + +import static org.junit.Assert.assertEquals; + +final class ClientConfigurationTests { + + private ClientConfigurationTests() { + } + + static void testCipherStream(CipherStreamHandler cipherStreamHandler, String content) throws IOException { + byte[] encrypted = encrypt(cipherStreamHandler, content); + String decrypted = decrypt(cipherStreamHandler, encrypted); + assertEquals(content, decrypted); + } + + + static byte[] encrypt(CipherStreamHandler cipherStreamHandler, String content) throws IOException { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + OutputStream encryptedOutput = cipherStreamHandler.encrypt(output); + encryptedOutput.write(content.getBytes(Charsets.UTF_8)); + encryptedOutput.close(); + return output.toByteArray(); + } + + static String decrypt(CipherStreamHandler cipherStreamHandler, byte[] encrypted) throws IOException { + InputStream input = new ByteArrayInputStream(encrypted); + input = cipherStreamHandler.decrypt(input); + byte[] decrypted = ByteStreams.toByteArray(input); + input.close(); + + return new String(decrypted, Charsets.UTF_8); + } + + static void assertSampleConfig(ScmClientConfig config) { + ServerConfig defaultConfig; + defaultConfig = config.getDefaultConfig(); + + assertEquals("http://localhost:8080/scm", defaultConfig.getServerUrl()); + assertEquals("admin", defaultConfig.getUsername()); + assertEquals("admin123", defaultConfig.getPassword()); + } + + static ScmClientConfig createSampleConfig() { + ScmClientConfig config = new ScmClientConfig(); + ServerConfig defaultConfig = config.getDefaultConfig(); + defaultConfig.setServerUrl("http://localhost:8080/scm"); + defaultConfig.setUsername("admin"); + defaultConfig.setPassword("admin123"); + return config; + } + + static void encrypt(CipherStreamHandler cipherStreamHandler, ScmClientConfig config, File file) throws IOException { + try (OutputStream output = cipherStreamHandler.encrypt(new FileOutputStream(file))) { + JAXB.marshal(config, output); + } + } + +} diff --git a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ConfigFilesTest.java b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ConfigFilesTest.java new file mode 100644 index 0000000000..5fbdfdc0c0 --- /dev/null +++ b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ConfigFilesTest.java @@ -0,0 +1,105 @@ +/** + * 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.config; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; + +import static org.junit.Assert.*; + +public class ConfigFilesTest { + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Test + public void testIsFormatV2() throws IOException { + byte[] content = "The door was the way to... to... The Door was The Way".getBytes(Charsets.UTF_8); + + File fileV1 = temporaryFolder.newFile(); + Files.write(content, fileV1); + + assertFalse(ConfigFiles.isFormatV2(fileV1)); + + File fileV2 = temporaryFolder.newFile(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + baos.write(ConfigFiles.VERSION_IDENTIFIER); + baos.write(content); + Files.write(baos.toByteArray(), fileV2); + + assertTrue(ConfigFiles.isFormatV2(fileV2)); + } + + @Test + public void testParseV1() throws IOException { + InMemoryKeyStore keyStore = createKeyStore(); + WeakCipherStreamHandler handler = new WeakCipherStreamHandler(keyStore.get()); + + ScmClientConfig config = ClientConfigurationTests.createSampleConfig(); + File file = temporaryFolder.newFile(); + ClientConfigurationTests.encrypt(handler, config, file); + + config = ConfigFiles.parseV1(keyStore, file); + ClientConfigurationTests.assertSampleConfig(config); + } + + @Test + public void storeAndParseV2() throws IOException { + InMemoryKeyStore keyStore = new InMemoryKeyStore(); + ScmClientConfig config = ClientConfigurationTests.createSampleConfig(); + File file = temporaryFolder.newFile(); + + ConfigFiles.store(keyStore, config, file); + + String key = keyStore.get(); + assertNotNull(key); + + config = ConfigFiles.parseV2(keyStore, file); + ClientConfigurationTests.assertSampleConfig(config); + } + + private InMemoryKeyStore createKeyStore() { + String secretKey = new SecureRandomKeyGenerator().createKey(); + InMemoryKeyStore keyStore = new InMemoryKeyStore(); + keyStore.set(secretKey); + return keyStore; + } + +} diff --git a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/InMemoryKeyStore.java b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/InMemoryKeyStore.java new file mode 100644 index 0000000000..1d0069a087 --- /dev/null +++ b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/InMemoryKeyStore.java @@ -0,0 +1,53 @@ +/** + * 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.config; + +public class InMemoryKeyStore implements KeyStore { + + private String secretKey; + + @Override + public void set(String secretKey) { + this.secretKey = secretKey; + } + + @Override + public String get() { + return secretKey; + } + + @Override + public void remove() { + this.secretKey = null; + } +} diff --git a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ScmClientConfigFileHandlerTest.java b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ScmClientConfigFileHandlerTest.java index ec598fd2d4..a9f6a46418 100644 --- a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ScmClientConfigFileHandlerTest.java +++ b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ScmClientConfigFileHandlerTest.java @@ -31,6 +31,8 @@ package sonia.scm.cli.config; +import com.google.common.io.Files; +import com.google.common.io.Resources; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -38,10 +40,9 @@ import sonia.scm.security.UUIDKeyGenerator; import java.io.File; import java.io.IOException; +import java.net.URL; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; public class ScmClientConfigFileHandlerTest { @@ -53,7 +54,7 @@ public class ScmClientConfigFileHandlerTest { File configFile = temporaryFolder.newFile(); ScmClientConfigFileHandler handler = new ScmClientConfigFileHandler( - new InMemoryKeyStore(), new UUIDKeyGenerator(), configFile + new InMemoryKeyStore(), configFile ); ScmClientConfig config = new ScmClientConfig(); @@ -76,23 +77,62 @@ public class ScmClientConfigFileHandlerTest { assertFalse(configFile.exists()); } - private static class InMemoryKeyStore implements KeyStore { + @Test + public void testClientConfigFileHandlerWithOldConfiguration() throws IOException { + File configFile = temporaryFolder.newFile(); - private String secretKey; + // old implementation has used uuids as keys + String key = new UUIDKeyGenerator().createKey(); - @Override - public void set(String secretKey) { - this.secretKey = secretKey; - } + WeakCipherStreamHandler weakCipherStreamHandler = new WeakCipherStreamHandler(key); + ScmClientConfig clientConfig = ClientConfigurationTests.createSampleConfig(); + ClientConfigurationTests.encrypt(weakCipherStreamHandler, clientConfig, configFile); - @Override - public String get() { - return secretKey; - } + assertFalse(ConfigFiles.isFormatV2(configFile)); - @Override - public void remove() { - this.secretKey = null; - } + KeyStore keyStore = new InMemoryKeyStore(); + keyStore.set(key); + + ScmClientConfigFileHandler handler = new ScmClientConfigFileHandler( + keyStore, configFile + ); + + ScmClientConfig config = handler.read(); + ClientConfigurationTests.assertSampleConfig(config); + + // ensure key has changed + assertNotEquals(key, keyStore.get()); + + // ensure config rewritten with v2 + assertTrue(ConfigFiles.isFormatV2(configFile)); + } + + @Test + public void testClientConfigFileHandlerWithRealMigration() throws IOException { + URL resource = Resources.getResource("sonia/scm/cli/config/scm-cli-config.enc.xml"); + byte[] bytes = Resources.toByteArray(resource); + + File configFile = temporaryFolder.newFile(); + Files.write(bytes, configFile); + + String key = "358e018a-0c3c-4339-8266-3874e597305f"; + KeyStore keyStore = new InMemoryKeyStore(); + keyStore.set(key); + + ScmClientConfigFileHandler handler = new ScmClientConfigFileHandler( + keyStore, configFile + ); + + ScmClientConfig config = handler.read(); + ServerConfig defaultConfig = config.getDefaultConfig(); + assertEquals("http://hitchhicker.com/scm", defaultConfig.getServerUrl()); + assertEquals("tricia", defaultConfig.getUsername()); + assertEquals("trillian123", defaultConfig.getPassword()); + + // ensure key has changed + assertNotEquals(key, keyStore.get()); + + // ensure config rewritten with v2 + assertTrue(ConfigFiles.isFormatV2(configFile)); } } diff --git a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/SecureRandomKeyGeneratorTest.java b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/SecureRandomKeyGeneratorTest.java new file mode 100644 index 0000000000..e847e89cb1 --- /dev/null +++ b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/SecureRandomKeyGeneratorTest.java @@ -0,0 +1,47 @@ +/** + * 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.config; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class SecureRandomKeyGeneratorTest { + + @Test + public void testCreateKey() { + SecureRandomKeyGenerator keyGenerator = new SecureRandomKeyGenerator(); + assertNotNull(keyGenerator.createKey()); + assertEquals(SecureRandomKeyGenerator.KEY_LENGTH, keyGenerator.createKey().length()); + } + +} diff --git a/scm-clients/scm-cli-client/src/test/resources/sonia/scm/cli/config/scm-cli-config.enc.xml b/scm-clients/scm-cli-client/src/test/resources/sonia/scm/cli/config/scm-cli-config.enc.xml new file mode 100644 index 0000000000000000000000000000000000000000..94132772a470186bfb3f7fcef19147caa328fb43 GIT binary patch literal 296 zcmV+@0oVRHh)0-9KiSs&h;Gc9iYttD@?y@sK-DK9rt+UqcB$|LJIGtiuWhPCD8AV|${J04dxuLvemaJDR8bujM$6VA+!l-1QGeQ)~D{8o;7;j|7E z{HjWNPp_;e+jmnC$8b58PmorI<1lg5!<=30g;E*#1Zoe+=vFqAjR2LPW0GvPwTh7{dS&&BRDH%NNkQTUEVsSI^Vz!`vE}xPm}6UZF0e3HMZ?%rM^3;`HLf89 ul*7JXT?4Q0fR^`g-Fk}4l+hkg?Dkrwzz~`30=lveB36|b^%kxKF|9s{3XnMf literal 0 HcmV?d00001 From cbecb3731bb77822aaafddb2b9e261ff6115864e Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 30 Apr 2018 09:27:00 +0200 Subject: [PATCH 61/78] #979 use a java 7 compatible cipher spec --- .../cli/config/AesCipherStreamHandler.java | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/AesCipherStreamHandler.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/AesCipherStreamHandler.java index 5955b8b762..680dd25563 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/AesCipherStreamHandler.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/AesCipherStreamHandler.java @@ -37,7 +37,7 @@ import com.google.common.base.Charsets; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; -import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.IOException; import java.io.InputStream; @@ -53,7 +53,9 @@ import java.security.SecureRandom; */ public class AesCipherStreamHandler implements CipherStreamHandler { - private static final String ALGORITHM = "AES/GCM/NoPadding"; + private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5PADDING"; + private static final String SECRET_KEY_ALGORITHM = "AES"; + private static final int IV_LENGTH = 16; private final SecureRandom random = new SecureRandom(); @@ -77,11 +79,15 @@ public class AesCipherStreamHandler implements CipherStreamHandler { } private Cipher createCipherForDecryption(InputStream inputStream) throws IOException { - byte[] iv =new byte[12]; + byte[] iv = createEmptyIvArray(); inputStream.read(iv); return createCipher(Cipher.DECRYPT_MODE, iv); } + private byte[] createEmptyIvArray() { + return new byte[IV_LENGTH]; + } + private Cipher createCipherForEncryption() { byte[] iv = generateIV(); return createCipher(Cipher.ENCRYPT_MODE, iv); @@ -90,16 +96,16 @@ public class AesCipherStreamHandler implements CipherStreamHandler { private byte[] generateIV() { // use 12 byte as described at nist // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf - byte[] iv = new byte[12]; + byte[] iv = createEmptyIvArray(); random.nextBytes(iv); return iv; } private Cipher createCipher(int mode, byte[] iv) { try { - Cipher cipher = Cipher.getInstance(ALGORITHM); - GCMParameterSpec parameterSpec = new GCMParameterSpec(128, iv); - cipher.init(mode, new SecretKeySpec(secretKey, "AES"), parameterSpec); + Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); + IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); + cipher.init(mode, new SecretKeySpec(secretKey, SECRET_KEY_ALGORITHM), ivParameterSpec); return cipher; } catch (Exception ex) { throw new ScmConfigException("failed to create cipher", ex); From 40b5ef485b7b002f5bdbddd2b86741ccc8f3ee40 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 30 Apr 2018 09:36:51 +0200 Subject: [PATCH 62/78] #979 encrypt the configuration keys before they are written to prefs --- .../cli/config/EncryptionKeyStoreWrapper.java | 138 ++++++++++++++++++ .../config/ScmClientConfigFileHandler.java | 6 +- .../config/EncryptionKeyStoreWrapperTest.java | 60 ++++++++ .../ScmClientConfigFileHandlerTest.java | 6 +- 4 files changed, 204 insertions(+), 6 deletions(-) create mode 100644 scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/EncryptionKeyStoreWrapper.java create mode 100644 scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/EncryptionKeyStoreWrapperTest.java diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/EncryptionKeyStoreWrapper.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/EncryptionKeyStoreWrapper.java new file mode 100644 index 0000000000..826660f00f --- /dev/null +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/EncryptionKeyStoreWrapper.java @@ -0,0 +1,138 @@ +/** + * 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.config; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Charsets; +import com.google.common.base.Strings; +import com.google.common.io.BaseEncoding; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.SecretKeySpec; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + +/** + * The EncryptionKeyStoreWrapper is a wrapper around the {@link KeyStore} interface. The wrapper will encrypt the passed + * keys, before they are written to the underlying {@link KeyStore} implementation. The wrapper will also honor old + * unencrypted keys. + * + * @author Sebastian Sdorra + * @since 1.60 + */ +public class EncryptionKeyStoreWrapper implements KeyStore { + + private static final String ALGORITHM = "AES"; + + private static final SecureRandom random = new SecureRandom(); + + // i know storing the key directly in the class is far away from a best practice, but this is a chicken egg type + // of problem. We need a key to encrypt the stored keys, however encrypting the keys with a static defined key + // is better as storing them as plain text. + private static final byte[] SECRET_KEY = new byte[]{ 0x50, 0x61, 0x41, 0x67, 0x55, 0x43, 0x48, 0x7a, 0x48, 0x59, + 0x7a, 0x57, 0x6b, 0x34, 0x54, 0x62 + }; + + @VisibleForTesting + static final String ENCRYPTED_PREFIX = "enc:"; + + private KeyStore wrappedKeyStore; + + EncryptionKeyStoreWrapper(KeyStore wrappedKeyStore) { + this.wrappedKeyStore = wrappedKeyStore; + } + + @Override + public void set(String secretKey) { + String encrypted = encrypt(secretKey); + wrappedKeyStore.set(ENCRYPTED_PREFIX.concat(encrypted)); + } + + private String encrypt(String value) { + try { + Cipher cipher = createCipher(Cipher.ENCRYPT_MODE); + byte[] raw = cipher.doFinal(value.getBytes(Charsets.UTF_8)); + return encode(raw); + } catch (IllegalBlockSizeException | BadPaddingException ex) { + throw new ScmConfigException("failed to encrypt key", ex); + } + } + + private String encode(byte[] raw) { + return BaseEncoding.base64().encode(raw); + } + + @Override + public String get() { + String value = wrappedKeyStore.get(); + if (Strings.nullToEmpty(value).startsWith(ENCRYPTED_PREFIX)) { + String encrypted = value.substring(ENCRYPTED_PREFIX.length()); + return decrypt(encrypted); + } + return value; + } + + private String decrypt(String encoded) { + try { + Cipher cipher = createCipher(Cipher.DECRYPT_MODE); + byte[] raw = decode(encoded); + return new String(cipher.doFinal(raw), Charsets.UTF_8); + } catch (IllegalBlockSizeException | BadPaddingException ex) { + throw new ScmConfigException("failed to decrypt key", ex); + } + } + + private byte[] decode(String encoded) { + return BaseEncoding.base64().decode(encoded); + } + + private Cipher createCipher(int mode) { + try { + Cipher cipher = Cipher.getInstance(ALGORITHM); + SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET_KEY, "AES"); + cipher.init(mode, secretKeySpec, random); + return cipher; + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException ex) { + throw new ScmConfigException("failed to create key", ex); + } + } + + @Override + public void remove() { + wrappedKeyStore.remove(); + } +} diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfigFileHandler.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfigFileHandler.java index 00a0eb6cf6..78efd5f149 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfigFileHandler.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfigFileHandler.java @@ -62,11 +62,11 @@ public class ScmClientConfigFileHandler /** - * Constructs a new ScmClientConfigFileHandler - * + * Constructs a new ScmClientConfigFileHandler with a encrypted {@link java.util.prefs.Preferences} based + * {@link KeyStore} and a determined default location. */ public ScmClientConfigFileHandler() { - this(new PrefsKeyStore(), getDefaultConfigFile()); + this(new EncryptionKeyStoreWrapper(new PrefsKeyStore()), getDefaultConfigFile()); } ScmClientConfigFileHandler(KeyStore keyStore,File file) { diff --git a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/EncryptionKeyStoreWrapperTest.java b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/EncryptionKeyStoreWrapperTest.java new file mode 100644 index 0000000000..0a77c9d772 --- /dev/null +++ b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/EncryptionKeyStoreWrapperTest.java @@ -0,0 +1,60 @@ +/** + * 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.config; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class EncryptionKeyStoreWrapperTest { + + private KeyStore keyStore = new InMemoryKeyStore(); + + @Test + public void testEncryptionKeyStoreWrapper() { + EncryptionKeyStoreWrapper wrapper = new EncryptionKeyStoreWrapper(keyStore); + wrapper.set("mysecretkey"); + + assertEquals("mysecretkey", wrapper.get()); + assertTrue(keyStore.get().startsWith(EncryptionKeyStoreWrapper.ENCRYPTED_PREFIX)); + } + + @Test + public void testEncryptionKeyStoreWrapperWithOldUnencryptedKey() { + keyStore.set("mysecretkey"); + EncryptionKeyStoreWrapper wrapper = new EncryptionKeyStoreWrapper(keyStore); + assertEquals("mysecretkey", wrapper.get()); + } + +} diff --git a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ScmClientConfigFileHandlerTest.java b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ScmClientConfigFileHandlerTest.java index a9f6a46418..f7dfc36deb 100644 --- a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ScmClientConfigFileHandlerTest.java +++ b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ScmClientConfigFileHandlerTest.java @@ -54,7 +54,7 @@ public class ScmClientConfigFileHandlerTest { File configFile = temporaryFolder.newFile(); ScmClientConfigFileHandler handler = new ScmClientConfigFileHandler( - new InMemoryKeyStore(), configFile + new EncryptionKeyStoreWrapper(new InMemoryKeyStore()), configFile ); ScmClientConfig config = new ScmClientConfig(); @@ -90,7 +90,7 @@ public class ScmClientConfigFileHandlerTest { assertFalse(ConfigFiles.isFormatV2(configFile)); - KeyStore keyStore = new InMemoryKeyStore(); + KeyStore keyStore = new EncryptionKeyStoreWrapper(new InMemoryKeyStore()); keyStore.set(key); ScmClientConfigFileHandler handler = new ScmClientConfigFileHandler( @@ -116,7 +116,7 @@ public class ScmClientConfigFileHandlerTest { Files.write(bytes, configFile); String key = "358e018a-0c3c-4339-8266-3874e597305f"; - KeyStore keyStore = new InMemoryKeyStore(); + KeyStore keyStore = new EncryptionKeyStoreWrapper(new InMemoryKeyStore()); keyStore.set(key); ScmClientConfigFileHandler handler = new ScmClientConfigFileHandler( From f3459729353b6c29c9570a225d72f8afcb9a173d Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 30 Apr 2018 11:01:00 +0200 Subject: [PATCH 63/78] #979 change encryption key prefix from enc to SKV2 (scm key version 2) --- .../java/sonia/scm/cli/config/EncryptionKeyStoreWrapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/EncryptionKeyStoreWrapper.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/EncryptionKeyStoreWrapper.java index 826660f00f..d86bfa40b6 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/EncryptionKeyStoreWrapper.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/EncryptionKeyStoreWrapper.java @@ -68,7 +68,7 @@ public class EncryptionKeyStoreWrapper implements KeyStore { }; @VisibleForTesting - static final String ENCRYPTED_PREFIX = "enc:"; + static final String ENCRYPTED_PREFIX = "SKV2:"; private KeyStore wrappedKeyStore; From 41dea4741337414ba96b89c659b5a75f2c63c8e2 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 4 May 2018 07:20:07 +0200 Subject: [PATCH 64/78] #979 rename KeyStore to SecretKeyStore --- .../sonia/scm/cli/config/ConfigFiles.java | 22 +++++++++---------- ...a => EncryptionSecretKeyStoreWrapper.java} | 20 ++++++++--------- ...KeyStore.java => PrefsSecretKeyStore.java} | 9 +++++--- .../config/ScmClientConfigFileHandler.java | 20 ++++++++--------- .../{KeyStore.java => SecretKeyStore.java} | 7 ++++-- .../sonia/scm/cli/config/ConfigFilesTest.java | 8 +++---- ... EncryptionSecretKeyStoreWrapperTest.java} | 12 +++++----- ...Store.java => InMemorySecretKeyStore.java} | 2 +- .../ScmClientConfigFileHandlerTest.java | 18 +++++++-------- 9 files changed, 62 insertions(+), 56 deletions(-) rename scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/{EncryptionKeyStoreWrapper.java => EncryptionSecretKeyStoreWrapper.java} (86%) rename scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/{PrefsKeyStore.java => PrefsSecretKeyStore.java} (91%) rename scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/{KeyStore.java => SecretKeyStore.java} (93%) rename scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/{EncryptionKeyStoreWrapperTest.java => EncryptionSecretKeyStoreWrapperTest.java} (81%) rename scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/{InMemoryKeyStore.java => InMemorySecretKeyStore.java} (96%) diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ConfigFiles.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ConfigFiles.java index 5087c50746..0f88ef662a 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ConfigFiles.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ConfigFiles.java @@ -78,15 +78,15 @@ final class ConfigFiles { /** * Decrypt and parse v1 configuration file. * - * @param keyStore key store + * @param secretKeyStore key store * @param file configuration file * * @return client configuration * * @throws IOException */ - static ScmClientConfig parseV1(KeyStore keyStore, File file) throws IOException { - String secretKey = secretKey(keyStore); + static ScmClientConfig parseV1(SecretKeyStore secretKeyStore, File file) throws IOException { + String secretKey = secretKey(secretKeyStore); CipherStreamHandler cipherStreamHandler = new WeakCipherStreamHandler(secretKey); return decrypt(cipherStreamHandler, new FileInputStream(file)); } @@ -94,15 +94,15 @@ final class ConfigFiles { /** * Decrypt and parse v12configuration file. * - * @param keyStore key store + * @param secretKeyStore key store * @param file configuration file * * @return client configuration * * @throws IOException */ - static ScmClientConfig parseV2(KeyStore keyStore, File file) throws IOException { - String secretKey = secretKey(keyStore); + static ScmClientConfig parseV2(SecretKeyStore secretKeyStore, File file) throws IOException { + String secretKey = secretKey(secretKeyStore); CipherStreamHandler cipherStreamHandler = new AesCipherStreamHandler(secretKey); try (InputStream input = new FileInputStream(file)) { input.skip(VERSION_IDENTIFIER.length); @@ -114,24 +114,24 @@ final class ConfigFiles { * Store encrypt and write the configuration to the given file. * Note the method uses always the latest available format. * - * @param keyStore key store + * @param secretKeyStore key store * @param config configuration * @param file configuration file * * @throws IOException */ - static void store(KeyStore keyStore, ScmClientConfig config, File file) throws IOException { + static void store(SecretKeyStore secretKeyStore, ScmClientConfig config, File file) throws IOException { String secretKey = keyGenerator.createKey(); CipherStreamHandler cipherStreamHandler = new AesCipherStreamHandler(secretKey); try (OutputStream output = new FileOutputStream(file)) { output.write(VERSION_IDENTIFIER); encrypt(cipherStreamHandler, output, config); } - keyStore.set(secretKey); + secretKeyStore.set(secretKey); } - private static String secretKey(KeyStore keyStore) { - String secretKey = keyStore.get(); + private static String secretKey(SecretKeyStore secretKeyStore) { + String secretKey = secretKeyStore.get(); Preconditions.checkState(!Strings.isNullOrEmpty(secretKey), "no stored secret key found"); return secretKey; } diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/EncryptionKeyStoreWrapper.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/EncryptionSecretKeyStoreWrapper.java similarity index 86% rename from scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/EncryptionKeyStoreWrapper.java rename to scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/EncryptionSecretKeyStoreWrapper.java index d86bfa40b6..123655a7e3 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/EncryptionKeyStoreWrapper.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/EncryptionSecretKeyStoreWrapper.java @@ -47,14 +47,14 @@ import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; /** - * The EncryptionKeyStoreWrapper is a wrapper around the {@link KeyStore} interface. The wrapper will encrypt the passed - * keys, before they are written to the underlying {@link KeyStore} implementation. The wrapper will also honor old - * unencrypted keys. + * The EncryptionSecretKeyStoreWrapper is a wrapper around the {@link SecretKeyStore} interface. The wrapper will + * encrypt the passed secret keys, before they are written to the underlying {@link SecretKeyStore} implementation. The + * wrapper will also honor old unencrypted keys. * * @author Sebastian Sdorra * @since 1.60 */ -public class EncryptionKeyStoreWrapper implements KeyStore { +public class EncryptionSecretKeyStoreWrapper implements SecretKeyStore { private static final String ALGORITHM = "AES"; @@ -70,16 +70,16 @@ public class EncryptionKeyStoreWrapper implements KeyStore { @VisibleForTesting static final String ENCRYPTED_PREFIX = "SKV2:"; - private KeyStore wrappedKeyStore; + private SecretKeyStore wrappedSecretKeyStore; - EncryptionKeyStoreWrapper(KeyStore wrappedKeyStore) { - this.wrappedKeyStore = wrappedKeyStore; + EncryptionSecretKeyStoreWrapper(SecretKeyStore wrappedSecretKeyStore) { + this.wrappedSecretKeyStore = wrappedSecretKeyStore; } @Override public void set(String secretKey) { String encrypted = encrypt(secretKey); - wrappedKeyStore.set(ENCRYPTED_PREFIX.concat(encrypted)); + wrappedSecretKeyStore.set(ENCRYPTED_PREFIX.concat(encrypted)); } private String encrypt(String value) { @@ -98,7 +98,7 @@ public class EncryptionKeyStoreWrapper implements KeyStore { @Override public String get() { - String value = wrappedKeyStore.get(); + String value = wrappedSecretKeyStore.get(); if (Strings.nullToEmpty(value).startsWith(ENCRYPTED_PREFIX)) { String encrypted = value.substring(ENCRYPTED_PREFIX.length()); return decrypt(encrypted); @@ -133,6 +133,6 @@ public class EncryptionKeyStoreWrapper implements KeyStore { @Override public void remove() { - wrappedKeyStore.remove(); + wrappedSecretKeyStore.remove(); } } diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/PrefsKeyStore.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/PrefsSecretKeyStore.java similarity index 91% rename from scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/PrefsKeyStore.java rename to scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/PrefsSecretKeyStore.java index 26a7e67b05..d3bd6847a8 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/PrefsKeyStore.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/PrefsSecretKeyStore.java @@ -34,15 +34,18 @@ package sonia.scm.cli.config; import java.util.prefs.Preferences; /** - * KeyStore implementation with uses {@link Preferences}. + * SecretKeyStore implementation with uses {@link Preferences}. + * + * @author Sebastian Sdorra + * @since 1.60 */ -public class PrefsKeyStore implements KeyStore { +public class PrefsSecretKeyStore implements SecretKeyStore { private static final String PREF_SECRET_KEY = "scm.client.key"; private final Preferences preferences; - public PrefsKeyStore() { + PrefsSecretKeyStore() { // we use ScmClientConfigFileHandler as base for backward compatibility preferences = Preferences.userNodeForPackage(ScmClientConfigFileHandler.class); } diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfigFileHandler.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfigFileHandler.java index 78efd5f149..5619d85f7e 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfigFileHandler.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/ScmClientConfigFileHandler.java @@ -57,20 +57,20 @@ public class ScmClientConfigFileHandler //~--- constructors --------------------------------------------------------- - private final KeyStore keyStore; + private final SecretKeyStore secretKeyStore; private final File file; /** * Constructs a new ScmClientConfigFileHandler with a encrypted {@link java.util.prefs.Preferences} based - * {@link KeyStore} and a determined default location. + * {@link SecretKeyStore} and a determined default location. */ public ScmClientConfigFileHandler() { - this(new EncryptionKeyStoreWrapper(new PrefsKeyStore()), getDefaultConfigFile()); + this(new EncryptionSecretKeyStoreWrapper(new PrefsSecretKeyStore()), getDefaultConfigFile()); } - ScmClientConfigFileHandler(KeyStore keyStore,File file) { - this.keyStore = keyStore; + ScmClientConfigFileHandler(SecretKeyStore secretKeyStore, File file) { + this.secretKeyStore = secretKeyStore; this.file = file; } @@ -94,7 +94,7 @@ public class ScmClientConfigFileHandler throw new ScmConfigException("could not delete config file"); } - keyStore.remove(); + secretKeyStore.remove(); } /** @@ -117,10 +117,10 @@ public class ScmClientConfigFileHandler ScmClientConfig config; try { if (ConfigFiles.isFormatV2(file)) { - config = ConfigFiles.parseV2(keyStore, file); + config = ConfigFiles.parseV2(secretKeyStore, file); } else { - config = ConfigFiles.parseV1(keyStore, file); - ConfigFiles.store(keyStore, config, file); + config = ConfigFiles.parseV1(secretKeyStore, file); + ConfigFiles.store(secretKeyStore, config, file); } } catch (IOException ex) { throw new ScmConfigException("could not read config file", ex); @@ -136,7 +136,7 @@ public class ScmClientConfigFileHandler */ public void write(ScmClientConfig config) { try { - ConfigFiles.store(keyStore, config, file); + ConfigFiles.store(secretKeyStore, config, file); } catch (IOException ex) { throw new ScmConfigException("could not write config file", ex); } diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/KeyStore.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/SecretKeyStore.java similarity index 93% rename from scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/KeyStore.java rename to scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/SecretKeyStore.java index 7ce64750ce..be600125b7 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/KeyStore.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/config/SecretKeyStore.java @@ -32,9 +32,12 @@ package sonia.scm.cli.config; /** - * KeyStore is able to read and write keys. + * SecretKeyStore is able to read and write secret keys. + * + * @author Sebastian Sdorra + * @since 1.60 */ -public interface KeyStore { +public interface SecretKeyStore { /** * Writes the given secret key to the store. diff --git a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ConfigFilesTest.java b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ConfigFilesTest.java index 5fbdfdc0c0..d9edc64884 100644 --- a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ConfigFilesTest.java +++ b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ConfigFilesTest.java @@ -69,7 +69,7 @@ public class ConfigFilesTest { @Test public void testParseV1() throws IOException { - InMemoryKeyStore keyStore = createKeyStore(); + InMemorySecretKeyStore keyStore = createKeyStore(); WeakCipherStreamHandler handler = new WeakCipherStreamHandler(keyStore.get()); ScmClientConfig config = ClientConfigurationTests.createSampleConfig(); @@ -82,7 +82,7 @@ public class ConfigFilesTest { @Test public void storeAndParseV2() throws IOException { - InMemoryKeyStore keyStore = new InMemoryKeyStore(); + InMemorySecretKeyStore keyStore = new InMemorySecretKeyStore(); ScmClientConfig config = ClientConfigurationTests.createSampleConfig(); File file = temporaryFolder.newFile(); @@ -95,9 +95,9 @@ public class ConfigFilesTest { ClientConfigurationTests.assertSampleConfig(config); } - private InMemoryKeyStore createKeyStore() { + private InMemorySecretKeyStore createKeyStore() { String secretKey = new SecureRandomKeyGenerator().createKey(); - InMemoryKeyStore keyStore = new InMemoryKeyStore(); + InMemorySecretKeyStore keyStore = new InMemorySecretKeyStore(); keyStore.set(secretKey); return keyStore; } diff --git a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/EncryptionKeyStoreWrapperTest.java b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/EncryptionSecretKeyStoreWrapperTest.java similarity index 81% rename from scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/EncryptionKeyStoreWrapperTest.java rename to scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/EncryptionSecretKeyStoreWrapperTest.java index 0a77c9d772..c9190c3357 100644 --- a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/EncryptionKeyStoreWrapperTest.java +++ b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/EncryptionSecretKeyStoreWrapperTest.java @@ -37,23 +37,23 @@ import org.junit.Test; import static org.junit.Assert.*; -public class EncryptionKeyStoreWrapperTest { +public class EncryptionSecretKeyStoreWrapperTest { - private KeyStore keyStore = new InMemoryKeyStore(); + private SecretKeyStore secretKeyStore = new InMemorySecretKeyStore(); @Test public void testEncryptionKeyStoreWrapper() { - EncryptionKeyStoreWrapper wrapper = new EncryptionKeyStoreWrapper(keyStore); + EncryptionSecretKeyStoreWrapper wrapper = new EncryptionSecretKeyStoreWrapper(secretKeyStore); wrapper.set("mysecretkey"); assertEquals("mysecretkey", wrapper.get()); - assertTrue(keyStore.get().startsWith(EncryptionKeyStoreWrapper.ENCRYPTED_PREFIX)); + assertTrue(secretKeyStore.get().startsWith(EncryptionSecretKeyStoreWrapper.ENCRYPTED_PREFIX)); } @Test public void testEncryptionKeyStoreWrapperWithOldUnencryptedKey() { - keyStore.set("mysecretkey"); - EncryptionKeyStoreWrapper wrapper = new EncryptionKeyStoreWrapper(keyStore); + secretKeyStore.set("mysecretkey"); + EncryptionSecretKeyStoreWrapper wrapper = new EncryptionSecretKeyStoreWrapper(secretKeyStore); assertEquals("mysecretkey", wrapper.get()); } diff --git a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/InMemoryKeyStore.java b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/InMemorySecretKeyStore.java similarity index 96% rename from scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/InMemoryKeyStore.java rename to scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/InMemorySecretKeyStore.java index 1d0069a087..4510a7a072 100644 --- a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/InMemoryKeyStore.java +++ b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/InMemorySecretKeyStore.java @@ -32,7 +32,7 @@ package sonia.scm.cli.config; -public class InMemoryKeyStore implements KeyStore { +public class InMemorySecretKeyStore implements SecretKeyStore { private String secretKey; diff --git a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ScmClientConfigFileHandlerTest.java b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ScmClientConfigFileHandlerTest.java index f7dfc36deb..9f65d34655 100644 --- a/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ScmClientConfigFileHandlerTest.java +++ b/scm-clients/scm-cli-client/src/test/java/sonia/scm/cli/config/ScmClientConfigFileHandlerTest.java @@ -54,7 +54,7 @@ public class ScmClientConfigFileHandlerTest { File configFile = temporaryFolder.newFile(); ScmClientConfigFileHandler handler = new ScmClientConfigFileHandler( - new EncryptionKeyStoreWrapper(new InMemoryKeyStore()), configFile + new EncryptionSecretKeyStoreWrapper(new InMemorySecretKeyStore()), configFile ); ScmClientConfig config = new ScmClientConfig(); @@ -90,18 +90,18 @@ public class ScmClientConfigFileHandlerTest { assertFalse(ConfigFiles.isFormatV2(configFile)); - KeyStore keyStore = new EncryptionKeyStoreWrapper(new InMemoryKeyStore()); - keyStore.set(key); + SecretKeyStore secretKeyStore = new EncryptionSecretKeyStoreWrapper(new InMemorySecretKeyStore()); + secretKeyStore.set(key); ScmClientConfigFileHandler handler = new ScmClientConfigFileHandler( - keyStore, configFile + secretKeyStore, configFile ); ScmClientConfig config = handler.read(); ClientConfigurationTests.assertSampleConfig(config); // ensure key has changed - assertNotEquals(key, keyStore.get()); + assertNotEquals(key, secretKeyStore.get()); // ensure config rewritten with v2 assertTrue(ConfigFiles.isFormatV2(configFile)); @@ -116,11 +116,11 @@ public class ScmClientConfigFileHandlerTest { Files.write(bytes, configFile); String key = "358e018a-0c3c-4339-8266-3874e597305f"; - KeyStore keyStore = new EncryptionKeyStoreWrapper(new InMemoryKeyStore()); - keyStore.set(key); + SecretKeyStore secretKeyStore = new EncryptionSecretKeyStoreWrapper(new InMemorySecretKeyStore()); + secretKeyStore.set(key); ScmClientConfigFileHandler handler = new ScmClientConfigFileHandler( - keyStore, configFile + secretKeyStore, configFile ); ScmClientConfig config = handler.read(); @@ -130,7 +130,7 @@ public class ScmClientConfigFileHandlerTest { assertEquals("trillian123", defaultConfig.getPassword()); // ensure key has changed - assertNotEquals(key, keyStore.get()); + assertNotEquals(key, secretKeyStore.get()); // ensure config rewritten with v2 assertTrue(ConfigFiles.isFormatV2(configFile)); From 418ad370e2bed25b3c6a89e5199eacdbd9594fed Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 4 May 2018 09:07:18 +0200 Subject: [PATCH 65/78] close branch issue-979 From a0b3b154c81cdf310fab618d0959910d8335e42e Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 4 May 2018 11:14:45 +0200 Subject: [PATCH 66/78] [maven-release-plugin] prepare release 1.60 --- maven/pom.xml | 4 ++-- maven/scm-maven-plugin/pom.xml | 4 ++-- maven/scm-plugin-archetype/pom.xml | 4 ++-- pom.xml | 4 ++-- scm-clients/pom.xml | 6 +++--- scm-clients/scm-cli-client/pom.xml | 6 +++--- scm-clients/scm-client-api/pom.xml | 4 ++-- scm-clients/scm-client-impl/pom.xml | 8 ++++---- scm-core/pom.xml | 4 ++-- scm-dao-xml/pom.xml | 8 ++++---- scm-plugin-backend/pom.xml | 6 +++--- scm-plugins/pom.xml | 8 ++++---- scm-plugins/scm-git-plugin/pom.xml | 6 +++--- scm-plugins/scm-hg-plugin/pom.xml | 6 +++--- scm-plugins/scm-svn-plugin/pom.xml | 6 +++--- scm-samples/pom.xml | 4 ++-- scm-samples/scm-sample-auth/pom.xml | 6 +++--- scm-samples/scm-sample-hello/pom.xml | 6 +++--- scm-server/pom.xml | 4 ++-- scm-test/pom.xml | 6 +++--- scm-webapp/pom.xml | 22 +++++++++++----------- support/pom.xml | 4 ++-- support/scm-support-btrace/pom.xml | 6 +++--- 23 files changed, 71 insertions(+), 71 deletions(-) diff --git a/maven/pom.xml b/maven/pom.xml index 9215c0c526..0796fc4477 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.60-SNAPSHOT + 1.60 sonia.scm.maven scm-maven-plugins pom - 1.60-SNAPSHOT + 1.60 scm-maven-plugins diff --git a/maven/scm-maven-plugin/pom.xml b/maven/scm-maven-plugin/pom.xml index 956a8339a4..8fc3a40f54 100644 --- a/maven/scm-maven-plugin/pom.xml +++ b/maven/scm-maven-plugin/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.60-SNAPSHOT + 1.60 sonia.scm.maven scm-maven-plugin - 1.60-SNAPSHOT + 1.60 maven-plugin scm-maven-plugin diff --git a/maven/scm-plugin-archetype/pom.xml b/maven/scm-plugin-archetype/pom.xml index 8031c1e2a6..88f00440af 100644 --- a/maven/scm-plugin-archetype/pom.xml +++ b/maven/scm-plugin-archetype/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.60-SNAPSHOT + 1.60 sonia.scm.maven scm-plugin-archetype - 1.60-SNAPSHOT + 1.60 scm-plugin-archetype diff --git a/pom.xml b/pom.xml index b27cbf84ea..8db5fede90 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ sonia.scm scm pom - 1.60-SNAPSHOT + 1.60 The easiest way to share your Git, Mercurial and Subversion repositories over http. @@ -36,7 +36,7 @@ scm:hg:http://bitbucket.org/sdorra/scm-manager scm:hg:https://bitbucket.org/sdorra/scm-manager http://bitbucket.org/sdorra/scm-manager - HEAD + 1.60 diff --git a/scm-clients/pom.xml b/scm-clients/pom.xml index dbbf9abe99..9b2108efa7 100644 --- a/scm-clients/pom.xml +++ b/scm-clients/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.60-SNAPSHOT + 1.60 sonia.scm.clients scm-clients pom - 1.60-SNAPSHOT + 1.60 scm-clients @@ -32,7 +32,7 @@ scm-core sonia.scm jar - 1.60-SNAPSHOT + 1.60 shiro-core diff --git a/scm-clients/scm-cli-client/pom.xml b/scm-clients/scm-cli-client/pom.xml index ee196d5c11..b29ea2d1d5 100644 --- a/scm-clients/scm-cli-client/pom.xml +++ b/scm-clients/scm-cli-client/pom.xml @@ -6,12 +6,12 @@ scm-clients sonia.scm.clients - 1.60-SNAPSHOT + 1.60 sonia.scm.clients scm-cli-client - 1.60-SNAPSHOT + 1.60 scm-cli-client @@ -34,7 +34,7 @@ sonia.scm.clients scm-client-impl - 1.60-SNAPSHOT + 1.60 diff --git a/scm-clients/scm-client-api/pom.xml b/scm-clients/scm-client-api/pom.xml index 498c3dac3d..efed7951f2 100644 --- a/scm-clients/scm-client-api/pom.xml +++ b/scm-clients/scm-client-api/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.60-SNAPSHOT + 1.60 sonia.scm.clients scm-client-api jar - 1.60-SNAPSHOT + 1.60 scm-client-api diff --git a/scm-clients/scm-client-impl/pom.xml b/scm-clients/scm-client-impl/pom.xml index 1150017db7..d4bb203488 100644 --- a/scm-clients/scm-client-impl/pom.xml +++ b/scm-clients/scm-client-impl/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.60-SNAPSHOT + 1.60 sonia.scm.clients scm-client-impl jar - 1.60-SNAPSHOT + 1.60 scm-client-impl @@ -36,7 +36,7 @@ sonia.scm.clients scm-client-api - 1.60-SNAPSHOT + 1.60 @@ -70,7 +70,7 @@ sonia.scm scm-test - 1.60-SNAPSHOT + 1.60 test diff --git a/scm-core/pom.xml b/scm-core/pom.xml index 411a3c1d78..cfe6c9b68d 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.60-SNAPSHOT + 1.60 sonia.scm scm-core - 1.60-SNAPSHOT + 1.60 scm-core diff --git a/scm-dao-xml/pom.xml b/scm-dao-xml/pom.xml index d42307809e..ee8089d480 100644 --- a/scm-dao-xml/pom.xml +++ b/scm-dao-xml/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.60-SNAPSHOT + 1.60 sonia.scm scm-dao-xml - 1.60-SNAPSHOT + 1.60 scm-dao-xml @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.60-SNAPSHOT + 1.60 @@ -34,7 +34,7 @@ sonia.scm scm-test - 1.60-SNAPSHOT + 1.60 test diff --git a/scm-plugin-backend/pom.xml b/scm-plugin-backend/pom.xml index 921e9756dd..d16fe4492a 100644 --- a/scm-plugin-backend/pom.xml +++ b/scm-plugin-backend/pom.xml @@ -6,13 +6,13 @@ scm sonia.scm - 1.60-SNAPSHOT + 1.60 sonia.scm scm-plugin-backend war - 1.60-SNAPSHOT + 1.60 ${project.artifactId} @@ -62,7 +62,7 @@ sonia.scm scm-core - 1.60-SNAPSHOT + 1.60 diff --git a/scm-plugins/pom.xml b/scm-plugins/pom.xml index 513dc0a6fe..12e78c8dc9 100644 --- a/scm-plugins/pom.xml +++ b/scm-plugins/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.60-SNAPSHOT + 1.60 sonia.scm.plugins scm-plugins pom - 1.60-SNAPSHOT + 1.60 scm-plugins @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.60-SNAPSHOT + 1.60 @@ -59,7 +59,7 @@ sonia.scm.maven scm-maven-plugin - 1.60-SNAPSHOT + 1.60 process-resources diff --git a/scm-plugins/scm-git-plugin/pom.xml b/scm-plugins/scm-git-plugin/pom.xml index 8b15ad31fa..51ab7b34e4 100644 --- a/scm-plugins/scm-git-plugin/pom.xml +++ b/scm-plugins/scm-git-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.60-SNAPSHOT + 1.60 sonia.scm.plugins scm-git-plugin - 1.60-SNAPSHOT + 1.60 scm-git-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Git @@ -54,7 +54,7 @@ sonia.scm scm-test - 1.60-SNAPSHOT + 1.60 test diff --git a/scm-plugins/scm-hg-plugin/pom.xml b/scm-plugins/scm-hg-plugin/pom.xml index bb339bb983..82c2355033 100644 --- a/scm-plugins/scm-hg-plugin/pom.xml +++ b/scm-plugins/scm-hg-plugin/pom.xml @@ -6,12 +6,12 @@ sonia.scm.plugins scm-plugins - 1.60-SNAPSHOT + 1.60 sonia.scm.plugins scm-hg-plugin - 1.60-SNAPSHOT + 1.60 scm-hg-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Mercurial @@ -42,7 +42,7 @@ sonia.scm scm-test - 1.60-SNAPSHOT + 1.60 test diff --git a/scm-plugins/scm-svn-plugin/pom.xml b/scm-plugins/scm-svn-plugin/pom.xml index 025193838d..e7382c5235 100644 --- a/scm-plugins/scm-svn-plugin/pom.xml +++ b/scm-plugins/scm-svn-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.60-SNAPSHOT + 1.60 sonia.scm.plugins scm-svn-plugin - 1.60-SNAPSHOT + 1.60 scm-svn-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Subversion @@ -48,7 +48,7 @@ sonia.scm scm-test - 1.60-SNAPSHOT + 1.60 test diff --git a/scm-samples/pom.xml b/scm-samples/pom.xml index 1b25fb0b18..5088dd9a29 100644 --- a/scm-samples/pom.xml +++ b/scm-samples/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.60-SNAPSHOT + 1.60 sonia.scm.samples scm-samples pom - 1.60-SNAPSHOT + 1.60 scm-samples diff --git a/scm-samples/scm-sample-auth/pom.xml b/scm-samples/scm-sample-auth/pom.xml index f443d37763..8f74ed5f3b 100644 --- a/scm-samples/scm-sample-auth/pom.xml +++ b/scm-samples/scm-sample-auth/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.60-SNAPSHOT + 1.60 sonia.scm.sample scm-sample-auth - 1.60-SNAPSHOT + 1.60 scm-sample-auth Sample Authentication Plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.60-SNAPSHOT + 1.60 diff --git a/scm-samples/scm-sample-hello/pom.xml b/scm-samples/scm-sample-hello/pom.xml index 21199294ba..3dec8f9e21 100644 --- a/scm-samples/scm-sample-hello/pom.xml +++ b/scm-samples/scm-sample-hello/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.60-SNAPSHOT + 1.60 sonia.scm.sample scm-sample-hello - 1.60-SNAPSHOT + 1.60 scm-sample-hello A simple hello world plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.60-SNAPSHOT + 1.60 diff --git a/scm-server/pom.xml b/scm-server/pom.xml index 7103b0a701..5bf22f2af0 100644 --- a/scm-server/pom.xml +++ b/scm-server/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.60-SNAPSHOT + 1.60 sonia.scm scm-server - 1.60-SNAPSHOT + 1.60 scm-server jar diff --git a/scm-test/pom.xml b/scm-test/pom.xml index 6401485329..b30ba2c534 100644 --- a/scm-test/pom.xml +++ b/scm-test/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.60-SNAPSHOT + 1.60 sonia.scm scm-test - 1.60-SNAPSHOT + 1.60 scm-test @@ -25,7 +25,7 @@ sonia.scm scm-core - 1.60-SNAPSHOT + 1.60 diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index d467061d1d..ec768b1cfc 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.60-SNAPSHOT + 1.60 sonia.scm scm-webapp war - 1.60-SNAPSHOT + 1.60 scm-webapp @@ -38,31 +38,31 @@ sonia.scm scm-core - 1.60-SNAPSHOT + 1.60 sonia.scm scm-dao-xml - 1.60-SNAPSHOT + 1.60 sonia.scm.plugins scm-hg-plugin - 1.60-SNAPSHOT + 1.60 sonia.scm.plugins scm-svn-plugin - 1.60-SNAPSHOT + 1.60 sonia.scm.plugins scm-git-plugin - 1.60-SNAPSHOT + 1.60 @@ -280,7 +280,7 @@ sonia.scm scm-test - 1.60-SNAPSHOT + 1.60 test @@ -293,7 +293,7 @@ sonia.scm.plugins scm-git-plugin - 1.60-SNAPSHOT + 1.60 tests test @@ -301,7 +301,7 @@ sonia.scm.plugins scm-hg-plugin - 1.60-SNAPSHOT + 1.60 tests test @@ -309,7 +309,7 @@ sonia.scm.plugins scm-svn-plugin - 1.60-SNAPSHOT + 1.60 tests test diff --git a/support/pom.xml b/support/pom.xml index 882727808b..084b056359 100644 --- a/support/pom.xml +++ b/support/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.60-SNAPSHOT + 1.60 sonia.scm.support scm-support pom - 1.60-SNAPSHOT + 1.60 scm-support diff --git a/support/scm-support-btrace/pom.xml b/support/scm-support-btrace/pom.xml index 9dc37271b2..cd53813efa 100644 --- a/support/scm-support-btrace/pom.xml +++ b/support/scm-support-btrace/pom.xml @@ -4,12 +4,12 @@ sonia.scm.support scm-support - 1.60-SNAPSHOT + 1.60 sonia.scm scm-support-btrace - 1.60-SNAPSHOT + 1.60 jar scm-support-btrace @@ -18,7 +18,7 @@ sonia.scm scm-core - 1.60-SNAPSHOT + 1.60 From 0ba7fab12c340e21c8708725ededb609c93f867e Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 4 May 2018 11:14:45 +0200 Subject: [PATCH 67/78] [maven-release-plugin] copy for tag 1.60 From 3f27dd8ccab7b208f727f60a1d07d9611e9dd914 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 4 May 2018 11:14:45 +0200 Subject: [PATCH 68/78] [maven-release-plugin] prepare for next development iteration --- maven/pom.xml | 4 ++-- maven/scm-maven-plugin/pom.xml | 4 ++-- maven/scm-plugin-archetype/pom.xml | 4 ++-- pom.xml | 4 ++-- scm-clients/pom.xml | 6 +++--- scm-clients/scm-cli-client/pom.xml | 6 +++--- scm-clients/scm-client-api/pom.xml | 4 ++-- scm-clients/scm-client-impl/pom.xml | 8 ++++---- scm-core/pom.xml | 4 ++-- scm-dao-xml/pom.xml | 8 ++++---- scm-plugin-backend/pom.xml | 6 +++--- scm-plugins/pom.xml | 8 ++++---- scm-plugins/scm-git-plugin/pom.xml | 6 +++--- scm-plugins/scm-hg-plugin/pom.xml | 6 +++--- scm-plugins/scm-svn-plugin/pom.xml | 6 +++--- scm-samples/pom.xml | 4 ++-- scm-samples/scm-sample-auth/pom.xml | 6 +++--- scm-samples/scm-sample-hello/pom.xml | 6 +++--- scm-server/pom.xml | 4 ++-- scm-test/pom.xml | 6 +++--- scm-webapp/pom.xml | 22 +++++++++++----------- support/pom.xml | 4 ++-- support/scm-support-btrace/pom.xml | 6 +++--- 23 files changed, 71 insertions(+), 71 deletions(-) diff --git a/maven/pom.xml b/maven/pom.xml index 0796fc4477..0135f1f40c 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.60 + 1.61-SNAPSHOT sonia.scm.maven scm-maven-plugins pom - 1.60 + 1.61-SNAPSHOT scm-maven-plugins diff --git a/maven/scm-maven-plugin/pom.xml b/maven/scm-maven-plugin/pom.xml index 8fc3a40f54..8b8bb20afe 100644 --- a/maven/scm-maven-plugin/pom.xml +++ b/maven/scm-maven-plugin/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.60 + 1.61-SNAPSHOT sonia.scm.maven scm-maven-plugin - 1.60 + 1.61-SNAPSHOT maven-plugin scm-maven-plugin diff --git a/maven/scm-plugin-archetype/pom.xml b/maven/scm-plugin-archetype/pom.xml index 88f00440af..5d86da291c 100644 --- a/maven/scm-plugin-archetype/pom.xml +++ b/maven/scm-plugin-archetype/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.60 + 1.61-SNAPSHOT sonia.scm.maven scm-plugin-archetype - 1.60 + 1.61-SNAPSHOT scm-plugin-archetype diff --git a/pom.xml b/pom.xml index 8db5fede90..840c9f1ec3 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ sonia.scm scm pom - 1.60 + 1.61-SNAPSHOT The easiest way to share your Git, Mercurial and Subversion repositories over http. @@ -36,7 +36,7 @@ scm:hg:http://bitbucket.org/sdorra/scm-manager scm:hg:https://bitbucket.org/sdorra/scm-manager http://bitbucket.org/sdorra/scm-manager - 1.60 + HEAD diff --git a/scm-clients/pom.xml b/scm-clients/pom.xml index 9b2108efa7..9a957975be 100644 --- a/scm-clients/pom.xml +++ b/scm-clients/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.60 + 1.61-SNAPSHOT sonia.scm.clients scm-clients pom - 1.60 + 1.61-SNAPSHOT scm-clients @@ -32,7 +32,7 @@ scm-core sonia.scm jar - 1.60 + 1.61-SNAPSHOT shiro-core diff --git a/scm-clients/scm-cli-client/pom.xml b/scm-clients/scm-cli-client/pom.xml index b29ea2d1d5..43b42e70ef 100644 --- a/scm-clients/scm-cli-client/pom.xml +++ b/scm-clients/scm-cli-client/pom.xml @@ -6,12 +6,12 @@ scm-clients sonia.scm.clients - 1.60 + 1.61-SNAPSHOT sonia.scm.clients scm-cli-client - 1.60 + 1.61-SNAPSHOT scm-cli-client @@ -34,7 +34,7 @@ sonia.scm.clients scm-client-impl - 1.60 + 1.61-SNAPSHOT diff --git a/scm-clients/scm-client-api/pom.xml b/scm-clients/scm-client-api/pom.xml index efed7951f2..71586cffe9 100644 --- a/scm-clients/scm-client-api/pom.xml +++ b/scm-clients/scm-client-api/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.60 + 1.61-SNAPSHOT sonia.scm.clients scm-client-api jar - 1.60 + 1.61-SNAPSHOT scm-client-api diff --git a/scm-clients/scm-client-impl/pom.xml b/scm-clients/scm-client-impl/pom.xml index d4bb203488..ba6edb9130 100644 --- a/scm-clients/scm-client-impl/pom.xml +++ b/scm-clients/scm-client-impl/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.60 + 1.61-SNAPSHOT sonia.scm.clients scm-client-impl jar - 1.60 + 1.61-SNAPSHOT scm-client-impl @@ -36,7 +36,7 @@ sonia.scm.clients scm-client-api - 1.60 + 1.61-SNAPSHOT @@ -70,7 +70,7 @@ sonia.scm scm-test - 1.60 + 1.61-SNAPSHOT test diff --git a/scm-core/pom.xml b/scm-core/pom.xml index cfe6c9b68d..ae0057dbdf 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.60 + 1.61-SNAPSHOT sonia.scm scm-core - 1.60 + 1.61-SNAPSHOT scm-core diff --git a/scm-dao-xml/pom.xml b/scm-dao-xml/pom.xml index ee8089d480..b26d86a9ad 100644 --- a/scm-dao-xml/pom.xml +++ b/scm-dao-xml/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.60 + 1.61-SNAPSHOT sonia.scm scm-dao-xml - 1.60 + 1.61-SNAPSHOT scm-dao-xml @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.60 + 1.61-SNAPSHOT @@ -34,7 +34,7 @@ sonia.scm scm-test - 1.60 + 1.61-SNAPSHOT test diff --git a/scm-plugin-backend/pom.xml b/scm-plugin-backend/pom.xml index d16fe4492a..ad29e34d1f 100644 --- a/scm-plugin-backend/pom.xml +++ b/scm-plugin-backend/pom.xml @@ -6,13 +6,13 @@ scm sonia.scm - 1.60 + 1.61-SNAPSHOT sonia.scm scm-plugin-backend war - 1.60 + 1.61-SNAPSHOT ${project.artifactId} @@ -62,7 +62,7 @@ sonia.scm scm-core - 1.60 + 1.61-SNAPSHOT diff --git a/scm-plugins/pom.xml b/scm-plugins/pom.xml index 12e78c8dc9..7d62a261b4 100644 --- a/scm-plugins/pom.xml +++ b/scm-plugins/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.60 + 1.61-SNAPSHOT sonia.scm.plugins scm-plugins pom - 1.60 + 1.61-SNAPSHOT scm-plugins @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.60 + 1.61-SNAPSHOT @@ -59,7 +59,7 @@ sonia.scm.maven scm-maven-plugin - 1.60 + 1.61-SNAPSHOT process-resources diff --git a/scm-plugins/scm-git-plugin/pom.xml b/scm-plugins/scm-git-plugin/pom.xml index 51ab7b34e4..dc02c4ab5a 100644 --- a/scm-plugins/scm-git-plugin/pom.xml +++ b/scm-plugins/scm-git-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.60 + 1.61-SNAPSHOT sonia.scm.plugins scm-git-plugin - 1.60 + 1.61-SNAPSHOT scm-git-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Git @@ -54,7 +54,7 @@ sonia.scm scm-test - 1.60 + 1.61-SNAPSHOT test diff --git a/scm-plugins/scm-hg-plugin/pom.xml b/scm-plugins/scm-hg-plugin/pom.xml index 82c2355033..b1b5f33d4a 100644 --- a/scm-plugins/scm-hg-plugin/pom.xml +++ b/scm-plugins/scm-hg-plugin/pom.xml @@ -6,12 +6,12 @@ sonia.scm.plugins scm-plugins - 1.60 + 1.61-SNAPSHOT sonia.scm.plugins scm-hg-plugin - 1.60 + 1.61-SNAPSHOT scm-hg-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Mercurial @@ -42,7 +42,7 @@ sonia.scm scm-test - 1.60 + 1.61-SNAPSHOT test diff --git a/scm-plugins/scm-svn-plugin/pom.xml b/scm-plugins/scm-svn-plugin/pom.xml index e7382c5235..e5ceb8b7ef 100644 --- a/scm-plugins/scm-svn-plugin/pom.xml +++ b/scm-plugins/scm-svn-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.60 + 1.61-SNAPSHOT sonia.scm.plugins scm-svn-plugin - 1.60 + 1.61-SNAPSHOT scm-svn-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Subversion @@ -48,7 +48,7 @@ sonia.scm scm-test - 1.60 + 1.61-SNAPSHOT test diff --git a/scm-samples/pom.xml b/scm-samples/pom.xml index 5088dd9a29..918606a1e8 100644 --- a/scm-samples/pom.xml +++ b/scm-samples/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.60 + 1.61-SNAPSHOT sonia.scm.samples scm-samples pom - 1.60 + 1.61-SNAPSHOT scm-samples diff --git a/scm-samples/scm-sample-auth/pom.xml b/scm-samples/scm-sample-auth/pom.xml index 8f74ed5f3b..1fdfe1fd0f 100644 --- a/scm-samples/scm-sample-auth/pom.xml +++ b/scm-samples/scm-sample-auth/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.60 + 1.61-SNAPSHOT sonia.scm.sample scm-sample-auth - 1.60 + 1.61-SNAPSHOT scm-sample-auth Sample Authentication Plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.60 + 1.61-SNAPSHOT diff --git a/scm-samples/scm-sample-hello/pom.xml b/scm-samples/scm-sample-hello/pom.xml index 3dec8f9e21..313cb5faad 100644 --- a/scm-samples/scm-sample-hello/pom.xml +++ b/scm-samples/scm-sample-hello/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.60 + 1.61-SNAPSHOT sonia.scm.sample scm-sample-hello - 1.60 + 1.61-SNAPSHOT scm-sample-hello A simple hello world plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.60 + 1.61-SNAPSHOT diff --git a/scm-server/pom.xml b/scm-server/pom.xml index 5bf22f2af0..562cd101fd 100644 --- a/scm-server/pom.xml +++ b/scm-server/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.60 + 1.61-SNAPSHOT sonia.scm scm-server - 1.60 + 1.61-SNAPSHOT scm-server jar diff --git a/scm-test/pom.xml b/scm-test/pom.xml index b30ba2c534..0e89e416cb 100644 --- a/scm-test/pom.xml +++ b/scm-test/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.60 + 1.61-SNAPSHOT sonia.scm scm-test - 1.60 + 1.61-SNAPSHOT scm-test @@ -25,7 +25,7 @@ sonia.scm scm-core - 1.60 + 1.61-SNAPSHOT diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index ec768b1cfc..3803b24e00 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.60 + 1.61-SNAPSHOT sonia.scm scm-webapp war - 1.60 + 1.61-SNAPSHOT scm-webapp @@ -38,31 +38,31 @@ sonia.scm scm-core - 1.60 + 1.61-SNAPSHOT sonia.scm scm-dao-xml - 1.60 + 1.61-SNAPSHOT sonia.scm.plugins scm-hg-plugin - 1.60 + 1.61-SNAPSHOT sonia.scm.plugins scm-svn-plugin - 1.60 + 1.61-SNAPSHOT sonia.scm.plugins scm-git-plugin - 1.60 + 1.61-SNAPSHOT @@ -280,7 +280,7 @@ sonia.scm scm-test - 1.60 + 1.61-SNAPSHOT test @@ -293,7 +293,7 @@ sonia.scm.plugins scm-git-plugin - 1.60 + 1.61-SNAPSHOT tests test @@ -301,7 +301,7 @@ sonia.scm.plugins scm-hg-plugin - 1.60 + 1.61-SNAPSHOT tests test @@ -309,7 +309,7 @@ sonia.scm.plugins scm-svn-plugin - 1.60 + 1.61-SNAPSHOT tests test diff --git a/support/pom.xml b/support/pom.xml index 084b056359..88be822886 100644 --- a/support/pom.xml +++ b/support/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.60 + 1.61-SNAPSHOT sonia.scm.support scm-support pom - 1.60 + 1.61-SNAPSHOT scm-support diff --git a/support/scm-support-btrace/pom.xml b/support/scm-support-btrace/pom.xml index cd53813efa..4e113fbfd7 100644 --- a/support/scm-support-btrace/pom.xml +++ b/support/scm-support-btrace/pom.xml @@ -4,12 +4,12 @@ sonia.scm.support scm-support - 1.60 + 1.61-SNAPSHOT sonia.scm scm-support-btrace - 1.60 + 1.61-SNAPSHOT jar scm-support-btrace @@ -18,7 +18,7 @@ sonia.scm scm-core - 1.60 + 1.61-SNAPSHOT From e826b833cc93365249831ec51ff12bdfeeb4376d Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Tue, 27 Jun 2017 20:16:05 +0200 Subject: [PATCH 69/78] switch from jersey 1.x to resteasy --- pom.xml | 355 +++++++------- scm-clients/scm-client-impl/pom.xml | 4 +- scm-core/pom.xml | 6 +- .../scm/security/DefaultCipherHandler.java | 7 +- .../java/sonia/scm/template/Viewable.java | 110 ++--- .../main/java/sonia/scm/web/HgCGIServlet.java | 34 +- scm-webapp/pom.xml | 434 ++++++++---------- .../main/java/sonia/scm/ScmServletModule.java | 209 ++------- .../scm/api/rest/TemplateEngineViewable.java | 64 +-- .../resources/AbstractPermissionResource.java | 8 +- .../resources/ChangePasswordResource.java | 2 +- .../rest/resources/ConfigurationResource.java | 4 +- .../scm/api/rest/resources/GroupResource.java | 8 +- .../api/rest/resources/PluginResource.java | 16 +- .../resources/RepositoryImportResource.java | 27 +- .../rest/resources/RepositoryResource.java | 22 +- .../resources/RepositoryRootResource.java | 21 +- .../api/rest/resources/SearchResource.java | 4 +- .../scm/api/rest/resources/UserResource.java | 8 +- .../java/sonia/scm/debug/DebugResource.java | 4 +- .../scm/net/ahc/JsonContentTransformer.java | 20 +- .../src/main/resources/logback.default.xml | 2 + scm-webapp/src/main/webapp/WEB-INF/web.xml | 38 +- .../sonia.action.changepasswordwindow.js | 2 +- .../js/config/sonia.config.scmconfigpanel.js | 4 +- .../js/group/sonia.group.formpanel.js | 4 +- .../resources/js/group/sonia.group.panel.js | 2 +- .../resources/js/login/sonia.login.form.js | 15 +- .../js/plugin/sonia.plugin.center.js | 6 +- .../resources/js/plugin/sonia.plugin.grid.js | 2 +- .../sonia.repository.branchcombobox.js | 2 +- .../sonia.repository.changesetviewerpanel.js | 2 +- .../sonia.repository.commitpanel.js | 2 +- .../repository/sonia.repository.formpanel.js | 4 +- .../js/repository/sonia.repository.grid.js | 2 +- .../sonia.repository.healthcheckfailure.js | 2 +- .../sonia.repository.importwindow.js | 4 +- .../js/repository/sonia.repository.js | 2 +- .../js/repository/sonia.repository.panel.js | 4 +- .../sonia.repository.repositorybrowser.js | 2 +- .../sonia.repository.tagcombobox.js | 2 +- .../sonia.security.permissionspanel.js | 8 +- .../main/webapp/resources/js/sonia.global.js | 4 +- .../src/main/webapp/resources/js/sonia.scm.js | 2 +- .../resources/js/user/sonia.user.formpanel.js | 4 +- .../resources/js/user/sonia.user.grid.js | 2 +- .../resources/js/user/sonia.user.panel.js | 2 +- .../test/java/sonia/scm/it/GitLfsITCase.java | 7 +- 48 files changed, 622 insertions(+), 877 deletions(-) rename scm-webapp/src/main/java/sonia/scm/api/rest/UriExtensionsConfig.java => scm-core/src/main/java/sonia/scm/template/Viewable.java (52%) diff --git a/pom.xml b/pom.xml index 840c9f1ec3..3674300b1d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ sonia.scm scm pom - 1.61-SNAPSHOT + 2.0.0-SNAPSHOT The easiest way to share your Git, Mercurial and Subversion repositories over http. @@ -59,18 +59,20 @@ https://scm-manager.ci.cloudbees.com/ + + 3.1.0 + + + scm-annotations + scm-annotation-processor scm-core scm-test - maven scm-plugins - scm-samples scm-dao-xml scm-webapp scm-server - scm-plugin-backend scm-clients - support @@ -80,6 +82,15 @@ scm-manager release repository http://maven.scm-manager.org/nexus/content/groups/public + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + true + daily + + @@ -128,20 +139,52 @@ ${mokito.version} test - + + + + org.apache.maven.plugins + maven-enforcer-plugin + 1.4.1 + + + enforce-java + compile + + enforce + + + + + + [1.8.0-101,) + + + + [3.1,) + + + true + + + + org.codehaus.mojo animal-sniffer-maven-plugin - 1.16 + 1.15 org.codehaus.mojo.signature - java17 + java18 1.0 @@ -155,51 +198,23 @@ - - org.apache.maven.plugins - maven-enforcer-plugin - 3.0.0-M1 - - - enforce-java - compile - - enforce - - - - - 1.7 - - - module-info - - - - true - - - - - - org.codehaus.mojo - extra-enforcer-rules - 1.0-beta-7 - - - - org.apache.maven.plugins maven-compiler-plugin - 3.0 + 3.5.1 + true + true ${project.build.javaLevel} ${project.build.javaLevel} + ${project.test.javaLevel} + ${project.test.javaLevel} ${project.build.sourceEncoding} + + -Xlint:unchecked,-options @@ -244,7 +259,7 @@ true true - http://download.oracle.com/javase/7/docs/api/ + http://download.oracle.com/javase/8/docs/api/ http://download.oracle.com/docs/cd/E17802_01/products/products/servlet/2.5/docs/servlet-2_5-mr2/ http://jersey.java.net/nonav/apidocs/${jersey.version}/jersey/ https://google.github.io/guice/api-docs/${guice.version}/javadoc @@ -301,59 +316,81 @@ maven-eclipse-plugin 2.6 - + + + + + org.jacoco + jacoco-maven-plugin + 0.7.7.201606060606 + + + + prepare-agent + + + + report + prepare-package + + report + + + + + org.apache.maven.plugins maven-site-plugin - 3.7 + 3.2 + + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 2.4 + + + + org.apache.maven.plugins + maven-jxr-plugin + 2.3 + + + + org.codehaus.mojo + findbugs-maven-plugin + 2.4.0 + + + + org.apache.maven.plugins + maven-surefire-report-plugin + 2.12 + + + + org.apache.maven.plugins + maven-pmd-plugin + 2.7.1 + + true + ${project.build.sourceEncoding} + ${project.build.javaLevel} + + + + + - - - - - org.apache.maven.plugins - maven-project-info-reports-plugin - 2.4 - - - - org.apache.maven.plugins - maven-jxr-plugin - 2.3 - - - - org.codehaus.mojo - findbugs-maven-plugin - 2.4.0 - - - - org.apache.maven.plugins - maven-surefire-report-plugin - 2.12 - - - - org.apache.maven.plugins - maven-pmd-plugin - 2.7.1 - - ${project.build.sourceEncoding} - ${project.build.javaLevel} - - - - - - @@ -397,9 +434,18 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.0.0 + 2.8.1 - false + org.jboss.apiviz.APIviz + + org.jboss.apiviz + apiviz + 1.3.2.GA + + + -sourceclasspath ${project.build.outputDirectory} + -nopackagediagram + @@ -410,101 +456,6 @@ - - - - - - - commons-beanutils - commons-beanutils - 1.9.3 - - - - commons-collections - commons-collections - 3.2.2 - - - - - - org.apache.httpcomponents - httpclient - 4.5.5 - - - - - - slf4j-api - org.slf4j - ${slf4j.version} - - - - ch.qos.logback - logback-classic - ${logback.version} - - - - - - - org.codehaus.jackson - jackson-core-asl - ${jackson.version} - - - - org.codehaus.jackson - jackson-mapper-asl - ${jackson.version} - - - - org.codehaus.jackson - jackson-jaxrs - ${jackson.version} - - - - org.codehaus.jackson - jackson-xc - ${jackson.version} - - - - - - javax.xml.bind - jaxb-api - ${jaxb.version} - - - - com.sun.xml.bind - jaxb-impl - ${jaxb.version} - - - - org.glassfish.jaxb - jaxb-runtime - ${jaxb.version} - - - - javax.activation - activation - 1.1.1 - - - - - @@ -528,31 +479,37 @@ 4.12 - 1.7.25 + 1.7.22 1.2.3 - 2.5 - 3.0 + 3.0.1 + 2.0.1 + 4.0 1.19.4 + + + 1.2.0 + 2.6.6 2.3.20 - 7.6.21.v20160908 - 7.6.16.v20140903 - 1.9.13 - 2.3.0 + + + 9.2.10.v20150310 + 9.2.10.v20150310 - 1.3.2 + 1.0.0-SNAPSHOT + 1.4.0-RC2 - - v4.5.3.201708160445-r-scm1 - 1.9.0-scm3 + + v4.5.2.201704071617-r-scm1 + 1.8.15-scm1 - 15.0 + 16.0.1 2.2.3 - 1.7 + 1.8 UTF-8 SCM-BSD diff --git a/scm-clients/scm-client-impl/pom.xml b/scm-clients/scm-client-impl/pom.xml index ba6edb9130..1e6847349f 100644 --- a/scm-clients/scm-client-impl/pom.xml +++ b/scm-clients/scm-client-impl/pom.xml @@ -42,13 +42,13 @@ com.sun.jersey jersey-client - ${jersey.version} + ${jersey-client.version} com.sun.jersey.contribs jersey-multipart - ${jersey.version} + ${jersey-client.version} diff --git a/scm-core/pom.xml b/scm-core/pom.xml index ae0057dbdf..fde7dceb47 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -69,9 +69,9 @@ - com.sun.jersey - jersey-core - ${jersey.version} + javax.ws.rs + javax.ws.rs-api + ${jaxrs.version} 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 ddb8a699a7..b4f0d81cd3 100644 --- a/scm-core/src/main/java/sonia/scm/security/DefaultCipherHandler.java +++ b/scm-core/src/main/java/sonia/scm/security/DefaultCipherHandler.java @@ -45,8 +45,6 @@ import sonia.scm.util.IOUtil; //~--- JDK imports ------------------------------------------------------------ -import com.sun.jersey.core.util.Base64; - import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; @@ -60,6 +58,7 @@ import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Arrays; +import java.util.Base64; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; @@ -165,7 +164,7 @@ public class DefaultCipherHandler implements CipherHandler { String result = null; try { - byte[] encodedInput = Base64.decode(value); + byte[] encodedInput = Base64.getDecoder().decode(value); byte[] salt = new byte[SALT_LENGTH]; byte[] encoded = new byte[encodedInput.length - SALT_LENGTH]; @@ -222,7 +221,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); - res = new String(Base64.encode(result), ENCODING); + res = new String(Base64.getEncoder().encode(result), ENCODING); } catch (IOException | GeneralSecurityException ex) { throw new CipherException("could not encode string", ex); } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/UriExtensionsConfig.java b/scm-core/src/main/java/sonia/scm/template/Viewable.java similarity index 52% rename from scm-webapp/src/main/java/sonia/scm/api/rest/UriExtensionsConfig.java rename to scm-core/src/main/java/sonia/scm/template/Viewable.java index 637866ad61..8344d2820e 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/UriExtensionsConfig.java +++ b/scm-core/src/main/java/sonia/scm/template/Viewable.java @@ -28,89 +28,63 @@ * http://bitbucket.org/sdorra/scm-manager * */ +package sonia.scm.template; +import com.google.common.base.Objects; -package sonia.scm.api.rest; - -//~--- JDK imports ------------------------------------------------------------ - -import com.sun.jersey.api.core.PackagesResourceConfig; - -import java.util.HashMap; -import java.util.Map; - -import javax.ws.rs.core.MediaType; - /** - * + * A viewable holds the path to a template and the context object which is used to render the template. Viewables can + * be used as return type of jax-rs resources. + * * @author Sebastian Sdorra + * @since 2.0.0 */ -public class UriExtensionsConfig extends PackagesResourceConfig -{ +public final class Viewable { + + private final String path; + private final Object context; - /** Field description */ - public static final String EXTENSION_JSON = "json"; - - /** Field description */ - public static final String EXTENSION_XML = "xml"; - - //~--- constructors --------------------------------------------------------- - - /** - * Constructs ... - * - */ - public UriExtensionsConfig() - { - super(); + public Viewable(String path, Object context) { + this.path = path; + this.context = context; } - /** - * Constructs ... - * - * - * @param props - */ - public UriExtensionsConfig(Map props) - { - super(props); + public String getPath() { + return path; } - /** - * Constructs ... - * - * - * @param paths - */ - public UriExtensionsConfig(String[] paths) - { - super(paths); + public Object getContext() { + return context; } - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @return - */ @Override - public Map getMediaTypeMappings() - { - if (mediaTypeMap == null) - { - mediaTypeMap = new HashMap(); - mediaTypeMap.put(EXTENSION_JSON, MediaType.APPLICATION_JSON_TYPE); - mediaTypeMap.put(EXTENSION_XML, MediaType.APPLICATION_XML_TYPE); - } - - return mediaTypeMap; + public int hashCode() { + return Objects.hashCode(path, context); } - //~--- fields --------------------------------------------------------------- + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Viewable other = (Viewable) obj; + return !Objects.equal(this.path, other.path) + && Objects.equal(this.context, other.context); + } - /** Field description */ - private Map mediaTypeMap; + @Override + public String toString() { + return Objects.toStringHelper(this) + .add("path", path) + .add("context", context) + .toString(); + } + } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java index 1fb78161e0..0befcf6f11 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java @@ -36,6 +36,7 @@ package sonia.scm.web; //~--- non-JDK imports -------------------------------------------------------- import com.google.common.base.Stopwatch; +import com.google.common.base.Strings; import com.google.inject.Inject; import com.google.inject.Singleton; @@ -52,18 +53,21 @@ import sonia.scm.repository.HgRepositoryHandler; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryProvider; import sonia.scm.repository.RepositoryRequestListenerUtil; +import sonia.scm.security.CipherUtil; import sonia.scm.util.AssertUtil; +import sonia.scm.util.HttpUtil; import sonia.scm.web.cgi.CGIExecutor; import sonia.scm.web.cgi.CGIExecutorFactory; import sonia.scm.web.cgi.EnvList; //~--- JDK imports ------------------------------------------------------------ +import com.sun.jersey.core.util.Base64; + import java.io.File; import java.io.IOException; import java.util.Enumeration; -import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -79,19 +83,18 @@ import javax.servlet.http.HttpSession; public class HgCGIServlet extends HttpServlet { - private static final String ENV_PYTHON_HTTPS_VERIFY = "PYTHONHTTPSVERIFY"; - /** Field description */ public static final String ENV_REPOSITORY_NAME = "REPO_NAME"; /** Field description */ public static final String ENV_REPOSITORY_PATH = "SCM_REPOSITORY_PATH"; - private static final String ENV_HTTP_POST_ARGS = "SCM_HTTP_POST_ARGS"; - /** Field description */ public static final String ENV_SESSION_PREFIX = "SCM_"; + /** Field description */ + private static final String SCM_CREDENTIALS = "SCM_CREDENTIALS"; + /** Field description */ private static final long serialVersionUID = -3492811300905099810L; @@ -228,6 +231,7 @@ public class HgCGIServlet extends HttpServlet * @param env * @param session */ + @SuppressWarnings("unchecked") private void passSessionAttributes(EnvList env, HttpSession session) { Enumeration enm = session.getAttributeNames(); @@ -273,27 +277,19 @@ public class HgCGIServlet extends HttpServlet directory.getAbsolutePath()); // add hook environment - Map environment = executor.getEnvironment().asMutableMap(); - if (handler.getConfig().isDisableHookSSLValidation()) { - // disable ssl validation - // Issue 959: https://goo.gl/zH5eY8 - environment.put(ENV_PYTHON_HTTPS_VERIFY, "0"); - } - - // enable experimental httppostargs protocol of mercurial - // Issue 970: https://goo.gl/poascp - environment.put(ENV_HTTP_POST_ARGS, String.valueOf(handler.getConfig().isEnableHttpPostArgs())); - //J- HgEnvironment.prepareEnvironment( - environment, + executor.getEnvironment().asMutableMap(), handler, - hookManager, + hookManager, request ); //J+ - HttpSession session = request.getSession(); + addCredentials(executor.getEnvironment(), request); + + // unused ??? + HttpSession session = request.getSession(false); if (session != null) { diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 3803b24e00..b22ceccb90 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -6,63 +6,54 @@ sonia.scm scm - 1.61-SNAPSHOT + 2.0.0-SNAPSHOT sonia.scm scm-webapp war - 1.61-SNAPSHOT + 2.0.0-SNAPSHOT scm-webapp + + + + sonia.scm + scm-annotation-processor + 2.0.0-SNAPSHOT + provided + + javax.servlet - servlet-api + javax.servlet-api ${servlet.version} provided - - + + javax.transaction jta 1.1 provided - + - + sonia.scm scm-core - 1.61-SNAPSHOT + 2.0.0-SNAPSHOT - + sonia.scm scm-dao-xml - 1.61-SNAPSHOT - - - - sonia.scm.plugins - scm-hg-plugin - 1.61-SNAPSHOT - - - - sonia.scm.plugins - scm-svn-plugin - 1.61-SNAPSHOT - - - - sonia.scm.plugins - scm-git-plugin - 1.61-SNAPSHOT + 2.0.0-SNAPSHOT @@ -72,12 +63,18 @@ shiro-web ${shiro.version} - + org.apache.shiro shiro-guice ${shiro.version} + + + io.jsonwebtoken + jjwt + 0.4 + @@ -116,13 +113,13 @@ provided - + com.sun.jersey.contribs jersey-multipart ${jersey.version} - + @@ -130,73 +127,66 @@ guice-multibindings ${guice.version} - + + + + + com.github.legman.support + shiro + ${legman.version} + + ch.qos.logback logback-classic + ${logback.version} - + org.slf4j jcl-over-slf4j ${slf4j.version} - + org.slf4j log4j-over-slf4j ${slf4j.version} - - - - - net.sf.ehcache - ehcache-core - ${ehcache.version} - - - - - - xml-apis - xml-apis - 1.4.01 - - + - + commons-beanutils commons-beanutils + 1.9.2 - + commons-collections commons-collections + 3.2.1 - - - + commons-codec commons-codec 1.9 - + com.google.guava guava ${guava.version} - + org.quartz-scheduler quartz @@ -208,67 +198,25 @@ - - - + + + - org.freemarker - freemarker - ${freemarker.version} + org.apache.httpcomponents + httpclient + 4.2.6 - + + + com.github.spullara.mustache.java compiler ${mustache.version} - - - - - org.eclipse.aether - aether-api - ${aether.version} - - - - org.eclipse.aether - aether-impl - ${aether.version} - - - - org.apache.maven - maven-aether-provider - ${maven.version} - - - plexus-component-annotations - org.codehaus.plexus - - - - - - org.eclipse.aether - aether-transport-http - ${aether.version} - - - - org.eclipse.aether - aether-transport-file - ${aether.version} - - - - org.eclipse.aether - aether-connector-basic - ${aether.version} - - + - + com.webcohesion.enunciate enunciate-core-annotations @@ -280,7 +228,7 @@ sonia.scm scm-test - 1.61-SNAPSHOT + 2.0.0-SNAPSHOT test @@ -289,31 +237,7 @@ - - - sonia.scm.plugins - scm-git-plugin - 1.61-SNAPSHOT - tests - test - - - - sonia.scm.plugins - scm-hg-plugin - 1.61-SNAPSHOT - tests - test - - - - sonia.scm.plugins - scm-svn-plugin - 1.61-SNAPSHOT - tests - test - - + org.seleniumhq.selenium selenium-java @@ -327,7 +251,7 @@ ${selenium.version} test - + org.seleniumhq.selenium htmlunit-driver @@ -348,23 +272,71 @@ ${jersey.version} test - + + + + com.github.sdorra shiro-unit 1.0.0 test - + + + sonia.scm.plugins + scm-git-plugin + 2.0.0-SNAPSHOT + tests + test + + + + sonia.scm.plugins + scm-git-plugin + 2.0.0-SNAPSHOT + test + + + + sonia.scm.plugins + scm-hg-plugin + 2.0.0-SNAPSHOT + tests + test + + + + sonia.scm.plugins + scm-hg-plugin + 2.0.0-SNAPSHOT + test + + + + sonia.scm.plugins + scm-svn-plugin + 2.0.0-SNAPSHOT + tests + test + + + + sonia.scm.plugins + scm-svn-plugin + 2.0.0-SNAPSHOT + test + + - + commons-logging commons-logging 1.1.3 provided - + log4j log4j @@ -375,9 +347,8 @@ - - + com.mycila.maven-license-plugin maven-license-plugin @@ -400,7 +371,6 @@ - org.apache.maven.plugins maven-dependency-plugin @@ -418,39 +388,49 @@ - + - org.apache.maven.plugins - maven-antrun-plugin - 1.6 + sonia.scm.maven + smp-maven-plugin + 1.0.0-alpha-2 + + + + sonia.scm.plugins + scm-hg-plugin + ${project.version} + smp + + + sonia.scm.plugins + scm-svn-plugin + ${project.version} + smp + + + sonia.scm.plugins + scm-git-plugin + ${project.version} + smp + + + sonia.scm.plugins + scm-legacy-plugin + ${project.version} + smp + + + - repack compile - run + copy-core-plugins - - - - - - - - - - - - - - - - + org.apache.maven.plugins maven-war-plugin @@ -464,7 +444,7 @@ - + sonia.maven change-env @@ -484,7 +464,7 @@ - org.mortbay.jetty + org.eclipse.jetty jetty-maven-plugin ${jetty.maven.version} @@ -504,23 +484,14 @@ true - - - 8081 - 60000 - 16384 - - /scm - ${project.build.javaLevel} - ${project.build.javaLevel} - ${project.build.sourceEncoding} + ${project.basedir}/src/main/conf/jetty.xml 0 - - + + scm-webapp @@ -532,9 +503,7 @@ default 2.53.1 2.9.1 - 1.1.0 1.0 - 3.3.9 0.8.17 Tomcat e1 @@ -544,21 +513,7 @@ - - - cluster - - - - - sonia.scm - scm-dao-orientdb - 1.58-SNAPSHOT - - - - - + release @@ -639,7 +594,7 @@ - org.mortbay.jetty + org.eclipse.jetty jetty-maven-plugin ${jetty.maven.version} @@ -655,16 +610,7 @@ ${scm.stage} - - - 8081 - 60000 - 16384 - - - ${project.build.javaLevel} - ${project.build.javaLevel} - ${project.build.sourceEncoding} + ${project.basedir}/src/main/conf/jetty.xml 0 true @@ -685,29 +631,29 @@ - + - + selenium - + - + org.apache.httpcomponents httpclient 4.3.2 test - + - + - + org.apache.maven.plugins maven-failsafe-plugin @@ -732,12 +678,15 @@ - + - org.mortbay.jetty + org.eclipse.jetty jetty-maven-plugin ${jetty.maven.version} + + 8082 + 8086 STOP @@ -746,16 +695,7 @@ target/scm-it - - - 8082 - 60000 - 16384 - - - ${project.build.javaLevel} - ${project.build.javaLevel} - ${project.build.sourceEncoding} + ${project.basedir}/src/main/conf/jetty.xml 0 true @@ -776,7 +716,7 @@ - + org.codehaus.mojo selenium-maven-plugin @@ -797,22 +737,22 @@ post-integration-test stop-server - + - + - + - + doc - + - + org.apache.maven.plugins maven-resources-plugin @@ -826,7 +766,7 @@ ${project.build.directory} - + src/main/doc true @@ -834,12 +774,12 @@ **/enunciate.xml - - + + - + com.webcohesion.enunciate enunciate-maven-plugin @@ -871,7 +811,7 @@ - + org.apache.maven.plugins maven-assembly-plugin @@ -890,12 +830,12 @@ - + - + diff --git a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java index 1b8e0c7803..12c30fd152 100644 --- a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java +++ b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java @@ -35,15 +35,13 @@ package sonia.scm; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.collect.Maps; import com.google.inject.Provider; import com.google.inject.multibindings.Multibinder; import com.google.inject.name.Names; import com.google.inject.servlet.RequestScoped; -import com.google.inject.servlet.ServletModule; import com.google.inject.throwingproviders.ThrowingProviderBinder; -import org.apache.shiro.authz.permission.PermissionResolver; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,11 +50,6 @@ import sonia.scm.cache.CacheManager; import sonia.scm.cache.GuavaCacheManager; import sonia.scm.config.ScmConfiguration; import sonia.scm.event.ScmEventBus; -import sonia.scm.filter.AdminSecurityFilter; -import sonia.scm.filter.BaseUrlFilter; -import sonia.scm.filter.GZipFilter; -import sonia.scm.filter.MDCFilter; -import sonia.scm.filter.SecurityFilter; import sonia.scm.group.DefaultGroupManager; import sonia.scm.group.GroupDAO; import sonia.scm.group.GroupManager; @@ -64,20 +57,14 @@ import sonia.scm.group.GroupManagerProvider; import sonia.scm.group.xml.XmlGroupDAO; import sonia.scm.io.DefaultFileSystem; import sonia.scm.io.FileSystem; -import sonia.scm.net.HttpClient; -import sonia.scm.net.URLHttpClient; import sonia.scm.plugin.DefaultPluginLoader; import sonia.scm.plugin.DefaultPluginManager; -import sonia.scm.plugin.Plugin; import sonia.scm.plugin.PluginLoader; import sonia.scm.plugin.PluginManager; -import sonia.scm.repository.ChangesetViewerUtil; 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.RepositoryBrowserUtil; import sonia.scm.repository.RepositoryDAO; import sonia.scm.repository.RepositoryManager; import sonia.scm.repository.RepositoryManagerProvider; @@ -92,15 +79,9 @@ import sonia.scm.resources.ResourceManager; import sonia.scm.resources.ScriptResourceServlet; import sonia.scm.security.CipherHandler; import sonia.scm.security.CipherUtil; -import sonia.scm.security.ConfigurableLoginAttemptHandler; import sonia.scm.security.DefaultKeyGenerator; import sonia.scm.security.DefaultSecuritySystem; -import sonia.scm.security.EncryptionHandler; import sonia.scm.security.KeyGenerator; -import sonia.scm.security.LoginAttemptHandler; -import sonia.scm.security.MessageDigestEncryptionHandler; -import sonia.scm.security.RepositoryPermissionResolver; -import sonia.scm.security.SecurityContext; import sonia.scm.security.SecuritySystem; import sonia.scm.store.BlobStoreFactory; import sonia.scm.store.ConfigurationEntryStoreFactory; @@ -108,16 +89,10 @@ import sonia.scm.store.DataStoreFactory; import sonia.scm.store.FileBlobStoreFactory; import sonia.scm.store.JAXBConfigurationEntryStoreFactory; import sonia.scm.store.JAXBDataStoreFactory; -import sonia.scm.store.JAXBStoreFactory; -import sonia.scm.store.ListenableStoreFactory; -import sonia.scm.store.StoreFactory; -import sonia.scm.template.DefaultEngine; -import sonia.scm.template.FreemarkerTemplateEngine; -import sonia.scm.template.FreemarkerTemplateHandler; +import sonia.scm.store.JAXBConfigurationStoreFactory; import sonia.scm.template.MustacheTemplateEngine; import sonia.scm.template.TemplateEngine; import sonia.scm.template.TemplateEngineFactory; -import sonia.scm.template.TemplateHandler; import sonia.scm.template.TemplateServlet; import sonia.scm.url.RestJsonUrlProvider; import sonia.scm.url.RestXmlUrlProvider; @@ -133,21 +108,16 @@ import sonia.scm.util.DebugServlet; import sonia.scm.util.ScmConfigurationUtil; import sonia.scm.web.cgi.CGIExecutorFactory; import sonia.scm.web.cgi.DefaultCGIExecutorFactory; -import sonia.scm.web.filter.AutoLoginFilter; import sonia.scm.web.filter.LoggingFilter; import sonia.scm.web.security.AdministrationContext; -import sonia.scm.web.security.ApiBasicAuthenticationFilter; -import sonia.scm.web.security.AuthenticationManager; -import sonia.scm.web.security.BasicSecurityContext; -import sonia.scm.web.security.ChainAuthenticatonManager; import sonia.scm.web.security.DefaultAdministrationContext; -import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ import com.sun.jersey.api.core.PackagesResourceConfig; import com.sun.jersey.api.core.ResourceConfig; import com.sun.jersey.api.json.JSONConfiguration; +import com.sun.jersey.guice.JerseyServletModule; import com.sun.jersey.guice.spi.container.servlet.GuiceContainer; import com.sun.jersey.spi.container.servlet.ServletContainer; @@ -157,6 +127,10 @@ import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; + +import javax.servlet.ServletContext; +import sonia.scm.store.ConfigurationStoreFactory; + import javax.net.ssl.SSLContext; import sonia.scm.net.SSLContextProvider; import sonia.scm.net.ahc.AdvancedHttpClient; @@ -166,15 +140,16 @@ import sonia.scm.net.ahc.JsonContentTransformer; import sonia.scm.net.ahc.XmlContentTransformer; import sonia.scm.schedule.QuartzScheduler; import sonia.scm.schedule.Scheduler; +import sonia.scm.security.ConfigurableLoginAttemptHandler; +import sonia.scm.security.LoginAttemptHandler; import sonia.scm.security.AuthorizationChangedEventProducer; -import sonia.scm.security.XsrfProtectionFilter; import sonia.scm.web.UserAgentParser; /** * * @author Sebastian Sdorra */ -public class ScmServletModule extends ServletModule +public class ScmServletModule extends JerseyServletModule { /** Field description */ @@ -239,11 +214,15 @@ public class ScmServletModule extends ServletModule * Constructs ... * * + * + * @param servletContext * @param pluginLoader * @param overrides */ - ScmServletModule(DefaultPluginLoader pluginLoader, ClassOverrides overrides) + ScmServletModule(ServletContext servletContext, + DefaultPluginLoader pluginLoader, ClassOverrides overrides) { + this.servletContext = servletContext; this.pluginLoader = pluginLoader; this.overrides = overrides; } @@ -263,22 +242,24 @@ public class ScmServletModule extends ServletModule bind(SCMContextProvider.class).toInstance(context); - ScmConfiguration config = getScmConfiguration(context); + ScmConfiguration config = getScmConfiguration(); CipherUtil cu = CipherUtil.getInstance(); - + // bind repository provider ThrowingProviderBinder.create(binder()).bind( RepositoryProvider.class, Repository.class).to( DefaultRepositoryProvider.class).in(RequestScoped.class); + // bind servlet context + bind(ServletContext.class).annotatedWith(Default.class).toInstance( + servletContext); + // bind event api bind(ScmEventBus.class).toInstance(ScmEventBus.getInstance()); // bind core - bind(StoreFactory.class, JAXBStoreFactory.class); - bind(ListenableStoreFactory.class, JAXBStoreFactory.class); - bind(ConfigurationEntryStoreFactory.class, - JAXBConfigurationEntryStoreFactory.class); + bind(ConfigurationStoreFactory.class, JAXBConfigurationStoreFactory.class); + bind(ConfigurationEntryStoreFactory.class, JAXBConfigurationEntryStoreFactory.class); bind(DataStoreFactory.class, JAXBDataStoreFactory.class); bind(BlobStoreFactory.class, FileBlobStoreFactory.class); bind(ScmConfiguration.class).toInstance(config); @@ -291,24 +272,20 @@ public class ScmServletModule extends ServletModule // note CipherUtil uses an other generator bind(KeyGenerator.class).to(DefaultKeyGenerator.class); bind(CipherHandler.class).toInstance(cu.getCipherHandler()); - bind(EncryptionHandler.class, MessageDigestEncryptionHandler.class); bind(FileSystem.class, DefaultFileSystem.class); // bind health check stuff bind(HealthCheckContextListener.class); // bind extensions - pluginLoader.processExtensions(binder()); + pluginLoader.getExtensionProcessor().processAutoBindExtensions(binder()); // bind security stuff + bind(LoginAttemptHandler.class).to(ConfigurableLoginAttemptHandler.class); bind(AuthorizationChangedEventProducer.class); - bind(PermissionResolver.class, RepositoryPermissionResolver.class); - bind(AuthenticationManager.class, ChainAuthenticatonManager.class); - bind(SecurityContext.class).to(BasicSecurityContext.class); - bind(WebSecurityContext.class).to(BasicSecurityContext.class); + bind(SecuritySystem.class).to(DefaultSecuritySystem.class); bind(AdministrationContext.class, DefaultAdministrationContext.class); - bind(LoginAttemptHandler.class, ConfigurableLoginAttemptHandler.class); // bind cache bind(CacheManager.class, GuavaCacheManager.class); @@ -326,14 +303,10 @@ public class ScmServletModule extends ServletModule bindDecorated(GroupManager.class, DefaultGroupManager.class, GroupManagerProvider.class); bind(CGIExecutorFactory.class, DefaultCGIExecutorFactory.class); - bind(ChangesetViewerUtil.class); - bind(RepositoryBrowserUtil.class); // bind sslcontext provider bind(SSLContext.class).toProvider(SSLContextProvider.class); - // bind httpclient - bind(HttpClient.class, URLHttpClient.class); // bind ahc Multibinder transformers = @@ -378,24 +351,7 @@ public class ScmServletModule extends ServletModule { filter(PATTERN_ALL).through(LoggingFilter.class); } - - // protect api agains xsrf attacks - filter(PATTERN_RESTAPI).through(XsrfProtectionFilter.class); - /* - * filter(PATTERN_PAGE, - * PATTERN_STATIC_RESOURCES).through(StaticResourceFilter.class); - */ - filter(PATTERN_ALL).through(BaseUrlFilter.class); - filter(PATTERN_ALL).through(AutoLoginFilter.class); - filterRegex(RESOURCE_REGEX).through(GZipFilter.class); - filter(PATTERN_RESTAPI, PATTERN_DEBUG).through(ApiBasicAuthenticationFilter.class); - filter(PATTERN_RESTAPI, PATTERN_DEBUG).through(SecurityFilter.class); - filter(PATTERN_CONFIG, PATTERN_ADMIN).through(AdminSecurityFilter.class); - - // added mdcs for logging - filter(PATTERN_ALL).through(MDCFilter.class); - // debug servlet serve(PATTERN_DEBUG).with(DebugServlet.class); @@ -403,23 +359,21 @@ public class ScmServletModule extends ServletModule serve(PATTERN_PLUGIN_SCRIPT).with(ScriptResourceServlet.class); // template - bind(TemplateHandler.class).to(FreemarkerTemplateHandler.class); serve(PATTERN_INDEX, "/").with(TemplateServlet.class); Multibinder engineBinder = Multibinder.newSetBinder(binder(), TemplateEngine.class); engineBinder.addBinding().to(MustacheTemplateEngine.class); - engineBinder.addBinding().to(FreemarkerTemplateEngine.class); - bind(TemplateEngine.class).annotatedWith(DefaultEngine.class).to( + bind(TemplateEngine.class).annotatedWith(Default.class).to( MustacheTemplateEngine.class); bind(TemplateEngineFactory.class); // bind events - bind(LastModifiedUpdateListener.class); + // bind(LastModifiedUpdateListener.class); // jersey - Map params = new HashMap(); + Map params = Maps.newHashMap(); /* * params.put("com.sun.jersey.spi.container.ContainerRequestFilters", @@ -432,63 +386,17 @@ public class ScmServletModule extends ServletModule 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()); - - String restPath = getRestPackages(); - logger.info("configure jersey with package path: {}", restPath); - - params.put(PackagesResourceConfig.PROPERTY_PACKAGES, restPath); + params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "unbound"); serve(PATTERN_RESTAPI).with(GuiceContainer.class, params); } - /** - * Method description - * - * - * @param packageSet - * @param plugin - */ - private void appendPluginPackages(Set packageSet, Plugin plugin) - { - Set pluginPackageSet = plugin.getPackageSet(); - - if (pluginPackageSet != null) - { - for (String pluginPkg : pluginPackageSet) - { - boolean append = true; - - for (String pkg : packageSet) - { - if (pluginPkg.startsWith(pkg)) - { - append = false; - - break; - } - } - - if (append) - { - if (logger.isDebugEnabled()) - { - String name = "unknown"; - - if (plugin.getInformation() != null) - { - name = plugin.getInformation().getName(); - } - - logger.debug("plugin {} added rest path {}", name, pluginPkg); - } - - packageSet.add(pluginPkg); - } - } - } - } - /** * Method description * @@ -576,44 +484,6 @@ public class ScmServletModule extends ServletModule //~--- get methods ---------------------------------------------------------- - /** - * Method description - * - * - * @return - */ - private String getRestPackages() - { - Set packageSet = new HashSet(); - - packageSet.add(SCMContext.DEFAULT_PACKAGE); - - Collection plugins = pluginLoader.getInstalledPlugins(); - - if (plugins != null) - { - for (Plugin plugin : plugins) - { - appendPluginPackages(packageSet, plugin); - } - } - - StringBuilder buffer = new StringBuilder(); - Iterator pkgIterator = packageSet.iterator(); - - while (pkgIterator.hasNext()) - { - buffer.append(pkgIterator.next()); - - if (pkgIterator.hasNext()) - { - buffer.append(";"); - } - } - - return buffer.toString(); - } - /** * Load ScmConfiguration with JAXB * @@ -622,7 +492,7 @@ public class ScmServletModule extends ServletModule * * @return */ - private ScmConfiguration getScmConfiguration(SCMContextProvider context) + private ScmConfiguration getScmConfiguration() { ScmConfiguration configuration = new ScmConfiguration(); @@ -634,8 +504,11 @@ public class ScmServletModule extends ServletModule //~--- fields --------------------------------------------------------------- /** Field description */ - private ClassOverrides overrides; + private final ClassOverrides overrides; /** Field description */ - private DefaultPluginLoader pluginLoader; + private final DefaultPluginLoader pluginLoader; + + /** Field description */ + private final ServletContext servletContext; } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/TemplateEngineViewable.java b/scm-webapp/src/main/java/sonia/scm/api/rest/TemplateEngineViewable.java index 4a089ab150..b36cf6c7e7 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/TemplateEngineViewable.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/TemplateEngineViewable.java @@ -42,65 +42,50 @@ import sonia.scm.template.TemplateEngineFactory; //~--- JDK imports ------------------------------------------------------------ -import com.sun.jersey.api.view.Viewable; -import com.sun.jersey.spi.template.ViewProcessor; - import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; +import sonia.scm.template.Viewable; /** * * @author Sebastian Sdorra */ @Provider -public class TemplateEngineViewable implements ViewProcessor +public class TemplateEngineViewable implements MessageBodyWriter { + + private final TemplateEngineFactory templateEngineFactory; - /** - * Constructs ... - * - * - * @param templateEngineFactory - */ @Inject public TemplateEngineViewable(TemplateEngineFactory templateEngineFactory) { this.templateEngineFactory = templateEngineFactory; } - //~--- methods -------------------------------------------------------------- - /** - * Method description - * - * - * @param name - * - * @return - */ @Override - public String resolve(String name) - { - return name; + public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { + return type.isAssignableFrom(Viewable.class); } - /** - * Method description - * - * - * @param path - * @param viewable - * @param out - * - * @throws IOException - */ @Override - public void writeTo(String path, Viewable viewable, OutputStream out) - throws IOException - { + public long getSize(Viewable viewable, Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { + return -1; + } + + @Override + public void writeTo(Viewable viewable, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { + String path = viewable.getPath(); + TemplateEngine engine = templateEngineFactory.getEngineByExtension(path); if (engine == null) @@ -115,14 +100,9 @@ public class TemplateEngineViewable implements ViewProcessor throw new IOException("could not find template for ".concat(path)); } - PrintWriter writer = new PrintWriter(out); + PrintWriter writer = new PrintWriter(entityStream); - template.execute(writer, viewable.getModel()); + template.execute(writer, viewable.getContext()); writer.flush(); } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - private TemplateEngineFactory templateEngineFactory; } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractPermissionResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractPermissionResource.java index e9e63d16d8..040eb6b2dc 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractPermissionResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractPermissionResource.java @@ -133,7 +133,7 @@ public abstract class AbstractPermissionResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response add(@Context UriInfo uriInfo, Permission permission) { AssignedPermission ap = transformPermission(permission); @@ -185,7 +185,7 @@ public abstract class AbstractPermissionResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response update(@PathParam("id") String id, Permission permission) { StoredAssignedPermission sap = getPermission(id); @@ -213,7 +213,7 @@ public abstract class AbstractPermissionResource @ResponseCode(code = 404, condition = "not found, no permission with the specified id available"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Permission get(@PathParam("id") String id) { StoredAssignedPermission sap = getPermission(id); @@ -231,7 +231,7 @@ public abstract class AbstractPermissionResource @ResponseCode(code = 204, condition = "success"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public List getAll() { return getPermissions(getPredicate()); diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ChangePasswordResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ChangePasswordResource.java index 52b8b02c37..87626c7045 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ChangePasswordResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ChangePasswordResource.java @@ -118,7 +118,7 @@ public class ChangePasswordResource @ResponseCode(code = 400, condition = "bad request, the old password is not correct"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response changePassword(@FormParam("old-password") String oldPassword, @FormParam("new-password") String newPassword) throws UserException, IOException diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ConfigurationResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ConfigurationResource.java index 2fb6bdda3d..a9beea7679 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ConfigurationResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ConfigurationResource.java @@ -89,7 +89,7 @@ public class ConfigurationResource * @return */ @GET - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response getConfiguration() { Response response = null; @@ -118,7 +118,7 @@ public class ConfigurationResource * @return */ @POST - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response setConfig(@Context UriInfo uriInfo, ScmConfiguration newConfig) { diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java index 808aaa498b..dd61f0aecb 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java @@ -119,7 +119,7 @@ public class GroupResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Override public Response create(@Context UriInfo uriInfo, Group group) { @@ -164,7 +164,7 @@ public class GroupResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Override public Response update(@Context UriInfo uriInfo, @PathParam("id") String name, Group group) @@ -191,7 +191,7 @@ public class GroupResource @ResponseCode(code = 404, condition = "not found, no group with the specified id/name available"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Override public Response get(@Context Request request, @PathParam("id") String id) { @@ -221,7 +221,7 @@ public class GroupResource * @return */ @GET - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @TypeHint(Group[].class) @StatusCodes({ @ResponseCode(code = 200, condition = "success"), diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/PluginResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/PluginResource.java index 54c9369a57..fda978b3fe 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/PluginResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/PluginResource.java @@ -52,7 +52,6 @@ import sonia.scm.plugin.PluginInformationComparator; //~--- JDK imports ------------------------------------------------------------ -import com.sun.jersey.multipart.FormDataParam; import com.webcohesion.enunciate.metadata.rs.ResponseCode; import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.TypeHint; @@ -66,6 +65,7 @@ import java.util.Iterator; import java.util.List; import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; @@ -124,9 +124,9 @@ public class PluginResource @ResponseCode(code = 500, condition = "internal server error") }) @Consumes(MediaType.MULTIPART_FORM_DATA) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response install( - @FormDataParam("package") InputStream uploadedInputStream) + /*@FormParam("package")*/ InputStream uploadedInputStream) throws IOException { Response response = null; @@ -194,7 +194,7 @@ public class PluginResource @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.TEXT_HTML) public Response installFromUI( - @FormDataParam("package") InputStream uploadedInputStream) + /*@FormParam("package")*/ InputStream uploadedInputStream) throws IOException { return install(uploadedInputStream); @@ -257,7 +257,7 @@ public class PluginResource @ResponseCode(code = 200, condition = "success"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Collection getAll() { return pluginManager.getAll(); @@ -274,7 +274,7 @@ public class PluginResource @ResponseCode(code = 200, condition = "success"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Collection getAvailable() { return pluginManager.getAvailable(); @@ -291,7 +291,7 @@ public class PluginResource @ResponseCode(code = 200, condition = "success"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Collection getAvailableUpdates() { return pluginManager.getAvailableUpdates(); @@ -325,7 +325,7 @@ public class PluginResource @ResponseCode(code = 200, condition = "success"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Collection getOverview() { //J- diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java index 9382f58c5c..9c01e3d4a8 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java @@ -69,8 +69,6 @@ import static com.google.common.base.Preconditions.*; //~--- JDK imports ------------------------------------------------------------ -import com.sun.jersey.api.client.ClientResponse.Status; -import com.sun.jersey.multipart.FormDataParam; import com.webcohesion.enunciate.metadata.rs.ResponseCode; import com.webcohesion.enunciate.metadata.rs.ResponseHeader; import com.webcohesion.enunciate.metadata.rs.StatusCodes; @@ -89,6 +87,7 @@ import java.util.Set; import javax.ws.rs.Consumes; import javax.ws.rs.DefaultValue; +import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; @@ -111,7 +110,7 @@ import javax.xml.bind.annotation.XmlRootElement; * * @author Sebastian Sdorra */ -@Path("import/repositories") +// @Path("import/repositories") public class RepositoryImportResource { @@ -170,8 +169,8 @@ public class RepositoryImportResource @TypeHint(TypeHint.NO_CONTENT.class) @Consumes(MediaType.MULTIPART_FORM_DATA) public Response importFromBundle(@Context UriInfo uriInfo, - @PathParam("type") String type, @FormDataParam("name") String name, - @FormDataParam("bundle") InputStream inputStream, @QueryParam("compressed") + @PathParam("type") String type, @FormParam("name") String name, + @FormParam("bundle") InputStream inputStream, @QueryParam("compressed") @DefaultValue("false") boolean compressed) { Repository repository = doImportFromBundle(type, name, inputStream, @@ -211,8 +210,8 @@ public class RepositoryImportResource @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.TEXT_HTML) public Response importFromBundleUI(@PathParam("type") String type, - @FormDataParam("name") String name, - @FormDataParam("bundle") InputStream inputStream, @QueryParam("compressed") + @FormParam("name") String name, + @FormParam("bundle") InputStream inputStream, @QueryParam("compressed") @DefaultValue("false") boolean compressed) { Response response; @@ -260,7 +259,7 @@ public class RepositoryImportResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response importFromUrl(@Context UriInfo uriInfo, @PathParam("type") String type, UrlImportRequest request) { @@ -320,7 +319,7 @@ public class RepositoryImportResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(Repository[].class) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response importRepositories(@PathParam("type") String type) { SecurityUtils.getSubject().checkRole(Role.ADMIN); @@ -352,7 +351,7 @@ public class RepositoryImportResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(Repository[].class) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response importRepositories() { SecurityUtils.getSubject().checkRole(Role.ADMIN); @@ -394,7 +393,7 @@ public class RepositoryImportResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(ImportResult.class) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response importRepositoriesFromDirectory( @PathParam("type") String type) { @@ -435,7 +434,7 @@ public class RepositoryImportResource .warn( "import feature is not supported by repository handler for type " .concat(type), ex); - response = Response.status(Status.BAD_REQUEST).build(); + response = Response.status(Response.Status.BAD_REQUEST).build(); } catch (IOException ex) { @@ -451,7 +450,7 @@ public class RepositoryImportResource else { logger.warn("could not find reposiotry handler for type {}", type); - response = Response.status(Status.BAD_REQUEST).build(); + response = Response.status(Response.Status.BAD_REQUEST).build(); } return response; @@ -475,7 +474,7 @@ public class RepositoryImportResource ), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response getImportableTypes() { SecurityUtils.getSubject().checkRole(Role.ADMIN); diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java index 16168aefc7..e9f7812ee0 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java @@ -166,7 +166,7 @@ public class RepositoryResource extends AbstractManagerResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Override public Response create(@Context UriInfo uriInfo, User user) { @@ -170,7 +170,7 @@ public class UserResource extends AbstractManagerResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Override public Response update(@Context UriInfo uriInfo, @PathParam("id") String name, User user) @@ -197,7 +197,7 @@ public class UserResource extends AbstractManagerResource @ResponseCode(code = 404, condition = "not found, no group with the specified id/name available"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Override public Response get(@Context Request request, @PathParam("id") String id) { @@ -233,7 +233,7 @@ public class UserResource extends AbstractManagerResource @ResponseCode(code = 403, condition = "forbidden, the current user has no admin privileges"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Override public Response getAll(@Context Request request, @DefaultValue("0") @QueryParam("start") int start, @DefaultValue("-1") diff --git a/scm-webapp/src/main/java/sonia/scm/debug/DebugResource.java b/scm-webapp/src/main/java/sonia/scm/debug/DebugResource.java index f65e0c7708..0933242b49 100644 --- a/scm-webapp/src/main/java/sonia/scm/debug/DebugResource.java +++ b/scm-webapp/src/main/java/sonia/scm/debug/DebugResource.java @@ -67,7 +67,7 @@ public final class DebugResource * @return all received hook data for the given repository */ @GET - @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Collection getAll(@PathParam("repository") String repository){ return debugService.getAll(repository); } @@ -81,7 +81,7 @@ public final class DebugResource */ @GET @Path("last") - @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public DebugHookData getLast(@PathParam("repository") String repository){ return debugService.getLast(repository); } diff --git a/scm-webapp/src/main/java/sonia/scm/net/ahc/JsonContentTransformer.java b/scm-webapp/src/main/java/sonia/scm/net/ahc/JsonContentTransformer.java index 5e61ed6965..2998f82890 100644 --- a/scm-webapp/src/main/java/sonia/scm/net/ahc/JsonContentTransformer.java +++ b/scm-webapp/src/main/java/sonia/scm/net/ahc/JsonContentTransformer.java @@ -33,13 +33,15 @@ package sonia.scm.net.ahc; //~--- non-JDK imports -------------------------------------------------------- -import com.google.common.io.ByteSource; +import com.fasterxml.jackson.databind.AnnotationIntrospector; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair; +import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; +import com.fasterxml.jackson.databind.type.TypeFactory; +import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector; -import org.codehaus.jackson.map.AnnotationIntrospector; -import org.codehaus.jackson.map.DeserializationConfig; -import org.codehaus.jackson.map.ObjectMapper; -import org.codehaus.jackson.map.introspect.JacksonAnnotationIntrospector; -import org.codehaus.jackson.xc.JaxbAnnotationIntrospector; +import com.google.common.io.ByteSource; import sonia.scm.plugin.ext.Extension; import sonia.scm.util.IOUtil; @@ -73,12 +75,12 @@ public class JsonContentTransformer implements ContentTransformer // allow jackson and jaxb annotations AnnotationIntrospector jackson = new JacksonAnnotationIntrospector(); - AnnotationIntrospector jaxb = new JaxbAnnotationIntrospector(); + AnnotationIntrospector jaxb = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance()); - this.mapper.setAnnotationIntrospector(new AnnotationIntrospector.Pair(jackson, jaxb)); + this.mapper.setAnnotationIntrospector(new AnnotationIntrospectorPair(jackson, jaxb)); // do not fail on unknown json properties - this.mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); + this.mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); } //~--- methods -------------------------------------------------------------- diff --git a/scm-webapp/src/main/resources/logback.default.xml b/scm-webapp/src/main/resources/logback.default.xml index 318cd6112a..bf18f02893 100644 --- a/scm-webapp/src/main/resources/logback.default.xml +++ b/scm-webapp/src/main/resources/logback.default.xml @@ -90,6 +90,8 @@ + + diff --git a/scm-webapp/src/main/webapp/WEB-INF/web.xml b/scm-webapp/src/main/webapp/WEB-INF/web.xml index 513c708e80..8a54ee72cd 100644 --- a/scm-webapp/src/main/webapp/WEB-INF/web.xml +++ b/scm-webapp/src/main/webapp/WEB-INF/web.xml @@ -40,7 +40,7 @@ SCM-Manager ${project.version} - sonia.scm.boot.BootstrapListener + sonia.scm.boot.BootstrapContextListener @@ -48,15 +48,45 @@ - guiceFilter - sonia.scm.boot.BootstrapFilter + BootstrapFilter + sonia.scm.boot.BootstrapContextFilter - guiceFilter + BootstrapFilter /* + + + + resteasy.servlet.mapping.prefix + /api/rest + + + + Resteasy + + org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher + + + + + Resteasy + /api/rest/* + + + + + + + sonia.scm.HttpSessionListenerHolder + + + + index.html diff --git a/scm-webapp/src/main/webapp/resources/js/action/sonia.action.changepasswordwindow.js b/scm-webapp/src/main/webapp/resources/js/action/sonia.action.changepasswordwindow.js index b1c0a5372f..3d044d69c5 100644 --- a/scm-webapp/src/main/webapp/resources/js/action/sonia.action.changepasswordwindow.js +++ b/scm-webapp/src/main/webapp/resources/js/action/sonia.action.changepasswordwindow.js @@ -55,7 +55,7 @@ Sonia.action.ChangePasswordWindow = Ext.extend(Ext.Window,{ title: this.titleText, items: [{ id: 'changePasswordForm', - url: restUrl + 'action/change-password.json', + url: restUrl + 'action/change-password', frame: true, xtype: 'form', monitorValid: true, diff --git a/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js b/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js index a985688a3e..0f9c2fdd57 100644 --- a/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js @@ -261,7 +261,7 @@ Sonia.config.ScmConfigPanel = Ext.extend(Sonia.config.ConfigPanel,{ onSubmit: function(values){ this.el.mask(this.submitText); Ext.Ajax.request({ - url: restUrl + 'config.json', + url: restUrl + 'config', method: 'POST', jsonData: values, scope: this, @@ -283,7 +283,7 @@ Sonia.config.ScmConfigPanel = Ext.extend(Sonia.config.ConfigPanel,{ onLoad: function(el){ var tid = setTimeout( function(){ el.mask(this.loadingText); }, 100); Ext.Ajax.request({ - url: restUrl + 'config.json', + url: restUrl + 'config', method: 'GET', scope: this, disableCaching: true, diff --git a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.formpanel.js b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.formpanel.js index 5d560d9717..4ec278bf6b 100644 --- a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.formpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.formpanel.js @@ -59,7 +59,7 @@ Sonia.group.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ // this.updateMembers(group); this.fireEvent('preUpdate', group); - var url = restUrl + 'groups/' + encodeURIComponent(group.name) + '.json'; + var url = restUrl + 'groups/' + encodeURIComponent(group.name); var el = this.el; var tid = setTimeout( function(){el.mask('Loading ...');}, 100); @@ -96,7 +96,7 @@ Sonia.group.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ } item.type = state.defaultUserType; - var url = restUrl + 'groups.json'; + var url = restUrl + 'groups'; var el = this.el; var tid = setTimeout( function(){el.mask('Loading ...');}, 100); diff --git a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js index 18d3841fc2..1bc3fbe819 100644 --- a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js +++ b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js @@ -95,7 +95,7 @@ Sonia.group.Panel = Ext.extend(Sonia.rest.Panel, { var selected = grid.getSelectionModel().getSelected(); if ( selected ){ var item = selected.data; - var url = restUrl + 'groups/' + encodeURIComponent(item.name) + '.json'; + var url = restUrl + 'groups/' + encodeURIComponent(item.name); Ext.MessageBox.show({ title: this.removeTitleText, diff --git a/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js b/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js index b27f2484b4..19ad6d0e15 100644 --- a/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js +++ b/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js @@ -41,7 +41,6 @@ Sonia.login.Form = Ext.extend(Ext.FormPanel,{ failedDescriptionText: 'Incorrect username, password or not enough permission. Please Try again.', accountLockedText: 'Account is locked.', accountTemporaryLockedText: 'Account is temporary locked. Please try again later.', - rememberMeText: 'Remember me', initComponent: function(){ var buttons = []; @@ -94,11 +93,14 @@ Sonia.login.Form = Ext.extend(Ext.FormPanel,{ scope: this } } - },{ - xtype: 'checkbox', - fieldLabel: this.rememberMeText, - name: 'rememberMe', - inputValue: 'true' + }, { + name: 'grant_type', + value: 'password', + xtype: 'hidden' + }, { + name: 'cookie', + value: 'true', + xtype: 'hidden' }], buttons: buttons }; @@ -116,6 +118,7 @@ Sonia.login.Form = Ext.extend(Ext.FormPanel,{ authenticate: function(){ var form = this.getForm(); + form.submit({ scope: this, method: 'POST', diff --git a/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.center.js b/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.center.js index 11113e2601..ebd2119886 100644 --- a/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.center.js +++ b/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.center.js @@ -81,7 +81,7 @@ Sonia.plugin.Center = Ext.extend(Ext.util.Observable, { var loadingBox = this.createLoadingBox( this.installWaitMsgText ); Ext.Ajax.request({ - url: restUrl + 'plugins/install/' + pluginId + '.json', + url: restUrl + 'plugins/install/' + pluginId, method: 'POST', scope: this, timeout: 300000, // 5min @@ -116,7 +116,7 @@ Sonia.plugin.Center = Ext.extend(Ext.util.Observable, { var loadingBox = this.createLoadingBox( this.uninstallWaitMsgText ); Ext.Ajax.request({ - url: restUrl + 'plugins/uninstall/' + pluginId + '.json', + url: restUrl + 'plugins/uninstall/' + pluginId, method: 'POST', scope: this, success: function(){ @@ -150,7 +150,7 @@ Sonia.plugin.Center = Ext.extend(Ext.util.Observable, { var loadingBox = this.createLoadingBox( this.updateWaitMsgText ); Ext.Ajax.request({ - url: restUrl + 'plugins/update/' + pluginId + '.json', + url: restUrl + 'plugins/update/' + pluginId, method: 'POST', scope: this, timeout: 300000, // 5min diff --git a/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.grid.js b/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.grid.js index cb5ea6bec1..5f44e51ebc 100644 --- a/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.grid.js +++ b/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.grid.js @@ -81,7 +81,7 @@ Sonia.plugin.Grid = Ext.extend(Sonia.rest.Grid, { var pluginStore = new Ext.data.GroupingStore({ proxy: new Ext.data.HttpProxy({ - url: restUrl + 'plugins/overview.json', + url: restUrl + 'plugins/overview', disableCaching: false }), reader: new Ext.data.JsonReader({ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.branchcombobox.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.branchcombobox.js index cddcad4552..4c3dcbc7c8 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.branchcombobox.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.branchcombobox.js @@ -38,7 +38,7 @@ Sonia.repository.BranchComboBox = Ext.extend(Ext.form.ComboBox, { initComponent: function(){ var branchStore = new Sonia.rest.JsonStore({ proxy: new Ext.data.HttpProxy({ - url: restUrl + 'repositories/' + this.repositoryId + '/branches.json', + url: restUrl + 'repositories/' + this.repositoryId + '/branches', method: 'GET', disableCaching: false }), diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewerpanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewerpanel.js index aa18d29e0d..468b99dbec 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewerpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewerpanel.js @@ -46,7 +46,7 @@ Sonia.repository.ChangesetViewerPanel = Ext.extend(Ext.Panel, { initComponent: function(){ if (! this.url){ - this.url = restUrl + 'repositories/' + this.repository.id + '/changesets.json'; + this.url = restUrl + 'repositories/' + this.repository.id + '/changesets'; } if ( ! this.startLimit ){ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.commitpanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.commitpanel.js index 7b72c4fca3..591d77d43f 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.commitpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.commitpanel.js @@ -131,7 +131,7 @@ Sonia.repository.CommitPanel = Ext.extend(Ext.Panel, { } Ext.Ajax.request({ - url: restUrl + 'repositories/' + this.repository.id + '/changeset/' + this.revision + '.json', + url: restUrl + 'repositories/' + this.repository.id + '/changeset/' + this.revision, method: 'GET', scope: this, success: function(response){ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.formpanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.formpanel.js index 66482399ac..422a81ce6b 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.formpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.formpanel.js @@ -73,7 +73,7 @@ Sonia.repository.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ if ( debug ){ console.debug( 'update repository: ' + item.name ); } - var url = restUrl + 'repositories/' + item.id + '.json'; + var url = restUrl + 'repositories/' + item.id; var el = this.el; var tid = setTimeout( function(){el.mask('Loading ...');}, 100); @@ -124,7 +124,7 @@ Sonia.repository.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ if ( debug ){ console.debug( 'create repository: ' + item.name ); } - var url = restUrl + 'repositories.json'; + var url = restUrl + 'repositories'; var el = this.el; var tid = setTimeout( function(){el.mask('Loading ...');}, 100); diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js index fb66b91a5a..9e2f76f607 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js @@ -71,7 +71,7 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, { var repositoryStore = new Ext.data.GroupingStore({ proxy: new Ext.data.HttpProxy({ - url: restUrl + 'repositories.json', + url: restUrl + 'repositories', disableCaching: false }), idProperty: 'id', diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.healthcheckfailure.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.healthcheckfailure.js index 195d7d7509..076f73e712 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.healthcheckfailure.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.healthcheckfailure.js @@ -75,7 +75,7 @@ Sonia.repository.HealthCheckFailure = Ext.extend(Ext.Panel, { }, rerunHealthChecks: function(){ - var url = restUrl + 'repositories/' + this.repository.id + '/healthcheck.json'; + var url = restUrl + 'repositories/' + this.repository.id + '/healthcheck'; var el = this.el; var tid = setTimeout( function(){el.mask('Loading ...');}, 100); diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js index 209b554e82..ac6bbc2206 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js @@ -514,7 +514,7 @@ Sonia.repository.ImportPanel = Ext.extend(Ext.Panel, { importFromUrl: function(layout, repository){ var lbox = this.showLoadingBox(); Ext.Ajax.request({ - url: restUrl + 'import/repositories/' + this.repositoryType + '/url.json', + url: restUrl + 'import/repositories/' + this.repositoryType + '/url', method: 'POST', scope: this, timeout: 300000, // 5min @@ -533,7 +533,7 @@ Sonia.repository.ImportPanel = Ext.extend(Ext.Panel, { importFromDirectory: function(layout){ var lbox = this.showLoadingBox(); Ext.Ajax.request({ - url: restUrl + 'import/repositories/' + this.repositoryType + '/directory.json', + url: restUrl + 'import/repositories/' + this.repositoryType + '/directory', timeout: 300000, // 5min method: 'POST', scope: this, diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js index 7e10a58f4e..e978c0ffe9 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js @@ -181,7 +181,7 @@ Sonia.repository.get = function(id, callback){ execCallback(repository); } else { Ext.Ajax.request({ - url: restUrl + 'repositories/' + id + '.json', + url: restUrl + 'repositories/' + id, method: 'GET', scope: this, success: function(response){ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js index 17a301509a..767c294242 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js @@ -311,7 +311,7 @@ Sonia.repository.Panel = Ext.extend(Sonia.rest.Panel, { console.debug('toggle repository ' + item.name + ' archive to ' + item.archived); } - var url = restUrl + 'repositories/' + item.id + '.json'; + var url = restUrl + 'repositories/' + item.id; this.executeRemoteCall(title, String.format(msg, item.name), 'PUT', url, item, function(result){ main.handleFailure( @@ -331,7 +331,7 @@ Sonia.repository.Panel = Ext.extend(Sonia.rest.Panel, { console.debug( 'remove repository ' + item.name ); } - var url = restUrl + 'repositories/' + item.id + '.json'; + var url = restUrl + 'repositories/' + item.id; this.executeRemoteCall(this.removeTitleText, String.format(this.removeMsgText, item.name), 'DELETE', url, null, function(result){ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 489dd3c06c..59677cab7e 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -58,7 +58,7 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { var browserStore = new Sonia.rest.JsonStore({ proxy: new Ext.data.HttpProxy({ - url: restUrl + 'repositories/' + this.repository.id + '/browse.json', + url: restUrl + 'repositories/' + this.repository.id, method: 'GET' }), fields: ['path', 'name', 'length', 'lastModified', 'directory', 'description', 'subrepository'], diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.tagcombobox.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.tagcombobox.js index 3f045a8cf6..5af3cc97f1 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.tagcombobox.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.tagcombobox.js @@ -37,7 +37,7 @@ Sonia.repository.TagComboBox = Ext.extend(Ext.form.ComboBox, { initComponent: function(){ var tagStore = new Sonia.rest.JsonStore({ proxy: new Ext.data.HttpProxy({ - url: restUrl + 'repositories/' + this.repositoryId + '/tags.json', + url: restUrl + 'repositories/' + this.repositoryId + '/tags', method: 'GET', disableCaching: false }), diff --git a/scm-webapp/src/main/webapp/resources/js/security/sonia.security.permissionspanel.js b/scm-webapp/src/main/webapp/resources/js/security/sonia.security.permissionspanel.js index 5ea8855251..676114fc78 100644 --- a/scm-webapp/src/main/webapp/resources/js/security/sonia.security.permissionspanel.js +++ b/scm-webapp/src/main/webapp/resources/js/security/sonia.security.permissionspanel.js @@ -53,7 +53,7 @@ Sonia.security.PermissionsPanel = Ext.extend(Ext.Panel, { this.permissionStore = new Sonia.rest.JsonStore({ proxy: new Ext.data.HttpProxy({ api: { - read: restUrl + this.baseUrl + '.json' + read: restUrl + this.baseUrl }, disableCaching: false }), @@ -179,7 +179,7 @@ Sonia.security.PermissionsPanel = Ext.extend(Ext.Panel, { addPermission: function(record){ Ext.Ajax.request({ - url: restUrl + this.baseUrl + '.json', + url: restUrl + this.baseUrl, method: 'POST', jsonData: record.data, scope: this, @@ -194,7 +194,7 @@ Sonia.security.PermissionsPanel = Ext.extend(Ext.Panel, { modifyPermission: function(id, record){ Ext.Ajax.request({ - url: restUrl + this.baseUrl + '/' + encodeURIComponent(id) + '.json', + url: restUrl + this.baseUrl + '/' + encodeURIComponent(id), method: 'PUT', jsonData: record.data, scope: this, @@ -207,7 +207,7 @@ Sonia.security.PermissionsPanel = Ext.extend(Ext.Panel, { removePermission: function(store, record){ Ext.Ajax.request({ - url: restUrl + this.baseUrl + '/' + encodeURIComponent(record.get('id')) + '.json', + url: restUrl + this.baseUrl + '/' + encodeURIComponent(record.get('id')), method: 'DELETE', scope: this, success: function(){ diff --git a/scm-webapp/src/main/webapp/resources/js/sonia.global.js b/scm-webapp/src/main/webapp/resources/js/sonia.global.js index a43feb824b..98299546b1 100644 --- a/scm-webapp/src/main/webapp/resources/js/sonia.global.js +++ b/scm-webapp/src/main/webapp/resources/js/sonia.global.js @@ -83,7 +83,7 @@ var userSearchStore = new Ext.data.JsonStore({ idProperty: 'value', fields: ['value','label'], proxy: new Ext.data.HttpProxy({ - url: restUrl + 'search/users.json', + url: restUrl + 'search/users', method: 'GET' }) }); @@ -93,7 +93,7 @@ var groupSearchStore = new Ext.data.JsonStore({ idProperty: 'value', fields: ['value','label'], proxy: new Ext.data.HttpProxy({ - url: restUrl + 'search/groups.json', + url: restUrl + 'search/groups', method: 'GET' }) }); diff --git a/scm-webapp/src/main/webapp/resources/js/sonia.scm.js b/scm-webapp/src/main/webapp/resources/js/sonia.scm.js index 6d7e6a3257..db92a77d60 100644 --- a/scm-webapp/src/main/webapp/resources/js/sonia.scm.js +++ b/scm-webapp/src/main/webapp/resources/js/sonia.scm.js @@ -689,4 +689,4 @@ Ext.onReady(function(){ main.init(); main.checkLogin(); -}); \ No newline at end of file +}); diff --git a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.formpanel.js b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.formpanel.js index 6ef00e73d7..e8a03e5966 100644 --- a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.formpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.formpanel.js @@ -129,7 +129,7 @@ Sonia.user.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ console.debug( 'update user: ' + item.name ); } this.fixRequest(item); - var url = restUrl + 'users/' + encodeURIComponent(item.name) + '.json'; + var url = restUrl + 'users/' + encodeURIComponent(item.name); Ext.Ajax.request({ url: url, jsonData: item, @@ -159,7 +159,7 @@ Sonia.user.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ this.fixRequest(user); // set user type user.type = state.defaultUserType; - var url = restUrl + 'users.json'; + var url = restUrl + 'users'; Ext.Ajax.request({ url: url, jsonData: user, diff --git a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.grid.js b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.grid.js index c44d336ba9..b671e67bdc 100644 --- a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.grid.js +++ b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.grid.js @@ -49,7 +49,7 @@ Sonia.user.Grid = Ext.extend(Sonia.rest.Grid, { var userStore = new Sonia.rest.JsonStore({ proxy: new Ext.data.HttpProxy({ - url: restUrl + 'users.json', + url: restUrl + 'users', disableCaching: false }), idProperty: 'name', diff --git a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.panel.js b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.panel.js index 8e98c645df..0ca0fd78e1 100644 --- a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.panel.js +++ b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.panel.js @@ -126,7 +126,7 @@ Sonia.user.Panel = Ext.extend(Sonia.rest.Panel, { var selected = grid.getSelectionModel().getSelected(); if ( selected ){ var item = selected.data; - var url = restUrl + 'users/' + encodeURIComponent(item.name) + '.json'; + var url = restUrl + 'users/' + encodeURIComponent(item.name); Ext.MessageBox.show({ title: this.removeTitleText, diff --git a/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java b/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java index f8adb90ff1..33e020f85d 100644 --- a/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java +++ b/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java @@ -32,6 +32,9 @@ package sonia.scm.it; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.type.TypeFactory; +import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector; import com.google.common.base.Charsets; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.UniformInterfaceException; @@ -41,8 +44,6 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; import org.apache.shiro.crypto.hash.Sha256Hash; -import org.codehaus.jackson.map.ObjectMapper; -import org.codehaus.jackson.xc.JaxbAnnotationIntrospector; import org.hamcrest.Matchers; import org.junit.After; import org.junit.Test; @@ -81,7 +82,7 @@ public class GitLfsITCase { private Repository repository; public GitLfsITCase() { - mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector()); + mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector(TypeFactory.defaultInstance())); } // lifecycle methods From a051eb159cfa6495c806001fa758dfb3ab58f4de Mon Sep 17 00:00:00 2001 From: Matt Harbison Date: Fri, 22 Jun 2018 16:06:35 -0400 Subject: [PATCH 70/78] #989 load global configuration in hgweb on Mercurial 4.1 and later --- .../src/main/resources/sonia/scm/python/hgweb.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/hgweb.py b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/hgweb.py index e2e7d8e931..7f99a85585 100644 --- a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/hgweb.py +++ b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/hgweb.py @@ -36,7 +36,11 @@ from mercurial.hgweb import hgweb, wsgicgi demandimport.enable() -u = uimod.ui() +try: + u = uimod.ui.load() +except AttributeError: + # For installations earlier than Mercurial 4.1 + u = uimod.ui() # pass SCM_HTTP_POST_ARGS to enable experimental httppostargs protocol of mercurial # SCM_HTTP_POST_ARGS is set by HgCGIServlet From 2d103b7f958939cc912f9bcc55dae47cda7c1492 Mon Sep 17 00:00:00 2001 From: Matt Harbison Date: Fri, 22 Jun 2018 16:33:52 -0400 Subject: [PATCH 71/78] optionally print tracebacks when the Mercurial hook swallows an exception If `ui.traceback=True` is set on the server, this prints the stacktrace for the exception on the client side. Otherwise, nothing happens. I tried allowing the exception to propagate back to Mercurial, but then the client sees this message with 4.4.2 and 4.6.1: abort: remote error: Mercurial/Python process ends with return code 1 Something odd changed when upgrading from CentOS 7.4 to 7.5 around forwarding requests from the loopback address that I don't fully understand. First, we were getting a ValueError from inside `opener.open()` saying that 'localhost' didn't match the host listed in the SSL certificate. That wasn't visible until adding this. Then what happened is a connection refused out of the same function, so the traceback is added to the other handler too. Running the equivalent command on the command line from the 'vcs' host stopped working in 7.5: $ curl https://vcs.domain.com/hook/hg/?ping=true curl: (7) Failed connect to vcs.domain.com:443; Connection refused But it works when run on another machine targeting that same 'vcs' host. Adding another firewall rule allows everything to work from the 'vcs' host again: $ iptables -t nat -I OUTPUT -p tcp -o lo --dport 443 -j REDIRECT --to-ports 8443 --- .../src/main/resources/sonia/scm/python/scmhooks.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/scmhooks.py b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/scmhooks.py index e9a58d589f..73b5bfe083 100644 --- a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/scmhooks.py +++ b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/scmhooks.py @@ -78,8 +78,10 @@ def callHookUrl(ui, repo, hooktype, node): printMessages(ui, msg.splitlines(True)) else: ui.warn( "ERROR: scm-hook failed with an unknown error\n" ) + ui.traceback() except ValueError: ui.warn( "scm-hook failed with an exception\n" ) + ui.traceback() return abort def callback(ui, repo, hooktype, node=None, source=None, pending=None, **kwargs): From 405dd672754ddd80ca9a7972eb9460aaf1fb67cf Mon Sep 17 00:00:00 2001 From: Matt Harbison Date: Fri, 22 Jun 2018 16:42:05 -0400 Subject: [PATCH 72/78] ensure each message line printed in the Mercurial hook gets a trailing newline I noticed that the exception printed in the previous commit started on the same line as the print for the `str(e)` case right before it. Since this also prints the content of urllib2.URLError.read(), it seems better to remove any existing newline and re-add it, than to just assume the `str(e)` case was the only problem. --- .../src/main/resources/sonia/scm/python/scmhooks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/scmhooks.py b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/scmhooks.py index 73b5bfe083..d4999cf2fd 100644 --- a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/scmhooks.py +++ b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/scmhooks.py @@ -46,7 +46,7 @@ def printMessages(ui, msgs): for line in msgs: if line.startswith("_e") or line.startswith("_n"): line = line[2:]; - ui.warn(line); + ui.warn('%s\n' % line.rstrip()) def callHookUrl(ui, repo, hooktype, node): abort = True From 83d6ab8e9cb49d40801abf023b63bce1c9aa7e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Mon, 25 Jun 2018 11:52:36 +0200 Subject: [PATCH 73/78] Backed out changeset 5d23ff274a2f --- pom.xml | 355 +++++++------- scm-clients/scm-client-impl/pom.xml | 4 +- scm-core/pom.xml | 6 +- .../scm/security/DefaultCipherHandler.java | 7 +- .../main/java/sonia/scm/web/HgCGIServlet.java | 34 +- scm-webapp/pom.xml | 436 ++++++++++-------- .../main/java/sonia/scm/ScmServletModule.java | 209 +++++++-- .../scm/api/rest/TemplateEngineViewable.java | 64 ++- .../scm/api/rest/UriExtensionsConfig.java | 110 +++-- .../resources/AbstractPermissionResource.java | 8 +- .../resources/ChangePasswordResource.java | 2 +- .../rest/resources/ConfigurationResource.java | 4 +- .../scm/api/rest/resources/GroupResource.java | 8 +- .../api/rest/resources/PluginResource.java | 16 +- .../resources/RepositoryImportResource.java | 27 +- .../rest/resources/RepositoryResource.java | 22 +- .../resources/RepositoryRootResource.java | 21 +- .../api/rest/resources/SearchResource.java | 4 +- .../scm/api/rest/resources/UserResource.java | 8 +- .../java/sonia/scm/debug/DebugResource.java | 4 +- .../scm/net/ahc/JsonContentTransformer.java | 20 +- .../src/main/resources/logback.default.xml | 2 - scm-webapp/src/main/webapp/WEB-INF/web.xml | 38 +- .../sonia.action.changepasswordwindow.js | 2 +- .../js/config/sonia.config.scmconfigpanel.js | 4 +- .../js/group/sonia.group.formpanel.js | 4 +- .../resources/js/group/sonia.group.panel.js | 2 +- .../resources/js/login/sonia.login.form.js | 15 +- .../js/plugin/sonia.plugin.center.js | 6 +- .../resources/js/plugin/sonia.plugin.grid.js | 2 +- .../sonia.repository.branchcombobox.js | 2 +- .../sonia.repository.changesetviewerpanel.js | 2 +- .../sonia.repository.commitpanel.js | 2 +- .../repository/sonia.repository.formpanel.js | 4 +- .../js/repository/sonia.repository.grid.js | 2 +- .../sonia.repository.healthcheckfailure.js | 2 +- .../sonia.repository.importwindow.js | 4 +- .../js/repository/sonia.repository.js | 2 +- .../js/repository/sonia.repository.panel.js | 4 +- .../sonia.repository.repositorybrowser.js | 2 +- .../sonia.repository.tagcombobox.js | 2 +- .../sonia.security.permissionspanel.js | 8 +- .../main/webapp/resources/js/sonia.global.js | 4 +- .../src/main/webapp/resources/js/sonia.scm.js | 2 +- .../resources/js/user/sonia.user.formpanel.js | 4 +- .../resources/js/user/sonia.user.grid.js | 2 +- .../resources/js/user/sonia.user.panel.js | 2 +- .../test/java/sonia/scm/it/GitLfsITCase.java | 7 +- 48 files changed, 878 insertions(+), 623 deletions(-) rename scm-core/src/main/java/sonia/scm/template/Viewable.java => scm-webapp/src/main/java/sonia/scm/api/rest/UriExtensionsConfig.java (52%) diff --git a/pom.xml b/pom.xml index 3674300b1d..840c9f1ec3 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ sonia.scm scm pom - 2.0.0-SNAPSHOT + 1.61-SNAPSHOT The easiest way to share your Git, Mercurial and Subversion repositories over http. @@ -59,20 +59,18 @@ https://scm-manager.ci.cloudbees.com/ - - 3.1.0 - - - scm-annotations - scm-annotation-processor scm-core scm-test + maven scm-plugins + scm-samples scm-dao-xml scm-webapp scm-server + scm-plugin-backend scm-clients + support @@ -82,15 +80,6 @@ scm-manager release repository http://maven.scm-manager.org/nexus/content/groups/public - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - true - daily - - @@ -139,52 +128,20 @@ ${mokito.version} test - + - - - org.apache.maven.plugins - maven-enforcer-plugin - 1.4.1 - - - enforce-java - compile - - enforce - - - - - - [1.8.0-101,) - - - - [3.1,) - - - true - - - - org.codehaus.mojo animal-sniffer-maven-plugin - 1.15 + 1.16 org.codehaus.mojo.signature - java18 + java17 1.0 @@ -198,23 +155,51 @@ + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M1 + + + enforce-java + compile + + enforce + + + + + 1.7 + + + module-info + + + + true + + + + + + org.codehaus.mojo + extra-enforcer-rules + 1.0-beta-7 + + + + org.apache.maven.plugins maven-compiler-plugin - 3.5.1 + 3.0 - true - true ${project.build.javaLevel} ${project.build.javaLevel} - ${project.test.javaLevel} - ${project.test.javaLevel} ${project.build.sourceEncoding} - - -Xlint:unchecked,-options @@ -259,7 +244,7 @@ true true - http://download.oracle.com/javase/8/docs/api/ + http://download.oracle.com/javase/7/docs/api/ http://download.oracle.com/docs/cd/E17802_01/products/products/servlet/2.5/docs/servlet-2_5-mr2/ http://jersey.java.net/nonav/apidocs/${jersey.version}/jersey/ https://google.github.io/guice/api-docs/${guice.version}/javadoc @@ -316,81 +301,59 @@ maven-eclipse-plugin 2.6 - - - - - org.jacoco - jacoco-maven-plugin - 0.7.7.201606060606 - - - - prepare-agent - - - - report - prepare-package - - report - - - - - + org.apache.maven.plugins maven-site-plugin - 3.2 - - - - - org.apache.maven.plugins - maven-project-info-reports-plugin - 2.4 - - - - org.apache.maven.plugins - maven-jxr-plugin - 2.3 - - - - org.codehaus.mojo - findbugs-maven-plugin - 2.4.0 - - - - org.apache.maven.plugins - maven-surefire-report-plugin - 2.12 - - - - org.apache.maven.plugins - maven-pmd-plugin - 2.7.1 - - true - ${project.build.sourceEncoding} - ${project.build.javaLevel} - - - - - + 3.7 + + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 2.4 + + + + org.apache.maven.plugins + maven-jxr-plugin + 2.3 + + + + org.codehaus.mojo + findbugs-maven-plugin + 2.4.0 + + + + org.apache.maven.plugins + maven-surefire-report-plugin + 2.12 + + + + org.apache.maven.plugins + maven-pmd-plugin + 2.7.1 + + ${project.build.sourceEncoding} + ${project.build.javaLevel} + + + + + + @@ -434,18 +397,9 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.8.1 + 3.0.0 - org.jboss.apiviz.APIviz - - org.jboss.apiviz - apiviz - 1.3.2.GA - - - -sourceclasspath ${project.build.outputDirectory} - -nopackagediagram - + false @@ -456,6 +410,101 @@ + + + + + + + commons-beanutils + commons-beanutils + 1.9.3 + + + + commons-collections + commons-collections + 3.2.2 + + + + + + org.apache.httpcomponents + httpclient + 4.5.5 + + + + + + slf4j-api + org.slf4j + ${slf4j.version} + + + + ch.qos.logback + logback-classic + ${logback.version} + + + + + + + org.codehaus.jackson + jackson-core-asl + ${jackson.version} + + + + org.codehaus.jackson + jackson-mapper-asl + ${jackson.version} + + + + org.codehaus.jackson + jackson-jaxrs + ${jackson.version} + + + + org.codehaus.jackson + jackson-xc + ${jackson.version} + + + + + + javax.xml.bind + jaxb-api + ${jaxb.version} + + + + com.sun.xml.bind + jaxb-impl + ${jaxb.version} + + + + org.glassfish.jaxb + jaxb-runtime + ${jaxb.version} + + + + javax.activation + activation + 1.1.1 + + + + + @@ -479,37 +528,31 @@ 4.12 - 1.7.22 + 1.7.25 1.2.3 - 3.0.1 - 2.0.1 - 4.0 + 2.5 + 3.0 1.19.4 - - - 1.2.0 - 2.6.6 2.3.20 - - - 9.2.10.v20150310 - 9.2.10.v20150310 + 7.6.21.v20160908 + 7.6.16.v20140903 + 1.9.13 + 2.3.0 - 1.0.0-SNAPSHOT - 1.4.0-RC2 + 1.3.2 - - v4.5.2.201704071617-r-scm1 - 1.8.15-scm1 + + v4.5.3.201708160445-r-scm1 + 1.9.0-scm3 - 16.0.1 + 15.0 2.2.3 - 1.8 + 1.7 UTF-8 SCM-BSD diff --git a/scm-clients/scm-client-impl/pom.xml b/scm-clients/scm-client-impl/pom.xml index 1e6847349f..ba6edb9130 100644 --- a/scm-clients/scm-client-impl/pom.xml +++ b/scm-clients/scm-client-impl/pom.xml @@ -42,13 +42,13 @@ com.sun.jersey jersey-client - ${jersey-client.version} + ${jersey.version} com.sun.jersey.contribs jersey-multipart - ${jersey-client.version} + ${jersey.version} diff --git a/scm-core/pom.xml b/scm-core/pom.xml index fde7dceb47..ae0057dbdf 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -69,9 +69,9 @@ - javax.ws.rs - javax.ws.rs-api - ${jaxrs.version} + com.sun.jersey + jersey-core + ${jersey.version} 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 b4f0d81cd3..ddb8a699a7 100644 --- a/scm-core/src/main/java/sonia/scm/security/DefaultCipherHandler.java +++ b/scm-core/src/main/java/sonia/scm/security/DefaultCipherHandler.java @@ -45,6 +45,8 @@ import sonia.scm.util.IOUtil; //~--- JDK imports ------------------------------------------------------------ +import com.sun.jersey.core.util.Base64; + import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; @@ -58,7 +60,6 @@ import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Arrays; -import java.util.Base64; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; @@ -164,7 +165,7 @@ public class DefaultCipherHandler implements CipherHandler { String result = null; try { - byte[] encodedInput = Base64.getDecoder().decode(value); + byte[] encodedInput = Base64.decode(value); byte[] salt = new byte[SALT_LENGTH]; byte[] encoded = new byte[encodedInput.length - SALT_LENGTH]; @@ -221,7 +222,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); - res = new String(Base64.getEncoder().encode(result), ENCODING); + res = new String(Base64.encode(result), ENCODING); } catch (IOException | GeneralSecurityException ex) { throw new CipherException("could not encode string", ex); } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java index 0befcf6f11..1fb78161e0 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java @@ -36,7 +36,6 @@ package sonia.scm.web; //~--- non-JDK imports -------------------------------------------------------- import com.google.common.base.Stopwatch; -import com.google.common.base.Strings; import com.google.inject.Inject; import com.google.inject.Singleton; @@ -53,21 +52,18 @@ import sonia.scm.repository.HgRepositoryHandler; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryProvider; import sonia.scm.repository.RepositoryRequestListenerUtil; -import sonia.scm.security.CipherUtil; import sonia.scm.util.AssertUtil; -import sonia.scm.util.HttpUtil; import sonia.scm.web.cgi.CGIExecutor; import sonia.scm.web.cgi.CGIExecutorFactory; import sonia.scm.web.cgi.EnvList; //~--- JDK imports ------------------------------------------------------------ -import com.sun.jersey.core.util.Base64; - import java.io.File; import java.io.IOException; import java.util.Enumeration; +import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -83,17 +79,18 @@ import javax.servlet.http.HttpSession; public class HgCGIServlet extends HttpServlet { + private static final String ENV_PYTHON_HTTPS_VERIFY = "PYTHONHTTPSVERIFY"; + /** 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 */ - public static final String ENV_SESSION_PREFIX = "SCM_"; + private static final String ENV_HTTP_POST_ARGS = "SCM_HTTP_POST_ARGS"; /** Field description */ - private static final String SCM_CREDENTIALS = "SCM_CREDENTIALS"; + public static final String ENV_SESSION_PREFIX = "SCM_"; /** Field description */ private static final long serialVersionUID = -3492811300905099810L; @@ -231,7 +228,6 @@ public class HgCGIServlet extends HttpServlet * @param env * @param session */ - @SuppressWarnings("unchecked") private void passSessionAttributes(EnvList env, HttpSession session) { Enumeration enm = session.getAttributeNames(); @@ -277,19 +273,27 @@ public class HgCGIServlet extends HttpServlet directory.getAbsolutePath()); // add hook environment + Map environment = executor.getEnvironment().asMutableMap(); + if (handler.getConfig().isDisableHookSSLValidation()) { + // disable ssl validation + // Issue 959: https://goo.gl/zH5eY8 + environment.put(ENV_PYTHON_HTTPS_VERIFY, "0"); + } + + // enable experimental httppostargs protocol of mercurial + // Issue 970: https://goo.gl/poascp + environment.put(ENV_HTTP_POST_ARGS, String.valueOf(handler.getConfig().isEnableHttpPostArgs())); + //J- HgEnvironment.prepareEnvironment( - executor.getEnvironment().asMutableMap(), + environment, handler, - hookManager, + hookManager, request ); //J+ - addCredentials(executor.getEnvironment(), request); - - // unused ??? - HttpSession session = request.getSession(false); + HttpSession session = request.getSession(); if (session != null) { diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index b22ceccb90..3803b24e00 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -6,54 +6,63 @@ sonia.scm scm - 2.0.0-SNAPSHOT + 1.61-SNAPSHOT sonia.scm scm-webapp war - 2.0.0-SNAPSHOT + 1.61-SNAPSHOT scm-webapp - - - - sonia.scm - scm-annotation-processor - 2.0.0-SNAPSHOT - provided - - javax.servlet - javax.servlet-api + servlet-api ${servlet.version} provided - - + + javax.transaction jta 1.1 provided - + - + sonia.scm scm-core - 2.0.0-SNAPSHOT + 1.61-SNAPSHOT - + sonia.scm scm-dao-xml - 2.0.0-SNAPSHOT + 1.61-SNAPSHOT + + + + sonia.scm.plugins + scm-hg-plugin + 1.61-SNAPSHOT + + + + sonia.scm.plugins + scm-svn-plugin + 1.61-SNAPSHOT + + + + sonia.scm.plugins + scm-git-plugin + 1.61-SNAPSHOT @@ -63,18 +72,12 @@ shiro-web ${shiro.version} - + org.apache.shiro shiro-guice ${shiro.version} - - - io.jsonwebtoken - jjwt - 0.4 - @@ -113,13 +116,13 @@ provided - + com.sun.jersey.contribs jersey-multipart ${jersey.version} - + @@ -127,66 +130,73 @@ guice-multibindings ${guice.version} - - - - - com.github.legman.support - shiro - ${legman.version} - - + ch.qos.logback logback-classic - ${logback.version} - + org.slf4j jcl-over-slf4j ${slf4j.version} - + org.slf4j log4j-over-slf4j ${slf4j.version} - + + + + + net.sf.ehcache + ehcache-core + ${ehcache.version} + + + + + + xml-apis + xml-apis + 1.4.01 + + - + commons-beanutils commons-beanutils - 1.9.2 - + commons-collections commons-collections - 3.2.1 - - - + commons-codec commons-codec 1.9 - + com.google.guava guava ${guava.version} - + org.quartz-scheduler quartz @@ -198,25 +208,67 @@ - - - - - org.apache.httpcomponents - httpclient - 4.2.6 - - + - + + + org.freemarker + freemarker + ${freemarker.version} + + com.github.spullara.mustache.java compiler ${mustache.version} - + + + + + org.eclipse.aether + aether-api + ${aether.version} + + + + org.eclipse.aether + aether-impl + ${aether.version} + + + + org.apache.maven + maven-aether-provider + ${maven.version} + + + plexus-component-annotations + org.codehaus.plexus + + + + + + org.eclipse.aether + aether-transport-http + ${aether.version} + + + + org.eclipse.aether + aether-transport-file + ${aether.version} + + + + org.eclipse.aether + aether-connector-basic + ${aether.version} + + - + com.webcohesion.enunciate enunciate-core-annotations @@ -228,7 +280,7 @@ sonia.scm scm-test - 2.0.0-SNAPSHOT + 1.61-SNAPSHOT test @@ -237,7 +289,31 @@ - + + + sonia.scm.plugins + scm-git-plugin + 1.61-SNAPSHOT + tests + test + + + + sonia.scm.plugins + scm-hg-plugin + 1.61-SNAPSHOT + tests + test + + + + sonia.scm.plugins + scm-svn-plugin + 1.61-SNAPSHOT + tests + test + + org.seleniumhq.selenium selenium-java @@ -251,7 +327,7 @@ ${selenium.version} test - + org.seleniumhq.selenium htmlunit-driver @@ -272,71 +348,23 @@ ${jersey.version} test - - - - + com.github.sdorra shiro-unit 1.0.0 test - - - sonia.scm.plugins - scm-git-plugin - 2.0.0-SNAPSHOT - tests - test - - - - sonia.scm.plugins - scm-git-plugin - 2.0.0-SNAPSHOT - test - - - - sonia.scm.plugins - scm-hg-plugin - 2.0.0-SNAPSHOT - tests - test - - - - sonia.scm.plugins - scm-hg-plugin - 2.0.0-SNAPSHOT - test - - - - sonia.scm.plugins - scm-svn-plugin - 2.0.0-SNAPSHOT - tests - test - - - - sonia.scm.plugins - scm-svn-plugin - 2.0.0-SNAPSHOT - test - - + - + commons-logging commons-logging 1.1.3 provided - + log4j log4j @@ -347,8 +375,9 @@ + - + com.mycila.maven-license-plugin maven-license-plugin @@ -371,6 +400,7 @@ + org.apache.maven.plugins maven-dependency-plugin @@ -388,49 +418,39 @@ - + - sonia.scm.maven - smp-maven-plugin - 1.0.0-alpha-2 - - - - sonia.scm.plugins - scm-hg-plugin - ${project.version} - smp - - - sonia.scm.plugins - scm-svn-plugin - ${project.version} - smp - - - sonia.scm.plugins - scm-git-plugin - ${project.version} - smp - - - sonia.scm.plugins - scm-legacy-plugin - ${project.version} - smp - - - + org.apache.maven.plugins + maven-antrun-plugin + 1.6 + repack compile - copy-core-plugins + run + + + + + + + + + + + + + + + - + org.apache.maven.plugins maven-war-plugin @@ -444,7 +464,7 @@ - + sonia.maven change-env @@ -464,7 +484,7 @@ - org.eclipse.jetty + org.mortbay.jetty jetty-maven-plugin ${jetty.maven.version} @@ -484,14 +504,23 @@ true + + + 8081 + 60000 + 16384 + + /scm - ${project.basedir}/src/main/conf/jetty.xml + ${project.build.javaLevel} + ${project.build.javaLevel} + ${project.build.sourceEncoding} 0 - - + + scm-webapp @@ -503,7 +532,9 @@ default 2.53.1 2.9.1 + 1.1.0 1.0 + 3.3.9 0.8.17 Tomcat e1 @@ -513,7 +544,21 @@ - + + + cluster + + + + + sonia.scm + scm-dao-orientdb + 1.58-SNAPSHOT + + + + + release @@ -594,7 +639,7 @@ - org.eclipse.jetty + org.mortbay.jetty jetty-maven-plugin ${jetty.maven.version} @@ -610,7 +655,16 @@ ${scm.stage} - ${project.basedir}/src/main/conf/jetty.xml + + + 8081 + 60000 + 16384 + + + ${project.build.javaLevel} + ${project.build.javaLevel} + ${project.build.sourceEncoding} 0 true @@ -631,29 +685,29 @@ - + - + selenium - + - + org.apache.httpcomponents httpclient 4.3.2 test - + - + - + org.apache.maven.plugins maven-failsafe-plugin @@ -678,15 +732,12 @@ - + - org.eclipse.jetty + org.mortbay.jetty jetty-maven-plugin ${jetty.maven.version} - - 8082 - 8086 STOP @@ -695,7 +746,16 @@ target/scm-it - ${project.basedir}/src/main/conf/jetty.xml + + + 8082 + 60000 + 16384 + + + ${project.build.javaLevel} + ${project.build.javaLevel} + ${project.build.sourceEncoding} 0 true @@ -716,7 +776,7 @@ - + org.codehaus.mojo selenium-maven-plugin @@ -737,22 +797,22 @@ post-integration-test stop-server - + - + - + - + doc - + - + org.apache.maven.plugins maven-resources-plugin @@ -766,7 +826,7 @@ ${project.build.directory} - + src/main/doc true @@ -774,12 +834,12 @@ **/enunciate.xml - - + + - + com.webcohesion.enunciate enunciate-maven-plugin @@ -811,7 +871,7 @@ - + org.apache.maven.plugins maven-assembly-plugin @@ -830,12 +890,12 @@ - + - + diff --git a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java index 12c30fd152..1b8e0c7803 100644 --- a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java +++ b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java @@ -35,13 +35,15 @@ package sonia.scm; //~--- non-JDK imports -------------------------------------------------------- -import com.google.common.collect.Maps; import com.google.inject.Provider; import com.google.inject.multibindings.Multibinder; import com.google.inject.name.Names; import com.google.inject.servlet.RequestScoped; +import com.google.inject.servlet.ServletModule; import com.google.inject.throwingproviders.ThrowingProviderBinder; +import org.apache.shiro.authz.permission.PermissionResolver; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,6 +52,11 @@ import sonia.scm.cache.CacheManager; import sonia.scm.cache.GuavaCacheManager; import sonia.scm.config.ScmConfiguration; import sonia.scm.event.ScmEventBus; +import sonia.scm.filter.AdminSecurityFilter; +import sonia.scm.filter.BaseUrlFilter; +import sonia.scm.filter.GZipFilter; +import sonia.scm.filter.MDCFilter; +import sonia.scm.filter.SecurityFilter; import sonia.scm.group.DefaultGroupManager; import sonia.scm.group.GroupDAO; import sonia.scm.group.GroupManager; @@ -57,14 +64,20 @@ import sonia.scm.group.GroupManagerProvider; import sonia.scm.group.xml.XmlGroupDAO; import sonia.scm.io.DefaultFileSystem; import sonia.scm.io.FileSystem; +import sonia.scm.net.HttpClient; +import sonia.scm.net.URLHttpClient; import sonia.scm.plugin.DefaultPluginLoader; import sonia.scm.plugin.DefaultPluginManager; +import sonia.scm.plugin.Plugin; import sonia.scm.plugin.PluginLoader; import sonia.scm.plugin.PluginManager; +import sonia.scm.repository.ChangesetViewerUtil; 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.RepositoryBrowserUtil; import sonia.scm.repository.RepositoryDAO; import sonia.scm.repository.RepositoryManager; import sonia.scm.repository.RepositoryManagerProvider; @@ -79,9 +92,15 @@ import sonia.scm.resources.ResourceManager; import sonia.scm.resources.ScriptResourceServlet; import sonia.scm.security.CipherHandler; import sonia.scm.security.CipherUtil; +import sonia.scm.security.ConfigurableLoginAttemptHandler; import sonia.scm.security.DefaultKeyGenerator; import sonia.scm.security.DefaultSecuritySystem; +import sonia.scm.security.EncryptionHandler; import sonia.scm.security.KeyGenerator; +import sonia.scm.security.LoginAttemptHandler; +import sonia.scm.security.MessageDigestEncryptionHandler; +import sonia.scm.security.RepositoryPermissionResolver; +import sonia.scm.security.SecurityContext; import sonia.scm.security.SecuritySystem; import sonia.scm.store.BlobStoreFactory; import sonia.scm.store.ConfigurationEntryStoreFactory; @@ -89,10 +108,16 @@ import sonia.scm.store.DataStoreFactory; import sonia.scm.store.FileBlobStoreFactory; import sonia.scm.store.JAXBConfigurationEntryStoreFactory; import sonia.scm.store.JAXBDataStoreFactory; -import sonia.scm.store.JAXBConfigurationStoreFactory; +import sonia.scm.store.JAXBStoreFactory; +import sonia.scm.store.ListenableStoreFactory; +import sonia.scm.store.StoreFactory; +import sonia.scm.template.DefaultEngine; +import sonia.scm.template.FreemarkerTemplateEngine; +import sonia.scm.template.FreemarkerTemplateHandler; import sonia.scm.template.MustacheTemplateEngine; import sonia.scm.template.TemplateEngine; import sonia.scm.template.TemplateEngineFactory; +import sonia.scm.template.TemplateHandler; import sonia.scm.template.TemplateServlet; import sonia.scm.url.RestJsonUrlProvider; import sonia.scm.url.RestXmlUrlProvider; @@ -108,16 +133,21 @@ import sonia.scm.util.DebugServlet; import sonia.scm.util.ScmConfigurationUtil; import sonia.scm.web.cgi.CGIExecutorFactory; import sonia.scm.web.cgi.DefaultCGIExecutorFactory; +import sonia.scm.web.filter.AutoLoginFilter; import sonia.scm.web.filter.LoggingFilter; import sonia.scm.web.security.AdministrationContext; +import sonia.scm.web.security.ApiBasicAuthenticationFilter; +import sonia.scm.web.security.AuthenticationManager; +import sonia.scm.web.security.BasicSecurityContext; +import sonia.scm.web.security.ChainAuthenticatonManager; import sonia.scm.web.security.DefaultAdministrationContext; +import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ import com.sun.jersey.api.core.PackagesResourceConfig; import com.sun.jersey.api.core.ResourceConfig; import com.sun.jersey.api.json.JSONConfiguration; -import com.sun.jersey.guice.JerseyServletModule; import com.sun.jersey.guice.spi.container.servlet.GuiceContainer; import com.sun.jersey.spi.container.servlet.ServletContainer; @@ -127,10 +157,6 @@ import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; - -import javax.servlet.ServletContext; -import sonia.scm.store.ConfigurationStoreFactory; - import javax.net.ssl.SSLContext; import sonia.scm.net.SSLContextProvider; import sonia.scm.net.ahc.AdvancedHttpClient; @@ -140,16 +166,15 @@ import sonia.scm.net.ahc.JsonContentTransformer; import sonia.scm.net.ahc.XmlContentTransformer; import sonia.scm.schedule.QuartzScheduler; import sonia.scm.schedule.Scheduler; -import sonia.scm.security.ConfigurableLoginAttemptHandler; -import sonia.scm.security.LoginAttemptHandler; import sonia.scm.security.AuthorizationChangedEventProducer; +import sonia.scm.security.XsrfProtectionFilter; import sonia.scm.web.UserAgentParser; /** * * @author Sebastian Sdorra */ -public class ScmServletModule extends JerseyServletModule +public class ScmServletModule extends ServletModule { /** Field description */ @@ -214,15 +239,11 @@ public class ScmServletModule extends JerseyServletModule * Constructs ... * * - * - * @param servletContext * @param pluginLoader * @param overrides */ - ScmServletModule(ServletContext servletContext, - DefaultPluginLoader pluginLoader, ClassOverrides overrides) + ScmServletModule(DefaultPluginLoader pluginLoader, ClassOverrides overrides) { - this.servletContext = servletContext; this.pluginLoader = pluginLoader; this.overrides = overrides; } @@ -242,24 +263,22 @@ public class ScmServletModule extends JerseyServletModule bind(SCMContextProvider.class).toInstance(context); - ScmConfiguration config = getScmConfiguration(); + ScmConfiguration config = getScmConfiguration(context); CipherUtil cu = CipherUtil.getInstance(); - + // bind repository provider ThrowingProviderBinder.create(binder()).bind( RepositoryProvider.class, Repository.class).to( DefaultRepositoryProvider.class).in(RequestScoped.class); - // bind servlet context - bind(ServletContext.class).annotatedWith(Default.class).toInstance( - servletContext); - // bind event api bind(ScmEventBus.class).toInstance(ScmEventBus.getInstance()); // bind core - bind(ConfigurationStoreFactory.class, JAXBConfigurationStoreFactory.class); - bind(ConfigurationEntryStoreFactory.class, JAXBConfigurationEntryStoreFactory.class); + bind(StoreFactory.class, JAXBStoreFactory.class); + bind(ListenableStoreFactory.class, JAXBStoreFactory.class); + bind(ConfigurationEntryStoreFactory.class, + JAXBConfigurationEntryStoreFactory.class); bind(DataStoreFactory.class, JAXBDataStoreFactory.class); bind(BlobStoreFactory.class, FileBlobStoreFactory.class); bind(ScmConfiguration.class).toInstance(config); @@ -272,20 +291,24 @@ public class ScmServletModule extends JerseyServletModule // note CipherUtil uses an other generator bind(KeyGenerator.class).to(DefaultKeyGenerator.class); bind(CipherHandler.class).toInstance(cu.getCipherHandler()); + bind(EncryptionHandler.class, MessageDigestEncryptionHandler.class); bind(FileSystem.class, DefaultFileSystem.class); // bind health check stuff bind(HealthCheckContextListener.class); // bind extensions - pluginLoader.getExtensionProcessor().processAutoBindExtensions(binder()); + pluginLoader.processExtensions(binder()); // bind security stuff - bind(LoginAttemptHandler.class).to(ConfigurableLoginAttemptHandler.class); bind(AuthorizationChangedEventProducer.class); - + bind(PermissionResolver.class, RepositoryPermissionResolver.class); + bind(AuthenticationManager.class, ChainAuthenticatonManager.class); + bind(SecurityContext.class).to(BasicSecurityContext.class); + bind(WebSecurityContext.class).to(BasicSecurityContext.class); bind(SecuritySystem.class).to(DefaultSecuritySystem.class); bind(AdministrationContext.class, DefaultAdministrationContext.class); + bind(LoginAttemptHandler.class, ConfigurableLoginAttemptHandler.class); // bind cache bind(CacheManager.class, GuavaCacheManager.class); @@ -303,10 +326,14 @@ public class ScmServletModule extends JerseyServletModule bindDecorated(GroupManager.class, DefaultGroupManager.class, GroupManagerProvider.class); bind(CGIExecutorFactory.class, DefaultCGIExecutorFactory.class); + bind(ChangesetViewerUtil.class); + bind(RepositoryBrowserUtil.class); // bind sslcontext provider bind(SSLContext.class).toProvider(SSLContextProvider.class); + // bind httpclient + bind(HttpClient.class, URLHttpClient.class); // bind ahc Multibinder transformers = @@ -351,7 +378,24 @@ public class ScmServletModule extends JerseyServletModule { filter(PATTERN_ALL).through(LoggingFilter.class); } + + // protect api agains xsrf attacks + filter(PATTERN_RESTAPI).through(XsrfProtectionFilter.class); + /* + * filter(PATTERN_PAGE, + * PATTERN_STATIC_RESOURCES).through(StaticResourceFilter.class); + */ + filter(PATTERN_ALL).through(BaseUrlFilter.class); + filter(PATTERN_ALL).through(AutoLoginFilter.class); + filterRegex(RESOURCE_REGEX).through(GZipFilter.class); + filter(PATTERN_RESTAPI, PATTERN_DEBUG).through(ApiBasicAuthenticationFilter.class); + filter(PATTERN_RESTAPI, PATTERN_DEBUG).through(SecurityFilter.class); + filter(PATTERN_CONFIG, PATTERN_ADMIN).through(AdminSecurityFilter.class); + + // added mdcs for logging + filter(PATTERN_ALL).through(MDCFilter.class); + // debug servlet serve(PATTERN_DEBUG).with(DebugServlet.class); @@ -359,21 +403,23 @@ public class ScmServletModule extends JerseyServletModule serve(PATTERN_PLUGIN_SCRIPT).with(ScriptResourceServlet.class); // template + bind(TemplateHandler.class).to(FreemarkerTemplateHandler.class); serve(PATTERN_INDEX, "/").with(TemplateServlet.class); Multibinder engineBinder = Multibinder.newSetBinder(binder(), TemplateEngine.class); engineBinder.addBinding().to(MustacheTemplateEngine.class); - bind(TemplateEngine.class).annotatedWith(Default.class).to( + engineBinder.addBinding().to(FreemarkerTemplateEngine.class); + bind(TemplateEngine.class).annotatedWith(DefaultEngine.class).to( MustacheTemplateEngine.class); bind(TemplateEngineFactory.class); // bind events - // bind(LastModifiedUpdateListener.class); + bind(LastModifiedUpdateListener.class); // jersey - Map params = Maps.newHashMap(); + Map params = new HashMap(); /* * params.put("com.sun.jersey.spi.container.ContainerRequestFilters", @@ -386,17 +432,63 @@ 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()); - params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "unbound"); + + String restPath = getRestPackages(); + logger.info("configure jersey with package path: {}", restPath); + + params.put(PackagesResourceConfig.PROPERTY_PACKAGES, restPath); serve(PATTERN_RESTAPI).with(GuiceContainer.class, params); } + /** + * Method description + * + * + * @param packageSet + * @param plugin + */ + private void appendPluginPackages(Set packageSet, Plugin plugin) + { + Set pluginPackageSet = plugin.getPackageSet(); + + if (pluginPackageSet != null) + { + for (String pluginPkg : pluginPackageSet) + { + boolean append = true; + + for (String pkg : packageSet) + { + if (pluginPkg.startsWith(pkg)) + { + append = false; + + break; + } + } + + if (append) + { + if (logger.isDebugEnabled()) + { + String name = "unknown"; + + if (plugin.getInformation() != null) + { + name = plugin.getInformation().getName(); + } + + logger.debug("plugin {} added rest path {}", name, pluginPkg); + } + + packageSet.add(pluginPkg); + } + } + } + } + /** * Method description * @@ -484,6 +576,44 @@ public class ScmServletModule extends JerseyServletModule //~--- get methods ---------------------------------------------------------- + /** + * Method description + * + * + * @return + */ + private String getRestPackages() + { + Set packageSet = new HashSet(); + + packageSet.add(SCMContext.DEFAULT_PACKAGE); + + Collection plugins = pluginLoader.getInstalledPlugins(); + + if (plugins != null) + { + for (Plugin plugin : plugins) + { + appendPluginPackages(packageSet, plugin); + } + } + + StringBuilder buffer = new StringBuilder(); + Iterator pkgIterator = packageSet.iterator(); + + while (pkgIterator.hasNext()) + { + buffer.append(pkgIterator.next()); + + if (pkgIterator.hasNext()) + { + buffer.append(";"); + } + } + + return buffer.toString(); + } + /** * Load ScmConfiguration with JAXB * @@ -492,7 +622,7 @@ public class ScmServletModule extends JerseyServletModule * * @return */ - private ScmConfiguration getScmConfiguration() + private ScmConfiguration getScmConfiguration(SCMContextProvider context) { ScmConfiguration configuration = new ScmConfiguration(); @@ -504,11 +634,8 @@ public class ScmServletModule extends JerseyServletModule //~--- fields --------------------------------------------------------------- /** Field description */ - private final ClassOverrides overrides; + private ClassOverrides overrides; /** Field description */ - private final DefaultPluginLoader pluginLoader; - - /** Field description */ - private final ServletContext servletContext; + private DefaultPluginLoader pluginLoader; } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/TemplateEngineViewable.java b/scm-webapp/src/main/java/sonia/scm/api/rest/TemplateEngineViewable.java index b36cf6c7e7..4a089ab150 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/TemplateEngineViewable.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/TemplateEngineViewable.java @@ -42,50 +42,65 @@ import sonia.scm.template.TemplateEngineFactory; //~--- JDK imports ------------------------------------------------------------ +import com.sun.jersey.api.view.Viewable; +import com.sun.jersey.spi.template.ViewProcessor; + import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; -import sonia.scm.template.Viewable; /** * * @author Sebastian Sdorra */ @Provider -public class TemplateEngineViewable implements MessageBodyWriter +public class TemplateEngineViewable implements ViewProcessor { - - private final TemplateEngineFactory templateEngineFactory; + /** + * Constructs ... + * + * + * @param templateEngineFactory + */ @Inject public TemplateEngineViewable(TemplateEngineFactory templateEngineFactory) { this.templateEngineFactory = templateEngineFactory; } + //~--- methods -------------------------------------------------------------- + /** + * Method description + * + * + * @param name + * + * @return + */ @Override - public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { - return type.isAssignableFrom(Viewable.class); + public String resolve(String name) + { + return name; } + /** + * Method description + * + * + * @param path + * @param viewable + * @param out + * + * @throws IOException + */ @Override - public long getSize(Viewable viewable, Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { - return -1; - } - - @Override - public void writeTo(Viewable viewable, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { - String path = viewable.getPath(); - + public void writeTo(String path, Viewable viewable, OutputStream out) + throws IOException + { TemplateEngine engine = templateEngineFactory.getEngineByExtension(path); if (engine == null) @@ -100,9 +115,14 @@ public class TemplateEngineViewable implements MessageBodyWriter throw new IOException("could not find template for ".concat(path)); } - PrintWriter writer = new PrintWriter(entityStream); + PrintWriter writer = new PrintWriter(out); - template.execute(writer, viewable.getContext()); + template.execute(writer, viewable.getModel()); writer.flush(); } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private TemplateEngineFactory templateEngineFactory; } diff --git a/scm-core/src/main/java/sonia/scm/template/Viewable.java b/scm-webapp/src/main/java/sonia/scm/api/rest/UriExtensionsConfig.java similarity index 52% rename from scm-core/src/main/java/sonia/scm/template/Viewable.java rename to scm-webapp/src/main/java/sonia/scm/api/rest/UriExtensionsConfig.java index 8344d2820e..637866ad61 100644 --- a/scm-core/src/main/java/sonia/scm/template/Viewable.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/UriExtensionsConfig.java @@ -28,63 +28,89 @@ * http://bitbucket.org/sdorra/scm-manager * */ -package sonia.scm.template; -import com.google.common.base.Objects; +package sonia.scm.api.rest; + +//~--- JDK imports ------------------------------------------------------------ + +import com.sun.jersey.api.core.PackagesResourceConfig; + +import java.util.HashMap; +import java.util.Map; + +import javax.ws.rs.core.MediaType; + /** - * A viewable holds the path to a template and the context object which is used to render the template. Viewables can - * be used as return type of jax-rs resources. - * + * * @author Sebastian Sdorra - * @since 2.0.0 */ -public final class Viewable { - - private final String path; - private final Object context; +public class UriExtensionsConfig extends PackagesResourceConfig +{ - public Viewable(String path, Object context) { - this.path = path; - this.context = context; + /** Field description */ + public static final String EXTENSION_JSON = "json"; + + /** Field description */ + public static final String EXTENSION_XML = "xml"; + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + */ + public UriExtensionsConfig() + { + super(); } - public String getPath() { - return path; + /** + * Constructs ... + * + * + * @param props + */ + public UriExtensionsConfig(Map props) + { + super(props); } - public Object getContext() { - return context; + /** + * Constructs ... + * + * + * @param paths + */ + public UriExtensionsConfig(String[] paths) + { + super(paths); } + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ @Override - public int hashCode() { - return Objects.hashCode(path, context); + public Map getMediaTypeMappings() + { + if (mediaTypeMap == null) + { + mediaTypeMap = new HashMap(); + mediaTypeMap.put(EXTENSION_JSON, MediaType.APPLICATION_JSON_TYPE); + mediaTypeMap.put(EXTENSION_XML, MediaType.APPLICATION_XML_TYPE); + } + + return mediaTypeMap; } - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final Viewable other = (Viewable) obj; - return !Objects.equal(this.path, other.path) - && Objects.equal(this.context, other.context); - } + //~--- fields --------------------------------------------------------------- - @Override - public String toString() { - return Objects.toStringHelper(this) - .add("path", path) - .add("context", context) - .toString(); - } - + /** Field description */ + private Map mediaTypeMap; } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractPermissionResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractPermissionResource.java index 040eb6b2dc..e9e63d16d8 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractPermissionResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractPermissionResource.java @@ -133,7 +133,7 @@ public abstract class AbstractPermissionResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public Response add(@Context UriInfo uriInfo, Permission permission) { AssignedPermission ap = transformPermission(permission); @@ -185,7 +185,7 @@ public abstract class AbstractPermissionResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public Response update(@PathParam("id") String id, Permission permission) { StoredAssignedPermission sap = getPermission(id); @@ -213,7 +213,7 @@ public abstract class AbstractPermissionResource @ResponseCode(code = 404, condition = "not found, no permission with the specified id available"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public Permission get(@PathParam("id") String id) { StoredAssignedPermission sap = getPermission(id); @@ -231,7 +231,7 @@ public abstract class AbstractPermissionResource @ResponseCode(code = 204, condition = "success"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public List getAll() { return getPermissions(getPredicate()); diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ChangePasswordResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ChangePasswordResource.java index 87626c7045..52b8b02c37 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ChangePasswordResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ChangePasswordResource.java @@ -118,7 +118,7 @@ public class ChangePasswordResource @ResponseCode(code = 400, condition = "bad request, the old password is not correct"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public Response changePassword(@FormParam("old-password") String oldPassword, @FormParam("new-password") String newPassword) throws UserException, IOException diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ConfigurationResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ConfigurationResource.java index a9beea7679..2fb6bdda3d 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ConfigurationResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ConfigurationResource.java @@ -89,7 +89,7 @@ public class ConfigurationResource * @return */ @GET - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public Response getConfiguration() { Response response = null; @@ -118,7 +118,7 @@ public class ConfigurationResource * @return */ @POST - @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public Response setConfig(@Context UriInfo uriInfo, ScmConfiguration newConfig) { diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java index dd61f0aecb..808aaa498b 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java @@ -119,7 +119,7 @@ public class GroupResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @Override public Response create(@Context UriInfo uriInfo, Group group) { @@ -164,7 +164,7 @@ public class GroupResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @Override public Response update(@Context UriInfo uriInfo, @PathParam("id") String name, Group group) @@ -191,7 +191,7 @@ public class GroupResource @ResponseCode(code = 404, condition = "not found, no group with the specified id/name available"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @Override public Response get(@Context Request request, @PathParam("id") String id) { @@ -221,7 +221,7 @@ public class GroupResource * @return */ @GET - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @TypeHint(Group[].class) @StatusCodes({ @ResponseCode(code = 200, condition = "success"), diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/PluginResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/PluginResource.java index fda978b3fe..54c9369a57 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/PluginResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/PluginResource.java @@ -52,6 +52,7 @@ import sonia.scm.plugin.PluginInformationComparator; //~--- JDK imports ------------------------------------------------------------ +import com.sun.jersey.multipart.FormDataParam; import com.webcohesion.enunciate.metadata.rs.ResponseCode; import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.TypeHint; @@ -65,7 +66,6 @@ import java.util.Iterator; import java.util.List; import javax.ws.rs.Consumes; -import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; @@ -124,9 +124,9 @@ public class PluginResource @ResponseCode(code = 500, condition = "internal server error") }) @Consumes(MediaType.MULTIPART_FORM_DATA) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public Response install( - /*@FormParam("package")*/ InputStream uploadedInputStream) + @FormDataParam("package") InputStream uploadedInputStream) throws IOException { Response response = null; @@ -194,7 +194,7 @@ public class PluginResource @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.TEXT_HTML) public Response installFromUI( - /*@FormParam("package")*/ InputStream uploadedInputStream) + @FormDataParam("package") InputStream uploadedInputStream) throws IOException { return install(uploadedInputStream); @@ -257,7 +257,7 @@ public class PluginResource @ResponseCode(code = 200, condition = "success"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public Collection getAll() { return pluginManager.getAll(); @@ -274,7 +274,7 @@ public class PluginResource @ResponseCode(code = 200, condition = "success"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public Collection getAvailable() { return pluginManager.getAvailable(); @@ -291,7 +291,7 @@ public class PluginResource @ResponseCode(code = 200, condition = "success"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public Collection getAvailableUpdates() { return pluginManager.getAvailableUpdates(); @@ -325,7 +325,7 @@ public class PluginResource @ResponseCode(code = 200, condition = "success"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public Collection getOverview() { //J- diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java index 9c01e3d4a8..9382f58c5c 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java @@ -69,6 +69,8 @@ import static com.google.common.base.Preconditions.*; //~--- JDK imports ------------------------------------------------------------ +import com.sun.jersey.api.client.ClientResponse.Status; +import com.sun.jersey.multipart.FormDataParam; import com.webcohesion.enunciate.metadata.rs.ResponseCode; import com.webcohesion.enunciate.metadata.rs.ResponseHeader; import com.webcohesion.enunciate.metadata.rs.StatusCodes; @@ -87,7 +89,6 @@ import java.util.Set; import javax.ws.rs.Consumes; import javax.ws.rs.DefaultValue; -import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; @@ -110,7 +111,7 @@ import javax.xml.bind.annotation.XmlRootElement; * * @author Sebastian Sdorra */ -// @Path("import/repositories") +@Path("import/repositories") public class RepositoryImportResource { @@ -169,8 +170,8 @@ public class RepositoryImportResource @TypeHint(TypeHint.NO_CONTENT.class) @Consumes(MediaType.MULTIPART_FORM_DATA) public Response importFromBundle(@Context UriInfo uriInfo, - @PathParam("type") String type, @FormParam("name") String name, - @FormParam("bundle") InputStream inputStream, @QueryParam("compressed") + @PathParam("type") String type, @FormDataParam("name") String name, + @FormDataParam("bundle") InputStream inputStream, @QueryParam("compressed") @DefaultValue("false") boolean compressed) { Repository repository = doImportFromBundle(type, name, inputStream, @@ -210,8 +211,8 @@ public class RepositoryImportResource @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.TEXT_HTML) public Response importFromBundleUI(@PathParam("type") String type, - @FormParam("name") String name, - @FormParam("bundle") InputStream inputStream, @QueryParam("compressed") + @FormDataParam("name") String name, + @FormDataParam("bundle") InputStream inputStream, @QueryParam("compressed") @DefaultValue("false") boolean compressed) { Response response; @@ -259,7 +260,7 @@ public class RepositoryImportResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public Response importFromUrl(@Context UriInfo uriInfo, @PathParam("type") String type, UrlImportRequest request) { @@ -319,7 +320,7 @@ public class RepositoryImportResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(Repository[].class) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public Response importRepositories(@PathParam("type") String type) { SecurityUtils.getSubject().checkRole(Role.ADMIN); @@ -351,7 +352,7 @@ public class RepositoryImportResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(Repository[].class) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public Response importRepositories() { SecurityUtils.getSubject().checkRole(Role.ADMIN); @@ -393,7 +394,7 @@ public class RepositoryImportResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(ImportResult.class) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public Response importRepositoriesFromDirectory( @PathParam("type") String type) { @@ -434,7 +435,7 @@ public class RepositoryImportResource .warn( "import feature is not supported by repository handler for type " .concat(type), ex); - response = Response.status(Response.Status.BAD_REQUEST).build(); + response = Response.status(Status.BAD_REQUEST).build(); } catch (IOException ex) { @@ -450,7 +451,7 @@ public class RepositoryImportResource else { logger.warn("could not find reposiotry handler for type {}", type); - response = Response.status(Response.Status.BAD_REQUEST).build(); + response = Response.status(Status.BAD_REQUEST).build(); } return response; @@ -474,7 +475,7 @@ public class RepositoryImportResource ), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public Response getImportableTypes() { SecurityUtils.getSubject().checkRole(Role.ADMIN); diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java index e9f7812ee0..16168aefc7 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java @@ -166,7 +166,7 @@ public class RepositoryResource extends AbstractManagerResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @Override public Response create(@Context UriInfo uriInfo, User user) { @@ -170,7 +170,7 @@ public class UserResource extends AbstractManagerResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @Override public Response update(@Context UriInfo uriInfo, @PathParam("id") String name, User user) @@ -197,7 +197,7 @@ public class UserResource extends AbstractManagerResource @ResponseCode(code = 404, condition = "not found, no group with the specified id/name available"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @Override public Response get(@Context Request request, @PathParam("id") String id) { @@ -233,7 +233,7 @@ public class UserResource extends AbstractManagerResource @ResponseCode(code = 403, condition = "forbidden, the current user has no admin privileges"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @Override public Response getAll(@Context Request request, @DefaultValue("0") @QueryParam("start") int start, @DefaultValue("-1") diff --git a/scm-webapp/src/main/java/sonia/scm/debug/DebugResource.java b/scm-webapp/src/main/java/sonia/scm/debug/DebugResource.java index 0933242b49..f65e0c7708 100644 --- a/scm-webapp/src/main/java/sonia/scm/debug/DebugResource.java +++ b/scm-webapp/src/main/java/sonia/scm/debug/DebugResource.java @@ -67,7 +67,7 @@ public final class DebugResource * @return all received hook data for the given repository */ @GET - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public Collection getAll(@PathParam("repository") String repository){ return debugService.getAll(repository); } @@ -81,7 +81,7 @@ public final class DebugResource */ @GET @Path("last") - @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public DebugHookData getLast(@PathParam("repository") String repository){ return debugService.getLast(repository); } diff --git a/scm-webapp/src/main/java/sonia/scm/net/ahc/JsonContentTransformer.java b/scm-webapp/src/main/java/sonia/scm/net/ahc/JsonContentTransformer.java index 2998f82890..5e61ed6965 100644 --- a/scm-webapp/src/main/java/sonia/scm/net/ahc/JsonContentTransformer.java +++ b/scm-webapp/src/main/java/sonia/scm/net/ahc/JsonContentTransformer.java @@ -33,16 +33,14 @@ package sonia.scm.net.ahc; //~--- non-JDK imports -------------------------------------------------------- -import com.fasterxml.jackson.databind.AnnotationIntrospector; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair; -import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; -import com.fasterxml.jackson.databind.type.TypeFactory; -import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector; - import com.google.common.io.ByteSource; +import org.codehaus.jackson.map.AnnotationIntrospector; +import org.codehaus.jackson.map.DeserializationConfig; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.introspect.JacksonAnnotationIntrospector; +import org.codehaus.jackson.xc.JaxbAnnotationIntrospector; + import sonia.scm.plugin.ext.Extension; import sonia.scm.util.IOUtil; @@ -75,12 +73,12 @@ public class JsonContentTransformer implements ContentTransformer // allow jackson and jaxb annotations AnnotationIntrospector jackson = new JacksonAnnotationIntrospector(); - AnnotationIntrospector jaxb = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance()); + AnnotationIntrospector jaxb = new JaxbAnnotationIntrospector(); - this.mapper.setAnnotationIntrospector(new AnnotationIntrospectorPair(jackson, jaxb)); + this.mapper.setAnnotationIntrospector(new AnnotationIntrospector.Pair(jackson, jaxb)); // do not fail on unknown json properties - this.mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + this.mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); } //~--- methods -------------------------------------------------------------- diff --git a/scm-webapp/src/main/resources/logback.default.xml b/scm-webapp/src/main/resources/logback.default.xml index bf18f02893..318cd6112a 100644 --- a/scm-webapp/src/main/resources/logback.default.xml +++ b/scm-webapp/src/main/resources/logback.default.xml @@ -90,8 +90,6 @@ - - diff --git a/scm-webapp/src/main/webapp/WEB-INF/web.xml b/scm-webapp/src/main/webapp/WEB-INF/web.xml index 8a54ee72cd..513c708e80 100644 --- a/scm-webapp/src/main/webapp/WEB-INF/web.xml +++ b/scm-webapp/src/main/webapp/WEB-INF/web.xml @@ -40,7 +40,7 @@ SCM-Manager ${project.version} - sonia.scm.boot.BootstrapContextListener + sonia.scm.boot.BootstrapListener @@ -48,45 +48,15 @@ - BootstrapFilter - sonia.scm.boot.BootstrapContextFilter + guiceFilter + sonia.scm.boot.BootstrapFilter - BootstrapFilter + guiceFilter /* - - - - resteasy.servlet.mapping.prefix - /api/rest - - - - Resteasy - - org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher - - - - - Resteasy - /api/rest/* - - - - - - - sonia.scm.HttpSessionListenerHolder - - - - index.html diff --git a/scm-webapp/src/main/webapp/resources/js/action/sonia.action.changepasswordwindow.js b/scm-webapp/src/main/webapp/resources/js/action/sonia.action.changepasswordwindow.js index 3d044d69c5..b1c0a5372f 100644 --- a/scm-webapp/src/main/webapp/resources/js/action/sonia.action.changepasswordwindow.js +++ b/scm-webapp/src/main/webapp/resources/js/action/sonia.action.changepasswordwindow.js @@ -55,7 +55,7 @@ Sonia.action.ChangePasswordWindow = Ext.extend(Ext.Window,{ title: this.titleText, items: [{ id: 'changePasswordForm', - url: restUrl + 'action/change-password', + url: restUrl + 'action/change-password.json', frame: true, xtype: 'form', monitorValid: true, diff --git a/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js b/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js index 0f9c2fdd57..a985688a3e 100644 --- a/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js @@ -261,7 +261,7 @@ Sonia.config.ScmConfigPanel = Ext.extend(Sonia.config.ConfigPanel,{ onSubmit: function(values){ this.el.mask(this.submitText); Ext.Ajax.request({ - url: restUrl + 'config', + url: restUrl + 'config.json', method: 'POST', jsonData: values, scope: this, @@ -283,7 +283,7 @@ Sonia.config.ScmConfigPanel = Ext.extend(Sonia.config.ConfigPanel,{ onLoad: function(el){ var tid = setTimeout( function(){ el.mask(this.loadingText); }, 100); Ext.Ajax.request({ - url: restUrl + 'config', + url: restUrl + 'config.json', method: 'GET', scope: this, disableCaching: true, diff --git a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.formpanel.js b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.formpanel.js index 4ec278bf6b..5d560d9717 100644 --- a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.formpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.formpanel.js @@ -59,7 +59,7 @@ Sonia.group.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ // this.updateMembers(group); this.fireEvent('preUpdate', group); - var url = restUrl + 'groups/' + encodeURIComponent(group.name); + var url = restUrl + 'groups/' + encodeURIComponent(group.name) + '.json'; var el = this.el; var tid = setTimeout( function(){el.mask('Loading ...');}, 100); @@ -96,7 +96,7 @@ Sonia.group.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ } item.type = state.defaultUserType; - var url = restUrl + 'groups'; + var url = restUrl + 'groups.json'; var el = this.el; var tid = setTimeout( function(){el.mask('Loading ...');}, 100); diff --git a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js index 1bc3fbe819..18d3841fc2 100644 --- a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js +++ b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js @@ -95,7 +95,7 @@ Sonia.group.Panel = Ext.extend(Sonia.rest.Panel, { var selected = grid.getSelectionModel().getSelected(); if ( selected ){ var item = selected.data; - var url = restUrl + 'groups/' + encodeURIComponent(item.name); + var url = restUrl + 'groups/' + encodeURIComponent(item.name) + '.json'; Ext.MessageBox.show({ title: this.removeTitleText, diff --git a/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js b/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js index 19ad6d0e15..b27f2484b4 100644 --- a/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js +++ b/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js @@ -41,6 +41,7 @@ Sonia.login.Form = Ext.extend(Ext.FormPanel,{ failedDescriptionText: 'Incorrect username, password or not enough permission. Please Try again.', accountLockedText: 'Account is locked.', accountTemporaryLockedText: 'Account is temporary locked. Please try again later.', + rememberMeText: 'Remember me', initComponent: function(){ var buttons = []; @@ -93,14 +94,11 @@ Sonia.login.Form = Ext.extend(Ext.FormPanel,{ scope: this } } - }, { - name: 'grant_type', - value: 'password', - xtype: 'hidden' - }, { - name: 'cookie', - value: 'true', - xtype: 'hidden' + },{ + xtype: 'checkbox', + fieldLabel: this.rememberMeText, + name: 'rememberMe', + inputValue: 'true' }], buttons: buttons }; @@ -118,7 +116,6 @@ Sonia.login.Form = Ext.extend(Ext.FormPanel,{ authenticate: function(){ var form = this.getForm(); - form.submit({ scope: this, method: 'POST', diff --git a/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.center.js b/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.center.js index ebd2119886..11113e2601 100644 --- a/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.center.js +++ b/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.center.js @@ -81,7 +81,7 @@ Sonia.plugin.Center = Ext.extend(Ext.util.Observable, { var loadingBox = this.createLoadingBox( this.installWaitMsgText ); Ext.Ajax.request({ - url: restUrl + 'plugins/install/' + pluginId, + url: restUrl + 'plugins/install/' + pluginId + '.json', method: 'POST', scope: this, timeout: 300000, // 5min @@ -116,7 +116,7 @@ Sonia.plugin.Center = Ext.extend(Ext.util.Observable, { var loadingBox = this.createLoadingBox( this.uninstallWaitMsgText ); Ext.Ajax.request({ - url: restUrl + 'plugins/uninstall/' + pluginId, + url: restUrl + 'plugins/uninstall/' + pluginId + '.json', method: 'POST', scope: this, success: function(){ @@ -150,7 +150,7 @@ Sonia.plugin.Center = Ext.extend(Ext.util.Observable, { var loadingBox = this.createLoadingBox( this.updateWaitMsgText ); Ext.Ajax.request({ - url: restUrl + 'plugins/update/' + pluginId, + url: restUrl + 'plugins/update/' + pluginId + '.json', method: 'POST', scope: this, timeout: 300000, // 5min diff --git a/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.grid.js b/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.grid.js index 5f44e51ebc..cb5ea6bec1 100644 --- a/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.grid.js +++ b/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.grid.js @@ -81,7 +81,7 @@ Sonia.plugin.Grid = Ext.extend(Sonia.rest.Grid, { var pluginStore = new Ext.data.GroupingStore({ proxy: new Ext.data.HttpProxy({ - url: restUrl + 'plugins/overview', + url: restUrl + 'plugins/overview.json', disableCaching: false }), reader: new Ext.data.JsonReader({ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.branchcombobox.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.branchcombobox.js index 4c3dcbc7c8..cddcad4552 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.branchcombobox.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.branchcombobox.js @@ -38,7 +38,7 @@ Sonia.repository.BranchComboBox = Ext.extend(Ext.form.ComboBox, { initComponent: function(){ var branchStore = new Sonia.rest.JsonStore({ proxy: new Ext.data.HttpProxy({ - url: restUrl + 'repositories/' + this.repositoryId + '/branches', + url: restUrl + 'repositories/' + this.repositoryId + '/branches.json', method: 'GET', disableCaching: false }), diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewerpanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewerpanel.js index 468b99dbec..aa18d29e0d 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewerpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewerpanel.js @@ -46,7 +46,7 @@ Sonia.repository.ChangesetViewerPanel = Ext.extend(Ext.Panel, { initComponent: function(){ if (! this.url){ - this.url = restUrl + 'repositories/' + this.repository.id + '/changesets'; + this.url = restUrl + 'repositories/' + this.repository.id + '/changesets.json'; } if ( ! this.startLimit ){ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.commitpanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.commitpanel.js index 591d77d43f..7b72c4fca3 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.commitpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.commitpanel.js @@ -131,7 +131,7 @@ Sonia.repository.CommitPanel = Ext.extend(Ext.Panel, { } Ext.Ajax.request({ - url: restUrl + 'repositories/' + this.repository.id + '/changeset/' + this.revision, + url: restUrl + 'repositories/' + this.repository.id + '/changeset/' + this.revision + '.json', method: 'GET', scope: this, success: function(response){ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.formpanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.formpanel.js index 422a81ce6b..66482399ac 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.formpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.formpanel.js @@ -73,7 +73,7 @@ Sonia.repository.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ if ( debug ){ console.debug( 'update repository: ' + item.name ); } - var url = restUrl + 'repositories/' + item.id; + var url = restUrl + 'repositories/' + item.id + '.json'; var el = this.el; var tid = setTimeout( function(){el.mask('Loading ...');}, 100); @@ -124,7 +124,7 @@ Sonia.repository.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ if ( debug ){ console.debug( 'create repository: ' + item.name ); } - var url = restUrl + 'repositories'; + var url = restUrl + 'repositories.json'; var el = this.el; var tid = setTimeout( function(){el.mask('Loading ...');}, 100); diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js index 9e2f76f607..fb66b91a5a 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js @@ -71,7 +71,7 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, { var repositoryStore = new Ext.data.GroupingStore({ proxy: new Ext.data.HttpProxy({ - url: restUrl + 'repositories', + url: restUrl + 'repositories.json', disableCaching: false }), idProperty: 'id', diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.healthcheckfailure.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.healthcheckfailure.js index 076f73e712..195d7d7509 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.healthcheckfailure.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.healthcheckfailure.js @@ -75,7 +75,7 @@ Sonia.repository.HealthCheckFailure = Ext.extend(Ext.Panel, { }, rerunHealthChecks: function(){ - var url = restUrl + 'repositories/' + this.repository.id + '/healthcheck'; + var url = restUrl + 'repositories/' + this.repository.id + '/healthcheck.json'; var el = this.el; var tid = setTimeout( function(){el.mask('Loading ...');}, 100); diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js index ac6bbc2206..209b554e82 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js @@ -514,7 +514,7 @@ Sonia.repository.ImportPanel = Ext.extend(Ext.Panel, { importFromUrl: function(layout, repository){ var lbox = this.showLoadingBox(); Ext.Ajax.request({ - url: restUrl + 'import/repositories/' + this.repositoryType + '/url', + url: restUrl + 'import/repositories/' + this.repositoryType + '/url.json', method: 'POST', scope: this, timeout: 300000, // 5min @@ -533,7 +533,7 @@ Sonia.repository.ImportPanel = Ext.extend(Ext.Panel, { importFromDirectory: function(layout){ var lbox = this.showLoadingBox(); Ext.Ajax.request({ - url: restUrl + 'import/repositories/' + this.repositoryType + '/directory', + url: restUrl + 'import/repositories/' + this.repositoryType + '/directory.json', timeout: 300000, // 5min method: 'POST', scope: this, diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js index e978c0ffe9..7e10a58f4e 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js @@ -181,7 +181,7 @@ Sonia.repository.get = function(id, callback){ execCallback(repository); } else { Ext.Ajax.request({ - url: restUrl + 'repositories/' + id, + url: restUrl + 'repositories/' + id + '.json', method: 'GET', scope: this, success: function(response){ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js index 767c294242..17a301509a 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js @@ -311,7 +311,7 @@ Sonia.repository.Panel = Ext.extend(Sonia.rest.Panel, { console.debug('toggle repository ' + item.name + ' archive to ' + item.archived); } - var url = restUrl + 'repositories/' + item.id; + var url = restUrl + 'repositories/' + item.id + '.json'; this.executeRemoteCall(title, String.format(msg, item.name), 'PUT', url, item, function(result){ main.handleFailure( @@ -331,7 +331,7 @@ Sonia.repository.Panel = Ext.extend(Sonia.rest.Panel, { console.debug( 'remove repository ' + item.name ); } - var url = restUrl + 'repositories/' + item.id; + var url = restUrl + 'repositories/' + item.id + '.json'; this.executeRemoteCall(this.removeTitleText, String.format(this.removeMsgText, item.name), 'DELETE', url, null, function(result){ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 59677cab7e..489dd3c06c 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -58,7 +58,7 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { var browserStore = new Sonia.rest.JsonStore({ proxy: new Ext.data.HttpProxy({ - url: restUrl + 'repositories/' + this.repository.id, + url: restUrl + 'repositories/' + this.repository.id + '/browse.json', method: 'GET' }), fields: ['path', 'name', 'length', 'lastModified', 'directory', 'description', 'subrepository'], diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.tagcombobox.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.tagcombobox.js index 5af3cc97f1..3f045a8cf6 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.tagcombobox.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.tagcombobox.js @@ -37,7 +37,7 @@ Sonia.repository.TagComboBox = Ext.extend(Ext.form.ComboBox, { initComponent: function(){ var tagStore = new Sonia.rest.JsonStore({ proxy: new Ext.data.HttpProxy({ - url: restUrl + 'repositories/' + this.repositoryId + '/tags', + url: restUrl + 'repositories/' + this.repositoryId + '/tags.json', method: 'GET', disableCaching: false }), diff --git a/scm-webapp/src/main/webapp/resources/js/security/sonia.security.permissionspanel.js b/scm-webapp/src/main/webapp/resources/js/security/sonia.security.permissionspanel.js index 676114fc78..5ea8855251 100644 --- a/scm-webapp/src/main/webapp/resources/js/security/sonia.security.permissionspanel.js +++ b/scm-webapp/src/main/webapp/resources/js/security/sonia.security.permissionspanel.js @@ -53,7 +53,7 @@ Sonia.security.PermissionsPanel = Ext.extend(Ext.Panel, { this.permissionStore = new Sonia.rest.JsonStore({ proxy: new Ext.data.HttpProxy({ api: { - read: restUrl + this.baseUrl + read: restUrl + this.baseUrl + '.json' }, disableCaching: false }), @@ -179,7 +179,7 @@ Sonia.security.PermissionsPanel = Ext.extend(Ext.Panel, { addPermission: function(record){ Ext.Ajax.request({ - url: restUrl + this.baseUrl, + url: restUrl + this.baseUrl + '.json', method: 'POST', jsonData: record.data, scope: this, @@ -194,7 +194,7 @@ Sonia.security.PermissionsPanel = Ext.extend(Ext.Panel, { modifyPermission: function(id, record){ Ext.Ajax.request({ - url: restUrl + this.baseUrl + '/' + encodeURIComponent(id), + url: restUrl + this.baseUrl + '/' + encodeURIComponent(id) + '.json', method: 'PUT', jsonData: record.data, scope: this, @@ -207,7 +207,7 @@ Sonia.security.PermissionsPanel = Ext.extend(Ext.Panel, { removePermission: function(store, record){ Ext.Ajax.request({ - url: restUrl + this.baseUrl + '/' + encodeURIComponent(record.get('id')), + url: restUrl + this.baseUrl + '/' + encodeURIComponent(record.get('id')) + '.json', method: 'DELETE', scope: this, success: function(){ diff --git a/scm-webapp/src/main/webapp/resources/js/sonia.global.js b/scm-webapp/src/main/webapp/resources/js/sonia.global.js index 98299546b1..a43feb824b 100644 --- a/scm-webapp/src/main/webapp/resources/js/sonia.global.js +++ b/scm-webapp/src/main/webapp/resources/js/sonia.global.js @@ -83,7 +83,7 @@ var userSearchStore = new Ext.data.JsonStore({ idProperty: 'value', fields: ['value','label'], proxy: new Ext.data.HttpProxy({ - url: restUrl + 'search/users', + url: restUrl + 'search/users.json', method: 'GET' }) }); @@ -93,7 +93,7 @@ var groupSearchStore = new Ext.data.JsonStore({ idProperty: 'value', fields: ['value','label'], proxy: new Ext.data.HttpProxy({ - url: restUrl + 'search/groups', + url: restUrl + 'search/groups.json', method: 'GET' }) }); diff --git a/scm-webapp/src/main/webapp/resources/js/sonia.scm.js b/scm-webapp/src/main/webapp/resources/js/sonia.scm.js index db92a77d60..6d7e6a3257 100644 --- a/scm-webapp/src/main/webapp/resources/js/sonia.scm.js +++ b/scm-webapp/src/main/webapp/resources/js/sonia.scm.js @@ -689,4 +689,4 @@ Ext.onReady(function(){ main.init(); main.checkLogin(); -}); +}); \ No newline at end of file diff --git a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.formpanel.js b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.formpanel.js index e8a03e5966..6ef00e73d7 100644 --- a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.formpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.formpanel.js @@ -129,7 +129,7 @@ Sonia.user.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ console.debug( 'update user: ' + item.name ); } this.fixRequest(item); - var url = restUrl + 'users/' + encodeURIComponent(item.name); + var url = restUrl + 'users/' + encodeURIComponent(item.name) + '.json'; Ext.Ajax.request({ url: url, jsonData: item, @@ -159,7 +159,7 @@ Sonia.user.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ this.fixRequest(user); // set user type user.type = state.defaultUserType; - var url = restUrl + 'users'; + var url = restUrl + 'users.json'; Ext.Ajax.request({ url: url, jsonData: user, diff --git a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.grid.js b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.grid.js index b671e67bdc..c44d336ba9 100644 --- a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.grid.js +++ b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.grid.js @@ -49,7 +49,7 @@ Sonia.user.Grid = Ext.extend(Sonia.rest.Grid, { var userStore = new Sonia.rest.JsonStore({ proxy: new Ext.data.HttpProxy({ - url: restUrl + 'users', + url: restUrl + 'users.json', disableCaching: false }), idProperty: 'name', diff --git a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.panel.js b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.panel.js index 0ca0fd78e1..8e98c645df 100644 --- a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.panel.js +++ b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.panel.js @@ -126,7 +126,7 @@ Sonia.user.Panel = Ext.extend(Sonia.rest.Panel, { var selected = grid.getSelectionModel().getSelected(); if ( selected ){ var item = selected.data; - var url = restUrl + 'users/' + encodeURIComponent(item.name); + var url = restUrl + 'users/' + encodeURIComponent(item.name) + '.json'; Ext.MessageBox.show({ title: this.removeTitleText, diff --git a/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java b/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java index 33e020f85d..f8adb90ff1 100644 --- a/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java +++ b/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java @@ -32,9 +32,6 @@ package sonia.scm.it; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.type.TypeFactory; -import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector; import com.google.common.base.Charsets; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.UniformInterfaceException; @@ -44,6 +41,8 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; import org.apache.shiro.crypto.hash.Sha256Hash; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.xc.JaxbAnnotationIntrospector; import org.hamcrest.Matchers; import org.junit.After; import org.junit.Test; @@ -82,7 +81,7 @@ public class GitLfsITCase { private Repository repository; public GitLfsITCase() { - mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector(TypeFactory.defaultInstance())); + mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector()); } // lifecycle methods From 1e1fd41bda60971f9bc9e52b835402244bde2220 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sat, 13 Oct 2018 17:34:36 +0200 Subject: [PATCH 74/78] #994 fixed empty repository name on non bare repositories --- .../sonia/scm/repository/RepositoryUtil.java | 22 +++--- .../scm/repository/RepositoryUtilTest.java | 73 +++++++++++++++++++ 2 files changed, 82 insertions(+), 13 deletions(-) create mode 100644 scm-core/src/test/java/sonia/scm/repository/RepositoryUtilTest.java diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryUtil.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryUtil.java index 41b1b0aec5..e91722ebfe 100644 --- a/scm-core/src/main/java/sonia/scm/repository/RepositoryUtil.java +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryUtil.java @@ -35,6 +35,7 @@ package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.base.Preconditions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -237,23 +238,18 @@ public final class RepositoryUtil public static String getRepositoryName(File baseDirectory, File directory) throws IOException { - String name = null; String path = directory.getCanonicalPath(); - int directoryLength = baseDirectory.getCanonicalPath().length(); + String basePath = baseDirectory.getCanonicalPath(); - if (directoryLength < path.length()) - { - name = IOUtil.trimSeperatorChars(path.substring(directoryLength)); + Preconditions.checkArgument( + path.startsWith(basePath), + "repository path %s is not in the main repository path %s", path, basePath + ); - // replace windows path seperator - name = name.replaceAll("\\\\", "/"); - } - else if (logger.isWarnEnabled()) - { - logger.warn("path is shorter as the main repository path"); - } + String name = IOUtil.trimSeperatorChars(path.substring(basePath.length())); - return name; + // replace windows path seperator + return name.replaceAll("\\\\", "/"); } /** diff --git a/scm-core/src/test/java/sonia/scm/repository/RepositoryUtilTest.java b/scm-core/src/test/java/sonia/scm/repository/RepositoryUtilTest.java new file mode 100644 index 0000000000..a32a089181 --- /dev/null +++ b/scm-core/src/test/java/sonia/scm/repository/RepositoryUtilTest.java @@ -0,0 +1,73 @@ +package sonia.scm.repository; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.io.File; +import java.io.IOException; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class RepositoryUtilTest { + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Mock + private AbstractRepositoryHandler repositoryHandler; + + private SimpleRepositoryConfig repositoryConfig; + + @Before + public void setUpMocks() { + repositoryConfig = new SimpleRepositoryConfig(); + when(repositoryHandler.getConfig()).thenReturn(repositoryConfig); + } + + @Test + public void testGetRepositoryName() throws IOException { + File repositoryTypeRoot = temporaryFolder.newFolder(); + repositoryConfig.setRepositoryDirectory(repositoryTypeRoot); + + File repository = new File(repositoryTypeRoot, "abc"); + String name = RepositoryUtil.getRepositoryName(repositoryHandler, repository.getPath()); + assertEquals("abc", name); + } + + @Test(expected = IllegalArgumentException.class) + public void testGetRepositoryNameWithInvalidPath() throws IOException { + File repositoryTypeRoot = temporaryFolder.newFolder(); + repositoryConfig.setRepositoryDirectory(repositoryTypeRoot); + + File repository = new File("/etc/abc"); + String name = RepositoryUtil.getRepositoryName(repositoryHandler, repository.getPath()); + assertEquals("abc", name); + } + + @Test(expected = IllegalArgumentException.class) + public void testGetRepositoryNameWithInvalidPathButSameLength() throws IOException { + File repositoryTypeRoot = temporaryFolder.newFolder(); + repositoryConfig.setRepositoryDirectory(repositoryTypeRoot); + + File repository = new File(temporaryFolder.newFolder(), "abc"); + + String name = RepositoryUtil.getRepositoryName(repositoryHandler, repository.getPath()); + assertEquals("abc", name); + } + + @Test + public void testGetRepositoryNameWithSubDirectory() throws IOException { + File repositoryTypeRoot = temporaryFolder.newFolder(); + repositoryConfig.setRepositoryDirectory(repositoryTypeRoot); + + File repository = new File(repositoryTypeRoot, "abc/123"); + String name = RepositoryUtil.getRepositoryName(repositoryHandler, repository.getPath()); + assertEquals("abc/123", name); + } +} From 24e2885524769bbf784b70d02e8229f94ceb3589 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 14 Oct 2018 19:11:56 +0200 Subject: [PATCH 75/78] #998 git: set repository head to default branch --- .../sonia/scm/repository/GitHeadHandler.java | 53 ++++++++ .../sonia/scm/repository/GitHeadModifier.java | 7 ++ .../sonia/scm/repository/GitHeadResolver.java | 7 ++ .../GitRepositoryModifyListener.java | 51 +++++--- .../scm/repository/GitHeadHandlerTest.java | 60 +++++++++ .../GitRepositoryModifyListenerTest.java | 116 ++++++++++++------ 6 files changed, 239 insertions(+), 55 deletions(-) create mode 100644 scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadHandler.java create mode 100644 scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadModifier.java create mode 100644 scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadResolver.java create mode 100644 scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitHeadHandlerTest.java diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadHandler.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadHandler.java new file mode 100644 index 0000000000..23e6156297 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadHandler.java @@ -0,0 +1,53 @@ +package sonia.scm.repository; + +import com.google.common.base.Charsets; +import com.google.common.base.Throwables; +import com.google.common.io.Files; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.io.File; +import java.io.IOException; + +@Singleton +public class GitHeadHandler implements GitHeadResolver, GitHeadModifier { + + private final GitRepositoryHandler repositoryHandler; + + @Inject + public GitHeadHandler(GitRepositoryHandler repositoryHandler) { + this.repositoryHandler = repositoryHandler; + } + + @Override + public String resolve(Repository repository) { + File headFile = findHeadFile(repository); + try { + String line = Files.readFirstLine(headFile, Charsets.UTF_8); + // TODO handle invalid head file + int index = line.indexOf(GitUtil.REF_HEAD_PREFIX); + return line.substring(index + GitUtil.REF_HEAD_PREFIX.length()); + } catch (IOException e) { + // TODO + throw Throwables.propagate(e); + } + } + + @Override + public void modify(Repository repository, String head) { + File headFile = findHeadFile(repository); + try { + String line = "ref: " + GitUtil.REF_HEAD_PREFIX + head + "\n"; + Files.write(line, headFile, Charsets.UTF_8); + } catch (IOException e) { + // TODO + throw Throwables.propagate(e); + } + } + + private File findHeadFile(Repository repository) { + // TODO handle non bare repositories + File directory = repositoryHandler.getDirectory(repository); + return new File(directory, "HEAD"); + } +} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadModifier.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadModifier.java new file mode 100644 index 0000000000..f6597e3958 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadModifier.java @@ -0,0 +1,7 @@ +package sonia.scm.repository; + +public interface GitHeadModifier { + + void modify(Repository repository, String head); + +} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadResolver.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadResolver.java new file mode 100644 index 0000000000..c9f3dce609 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadResolver.java @@ -0,0 +1,7 @@ +package sonia.scm.repository; + +public interface GitHeadResolver { + + String resolve(Repository repository); + +} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryModifyListener.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryModifyListener.java index 4309257350..64f93d45de 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryModifyListener.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryModifyListener.java @@ -32,6 +32,7 @@ package sonia.scm.repository; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Objects; +import com.google.common.base.Strings; import com.google.common.eventbus.Subscribe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,58 +41,74 @@ import sonia.scm.HandlerEvent; import sonia.scm.event.ScmEventBus; import sonia.scm.plugin.ext.Extension; +import javax.inject.Inject; + /** * Repository listener which handles git related repository events. - * + * * @author Sebastian Sdorra * @since 1.50 */ @Extension @EagerSingleton public class GitRepositoryModifyListener { - + /** * the logger for GitRepositoryModifyListener */ private static final Logger logger = LoggerFactory.getLogger(GitRepositoryModifyListener.class); - + + private final GitHeadResolver headResolver; + private final GitHeadModifier headModifier; + + @Inject + public GitRepositoryModifyListener(GitHeadResolver headResolver, GitHeadModifier headModifier) { + this.headResolver = headResolver; + this.headModifier = headModifier; + } + /** * Receives {@link RepositoryModificationEvent} and fires a {@link ClearRepositoryCacheEvent} if * the default branch of a git repository was modified. - * + * * @param event repository modification event */ @Subscribe public void handleEvent(RepositoryModificationEvent event){ Repository repository = event.getItem(); - - if ( isModifyEvent(event) && - isGitRepository(event.getItem()) && - hasDefaultBranchChanged(event.getItemBeforeModification(), repository)) + + if ( isModifyEvent(event) && isGitRepository(event.getItem()) ) { - logger.info("git default branch of repository {} has changed, sending clear cache event", repository.getId()); - sendClearRepositoryCacheEvent(repository); + if (hasDefaultBranchChanged(event.getItemBeforeModification(), repository)) { + logger.info("git default branch of repository {} has changed, sending clear cache event", repository.getId()); + sendClearRepositoryCacheEvent(repository); + } + + String defaultBranch = repository.getProperty(GitConstants.PROPERTY_DEFAULT_BRANCH); + if (defaultBranch != null && ! defaultBranch.equals(headResolver.resolve(repository))) { + headModifier.modify(repository, defaultBranch); + } } } - + @VisibleForTesting protected void sendClearRepositoryCacheEvent(Repository repository) { - ScmEventBus.getInstance().post(new ClearRepositoryCacheEvent(repository)); + ScmEventBus.getInstance().post(new ClearRepositoryCacheEvent(repository)); } - + private boolean isModifyEvent(RepositoryEvent event) { return event.getEventType() == HandlerEvent.MODIFY; } - + private boolean isGitRepository(Repository repository) { return GitRepositoryHandler.TYPE_NAME.equals(repository.getType()); } - + private boolean hasDefaultBranchChanged(Repository old, Repository current) { return !Objects.equal( - old.getProperty(GitConstants.PROPERTY_DEFAULT_BRANCH), + old.getProperty(GitConstants.PROPERTY_DEFAULT_BRANCH), current.getProperty(GitConstants.PROPERTY_DEFAULT_BRANCH) ); } - + } diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitHeadHandlerTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitHeadHandlerTest.java new file mode 100644 index 0000000000..e3ae85baa2 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitHeadHandlerTest.java @@ -0,0 +1,60 @@ +package sonia.scm.repository; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.io.File; +import java.io.IOException; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class GitHeadHandlerTest { + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Mock + private GitRepositoryHandler repositoryHandler; + + @InjectMocks + private GitHeadHandler headHandler; + + @Test + public void testResolve() throws IOException { + Repository repository = RepositoryTestData.createHeartOfGold("git"); + create(repository, "master"); + + String head = headHandler.resolve(repository); + assertEquals("master", head); + } + + @Test + public void testModify() throws IOException { + Repository repository = RepositoryTestData.createHeartOfGold("git"); + File file = create(repository, "master"); + + headHandler.modify(repository, "develop"); + + assertEquals("ref: refs/heads/develop", Files.readFirstLine(file, Charsets.UTF_8)); + } + + private File create(Repository repository, String head) throws IOException { + File directory = temporaryFolder.newFolder(); + File headFile = new File(directory, "HEAD"); + Files.write(String.format("ref: refs/heads/%s\n", head), headFile, Charsets.UTF_8); + + when(repositoryHandler.getDirectory(repository)).thenReturn(directory); + + return headFile; + } + +} diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitRepositoryModifyListenerTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitRepositoryModifyListenerTest.java index 9f6768aeac..008000daef 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitRepositoryModifyListenerTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitRepositoryModifyListenerTest.java @@ -1,10 +1,10 @@ /** * Copyright (c) 2014, 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, @@ -13,7 +13,7 @@ * 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 @@ -24,34 +24,42 @@ * 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; import org.junit.Test; import static org.junit.Assert.*; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import org.junit.Before; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; import sonia.scm.HandlerEvent; /** * Unit tests for {@link GitRepositoryModifyListener}. - * + * * @author Sebastian Sdorra */ +@RunWith(MockitoJUnitRunner.class) public class GitRepositoryModifyListenerTest { + @Mock + private GitHeadResolver headResolver; + + @Mock + private GitHeadModifier headModifier; + + @InjectMocks private GitRepositoryModifyTestListener repositoryModifyListener; - - /** - * Set up test object. - */ - @Before - public void setUpObjectUnderTest(){ - repositoryModifyListener = new GitRepositoryModifyTestListener(); - } /** * Tests happy path. @@ -62,14 +70,14 @@ public class GitRepositoryModifyListenerTest { old.setProperty(GitConstants.PROPERTY_DEFAULT_BRANCH, "master"); Repository current = RepositoryTestData.createHeartOfGold("git"); current.setProperty(GitConstants.PROPERTY_DEFAULT_BRANCH, "develop"); - + RepositoryModificationEvent event = new RepositoryModificationEvent(current, old, HandlerEvent.MODIFY); repositoryModifyListener.handleEvent(event); - + assertNotNull(repositoryModifyListener.repository); assertSame(current, repositoryModifyListener.repository); } - + /** * Tests with new default branch. */ @@ -78,14 +86,14 @@ public class GitRepositoryModifyListenerTest { Repository old = RepositoryTestData.createHeartOfGold("git"); Repository current = RepositoryTestData.createHeartOfGold("git"); current.setProperty(GitConstants.PROPERTY_DEFAULT_BRANCH, "develop"); - + RepositoryModificationEvent event = new RepositoryModificationEvent(current, old, HandlerEvent.MODIFY); repositoryModifyListener.handleEvent(event); - + assertNotNull(repositoryModifyListener.repository); assertSame(current, repositoryModifyListener.repository); } - + /** * Tests with non git repositories. */ @@ -95,13 +103,13 @@ public class GitRepositoryModifyListenerTest { old.setProperty(GitConstants.PROPERTY_DEFAULT_BRANCH, "master"); Repository current = RepositoryTestData.createHeartOfGold("hg"); current.setProperty(GitConstants.PROPERTY_DEFAULT_BRANCH, "develop"); - + RepositoryModificationEvent event = new RepositoryModificationEvent(current, old, HandlerEvent.MODIFY); repositoryModifyListener.handleEvent(event); - + assertNull(repositoryModifyListener.repository); } - + /** * Tests without default branch. */ @@ -109,13 +117,13 @@ public class GitRepositoryModifyListenerTest { public void testWithoutDefaultBranch(){ Repository old = RepositoryTestData.createHeartOfGold("git"); Repository current = RepositoryTestData.createHeartOfGold("git"); - + RepositoryModificationEvent event = new RepositoryModificationEvent(current, old, HandlerEvent.MODIFY); repositoryModifyListener.handleEvent(event); - + assertNull(repositoryModifyListener.repository); } - + /** * Tests with non modify event. */ @@ -125,13 +133,13 @@ public class GitRepositoryModifyListenerTest { old.setProperty(GitConstants.PROPERTY_DEFAULT_BRANCH, "master"); Repository current = RepositoryTestData.createHeartOfGold("git"); current.setProperty(GitConstants.PROPERTY_DEFAULT_BRANCH, "develop"); - + RepositoryModificationEvent event = new RepositoryModificationEvent(current, old, HandlerEvent.CREATE); repositoryModifyListener.handleEvent(event); - + assertNull(repositoryModifyListener.repository); } - + /** * Tests with non git repositories. */ @@ -144,20 +152,52 @@ public class GitRepositoryModifyListenerTest { RepositoryModificationEvent event = new RepositoryModificationEvent(current, old, HandlerEvent.MODIFY); repositoryModifyListener.handleEvent(event); - + assertNull(repositoryModifyListener.repository); } - + + @Test + public void testModifyRepositoryHead() { + Repository old = RepositoryTestData.createHeartOfGold("git"); + Repository current = RepositoryTestData.createHeartOfGold("git"); + current.setProperty(GitConstants.PROPERTY_DEFAULT_BRANCH, "develop"); + + when(headResolver.resolve(current)).thenReturn("master"); + + RepositoryModificationEvent event = new RepositoryModificationEvent(current, old, HandlerEvent.MODIFY); + repositoryModifyListener.handleEvent(event); + + verify(headModifier).modify(current, "develop"); + } + + @Test + public void testWithEqualHeads() { + Repository old = RepositoryTestData.createHeartOfGold("git"); + Repository current = RepositoryTestData.createHeartOfGold("git"); + current.setProperty(GitConstants.PROPERTY_DEFAULT_BRANCH, "develop"); + + when(headResolver.resolve(current)).thenReturn("develop"); + + RepositoryModificationEvent event = new RepositoryModificationEvent(current, old, HandlerEvent.MODIFY); + repositoryModifyListener.handleEvent(event); + + verify(headModifier, never()).modify(current, "develop"); + } + private static class GitRepositoryModifyTestListener extends GitRepositoryModifyListener { - + private Repository repository; - + + public GitRepositoryModifyTestListener(GitHeadResolver headResolver, GitHeadModifier headModifier) { + super(headResolver, headModifier); + } + @Override protected void sendClearRepositoryCacheEvent(Repository repository) { this.repository = repository; - } - - } - + } -} \ No newline at end of file + } + + +} From 6fb99b70cd419d7b4836e5e1437b90c0b5fbe141 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 15 Oct 2018 21:32:03 +0200 Subject: [PATCH 76/78] #998 simplify api and use jgit to link new head --- .../sonia/scm/repository/GitHeadHandler.java | 53 ---------- .../sonia/scm/repository/GitHeadModifier.java | 98 ++++++++++++++++- .../sonia/scm/repository/GitHeadResolver.java | 7 -- .../GitRepositoryModifyListener.java | 9 +- .../scm/repository/GitHeadHandlerTest.java | 60 ----------- .../scm/repository/GitHeadModifierTest.java | 100 ++++++++++++++++++ .../GitRepositoryModifyListenerTest.java | 24 +---- 7 files changed, 202 insertions(+), 149 deletions(-) delete mode 100644 scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadHandler.java delete mode 100644 scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadResolver.java delete mode 100644 scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitHeadHandlerTest.java create mode 100644 scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitHeadModifierTest.java diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadHandler.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadHandler.java deleted file mode 100644 index 23e6156297..0000000000 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadHandler.java +++ /dev/null @@ -1,53 +0,0 @@ -package sonia.scm.repository; - -import com.google.common.base.Charsets; -import com.google.common.base.Throwables; -import com.google.common.io.Files; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.File; -import java.io.IOException; - -@Singleton -public class GitHeadHandler implements GitHeadResolver, GitHeadModifier { - - private final GitRepositoryHandler repositoryHandler; - - @Inject - public GitHeadHandler(GitRepositoryHandler repositoryHandler) { - this.repositoryHandler = repositoryHandler; - } - - @Override - public String resolve(Repository repository) { - File headFile = findHeadFile(repository); - try { - String line = Files.readFirstLine(headFile, Charsets.UTF_8); - // TODO handle invalid head file - int index = line.indexOf(GitUtil.REF_HEAD_PREFIX); - return line.substring(index + GitUtil.REF_HEAD_PREFIX.length()); - } catch (IOException e) { - // TODO - throw Throwables.propagate(e); - } - } - - @Override - public void modify(Repository repository, String head) { - File headFile = findHeadFile(repository); - try { - String line = "ref: " + GitUtil.REF_HEAD_PREFIX + head + "\n"; - Files.write(line, headFile, Charsets.UTF_8); - } catch (IOException e) { - // TODO - throw Throwables.propagate(e); - } - } - - private File findHeadFile(Repository repository) { - // TODO handle non bare repositories - File directory = repositoryHandler.getDirectory(repository); - return new File(directory, "HEAD"); - } -} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadModifier.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadModifier.java index f6597e3958..d6613ad6da 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadModifier.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadModifier.java @@ -1,7 +1,101 @@ +/** + * Copyright (c) 2014, 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; -public interface GitHeadModifier { +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.RefUpdate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; - void modify(Repository repository, String head); +import javax.inject.Inject; +import java.io.File; +import java.io.IOException; +import java.util.Objects; +/** + * The GitHeadModifier is able to modify the head of a git repository. + * + * @author Sebastian Sdorra + * @since 1.61 + */ +public class GitHeadModifier { + + private static final Logger LOG = LoggerFactory.getLogger(GitHeadModifier.class); + + private final GitRepositoryHandler repositoryHandler; + + @Inject + public GitHeadModifier(GitRepositoryHandler repositoryHandler) { + this.repositoryHandler = repositoryHandler; + } + + /** + * Ensures that the repositories head points to the given branch. The method will return {@code false} if the + * repositories head points already to the given branch. + * + * @param repository repository to modify + * @param newHead branch which should be the new head of the repository + * + * @return {@code true} if the head has changed + */ + public boolean ensure(Repository repository, String newHead) { + try (org.eclipse.jgit.lib.Repository gitRepository = open(repository)) { + String currentHead = resolve(gitRepository); + if (!Objects.equals(currentHead, newHead)) { + return modify(gitRepository, newHead); + } + } catch (IOException ex) { + LOG.warn("failed to change head of repository", ex); + } + return false; + } + + private String resolve(org.eclipse.jgit.lib.Repository gitRepository) throws IOException { + Ref ref = gitRepository.getRefDatabase().getRef(Constants.HEAD); + if ( ref.isSymbolic() ) { + ref = ref.getTarget(); + } + return GitUtil.getBranch(ref); + } + + private boolean modify(org.eclipse.jgit.lib.Repository gitRepository, String newHead) throws IOException { + RefUpdate refUpdate = gitRepository.getRefDatabase().newUpdate(Constants.HEAD, true); + refUpdate.setForceUpdate(true); + RefUpdate.Result result = refUpdate.link(Constants.R_HEADS + newHead); + return result == RefUpdate.Result.FORCED; + } + + private org.eclipse.jgit.lib.Repository open(Repository repository) throws IOException { + File directory = repositoryHandler.getDirectory(repository); + return GitUtil.open(directory); + } } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadResolver.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadResolver.java deleted file mode 100644 index c9f3dce609..0000000000 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitHeadResolver.java +++ /dev/null @@ -1,7 +0,0 @@ -package sonia.scm.repository; - -public interface GitHeadResolver { - - String resolve(Repository repository); - -} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryModifyListener.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryModifyListener.java index 64f93d45de..c0ab21af9d 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryModifyListener.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryModifyListener.java @@ -32,7 +32,6 @@ package sonia.scm.repository; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Objects; -import com.google.common.base.Strings; import com.google.common.eventbus.Subscribe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,12 +57,10 @@ public class GitRepositoryModifyListener { */ private static final Logger logger = LoggerFactory.getLogger(GitRepositoryModifyListener.class); - private final GitHeadResolver headResolver; private final GitHeadModifier headModifier; @Inject - public GitRepositoryModifyListener(GitHeadResolver headResolver, GitHeadModifier headModifier) { - this.headResolver = headResolver; + public GitRepositoryModifyListener(GitHeadModifier headModifier) { this.headModifier = headModifier; } @@ -85,8 +82,8 @@ public class GitRepositoryModifyListener { } String defaultBranch = repository.getProperty(GitConstants.PROPERTY_DEFAULT_BRANCH); - if (defaultBranch != null && ! defaultBranch.equals(headResolver.resolve(repository))) { - headModifier.modify(repository, defaultBranch); + if (defaultBranch != null) { + headModifier.ensure(repository, defaultBranch); } } } diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitHeadHandlerTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitHeadHandlerTest.java deleted file mode 100644 index e3ae85baa2..0000000000 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitHeadHandlerTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package sonia.scm.repository; - -import com.google.common.base.Charsets; -import com.google.common.io.Files; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import java.io.File; -import java.io.IOException; - -import static org.junit.Assert.*; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class GitHeadHandlerTest { - - @Rule - public TemporaryFolder temporaryFolder = new TemporaryFolder(); - - @Mock - private GitRepositoryHandler repositoryHandler; - - @InjectMocks - private GitHeadHandler headHandler; - - @Test - public void testResolve() throws IOException { - Repository repository = RepositoryTestData.createHeartOfGold("git"); - create(repository, "master"); - - String head = headHandler.resolve(repository); - assertEquals("master", head); - } - - @Test - public void testModify() throws IOException { - Repository repository = RepositoryTestData.createHeartOfGold("git"); - File file = create(repository, "master"); - - headHandler.modify(repository, "develop"); - - assertEquals("ref: refs/heads/develop", Files.readFirstLine(file, Charsets.UTF_8)); - } - - private File create(Repository repository, String head) throws IOException { - File directory = temporaryFolder.newFolder(); - File headFile = new File(directory, "HEAD"); - Files.write(String.format("ref: refs/heads/%s\n", head), headFile, Charsets.UTF_8); - - when(repositoryHandler.getDirectory(repository)).thenReturn(directory); - - return headFile; - } - -} diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitHeadModifierTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitHeadModifierTest.java new file mode 100644 index 0000000000..7a205d2584 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitHeadModifierTest.java @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2014, 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; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.io.File; +import java.io.IOException; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class GitHeadModifierTest { + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Mock + private GitRepositoryHandler repositoryHandler; + + @InjectMocks + private GitHeadModifier modifier; + + @Test + public void testEnsure() throws IOException, GitAPIException { + Repository repository = RepositoryTestData.createHeartOfGold("git"); + File headFile = create(repository, "master"); + + boolean result = modifier.ensure(repository, "develop"); + + assertEquals("ref: refs/heads/develop", Files.readFirstLine(headFile, Charsets.UTF_8)); + assertTrue(result); + } + + @Test + public void testEnsureWithSameBranch() throws IOException, GitAPIException { + Repository repository = RepositoryTestData.createHeartOfGold("git"); + create(repository, "develop"); + + boolean result = modifier.ensure(repository, "develop"); + + assertFalse(result); + } + + private File create(Repository repository, String head) throws IOException, GitAPIException { + File directory = temporaryFolder.newFolder(); + + Git.init() + .setBare(true) + .setDirectory(directory) + .call(); + + File headFile = new File(directory, "HEAD"); + Files.write(String.format("ref: refs/heads/%s\n", head), headFile, Charsets.UTF_8); + + when(repositoryHandler.getDirectory(repository)).thenReturn(directory); + + return headFile; + } + +} diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitRepositoryModifyListenerTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitRepositoryModifyListenerTest.java index 008000daef..5f0f0aca29 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitRepositoryModifyListenerTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/GitRepositoryModifyListenerTest.java @@ -52,9 +52,6 @@ import sonia.scm.HandlerEvent; @RunWith(MockitoJUnitRunner.class) public class GitRepositoryModifyListenerTest { - @Mock - private GitHeadResolver headResolver; - @Mock private GitHeadModifier headModifier; @@ -162,34 +159,19 @@ public class GitRepositoryModifyListenerTest { Repository current = RepositoryTestData.createHeartOfGold("git"); current.setProperty(GitConstants.PROPERTY_DEFAULT_BRANCH, "develop"); - when(headResolver.resolve(current)).thenReturn("master"); - RepositoryModificationEvent event = new RepositoryModificationEvent(current, old, HandlerEvent.MODIFY); repositoryModifyListener.handleEvent(event); - verify(headModifier).modify(current, "develop"); + verify(headModifier).ensure(current, "develop"); } - @Test - public void testWithEqualHeads() { - Repository old = RepositoryTestData.createHeartOfGold("git"); - Repository current = RepositoryTestData.createHeartOfGold("git"); - current.setProperty(GitConstants.PROPERTY_DEFAULT_BRANCH, "develop"); - - when(headResolver.resolve(current)).thenReturn("develop"); - - RepositoryModificationEvent event = new RepositoryModificationEvent(current, old, HandlerEvent.MODIFY); - repositoryModifyListener.handleEvent(event); - - verify(headModifier, never()).modify(current, "develop"); - } private static class GitRepositoryModifyTestListener extends GitRepositoryModifyListener { private Repository repository; - public GitRepositoryModifyTestListener(GitHeadResolver headResolver, GitHeadModifier headModifier) { - super(headResolver, headModifier); + public GitRepositoryModifyTestListener(GitHeadModifier headModifier) { + super(headModifier); } @Override From c188e2cd96419471e0d7d37bb6cc25be369187e2 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 19 Oct 2018 18:55:14 +0200 Subject: [PATCH 77/78] close branch issue-998 From 628973ed7d52439b2fabfc366207f8979762c17f Mon Sep 17 00:00:00 2001 From: Matt Harbison Date: Wed, 23 Jan 2019 11:49:57 -0500 Subject: [PATCH 78/78] #1001 support Mercurial 4.7 through 4.9 The command fallback is per the documented example[1], and the date fallback is adapted from hg-evolve. [1] https://www.mercurial-scm.org/repo/hg/rev/86f6b441adea --- .../resources/sonia/scm/hg/ext/fileview.py | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg/ext/fileview.py b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg/ext/fileview.py index 518f229011..02f3eb3e06 100644 --- a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg/ext/fileview.py +++ b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg/ext/fileview.py @@ -32,10 +32,24 @@ Prints date, size and last message of files. """ -from mercurial import cmdutil,util cmdtable = {} -command = cmdutil.command(cmdtable) + +try: + from mercurial import registrar + command = registrar.command(cmdtable) +except (AttributeError, ImportError): + # Fallback to hg < 4.3 support + from mercurial import cmdutil + command = cmdutil.command(cmdtable) + +try: + from mercurial.utils import dateutil + _parsedate = dateutil.parsedate +except ImportError: + # compat with hg < 4.6 + from mercurial import util + _parsedate = util.parsedate class SubRepository: url = None @@ -129,7 +143,7 @@ def printFile(ui, repo, file, disableLastCommit, transport): description = 'n/a' if not disableLastCommit: linkrev = repo[file.linkrev()] - date = '%d %d' % util.parsedate(linkrev.date()) + date = '%d %d' % _parsedate(linkrev.date()) description = linkrev.description() format = '%s %i %s %s\n' if transport: