Skip to content

Commit

Permalink
add a security check to all admin endpoints
Browse files Browse the repository at this point in the history
Either using the `@RoleAllowed` annotation, or by calling the
`RestxSecurityManager`
  • Loading branch information
a-peyrard committed Feb 10, 2016
1 parent 418811f commit e0e01e5
Show file tree
Hide file tree
Showing 17 changed files with 122 additions and 18 deletions.
3 changes: 3 additions & 0 deletions restx-admin/src/main/java/restx/config/ConfigResource.java
@@ -1,10 +1,12 @@
package restx.config;

import restx.admin.AdminModule;
import restx.annotations.GET;
import restx.annotations.RestxResource;
import restx.common.ConfigElement;
import restx.common.RestxConfig;
import restx.factory.Component;
import restx.security.RolesAllowed;

/**
*/
Expand All @@ -16,6 +18,7 @@ public ConfigResource(RestxConfig config) {
this.config = config;
}

@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
@GET("/@/config/elements")
public Iterable<ConfigElement> findConfigElements() {
return config.elements();
Expand Down
@@ -1,5 +1,8 @@
package restx.exceptions;

import static restx.security.Permissions.hasRole;


import com.fasterxml.jackson.databind.ObjectWriter;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableCollection;
Expand All @@ -8,9 +11,11 @@
import restx.RestxRequest;
import restx.RestxRequestMatch;
import restx.StdRestxRequestMatcher;
import restx.admin.AdminModule;
import restx.factory.Component;
import restx.jackson.FrontObjectMapperFactory;
import restx.jackson.StdJsonProducerEntityRoute;
import restx.security.RestxSecurityManager;

import javax.inject.Named;
import java.io.IOException;
Expand All @@ -25,9 +30,12 @@
public class ErrorDescriptorsRoute extends StdJsonProducerEntityRoute {

private final ImmutableMap<String, ErrorDescriptor> errorDescriptors;
private final RestxSecurityManager securityManager;

public ErrorDescriptorsRoute(Iterable<ErrorDescriptor> errorDescriptors,
@Named(FrontObjectMapperFactory.WRITER_NAME) ObjectWriter objectWriter) {
@Named(FrontObjectMapperFactory.WRITER_NAME) ObjectWriter objectWriter,
RestxSecurityManager securityManager) {

super("ErrorDescriptorsRoute", ImmutableCollection.class, objectWriter, new StdRestxRequestMatcher("GET", "/@/errors/descriptors"));
Map<String, ErrorDescriptor> map = Maps.newLinkedHashMap();
for (ErrorDescriptor errorDescriptor : errorDescriptors) {
Expand All @@ -37,10 +45,12 @@ public ErrorDescriptorsRoute(Iterable<ErrorDescriptor> errorDescriptors,
map.put(errorDescriptor.getErrorCode(), errorDescriptor);
}
this.errorDescriptors = ImmutableMap.copyOf(map);
this.securityManager = securityManager;
}

@Override
protected Optional<?> doRoute(RestxRequest restxRequest, RestxRequestMatch match, Object i) throws IOException {
securityManager.check(restxRequest, hasRole(AdminModule.RESTX_ADMIN_ROLE));
return Optional.of(errorDescriptors.values());
}
}
Expand Up @@ -5,20 +5,23 @@
import com.google.common.base.Optional;
import com.google.common.collect.*;
import restx.*;
import restx.admin.AdminModule;
import restx.description.*;
import restx.factory.Component;
import restx.factory.Factory;
import restx.factory.Name;
import restx.factory.NamedComponent;
import restx.jackson.FrontObjectMapperFactory;
import restx.jackson.StdJsonProducerEntityRoute;
import restx.security.RestxSecurityManager;

import javax.inject.Inject;
import javax.inject.Named;
import java.io.IOException;
import java.util.*;

import static restx.apidocs.ApiDocsIndexRoute.getRouterApiPath;
import static restx.security.Permissions.hasRole;

/**
* Serves the swagger api declaration of one router, which looks like that:
Expand All @@ -41,16 +44,19 @@
@Component
public class ApiDeclarationRoute extends StdJsonProducerEntityRoute {
private final Factory factory;
private final RestxSecurityManager securityManager;

@Inject
public ApiDeclarationRoute(@Named(FrontObjectMapperFactory.WRITER_NAME) ObjectWriter writer,
Factory factory) {
Factory factory, RestxSecurityManager securityManager) {
super("ApiDeclarationRoute", Map.class, writer, new StdRestxRequestMatcher("GET", "/@/api-docs/{router}"));
this.factory = factory;
this.securityManager = securityManager;
}

@Override
protected Optional<?> doRoute(RestxRequest restxRequest, RestxRequestMatch match, Object body) throws IOException {
securityManager.check(restxRequest, hasRole(AdminModule.RESTX_ADMIN_ROLE));
String routerName = match.getPathParam("router");
Optional<NamedComponent<RestxRouter>> router = getRouterByName(factory, routerName);

Expand Down
14 changes: 12 additions & 2 deletions restx-apidocs/src/main/java/restx/apidocs/ApiDocsIndexRoute.java
@@ -1,17 +1,21 @@
package restx.apidocs;

import com.fasterxml.jackson.databind.ObjectMapper;
import static restx.security.Permissions.hasRole;


import com.fasterxml.jackson.databind.ObjectWriter;
import com.google.common.base.CaseFormat;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import restx.*;
import restx.admin.AdminModule;
import restx.factory.Component;
import restx.factory.Factory;
import restx.factory.NamedComponent;
import restx.jackson.FrontObjectMapperFactory;
import restx.jackson.StdJsonProducerEntityRoute;
import restx.security.RestxSecurityManager;

import javax.inject.Inject;
import javax.inject.Named;
Expand Down Expand Up @@ -41,15 +45,21 @@
@Component
public class ApiDocsIndexRoute extends StdJsonProducerEntityRoute {
private final Factory factory;
private final RestxSecurityManager securityManager;

@Inject
public ApiDocsIndexRoute(@Named(FrontObjectMapperFactory.WRITER_NAME) ObjectWriter writer, Factory factory) {
public ApiDocsIndexRoute(@Named(FrontObjectMapperFactory.WRITER_NAME) ObjectWriter writer,
Factory factory,
RestxSecurityManager securityManager) {

super("ApiDocsIndexRoute", Map.class, writer, new StdRestxRequestMatcher("GET", "/@/api-docs"));
this.factory = factory;
this.securityManager = securityManager;
}

@Override
protected Optional<?> doRoute(RestxRequest restxRequest, RestxRequestMatch match, Object i) throws IOException {
securityManager.check(restxRequest, hasRole(AdminModule.RESTX_ADMIN_ROLE));
return Optional.of(ImmutableMap.builder()
.put("apiVersion", "0.1") // TODO
.put("swaggerVersion", "1.1")
Expand Down
Expand Up @@ -6,11 +6,13 @@
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
import com.fasterxml.jackson.module.jsonSchema.factories.SchemaFactoryWrapper;
import restx.WebException;
import restx.admin.AdminModule;
import restx.annotations.GET;
import restx.annotations.RestxResource;
import restx.factory.Component;
import restx.http.HttpStatus;
import restx.jackson.FrontObjectMapperFactory;
import restx.security.RolesAllowed;

import javax.inject.Named;

Expand All @@ -27,6 +29,7 @@ public JsonSchemaResource(@Named(FrontObjectMapperFactory.MAPPER_NAME) ObjectMap
}

@GET("/@/api-docs/schemas/{fqcn}")
@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
public String getJsonSchema(String fqcn) {
SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();
try {
Expand Down
6 changes: 6 additions & 0 deletions restx-apidocs/src/main/java/restx/apidocs/SpecsResource.java
Expand Up @@ -2,10 +2,13 @@

import com.google.common.base.Charsets;
import com.google.common.base.Optional;

import restx.admin.AdminModule;
import restx.annotations.GET;
import restx.annotations.PUT;
import restx.annotations.RestxResource;
import restx.factory.Component;
import restx.security.RolesAllowed;
import restx.specs.RestxSpec;
import restx.specs.RestxSpecRepository;
import restx.specs.ThenHttpResponse;
Expand All @@ -30,11 +33,13 @@ public SpecsResource(RestxSpecRepository repository, RestxSpec.StorageSettings s
storage = RestxSpec.Storage.with(storageSettings);
}

@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
@GET("/@/specs")
public Iterable<String> findSpecsForOperation(String httpMethod, String path) {
return repository.findSpecsByOperation(httpMethod, path);
}

@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
@GET("/@/specs/{id}")
public Optional<RestxSpec> getSpecById(String id) {
try {
Expand All @@ -49,6 +54,7 @@ public Optional<RestxSpec> getSpecById(String id) {
}
}

@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
@PUT("/@/specs/{id}/wts/{wtsIndex}/then")
public Optional<ThenHttpResponse> updateSpecThenHttp(String id, int wtsIndex, ThenHttpResponse response) throws IOException {
try {
Expand Down
@@ -1,22 +1,30 @@
package restx.factory;

import static restx.security.Permissions.hasRole;


import restx.*;
import restx.admin.AdminModule;
import restx.security.RestxSecurityManager;

import javax.inject.Inject;
import java.io.IOException;

@Component
public class FactoryDumpRoute extends StdRoute {
private final Factory factory;
private final RestxSecurityManager securityManager;

@Inject
public FactoryDumpRoute(Factory factory) {
public FactoryDumpRoute(Factory factory, RestxSecurityManager securityManager) {
super("FactoryRoute", new StdRestxRequestMatcher("GET", "/@/factory"));
this.factory = factory;
this.securityManager = securityManager;
}

@Override
public void handle(RestxRequestMatch match, RestxRequest req, RestxResponse resp, RestxContext ctx) throws IOException {
securityManager.check(req, hasRole(AdminModule.RESTX_ADMIN_ROLE));
resp.setContentType("text/plain");
resp.getWriter().println(factory.dump());
}
Expand Down
@@ -1,9 +1,14 @@
package restx.factory;

import static restx.security.Permissions.hasRole;


import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import restx.*;
import restx.admin.AdminModule;
import restx.annotations.RestxResource;
import restx.security.RestxSecurityManager;

import javax.inject.Inject;
import java.io.IOException;
Expand All @@ -13,19 +18,22 @@
@Component
public class WarehouseRoute extends StdRoute {
private final Warehouse warehouse;
private final RestxSecurityManager securityManager;

@Inject
public WarehouseRoute(Factory factory) {
this(factory.getWarehouse());
public WarehouseRoute(Factory factory, RestxSecurityManager securityManager) {
this(factory.getWarehouse(), securityManager);
}

public WarehouseRoute(Warehouse warehouse) {
public WarehouseRoute(Warehouse warehouse, RestxSecurityManager securityManager) {
super("WarehouseRoute", new StdRestxRequestMatcher("GET", "/@/warehouse"));
this.warehouse = warehouse;
this.securityManager = securityManager;
}

@Override
public void handle(RestxRequestMatch match, RestxRequest req, RestxResponse resp, RestxContext ctx) throws IOException {
securityManager.check(req, hasRole(AdminModule.RESTX_ADMIN_ROLE));
resp.setContentType("application/json");

List<String> nodesCode = Lists.newArrayList();
Expand Down
@@ -1,12 +1,14 @@
package restx.i18n.admin;

import restx.admin.AdminModule;
import restx.annotations.GET;
import restx.annotations.POST;
import restx.annotations.RestxResource;
import restx.factory.Component;
import restx.i18n.Messages;
import restx.i18n.MutableMessages;
import restx.i18n.SupportedLocale;
import restx.security.RolesAllowed;

import javax.inject.Named;
import java.io.IOException;
Expand All @@ -27,11 +29,13 @@ public MessagesAdminResource(@Named("Messages") Messages messages, Collection<Su
this.supportedLocales = supportedLocales;
}

@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
@GET("/@/i18n/keys")
public Iterable<String> keys() {
return messages.keys();
}

@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
@GET("/@/i18n/locales")
public Iterable<String> locales() {
Collection<String> locales = new ArrayList<>();
Expand All @@ -42,6 +46,7 @@ public Iterable<String> locales() {
return locales;
}

@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
@GET("/@/i18n/messages/{locale}")
public Map<String, String> messages(String locale) {
Locale l = toLocale(locale);
Expand All @@ -52,6 +57,7 @@ public Map<String, String> messages(String locale) {
return m;
}

@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
@POST("/@/i18n/messages/{locale}")
public void setMessage(String locale, Map<String, String> entries) {
if (!(messages instanceof MutableMessages)) {
Expand Down
Expand Up @@ -8,11 +8,13 @@
import org.slf4j.ILoggerFactory;
import org.slf4j.LoggerFactory;
import restx.WebException;
import restx.admin.AdminModule;
import restx.annotations.GET;
import restx.annotations.PUT;
import restx.annotations.RestxResource;
import restx.common.MorePreconditions;
import restx.factory.Component;
import restx.security.RolesAllowed;

import java.io.File;
import java.io.IOException;
Expand All @@ -39,6 +41,7 @@ public Logger(String name, String level) {
}
}

@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
@GET("/@/logs")
public String getLogs() {
// quick and dirty basic implementation to get logs from the default log file.
Expand All @@ -64,6 +67,7 @@ public String getLogs() {
}
}

@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
@GET("/@/loggers")
public Iterable<Logger> getLoggers() {
ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
Expand All @@ -81,6 +85,7 @@ public Iterable<Logger> getLoggers() {
}
}

@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
@PUT("/@/loggers/{name}")
public Logger updateLogger(String name, Logger logger) {
logger.name = name;
Expand Down

0 comments on commit e0e01e5

Please sign in to comment.