diff --git a/src/main/java/de/thm/arsnova/controller/JsonViewControllerAdvice.java b/src/main/java/de/thm/arsnova/controller/JsonViewControllerAdvice.java new file mode 100644 index 0000000000000000000000000000000000000000..1e0b1c79a5f5305eb00895b12ed639b60696c643 --- /dev/null +++ b/src/main/java/de/thm/arsnova/controller/JsonViewControllerAdvice.java @@ -0,0 +1,87 @@ +/* + * This file is part of ARSnova Backend. + * Copyright (C) 2012-2019 The ARSnova Team and Contributors + * + * ARSnova Backend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ARSnova Backend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package de.thm.arsnova.controller; + +import de.thm.arsnova.model.serialization.View; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.MethodParameter; +import org.springframework.http.MediaType; +import org.springframework.http.converter.json.MappingJacksonValue; +import org.springframework.http.server.ServerHttpRequest; +import org.springframework.http.server.ServerHttpResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.AbstractMappingJacksonResponseBodyAdvice; +import org.springframework.web.util.UriComponentsBuilder; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * This {@link ControllerAdvice} applies a {@link View} based on the + * <code>view</code> query parameter which is used by + * {@link com.fasterxml.jackson.annotation.JsonView} for serialization and makes + * sure that the user is authorized. + * + * @author Daniel Gerhardt + */ +@ControllerAdvice +public class JsonViewControllerAdvice extends AbstractMappingJacksonResponseBodyAdvice { + private static final String VIEW_PARAMETER = "view"; + + private static final Logger logger = LoggerFactory.getLogger(JsonViewControllerAdvice.class); + + @Override + protected void beforeBodyWriteInternal(final MappingJacksonValue bodyContainer, + final MediaType contentType, final MethodParameter returnType, + final ServerHttpRequest request, final ServerHttpResponse response) { + /* TODO: Why does @ControllerAdvice(assignableTypes = AbstractEntityController.class) not work? */ + if (!AbstractEntityController.class.isAssignableFrom(returnType.getContainingClass())) { + return; + } + + final List<String> viewList = UriComponentsBuilder.fromUri(request.getURI()).build() + .getQueryParams().getOrDefault(VIEW_PARAMETER, Collections.emptyList()); + if (viewList.isEmpty()) { + return; + } + final String view = viewList.get(0); + logger.debug("'{}' parameter found in request URI: {}", VIEW_PARAMETER, view); + if (bodyContainer.getValue() instanceof Collection) { + logger.warn("'{}' parameter is currently not supported for listing endpoints.", VIEW_PARAMETER); + } + tryAccess(bodyContainer.getValue(), view); + switch (view) { + case "owner": + bodyContainer.setSerializationView(View.Owner.class); + break; + case "admin": + bodyContainer.setSerializationView(View.Admin.class); + break; + default: + return; + } + } + + @PreAuthorize("hasPermission(#targetDomainObject, #permission)") + protected void tryAccess(final Object targetDomainObject, final Object permission) { + /* Access check is done by aspect. No additional implementation needed. */ + } +} diff --git a/src/main/java/de/thm/arsnova/model/serialization/View.java b/src/main/java/de/thm/arsnova/model/serialization/View.java index 3e056daa3cb65feb88022d04fef840b74d228b9c..b97ab7860348df7c01713e588b0b7ed505137708 100644 --- a/src/main/java/de/thm/arsnova/model/serialization/View.java +++ b/src/main/java/de/thm/arsnova/model/serialization/View.java @@ -18,6 +18,8 @@ package de.thm.arsnova.model.serialization; public class View { - public interface Public {} public interface Persistence {} + public interface Public {} + public interface Owner extends Public {} + public interface Admin extends Owner {} }