Skip to content

Commit e0e01e5

Browse files
committed
add a security check to all admin endpoints
Either using the `@RoleAllowed` annotation, or by calling the `RestxSecurityManager`
1 parent 418811f commit e0e01e5

File tree

17 files changed

+122
-18
lines changed

17 files changed

+122
-18
lines changed

restx-admin/src/main/java/restx/config/ConfigResource.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package restx.config;
22

3+
import restx.admin.AdminModule;
34
import restx.annotations.GET;
45
import restx.annotations.RestxResource;
56
import restx.common.ConfigElement;
67
import restx.common.RestxConfig;
78
import restx.factory.Component;
9+
import restx.security.RolesAllowed;
810

911
/**
1012
*/
@@ -16,6 +18,7 @@ public ConfigResource(RestxConfig config) {
1618
this.config = config;
1719
}
1820

21+
@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
1922
@GET("/@/config/elements")
2023
public Iterable<ConfigElement> findConfigElements() {
2124
return config.elements();

restx-admin/src/main/java/restx/exceptions/ErrorDescriptorsRoute.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package restx.exceptions;
22

3+
import static restx.security.Permissions.hasRole;
4+
5+
36
import com.fasterxml.jackson.databind.ObjectWriter;
47
import com.google.common.base.Optional;
58
import com.google.common.collect.ImmutableCollection;
@@ -8,9 +11,11 @@
811
import restx.RestxRequest;
912
import restx.RestxRequestMatch;
1013
import restx.StdRestxRequestMatcher;
14+
import restx.admin.AdminModule;
1115
import restx.factory.Component;
1216
import restx.jackson.FrontObjectMapperFactory;
1317
import restx.jackson.StdJsonProducerEntityRoute;
18+
import restx.security.RestxSecurityManager;
1419

1520
import javax.inject.Named;
1621
import java.io.IOException;
@@ -25,9 +30,12 @@
2530
public class ErrorDescriptorsRoute extends StdJsonProducerEntityRoute {
2631

2732
private final ImmutableMap<String, ErrorDescriptor> errorDescriptors;
33+
private final RestxSecurityManager securityManager;
2834

2935
public ErrorDescriptorsRoute(Iterable<ErrorDescriptor> errorDescriptors,
30-
@Named(FrontObjectMapperFactory.WRITER_NAME) ObjectWriter objectWriter) {
36+
@Named(FrontObjectMapperFactory.WRITER_NAME) ObjectWriter objectWriter,
37+
RestxSecurityManager securityManager) {
38+
3139
super("ErrorDescriptorsRoute", ImmutableCollection.class, objectWriter, new StdRestxRequestMatcher("GET", "/@/errors/descriptors"));
3240
Map<String, ErrorDescriptor> map = Maps.newLinkedHashMap();
3341
for (ErrorDescriptor errorDescriptor : errorDescriptors) {
@@ -37,10 +45,12 @@ public ErrorDescriptorsRoute(Iterable<ErrorDescriptor> errorDescriptors,
3745
map.put(errorDescriptor.getErrorCode(), errorDescriptor);
3846
}
3947
this.errorDescriptors = ImmutableMap.copyOf(map);
48+
this.securityManager = securityManager;
4049
}
4150

4251
@Override
4352
protected Optional<?> doRoute(RestxRequest restxRequest, RestxRequestMatch match, Object i) throws IOException {
53+
securityManager.check(restxRequest, hasRole(AdminModule.RESTX_ADMIN_ROLE));
4454
return Optional.of(errorDescriptors.values());
4555
}
4656
}

restx-apidocs/src/main/java/restx/apidocs/ApiDeclarationRoute.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,23 @@
55
import com.google.common.base.Optional;
66
import com.google.common.collect.*;
77
import restx.*;
8+
import restx.admin.AdminModule;
89
import restx.description.*;
910
import restx.factory.Component;
1011
import restx.factory.Factory;
1112
import restx.factory.Name;
1213
import restx.factory.NamedComponent;
1314
import restx.jackson.FrontObjectMapperFactory;
1415
import restx.jackson.StdJsonProducerEntityRoute;
16+
import restx.security.RestxSecurityManager;
1517

1618
import javax.inject.Inject;
1719
import javax.inject.Named;
1820
import java.io.IOException;
1921
import java.util.*;
2022

2123
import static restx.apidocs.ApiDocsIndexRoute.getRouterApiPath;
24+
import static restx.security.Permissions.hasRole;
2225

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

4549
@Inject
4650
public ApiDeclarationRoute(@Named(FrontObjectMapperFactory.WRITER_NAME) ObjectWriter writer,
47-
Factory factory) {
51+
Factory factory, RestxSecurityManager securityManager) {
4852
super("ApiDeclarationRoute", Map.class, writer, new StdRestxRequestMatcher("GET", "/@/api-docs/{router}"));
4953
this.factory = factory;
54+
this.securityManager = securityManager;
5055
}
5156

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

restx-apidocs/src/main/java/restx/apidocs/ApiDocsIndexRoute.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
package restx.apidocs;
22

3-
import com.fasterxml.jackson.databind.ObjectMapper;
3+
import static restx.security.Permissions.hasRole;
4+
5+
46
import com.fasterxml.jackson.databind.ObjectWriter;
57
import com.google.common.base.CaseFormat;
68
import com.google.common.base.Optional;
79
import com.google.common.collect.ImmutableMap;
810
import com.google.common.collect.Lists;
911
import restx.*;
12+
import restx.admin.AdminModule;
1013
import restx.factory.Component;
1114
import restx.factory.Factory;
1215
import restx.factory.NamedComponent;
1316
import restx.jackson.FrontObjectMapperFactory;
1417
import restx.jackson.StdJsonProducerEntityRoute;
18+
import restx.security.RestxSecurityManager;
1519

1620
import javax.inject.Inject;
1721
import javax.inject.Named;
@@ -41,15 +45,21 @@
4145
@Component
4246
public class ApiDocsIndexRoute extends StdJsonProducerEntityRoute {
4347
private final Factory factory;
48+
private final RestxSecurityManager securityManager;
4449

4550
@Inject
46-
public ApiDocsIndexRoute(@Named(FrontObjectMapperFactory.WRITER_NAME) ObjectWriter writer, Factory factory) {
51+
public ApiDocsIndexRoute(@Named(FrontObjectMapperFactory.WRITER_NAME) ObjectWriter writer,
52+
Factory factory,
53+
RestxSecurityManager securityManager) {
54+
4755
super("ApiDocsIndexRoute", Map.class, writer, new StdRestxRequestMatcher("GET", "/@/api-docs"));
4856
this.factory = factory;
57+
this.securityManager = securityManager;
4958
}
5059

5160
@Override
5261
protected Optional<?> doRoute(RestxRequest restxRequest, RestxRequestMatch match, Object i) throws IOException {
62+
securityManager.check(restxRequest, hasRole(AdminModule.RESTX_ADMIN_ROLE));
5363
return Optional.of(ImmutableMap.builder()
5464
.put("apiVersion", "0.1") // TODO
5565
.put("swaggerVersion", "1.1")

restx-apidocs/src/main/java/restx/apidocs/JsonSchemaResource.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
77
import com.fasterxml.jackson.module.jsonSchema.factories.SchemaFactoryWrapper;
88
import restx.WebException;
9+
import restx.admin.AdminModule;
910
import restx.annotations.GET;
1011
import restx.annotations.RestxResource;
1112
import restx.factory.Component;
1213
import restx.http.HttpStatus;
1314
import restx.jackson.FrontObjectMapperFactory;
15+
import restx.security.RolesAllowed;
1416

1517
import javax.inject.Named;
1618

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

2931
@GET("/@/api-docs/schemas/{fqcn}")
32+
@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
3033
public String getJsonSchema(String fqcn) {
3134
SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();
3235
try {

restx-apidocs/src/main/java/restx/apidocs/SpecsResource.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22

33
import com.google.common.base.Charsets;
44
import com.google.common.base.Optional;
5+
6+
import restx.admin.AdminModule;
57
import restx.annotations.GET;
68
import restx.annotations.PUT;
79
import restx.annotations.RestxResource;
810
import restx.factory.Component;
11+
import restx.security.RolesAllowed;
912
import restx.specs.RestxSpec;
1013
import restx.specs.RestxSpecRepository;
1114
import restx.specs.ThenHttpResponse;
@@ -30,11 +33,13 @@ public SpecsResource(RestxSpecRepository repository, RestxSpec.StorageSettings s
3033
storage = RestxSpec.Storage.with(storageSettings);
3134
}
3235

36+
@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
3337
@GET("/@/specs")
3438
public Iterable<String> findSpecsForOperation(String httpMethod, String path) {
3539
return repository.findSpecsByOperation(httpMethod, path);
3640
}
3741

42+
@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
3843
@GET("/@/specs/{id}")
3944
public Optional<RestxSpec> getSpecById(String id) {
4045
try {
@@ -49,6 +54,7 @@ public Optional<RestxSpec> getSpecById(String id) {
4954
}
5055
}
5156

57+
@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
5258
@PUT("/@/specs/{id}/wts/{wtsIndex}/then")
5359
public Optional<ThenHttpResponse> updateSpecThenHttp(String id, int wtsIndex, ThenHttpResponse response) throws IOException {
5460
try {

restx-factory-admin/src/main/java/restx/factory/FactoryDumpRoute.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
11
package restx.factory;
22

3+
import static restx.security.Permissions.hasRole;
4+
5+
36
import restx.*;
7+
import restx.admin.AdminModule;
8+
import restx.security.RestxSecurityManager;
49

510
import javax.inject.Inject;
611
import java.io.IOException;
712

813
@Component
914
public class FactoryDumpRoute extends StdRoute {
1015
private final Factory factory;
16+
private final RestxSecurityManager securityManager;
1117

1218
@Inject
13-
public FactoryDumpRoute(Factory factory) {
19+
public FactoryDumpRoute(Factory factory, RestxSecurityManager securityManager) {
1420
super("FactoryRoute", new StdRestxRequestMatcher("GET", "/@/factory"));
1521
this.factory = factory;
22+
this.securityManager = securityManager;
1623
}
1724

1825
@Override
1926
public void handle(RestxRequestMatch match, RestxRequest req, RestxResponse resp, RestxContext ctx) throws IOException {
27+
securityManager.check(req, hasRole(AdminModule.RESTX_ADMIN_ROLE));
2028
resp.setContentType("text/plain");
2129
resp.getWriter().println(factory.dump());
2230
}

restx-factory-admin/src/main/java/restx/factory/WarehouseRoute.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
package restx.factory;
22

3+
import static restx.security.Permissions.hasRole;
4+
5+
36
import com.google.common.base.Joiner;
47
import com.google.common.collect.Lists;
58
import restx.*;
9+
import restx.admin.AdminModule;
610
import restx.annotations.RestxResource;
11+
import restx.security.RestxSecurityManager;
712

813
import javax.inject.Inject;
914
import java.io.IOException;
@@ -13,19 +18,22 @@
1318
@Component
1419
public class WarehouseRoute extends StdRoute {
1520
private final Warehouse warehouse;
21+
private final RestxSecurityManager securityManager;
1622

1723
@Inject
18-
public WarehouseRoute(Factory factory) {
19-
this(factory.getWarehouse());
24+
public WarehouseRoute(Factory factory, RestxSecurityManager securityManager) {
25+
this(factory.getWarehouse(), securityManager);
2026
}
2127

22-
public WarehouseRoute(Warehouse warehouse) {
28+
public WarehouseRoute(Warehouse warehouse, RestxSecurityManager securityManager) {
2329
super("WarehouseRoute", new StdRestxRequestMatcher("GET", "/@/warehouse"));
2430
this.warehouse = warehouse;
31+
this.securityManager = securityManager;
2532
}
2633

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

3139
List<String> nodesCode = Lists.newArrayList();

restx-i18n-admin/src/main/java/restx/i18n/admin/MessagesAdminResource.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package restx.i18n.admin;
22

3+
import restx.admin.AdminModule;
34
import restx.annotations.GET;
45
import restx.annotations.POST;
56
import restx.annotations.RestxResource;
67
import restx.factory.Component;
78
import restx.i18n.Messages;
89
import restx.i18n.MutableMessages;
910
import restx.i18n.SupportedLocale;
11+
import restx.security.RolesAllowed;
1012

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

32+
@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
3033
@GET("/@/i18n/keys")
3134
public Iterable<String> keys() {
3235
return messages.keys();
3336
}
3437

38+
@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
3539
@GET("/@/i18n/locales")
3640
public Iterable<String> locales() {
3741
Collection<String> locales = new ArrayList<>();
@@ -42,6 +46,7 @@ public Iterable<String> locales() {
4246
return locales;
4347
}
4448

49+
@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
4550
@GET("/@/i18n/messages/{locale}")
4651
public Map<String, String> messages(String locale) {
4752
Locale l = toLocale(locale);
@@ -52,6 +57,7 @@ public Map<String, String> messages(String locale) {
5257
return m;
5358
}
5459

60+
@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
5561
@POST("/@/i18n/messages/{locale}")
5662
public void setMessage(String locale, Map<String, String> entries) {
5763
if (!(messages instanceof MutableMessages)) {

restx-log-admin/src/main/java/restx/log/admin/LogAdminResource.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@
88
import org.slf4j.ILoggerFactory;
99
import org.slf4j.LoggerFactory;
1010
import restx.WebException;
11+
import restx.admin.AdminModule;
1112
import restx.annotations.GET;
1213
import restx.annotations.PUT;
1314
import restx.annotations.RestxResource;
1415
import restx.common.MorePreconditions;
1516
import restx.factory.Component;
17+
import restx.security.RolesAllowed;
1618

1719
import java.io.File;
1820
import java.io.IOException;
@@ -39,6 +41,7 @@ public Logger(String name, String level) {
3941
}
4042
}
4143

44+
@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
4245
@GET("/@/logs")
4346
public String getLogs() {
4447
// quick and dirty basic implementation to get logs from the default log file.
@@ -64,6 +67,7 @@ public String getLogs() {
6467
}
6568
}
6669

70+
@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
6771
@GET("/@/loggers")
6872
public Iterable<Logger> getLoggers() {
6973
ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
@@ -81,6 +85,7 @@ public Iterable<Logger> getLoggers() {
8185
}
8286
}
8387

88+
@RolesAllowed(AdminModule.RESTX_ADMIN_ROLE)
8489
@PUT("/@/loggers/{name}")
8590
public Logger updateLogger(String name, Logger logger) {
8691
logger.name = name;

0 commit comments

Comments
 (0)