diff --git a/src/main/java/org/gridsuite/gateway/endpoints/ContingencyServer.java b/src/main/java/org/gridsuite/gateway/endpoints/ContingencyServer.java index a3afeeb..f3498b8 100644 --- a/src/main/java/org/gridsuite/gateway/endpoints/ContingencyServer.java +++ b/src/main/java/org/gridsuite/gateway/endpoints/ContingencyServer.java @@ -13,7 +13,7 @@ * @author Slimane Amar */ @Component(value = ContingencyServer.ENDPOINT_NAME) -public class ContingencyServer implements EndPointElementServer { +public class ContingencyServer implements EndPointAccessControlledServer { public static final String ENDPOINT_NAME = "actions"; diff --git a/src/main/java/org/gridsuite/gateway/endpoints/EndPointElementServer.java b/src/main/java/org/gridsuite/gateway/endpoints/EndPointAccessControlledServer.java similarity index 89% rename from src/main/java/org/gridsuite/gateway/endpoints/EndPointElementServer.java rename to src/main/java/org/gridsuite/gateway/endpoints/EndPointAccessControlledServer.java index 367c932..64423bc 100644 --- a/src/main/java/org/gridsuite/gateway/endpoints/EndPointElementServer.java +++ b/src/main/java/org/gridsuite/gateway/endpoints/EndPointAccessControlledServer.java @@ -18,15 +18,15 @@ import static org.springframework.http.HttpMethod.*; /** + * {@link EndPointServer Server} with access allowed under defined rules + * * @author Slimane Amar */ -public interface EndPointElementServer extends EndPointServer { +public interface EndPointAccessControlledServer extends EndPointServer { String QUERY_PARAM_IDS = "ids"; - Set ALLOWED_HTTP_METHODS = Set.of(GET, HEAD, - PUT, POST, DELETE - ); + Set ALLOWED_HTTP_METHODS = Set.of(GET, HEAD, PUT, POST, DELETE); static UUID getUuid(String uuid) { try { @@ -52,11 +52,6 @@ default boolean isNotControlledRootPath(String rootPath) { return getUncontrolledRootPaths().contains(rootPath); } - @Override - default boolean hasElementsAccessControl() { - return true; - } - default Optional getAccessControlInfos(@NonNull ServerHttpRequest request) { RequestPath path = Objects.requireNonNull(request.getPath()); UUID elementUuid = getElementUuidIfExist(path); @@ -71,7 +66,7 @@ default Optional getAccessControlInfos(@NonNull ServerHttpRe return Optional.empty(); } else { List ids = request.getQueryParams().get(QUERY_PARAM_IDS); - List elementUuids = ids.stream().map(EndPointElementServer::getUuid).filter(Objects::nonNull).collect(Collectors.toList()); + List elementUuids = ids.stream().map(EndPointAccessControlledServer::getUuid).filter(Objects::nonNull).collect(Collectors.toList()); return elementUuids.size() == ids.size() ? Optional.of(AccessControlInfos.create(elementUuids)) : Optional.empty(); } } diff --git a/src/main/java/org/gridsuite/gateway/endpoints/EndPointServer.java b/src/main/java/org/gridsuite/gateway/endpoints/EndPointServer.java index 2d2e4e4..c2fbc9a 100644 --- a/src/main/java/org/gridsuite/gateway/endpoints/EndPointServer.java +++ b/src/main/java/org/gridsuite/gateway/endpoints/EndPointServer.java @@ -14,6 +14,9 @@ import static org.gridsuite.gateway.GatewayConfig.END_POINT_SERVICE_NAME; /** + * Declare a service/server accessible on this gateway under path {@code //*} + * and redirect it to {@code /*}. + * * @author Slimane Amar */ public interface EndPointServer { @@ -27,8 +30,4 @@ default Buildable getRoute(@NonNull PredicateSpec p) { .metadata(END_POINT_SERVICE_NAME, getEndpointName()) .uri(getEndpointBaseUri()); } - - default boolean hasElementsAccessControl() { - return false; - } } diff --git a/src/main/java/org/gridsuite/gateway/endpoints/ExploreServer.java b/src/main/java/org/gridsuite/gateway/endpoints/ExploreServer.java index ecf5933..60ed73f 100644 --- a/src/main/java/org/gridsuite/gateway/endpoints/ExploreServer.java +++ b/src/main/java/org/gridsuite/gateway/endpoints/ExploreServer.java @@ -23,7 +23,7 @@ * @author Slimane Amar */ @Component(value = ExploreServer.ENDPOINT_NAME) -public class ExploreServer implements EndPointElementServer { +public class ExploreServer implements EndPointAccessControlledServer { public static final String ENDPOINT_NAME = "explore"; @@ -37,7 +37,7 @@ public ExploreServer(ServiceURIsConfig servicesURIsConfig) { @Override public UUID getElementUuidIfExist(@NonNull RequestPath path) { - return (path.elements().size() > 7) ? EndPointElementServer.getUuid(path.elements().get(7).value()) : null; + return (path.elements().size() > 7) ? EndPointAccessControlledServer.getUuid(path.elements().get(7).value()) : null; } @Override @@ -50,11 +50,6 @@ public String getEndpointName() { return ENDPOINT_NAME; } - @Override - public boolean hasElementsAccessControl() { - return true; - } - @Override public Optional getAccessControlInfos(@NonNull ServerHttpRequest request) { RequestPath path = Objects.requireNonNull(request.getPath()); @@ -69,12 +64,12 @@ public Optional getAccessControlInfos(@NonNull ServerHttpReq if (ids == null || ids.size() != 1) { return Optional.empty(); } else { - UUID uuid = EndPointElementServer.getUuid(ids.get(0)); + UUID uuid = EndPointAccessControlledServer.getUuid(ids.get(0)); return uuid == null ? Optional.empty() : Optional.of(AccessControlInfos.create(List.of(uuid))); } } } else { - return EndPointElementServer.super.getAccessControlInfos(request); + return EndPointAccessControlledServer.super.getAccessControlInfos(request); } } } diff --git a/src/main/java/org/gridsuite/gateway/endpoints/FilterServer.java b/src/main/java/org/gridsuite/gateway/endpoints/FilterServer.java index 29d7702..02db948 100644 --- a/src/main/java/org/gridsuite/gateway/endpoints/FilterServer.java +++ b/src/main/java/org/gridsuite/gateway/endpoints/FilterServer.java @@ -13,7 +13,7 @@ * @author Slimane Amar */ @Component(value = FilterServer.ENDPOINT_NAME) -public class FilterServer implements EndPointElementServer { +public class FilterServer implements EndPointAccessControlledServer { public static final String ENDPOINT_NAME = "filter"; diff --git a/src/main/java/org/gridsuite/gateway/endpoints/StudyServer.java b/src/main/java/org/gridsuite/gateway/endpoints/StudyServer.java index 2d0ec2d..3c5b55d 100644 --- a/src/main/java/org/gridsuite/gateway/endpoints/StudyServer.java +++ b/src/main/java/org/gridsuite/gateway/endpoints/StudyServer.java @@ -15,7 +15,7 @@ * @author Slimane Amar */ @Component(value = StudyServer.ENDPOINT_NAME) -public class StudyServer implements EndPointElementServer { +public class StudyServer implements EndPointAccessControlledServer { public static final String ENDPOINT_NAME = "study"; diff --git a/src/main/java/org/gridsuite/gateway/filters/ElementAccessControllerGlobalPreFilter.java b/src/main/java/org/gridsuite/gateway/filters/ElementAccessControllerGlobalPreFilter.java index 0ddef95..771073a 100644 --- a/src/main/java/org/gridsuite/gateway/filters/ElementAccessControllerGlobalPreFilter.java +++ b/src/main/java/org/gridsuite/gateway/filters/ElementAccessControllerGlobalPreFilter.java @@ -10,7 +10,7 @@ import lombok.NonNull; import org.gridsuite.gateway.ServiceURIsConfig; import org.gridsuite.gateway.dto.AccessControlInfos; -import org.gridsuite.gateway.endpoints.EndPointElementServer; +import org.gridsuite.gateway.endpoints.EndPointAccessControlledServer; import org.gridsuite.gateway.endpoints.EndPointServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,7 +36,7 @@ import static org.gridsuite.gateway.GatewayConfig.END_POINT_SERVICE_NAME; import static org.gridsuite.gateway.GatewayConfig.HEADER_USER_ID; -import static org.gridsuite.gateway.endpoints.EndPointElementServer.QUERY_PARAM_IDS; +import static org.gridsuite.gateway.endpoints.EndPointAccessControlledServer.QUERY_PARAM_IDS; import static org.springframework.http.HttpStatus.*; /** @@ -48,11 +48,10 @@ public class ElementAccessControllerGlobalPreFilter extends AbstractGlobalPreFil private static final Logger LOGGER = LoggerFactory.getLogger(ElementAccessControllerGlobalPreFilter.class); private static final String ROOT_CATEGORY_REACTOR = "reactor."; - private static final String ELEMENTS_ROOT_PATH = "elements"; + private static final Pattern PATH_API_VERSION = Pattern.compile("^/v(\\d)+/.*"); private final WebClient webClient; - private final ApplicationContext applicationContext; public ElementAccessControllerGlobalPreFilter(ApplicationContext context, ServiceURIsConfig servicesURIsConfig, WebClient.Builder webClientBuilder) { @@ -72,31 +71,34 @@ public Mono filter(@NonNull ServerWebExchange exchange, @NonNull GatewayFi RequestPath path = exchange.getRequest().getPath(); - // Filter only requests to the endpoint servers with this pattern : /v/ - if (!Pattern.matches("/v(\\d)+/.*", path.value())) { + // Filter only requests to the endpoint servers with this pattern: /v/ + if (!PATH_API_VERSION.matcher(path.value()).matches()) { return chain.filter(exchange); } - // Is an elements' endpoint with a controlled access ? - String endPointServiceName = Objects.requireNonNull((String) (Objects.requireNonNull((Route) exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR)).getMetadata()).get(END_POINT_SERVICE_NAME)); - EndPointServer endPointServer = applicationContext.containsBean(endPointServiceName) ? (EndPointServer) applicationContext.getBean(endPointServiceName) : null; - if (endPointServer == null || !endPointServer.hasElementsAccessControl()) { + // Is an elements' endpoint with controlled access? + final EndPointServer endPointServer = Optional.ofNullable((Route) exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR)) + .map(Route::getMetadata) + .map(metadata -> (String) metadata.get(END_POINT_SERVICE_NAME)) + .map(endPointServiceName -> applicationContext.containsBean(endPointServiceName) ? (EndPointServer) applicationContext.getBean(endPointServiceName) : null) + .orElse(null); + if (!(endPointServer instanceof EndPointAccessControlledServer accessControlledServer)) { return chain.filter(exchange); } - // Is a root path with a controlled access ? - EndPointElementServer endPointElementServer = (EndPointElementServer) endPointServer; - if (endPointElementServer.isNotControlledRootPath(path.elements().get(3).value())) { + // Is a root path with controlled access? + if (accessControlledServer.isNotControlledRootPath(path.elements().get(3).value())) { return chain.filter(exchange); } - // Is a method allowed ? - if (!endPointElementServer.isAllowedMethod(exchange.getRequest().getMethod())) { + // Is a method allowed? + if (!accessControlledServer.isAllowedMethod(exchange.getRequest().getMethod())) { return completeWithCode(exchange, FORBIDDEN); } - Optional accessControlInfos = endPointElementServer.getAccessControlInfos(exchange.getRequest()); - return accessControlInfos.isEmpty() ? completeWithCode(exchange, FORBIDDEN) : isAccessAllowed(exchange, chain, accessControlInfos.get()); + return accessControlledServer.getAccessControlInfos(exchange.getRequest()) + .map(controlInfos -> isAccessAllowed(exchange, chain, controlInfos)) + .orElseGet(() -> completeWithCode(exchange, FORBIDDEN)); } private Mono isAccessAllowed(ServerWebExchange exchange, GatewayFilterChain chain, AccessControlInfos accessControlInfos) {