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