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