mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-11 07:55:47 +01:00
Cleanup and documentation
This commit is contained in:
@@ -3,6 +3,10 @@ package sonia.scm;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This represents the result of a page request. Contains the results for
|
||||||
|
* the page and a flag whether there are more pages or not.
|
||||||
|
*/
|
||||||
public class PageResult<T extends ModelObject> {
|
public class PageResult<T extends ModelObject> {
|
||||||
|
|
||||||
private final Collection<T> entities;
|
private final Collection<T> entities;
|
||||||
@@ -13,10 +17,16 @@ public class PageResult<T extends ModelObject> {
|
|||||||
this.hasMore = hasMore;
|
this.hasMore = hasMore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The entities for the current page.
|
||||||
|
*/
|
||||||
public Collection<T> getEntities() {
|
public Collection<T> getEntities() {
|
||||||
return Collections.unmodifiableCollection(entities);
|
return Collections.unmodifiableCollection(entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this is <code>true</code>, there are more pages (that is, mor entities).
|
||||||
|
*/
|
||||||
public boolean hasMore() {
|
public boolean hasMore() {
|
||||||
return hasMore;
|
return hasMore;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,11 @@ package sonia.scm.web;
|
|||||||
|
|
||||||
import sonia.scm.plugin.ExtensionPoint;
|
import sonia.scm.plugin.ExtensionPoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementing this extension point you can post process json response objects.
|
||||||
|
* To do so, you get a {@link JsonEnricherContext} with the complete json tree,
|
||||||
|
* that can be modified.
|
||||||
|
*/
|
||||||
@ExtensionPoint
|
@ExtensionPoint
|
||||||
public interface JsonEnricher {
|
public interface JsonEnricher {
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ import com.fasterxml.jackson.databind.JsonNode;
|
|||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process data for the {@link JsonEnricher} extension point giving context for
|
||||||
|
* post processing json results.
|
||||||
|
*/
|
||||||
public class JsonEnricherContext {
|
public class JsonEnricherContext {
|
||||||
|
|
||||||
private URI requestUri;
|
private URI requestUri;
|
||||||
@@ -17,14 +21,24 @@ public class JsonEnricherContext {
|
|||||||
this.responseEntity = responseEntity;
|
this.responseEntity = responseEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URI of the originating request.
|
||||||
|
*/
|
||||||
public URI getRequestUri() {
|
public URI getRequestUri() {
|
||||||
return requestUri;
|
return requestUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The media type of the response. Using this you can determine the content of the result.
|
||||||
|
* @see VndMediaType
|
||||||
|
*/
|
||||||
public MediaType getResponseMediaType() {
|
public MediaType getResponseMediaType() {
|
||||||
return responseMediaType;
|
return responseMediaType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The json result represented by nodes, that can be modified.
|
||||||
|
*/
|
||||||
public JsonNode getResponseEntity() {
|
public JsonNode getResponseEntity() {
|
||||||
return responseEntity;
|
return responseEntity;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ package sonia.scm.web;
|
|||||||
|
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vendor media types used by SCMM.
|
||||||
|
*/
|
||||||
public class VndMediaType {
|
public class VndMediaType {
|
||||||
private static final String VERSION = "2";
|
private static final String VERSION = "2";
|
||||||
private static final String TYPE = "application";
|
private static final String TYPE = "application";
|
||||||
@@ -10,18 +13,14 @@ public class VndMediaType {
|
|||||||
private static final String SUFFIX = "+json;v=" + VERSION;
|
private static final String SUFFIX = "+json;v=" + VERSION;
|
||||||
|
|
||||||
public static final String USER = PREFIX + "user" + SUFFIX;
|
public static final String USER = PREFIX + "user" + SUFFIX;
|
||||||
|
public static final String USER_COLLECTION = PREFIX + "userCollection" + SUFFIX;
|
||||||
|
|
||||||
private VndMediaType() {
|
private VndMediaType() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MediaType jsonType(String resource) {
|
/**
|
||||||
return MediaType.valueOf(json(resource));
|
* Checks whether the given media type is a media type used by SCMM.
|
||||||
}
|
*/
|
||||||
|
|
||||||
public static String json(String resource) {
|
|
||||||
return PREFIX + resource + SUFFIX;// ".v2+json";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isVndType(MediaType type) {
|
public static boolean isVndType(MediaType type) {
|
||||||
return type.getType().equals(TYPE) && type.getSubtype().startsWith(SUBTYPE_PREFIX);
|
return type.getType().equals(TYPE) && type.getSubtype().startsWith(SUBTYPE_PREFIX);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<groupId>sonia.scm</groupId>
|
<groupId>sonia.scm</groupId>
|
||||||
<artifactId>scm-annotation-processor</artifactId>
|
<artifactId>scm-annotation-processor</artifactId>
|
||||||
<version>2.0.0-SNAPSHOT</version>
|
<version>2.0.0-SNAPSHOT</version>
|
||||||
<optional>true</optional>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -39,10 +39,14 @@ import com.google.common.base.Throwables;
|
|||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
|
||||||
import org.apache.shiro.guice.web.ShiroWebModule;
|
import org.apache.shiro.guice.web.ShiroWebModule;
|
||||||
import org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener;
|
||||||
|
|
||||||
import sonia.scm.api.v2.resources.MapperModule;
|
import sonia.scm.api.v2.resources.MapperModule;
|
||||||
import sonia.scm.cache.CacheManager;
|
import sonia.scm.cache.CacheManager;
|
||||||
import sonia.scm.debug.DebugModule;
|
import sonia.scm.debug.DebugModule;
|
||||||
@@ -57,13 +61,14 @@ import sonia.scm.upgrade.UpgradeManager;
|
|||||||
import sonia.scm.user.UserManager;
|
import sonia.scm.user.UserManager;
|
||||||
import sonia.scm.util.IOUtil;
|
import sonia.scm.util.IOUtil;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
import javax.servlet.ServletContextEvent;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletContextEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -42,8 +42,10 @@ import com.google.inject.name.Names;
|
|||||||
import com.google.inject.servlet.RequestScoped;
|
import com.google.inject.servlet.RequestScoped;
|
||||||
import com.google.inject.servlet.ServletModule;
|
import com.google.inject.servlet.ServletModule;
|
||||||
import com.google.inject.throwingproviders.ThrowingProviderBinder;
|
import com.google.inject.throwingproviders.ThrowingProviderBinder;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import sonia.scm.api.rest.ObjectMapperProvider;
|
import sonia.scm.api.rest.ObjectMapperProvider;
|
||||||
import sonia.scm.cache.CacheManager;
|
import sonia.scm.cache.CacheManager;
|
||||||
import sonia.scm.cache.GuavaCacheManager;
|
import sonia.scm.cache.GuavaCacheManager;
|
||||||
@@ -56,13 +58,18 @@ import sonia.scm.group.GroupManagerProvider;
|
|||||||
import sonia.scm.group.xml.XmlGroupDAO;
|
import sonia.scm.group.xml.XmlGroupDAO;
|
||||||
import sonia.scm.io.DefaultFileSystem;
|
import sonia.scm.io.DefaultFileSystem;
|
||||||
import sonia.scm.io.FileSystem;
|
import sonia.scm.io.FileSystem;
|
||||||
import sonia.scm.net.SSLContextProvider;
|
|
||||||
import sonia.scm.net.ahc.*;
|
|
||||||
import sonia.scm.plugin.DefaultPluginLoader;
|
import sonia.scm.plugin.DefaultPluginLoader;
|
||||||
import sonia.scm.plugin.DefaultPluginManager;
|
import sonia.scm.plugin.DefaultPluginManager;
|
||||||
import sonia.scm.plugin.PluginLoader;
|
import sonia.scm.plugin.PluginLoader;
|
||||||
import sonia.scm.plugin.PluginManager;
|
import sonia.scm.plugin.PluginManager;
|
||||||
import sonia.scm.repository.*;
|
import sonia.scm.repository.DefaultRepositoryManager;
|
||||||
|
import sonia.scm.repository.DefaultRepositoryProvider;
|
||||||
|
import sonia.scm.repository.HealthCheckContextListener;
|
||||||
|
import sonia.scm.repository.Repository;
|
||||||
|
import sonia.scm.repository.RepositoryDAO;
|
||||||
|
import sonia.scm.repository.RepositoryManager;
|
||||||
|
import sonia.scm.repository.RepositoryManagerProvider;
|
||||||
|
import sonia.scm.repository.RepositoryProvider;
|
||||||
import sonia.scm.repository.api.HookContextFactory;
|
import sonia.scm.repository.api.HookContextFactory;
|
||||||
import sonia.scm.repository.api.RepositoryServiceFactory;
|
import sonia.scm.repository.api.RepositoryServiceFactory;
|
||||||
import sonia.scm.repository.spi.HookEventFacade;
|
import sonia.scm.repository.spi.HookEventFacade;
|
||||||
@@ -71,15 +78,28 @@ import sonia.scm.resources.DefaultResourceManager;
|
|||||||
import sonia.scm.resources.DevelopmentResourceManager;
|
import sonia.scm.resources.DevelopmentResourceManager;
|
||||||
import sonia.scm.resources.ResourceManager;
|
import sonia.scm.resources.ResourceManager;
|
||||||
import sonia.scm.resources.ScriptResourceServlet;
|
import sonia.scm.resources.ScriptResourceServlet;
|
||||||
import sonia.scm.schedule.QuartzScheduler;
|
import sonia.scm.security.CipherHandler;
|
||||||
import sonia.scm.schedule.Scheduler;
|
import sonia.scm.security.CipherUtil;
|
||||||
import sonia.scm.security.*;
|
import sonia.scm.security.DefaultKeyGenerator;
|
||||||
import sonia.scm.store.*;
|
import sonia.scm.security.DefaultSecuritySystem;
|
||||||
|
import sonia.scm.security.KeyGenerator;
|
||||||
|
import sonia.scm.security.SecuritySystem;
|
||||||
|
import sonia.scm.store.BlobStoreFactory;
|
||||||
|
import sonia.scm.store.ConfigurationEntryStoreFactory;
|
||||||
|
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.template.MustacheTemplateEngine;
|
import sonia.scm.template.MustacheTemplateEngine;
|
||||||
import sonia.scm.template.TemplateEngine;
|
import sonia.scm.template.TemplateEngine;
|
||||||
import sonia.scm.template.TemplateEngineFactory;
|
import sonia.scm.template.TemplateEngineFactory;
|
||||||
import sonia.scm.template.TemplateServlet;
|
import sonia.scm.template.TemplateServlet;
|
||||||
import sonia.scm.url.*;
|
import sonia.scm.url.RestJsonUrlProvider;
|
||||||
|
import sonia.scm.url.RestXmlUrlProvider;
|
||||||
|
import sonia.scm.url.UrlProvider;
|
||||||
|
import sonia.scm.url.UrlProviderFactory;
|
||||||
|
import sonia.scm.url.WebUIUrlProvider;
|
||||||
import sonia.scm.user.DefaultUserManager;
|
import sonia.scm.user.DefaultUserManager;
|
||||||
import sonia.scm.user.UserDAO;
|
import sonia.scm.user.UserDAO;
|
||||||
import sonia.scm.user.UserManager;
|
import sonia.scm.user.UserManager;
|
||||||
@@ -87,18 +107,32 @@ import sonia.scm.user.UserManagerProvider;
|
|||||||
import sonia.scm.user.xml.XmlUserDAO;
|
import sonia.scm.user.xml.XmlUserDAO;
|
||||||
import sonia.scm.util.DebugServlet;
|
import sonia.scm.util.DebugServlet;
|
||||||
import sonia.scm.util.ScmConfigurationUtil;
|
import sonia.scm.util.ScmConfigurationUtil;
|
||||||
import sonia.scm.web.UserAgentParser;
|
|
||||||
import sonia.scm.web.cgi.CGIExecutorFactory;
|
import sonia.scm.web.cgi.CGIExecutorFactory;
|
||||||
import sonia.scm.web.cgi.DefaultCGIExecutorFactory;
|
import sonia.scm.web.cgi.DefaultCGIExecutorFactory;
|
||||||
import sonia.scm.web.filter.LoggingFilter;
|
import sonia.scm.web.filter.LoggingFilter;
|
||||||
import sonia.scm.web.security.AdministrationContext;
|
import sonia.scm.web.security.AdministrationContext;
|
||||||
import sonia.scm.web.security.DefaultAdministrationContext;
|
import sonia.scm.web.security.DefaultAdministrationContext;
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
import sonia.scm.net.ahc.ContentTransformer;
|
||||||
|
import sonia.scm.net.ahc.DefaultAdvancedHttpClient;
|
||||||
|
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.web.UserAgentParser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
|
|||||||
@@ -37,8 +37,10 @@ package sonia.scm.api.rest.resources;
|
|||||||
|
|
||||||
import org.apache.commons.beanutils.BeanComparator;
|
import org.apache.commons.beanutils.BeanComparator;
|
||||||
import org.apache.shiro.authz.AuthorizationException;
|
import org.apache.shiro.authz.AuthorizationException;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import sonia.scm.LastModifiedAware;
|
import sonia.scm.LastModifiedAware;
|
||||||
import sonia.scm.Manager;
|
import sonia.scm.Manager;
|
||||||
import sonia.scm.ModelObject;
|
import sonia.scm.ModelObject;
|
||||||
@@ -48,13 +50,19 @@ import sonia.scm.util.AssertUtil;
|
|||||||
import sonia.scm.util.HttpUtil;
|
import sonia.scm.util.HttpUtil;
|
||||||
import sonia.scm.util.Util;
|
import sonia.scm.util.Util;
|
||||||
|
|
||||||
import javax.ws.rs.core.*;
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
import javax.ws.rs.core.Response.Status;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
import javax.ws.rs.core.CacheControl;
|
||||||
|
import javax.ws.rs.core.EntityTag;
|
||||||
|
import javax.ws.rs.core.GenericEntity;
|
||||||
|
import javax.ws.rs.core.Request;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -559,7 +567,7 @@ public abstract class AbstractManagerResource<T extends ModelObject,
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected Collection<T> fetchItems(String sortby, boolean desc, int start,
|
private Collection<T> fetchItems(String sortby, boolean desc, int start,
|
||||||
int limit)
|
int limit)
|
||||||
{
|
{
|
||||||
AssertUtil.assertPositive(start);
|
AssertUtil.assertPositive(start);
|
||||||
|
|||||||
@@ -41,17 +41,34 @@ import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
|||||||
import com.webcohesion.enunciate.metadata.rs.ResponseHeader;
|
import com.webcohesion.enunciate.metadata.rs.ResponseHeader;
|
||||||
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||||
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
||||||
|
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
|
|
||||||
import sonia.scm.group.Group;
|
import sonia.scm.group.Group;
|
||||||
import sonia.scm.group.GroupException;
|
import sonia.scm.group.GroupException;
|
||||||
import sonia.scm.group.GroupManager;
|
import sonia.scm.group.GroupManager;
|
||||||
import sonia.scm.security.Role;
|
import sonia.scm.security.Role;
|
||||||
|
|
||||||
import javax.ws.rs.*;
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
import javax.ws.rs.core.*;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.DefaultValue;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
|
import javax.ws.rs.core.GenericEntity;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Request;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RESTful Web Service Resource to manage groups and their members.
|
* RESTful Web Service Resource to manage groups and their members.
|
||||||
|
|||||||
@@ -42,26 +42,66 @@ import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
|||||||
import com.webcohesion.enunciate.metadata.rs.ResponseHeader;
|
import com.webcohesion.enunciate.metadata.rs.ResponseHeader;
|
||||||
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||||
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
||||||
|
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import org.apache.shiro.authz.AuthorizationException;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import sonia.scm.config.ScmConfiguration;
|
import sonia.scm.config.ScmConfiguration;
|
||||||
import sonia.scm.repository.*;
|
import sonia.scm.repository.BlameResult;
|
||||||
import sonia.scm.repository.api.*;
|
import sonia.scm.repository.Branches;
|
||||||
|
import sonia.scm.repository.BrowserResult;
|
||||||
|
import sonia.scm.repository.Changeset;
|
||||||
|
import sonia.scm.repository.ChangesetPagingResult;
|
||||||
|
import sonia.scm.repository.HealthChecker;
|
||||||
|
import sonia.scm.repository.Permission;
|
||||||
|
import sonia.scm.repository.Repository;
|
||||||
|
import sonia.scm.repository.RepositoryException;
|
||||||
|
import sonia.scm.repository.RepositoryIsNotArchivedException;
|
||||||
|
import sonia.scm.repository.RepositoryManager;
|
||||||
|
import sonia.scm.repository.RepositoryNotFoundException;
|
||||||
|
import sonia.scm.repository.Tags;
|
||||||
|
import sonia.scm.repository.api.BlameCommandBuilder;
|
||||||
|
import sonia.scm.repository.api.BrowseCommandBuilder;
|
||||||
|
import sonia.scm.repository.api.CatCommandBuilder;
|
||||||
|
import sonia.scm.repository.api.CommandNotSupportedException;
|
||||||
|
import sonia.scm.repository.api.DiffCommandBuilder;
|
||||||
|
import sonia.scm.repository.api.DiffFormat;
|
||||||
|
import sonia.scm.repository.api.LogCommandBuilder;
|
||||||
|
import sonia.scm.repository.api.RepositoryService;
|
||||||
|
import sonia.scm.repository.api.RepositoryServiceFactory;
|
||||||
import sonia.scm.util.AssertUtil;
|
import sonia.scm.util.AssertUtil;
|
||||||
import sonia.scm.util.HttpUtil;
|
import sonia.scm.util.HttpUtil;
|
||||||
import sonia.scm.util.IOUtil;
|
import sonia.scm.util.IOUtil;
|
||||||
import sonia.scm.util.Util;
|
import sonia.scm.util.Util;
|
||||||
|
|
||||||
import javax.ws.rs.*;
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
import javax.ws.rs.core.*;
|
|
||||||
import javax.ws.rs.core.Response.Status;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.DefaultValue;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
|
import javax.ws.rs.core.GenericEntity;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Request;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
import javax.ws.rs.core.StreamingOutput;
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
import org.apache.shiro.authz.AuthorizationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repository related RESTful Web Service Endpoint.
|
* Repository related RESTful Web Service Endpoint.
|
||||||
|
|||||||
@@ -41,8 +41,10 @@ import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
|||||||
import com.webcohesion.enunciate.metadata.rs.ResponseHeader;
|
import com.webcohesion.enunciate.metadata.rs.ResponseHeader;
|
||||||
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||||
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
||||||
|
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import org.apache.shiro.authc.credential.PasswordService;
|
import org.apache.shiro.authc.credential.PasswordService;
|
||||||
|
|
||||||
import sonia.scm.security.Role;
|
import sonia.scm.security.Role;
|
||||||
import sonia.scm.user.User;
|
import sonia.scm.user.User;
|
||||||
import sonia.scm.user.UserException;
|
import sonia.scm.user.UserException;
|
||||||
@@ -50,11 +52,26 @@ import sonia.scm.user.UserManager;
|
|||||||
import sonia.scm.util.AssertUtil;
|
import sonia.scm.util.AssertUtil;
|
||||||
import sonia.scm.util.Util;
|
import sonia.scm.util.Util;
|
||||||
|
|
||||||
import javax.ws.rs.*;
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
import javax.ws.rs.core.*;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.DefaultValue;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
|
import javax.ws.rs.core.GenericEntity;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Request;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RESTful Web Service Resource to manage users.
|
* RESTful Web Service Resource to manage users.
|
||||||
|
|||||||
@@ -13,6 +13,13 @@ import javax.ws.rs.ext.Provider;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Post processor for rest requests filtering json responses when a {@value PARAMETER_FIELDS} query
|
||||||
|
* parameter is provided. In this case, only the given fields will returned. It is possible, to specify
|
||||||
|
* paths for nested fields. Multiple fields have to be devided using {@value FIELD_SEPARATOR}.</p>
|
||||||
|
* <p>This requires the {@link JsonMarshallingResponseFilter} to be processed first to create
|
||||||
|
* the {@link JsonNode} tree.</p>
|
||||||
|
*/
|
||||||
@Provider
|
@Provider
|
||||||
@Priority(Priorities.USER)
|
@Priority(Priorities.USER)
|
||||||
public class FieldContainerResponseFilter implements ContainerResponseFilter {
|
public class FieldContainerResponseFilter implements ContainerResponseFilter {
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ import javax.ws.rs.container.ContainerResponseFilter;
|
|||||||
import javax.ws.rs.ext.Provider;
|
import javax.ws.rs.ext.Provider;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms json rest responses to {@link JsonNode} trees to support further post processing
|
||||||
|
* and processes all registered plugins for the {@link JsonEnricher} extension point.
|
||||||
|
*/
|
||||||
@Provider
|
@Provider
|
||||||
@Priority(Priorities.USER + 1000)
|
@Priority(Priorities.USER + 1000)
|
||||||
public class JsonMarshallingResponseFilter implements ContainerResponseFilter {
|
public class JsonMarshallingResponseFilter implements ContainerResponseFilter {
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
package sonia.scm.api.v2.resources;
|
|
||||||
|
|
||||||
public class ScmMediaType {
|
|
||||||
}
|
|
||||||
@@ -5,6 +5,7 @@ import org.mapstruct.*;
|
|||||||
import sonia.scm.api.rest.resources.UserResource;
|
import sonia.scm.api.rest.resources.UserResource;
|
||||||
import sonia.scm.user.User;
|
import sonia.scm.user.User;
|
||||||
import sonia.scm.user.UserPermissions;
|
import sonia.scm.user.UserPermissions;
|
||||||
|
import sonia.scm.util.AssertUtil;
|
||||||
|
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@@ -43,7 +44,7 @@ public abstract class User2UserDtoMapper {
|
|||||||
|
|
||||||
@Mapping(target = "creationDate")
|
@Mapping(target = "creationDate")
|
||||||
Instant mapTime(Long epochMilli) {
|
Instant mapTime(Long epochMilli) {
|
||||||
// TODO assert parameter not null
|
AssertUtil.assertIsNotNull(epochMilli);
|
||||||
return Instant.ofEpochMilli(epochMilli);
|
return Instant.ofEpochMilli(epochMilli);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public class UserCollection2DtoMapper {
|
|||||||
this.userToDtoMapper = userToDtoMapper;
|
this.userToDtoMapper = userToDtoMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserCollectionDto userCollectionToUserDto(UriInfo uriInfo, int pageNumber, int pageSize, PageResult<User> pageResult) {
|
public UserCollectionDto userCollectionToDto(UriInfo uriInfo, int pageNumber, int pageSize, PageResult<User> pageResult) {
|
||||||
NumberedPaging paging = zeroBasedNumberedPaging(pageNumber, pageSize, pageResult.hasMore());
|
NumberedPaging paging = zeroBasedNumberedPaging(pageNumber, pageSize, pageResult.hasMore());
|
||||||
List<UserDto> dtos = pageResult.getEntities().stream().map(user -> userToDtoMapper.userToUserDto(user, uriInfo)).collect(Collectors.toList());
|
List<UserDto> dtos = pageResult.getEntities().stream().map(user -> userToDtoMapper.userToUserDto(user, uriInfo)).collect(Collectors.toList());
|
||||||
|
|
||||||
|
|||||||
@@ -12,12 +12,21 @@ import sonia.scm.user.UserException;
|
|||||||
import sonia.scm.user.UserManager;
|
import sonia.scm.user.UserManager;
|
||||||
import sonia.scm.web.VndMediaType;
|
import sonia.scm.web.VndMediaType;
|
||||||
|
|
||||||
import javax.ws.rs.*;
|
import javax.ws.rs.DefaultValue;
|
||||||
import javax.ws.rs.core.*;
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
|
import javax.ws.rs.core.GenericEntity;
|
||||||
|
import javax.ws.rs.core.Request;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
@Produces(VndMediaType.USER)
|
@Produces(VndMediaType.USER_COLLECTION)
|
||||||
public class UserCollectionResource extends AbstractManagerResource<User, UserException> {
|
public class UserCollectionResource extends AbstractManagerResource<User, UserException> {
|
||||||
public static final int DEFAULT_PAGE_SIZE = 10;
|
public static final int DEFAULT_PAGE_SIZE = 10;
|
||||||
private final UserDto2UserMapper dtoToUserMapper;
|
private final UserDto2UserMapper dtoToUserMapper;
|
||||||
@@ -57,9 +66,14 @@ public class UserCollectionResource extends AbstractManagerResource<User, UserEx
|
|||||||
@QueryParam("desc") boolean desc) {
|
@QueryParam("desc") boolean desc) {
|
||||||
PageResult<User> pageResult = fetchPage(sortby, desc, page, pageSize);
|
PageResult<User> pageResult = fetchPage(sortby, desc, page, pageSize);
|
||||||
|
|
||||||
return Response.ok(new UserCollection2DtoMapper(userToDtoMapper).userCollectionToUserDto(uriInfo, page, pageSize, pageResult)).build();
|
return Response.ok(new UserCollection2DtoMapper(userToDtoMapper).userCollectionToDto(uriInfo, page, pageSize, pageResult)).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new user.
|
||||||
|
* @param userDto The user to be created.
|
||||||
|
* @return A response with the link to the new user (if created successfully).
|
||||||
|
*/
|
||||||
@POST
|
@POST
|
||||||
@Path("")
|
@Path("")
|
||||||
@StatusCodes({
|
@StatusCodes({
|
||||||
|
|||||||
@@ -12,8 +12,17 @@ import sonia.scm.user.UserException;
|
|||||||
import sonia.scm.user.UserManager;
|
import sonia.scm.user.UserManager;
|
||||||
import sonia.scm.web.VndMediaType;
|
import sonia.scm.web.VndMediaType;
|
||||||
|
|
||||||
import javax.ws.rs.*;
|
import javax.ws.rs.DELETE;
|
||||||
import javax.ws.rs.core.*;
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
|
import javax.ws.rs.core.GenericEntity;
|
||||||
|
import javax.ws.rs.core.Request;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public class JsonMarshallingResponseFilterTest {
|
|||||||
public void testFilter() {
|
public void testFilter() {
|
||||||
when(responseContext.hasEntity()).thenReturn(Boolean.TRUE);
|
when(responseContext.hasEntity()).thenReturn(Boolean.TRUE);
|
||||||
when(responseContext.getEntity()).thenReturn(new JsonMarshallingResponseFilterTest.Sample("one-two-three"));
|
when(responseContext.getEntity()).thenReturn(new JsonMarshallingResponseFilterTest.Sample("one-two-three"));
|
||||||
when(responseContext.getMediaType()).thenReturn(VndMediaType.jsonType("sample"));
|
when(responseContext.getMediaType()).thenReturn(MediaType.valueOf(VndMediaType.USER));
|
||||||
|
|
||||||
filter.filter(requestContext, responseContext);
|
filter.filter(requestContext, responseContext);
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ public class JsonMarshallingResponseFilterTest {
|
|||||||
|
|
||||||
when(responseContext.hasEntity()).thenReturn(Boolean.TRUE);
|
when(responseContext.hasEntity()).thenReturn(Boolean.TRUE);
|
||||||
when(responseContext.getEntity()).thenReturn(new JsonMarshallingResponseFilterTest.Sample("one-two-three"));
|
when(responseContext.getEntity()).thenReturn(new JsonMarshallingResponseFilterTest.Sample("one-two-three"));
|
||||||
when(responseContext.getMediaType()).thenReturn(VndMediaType.jsonType("sample"));
|
when(responseContext.getMediaType()).thenReturn(MediaType.valueOf(VndMediaType.USER));
|
||||||
|
|
||||||
filter.filter(requestContext, responseContext);
|
filter.filter(requestContext, responseContext);
|
||||||
|
|
||||||
|
|||||||
@@ -45,28 +45,28 @@ public class UserCollection2DtoMapperTest {
|
|||||||
@Test
|
@Test
|
||||||
public void shouldSetPageNumber() {
|
public void shouldSetPageNumber() {
|
||||||
PageResult<User> pageResult = mockPageResult(true, "Hannes");
|
PageResult<User> pageResult = mockPageResult(true, "Hannes");
|
||||||
UserCollectionDto userCollectionDto = mapper.userCollectionToUserDto(uriInfo, 1, 1, pageResult);
|
UserCollectionDto userCollectionDto = mapper.userCollectionToDto(uriInfo, 1, 1, pageResult);
|
||||||
assertEquals(1, userCollectionDto.getPage());
|
assertEquals(1, userCollectionDto.getPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldHaveSelfLink() {
|
public void shouldHaveSelfLink() {
|
||||||
PageResult<User> pageResult = mockPageResult(true, "Hannes");
|
PageResult<User> pageResult = mockPageResult(true, "Hannes");
|
||||||
UserCollectionDto userCollectionDto = mapper.userCollectionToUserDto(uriInfo, 1, 1, pageResult);
|
UserCollectionDto userCollectionDto = mapper.userCollectionToDto(uriInfo, 1, 1, pageResult);
|
||||||
assertTrue(userCollectionDto.getLinks().getLinkBy("self").get().getHref().startsWith(expectedBaseUri.toString()));
|
assertTrue(userCollectionDto.getLinks().getLinkBy("self").get().getHref().startsWith(expectedBaseUri.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldCreateNextPageLink_whenHasMore() {
|
public void shouldCreateNextPageLink_whenHasMore() {
|
||||||
PageResult<User> pageResult = mockPageResult(true, "Hannes");
|
PageResult<User> pageResult = mockPageResult(true, "Hannes");
|
||||||
UserCollectionDto userCollectionDto = mapper.userCollectionToUserDto(uriInfo, 1, 1, pageResult);
|
UserCollectionDto userCollectionDto = mapper.userCollectionToDto(uriInfo, 1, 1, pageResult);
|
||||||
assertTrue(userCollectionDto.getLinks().getLinkBy("next").get().getHref().contains("page=2"));
|
assertTrue(userCollectionDto.getLinks().getLinkBy("next").get().getHref().contains("page=2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldNotCreateNextPageLink_whenNoMore() {
|
public void shouldNotCreateNextPageLink_whenNoMore() {
|
||||||
PageResult<User> pageResult = mockPageResult(false, "Hannes");
|
PageResult<User> pageResult = mockPageResult(false, "Hannes");
|
||||||
UserCollectionDto userCollectionDto = mapper.userCollectionToUserDto(uriInfo, 1, 1, pageResult);
|
UserCollectionDto userCollectionDto = mapper.userCollectionToDto(uriInfo, 1, 1, pageResult);
|
||||||
assertFalse(userCollectionDto.getLinks().stream().anyMatch(link -> link.getHref().contains("page=2")));
|
assertFalse(userCollectionDto.getLinks().stream().anyMatch(link -> link.getHref().contains("page=2")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ public class UserCollection2DtoMapperTest {
|
|||||||
PageResult<User> pageResult = mockPageResult(false, "Hannes");
|
PageResult<User> pageResult = mockPageResult(false, "Hannes");
|
||||||
when(subject.isPermitted("user:create")).thenReturn(true);
|
when(subject.isPermitted("user:create")).thenReturn(true);
|
||||||
|
|
||||||
UserCollectionDto userCollectionDto = mapper.userCollectionToUserDto(uriInfo, 1, 1, pageResult);
|
UserCollectionDto userCollectionDto = mapper.userCollectionToDto(uriInfo, 1, 1, pageResult);
|
||||||
|
|
||||||
assertTrue(userCollectionDto.getLinks().getLinkBy("create").isPresent());
|
assertTrue(userCollectionDto.getLinks().getLinkBy("create").isPresent());
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@ public class UserCollection2DtoMapperTest {
|
|||||||
PageResult<User> pageResult = mockPageResult(false, "Hannes");
|
PageResult<User> pageResult = mockPageResult(false, "Hannes");
|
||||||
when(subject.isPermitted("user:create")).thenReturn(false);
|
when(subject.isPermitted("user:create")).thenReturn(false);
|
||||||
|
|
||||||
UserCollectionDto userCollectionDto = mapper.userCollectionToUserDto(uriInfo, 1, 1, pageResult);
|
UserCollectionDto userCollectionDto = mapper.userCollectionToDto(uriInfo, 1, 1, pageResult);
|
||||||
|
|
||||||
assertFalse(userCollectionDto.getLinks().getLinkBy("create").isPresent());
|
assertFalse(userCollectionDto.getLinks().getLinkBy("create").isPresent());
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ public class UserCollection2DtoMapperTest {
|
|||||||
@Test
|
@Test
|
||||||
public void shouldMapUsers() {
|
public void shouldMapUsers() {
|
||||||
PageResult<User> pageResult = mockPageResult(false, "Hannes", "Wurst");
|
PageResult<User> pageResult = mockPageResult(false, "Hannes", "Wurst");
|
||||||
UserCollectionDto userCollectionDto = mapper.userCollectionToUserDto(uriInfo, 1, 2, pageResult);
|
UserCollectionDto userCollectionDto = mapper.userCollectionToDto(uriInfo, 1, 2, pageResult);
|
||||||
List<HalRepresentation> users = userCollectionDto.getEmbedded().getItemsBy("users");
|
List<HalRepresentation> users = userCollectionDto.getEmbedded().getItemsBy("users");
|
||||||
assertEquals(2, users.size());
|
assertEquals(2, users.size());
|
||||||
assertEquals("Hannes", ((UserDto) users.get(0)).getName());
|
assertEquals("Hannes", ((UserDto) users.get(0)).getName());
|
||||||
|
|||||||
Reference in New Issue
Block a user