Skip to content
Snippets Groups Projects
Commit 65764bfb authored by Nicola Fulvio Calabria's avatar Nicola Fulvio Calabria
Browse files

#3636 - Handle permissions in ListNodeController

parent 9713a744
No related branches found
No related tags found
No related merge requests found
Pipeline #1040 passed
...@@ -13,6 +13,10 @@ import javax.servlet.http.HttpServletRequest; ...@@ -13,6 +13,10 @@ import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import it.inaf.ia2.aa.data.User;
import it.inaf.oats.vospace.datamodel.NodeUtils;
import java.util.Optional;
import it.inaf.oats.vospace.exception.PermissionDeniedException;
@RestController @RestController
public class ListNodeController extends BaseNodeController { public class ListNodeController extends BaseNodeController {
...@@ -24,10 +28,21 @@ public class ListNodeController extends BaseNodeController { ...@@ -24,10 +28,21 @@ public class ListNodeController extends BaseNodeController {
@GetMapping(value = {"/nodes", "/nodes/**"}, @GetMapping(value = {"/nodes", "/nodes/**"},
produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_XML_VALUE}) produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_XML_VALUE})
public ResponseEntity<Node> listNode(HttpServletRequest request) { public ResponseEntity<Node> listNode(HttpServletRequest request, User principal) {
String path = getPath(); String path = getPath();
LOG.debug("listNode called for path {}", path); LOG.debug("listNode called for path {}", path);
return ResponseEntity.ok(nodeDAO.listNode(path)
.orElseThrow(() -> new NodeNotFoundException(path))); Optional<Node> optNode = nodeDAO.listNode(path);
if (optNode.isEmpty()) {
throw new NodeNotFoundException(path);
} else {
if (!NodeUtils.checkIfReadable(
optNode.get(), principal.getName(), principal.getGroups())) {
throw new PermissionDeniedException(path);
}
}
return ResponseEntity.ok(optNode.get());
} }
} }
package it.inaf.oats.vospace; package it.inaf.oats.vospace;
import static it.inaf.oats.vospace.VOSpaceXmlTestUtil.loadDocument; import static it.inaf.oats.vospace.VOSpaceXmlTestUtil.loadDocument;
import it.inaf.oats.vospace.datamodel.NodeProperties;
import it.inaf.oats.vospace.persistence.NodeDAO; import it.inaf.oats.vospace.persistence.NodeDAO;
import java.util.Optional; import java.util.Optional;
import net.ivoa.xml.vospace.v2.ContainerNode; import net.ivoa.xml.vospace.v2.ContainerNode;
import net.ivoa.xml.vospace.v2.DataNode; import net.ivoa.xml.vospace.v2.DataNode;
import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Node;
import net.ivoa.xml.vospace.v2.Property;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
...@@ -16,7 +18,10 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -16,7 +18,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
...@@ -25,6 +30,8 @@ import org.w3c.dom.Document; ...@@ -25,6 +30,8 @@ import org.w3c.dom.Document;
@SpringBootTest @SpringBootTest
@AutoConfigureMockMvc @AutoConfigureMockMvc
@ContextConfiguration(classes = {TokenFilterConfig.class})
@TestPropertySource(properties = "spring.main.allow-bean-definition-overriding=true")
public class ListNodeControllerTest { public class ListNodeControllerTest {
private static final String URI_PREFIX = "vos://example.com!vospace"; private static final String URI_PREFIX = "vos://example.com!vospace";
...@@ -78,9 +85,38 @@ public class ListNodeControllerTest { ...@@ -78,9 +85,38 @@ public class ListNodeControllerTest {
.andExpect(status().isNotFound()); .andExpect(status().isNotFound());
} }
@Test
public void testPermissionDeniedUser() throws Exception {
Node node = getDataNodeByOwnership("user2","group1");
when(dao.listNode(eq("/mynode"))).thenReturn(Optional.of(node));
mockMvc.perform(get("/nodes/mynode")
.header("Authorization", "Bearer user1_token")
.accept(MediaType.APPLICATION_XML))
.andExpect(status().is4xxClientError());
}
@Test
public void testGrantedByGroup() throws Exception {
Node node = getDataNodeByOwnership("user1","group1");
when(dao.listNode(eq("/mynode"))).thenReturn(Optional.of(node));
mockMvc.perform(get("/nodes/mynode")
.header("Authorization", "Bearer user2_token")
.accept(MediaType.APPLICATION_XML))
.andExpect(status().is2xxSuccessful());
}
private Optional<Node> getRootNode() { private Optional<Node> getRootNode() {
ContainerNode root = new ContainerNode(); ContainerNode root = new ContainerNode();
root.setUri(URI_PREFIX + "/"); root.setUri(URI_PREFIX + "/");
Property publicProperty = new Property();
publicProperty.setUri(NodeProperties.PUBLIC_READ_URI);
publicProperty.setValue("true");
root.getProperties().add(publicProperty);
root.getNodes().add(getDataNode()); root.getNodes().add(getDataNode());
return Optional.of(root); return Optional.of(root);
} }
...@@ -88,6 +124,29 @@ public class ListNodeControllerTest { ...@@ -88,6 +124,29 @@ public class ListNodeControllerTest {
private Node getDataNode() { private Node getDataNode() {
DataNode node = new DataNode(); DataNode node = new DataNode();
node.setUri(URI_PREFIX + "/mynode"); node.setUri(URI_PREFIX + "/mynode");
Property publicProperty = new Property();
publicProperty.setUri(NodeProperties.PUBLIC_READ_URI);
publicProperty.setValue("true");
node.getProperties().add(publicProperty);
return node;
}
private Node getDataNodeByOwnership(String ownerID, String group)
{
DataNode node = new DataNode();
node.setUri(URI_PREFIX + "/mynode");
// Set owner
Property creatorProperty = new Property();
creatorProperty.setUri(NodeProperties.CREATOR_URI);
creatorProperty.setValue(ownerID);
node.getProperties().add(creatorProperty);
// set group
Property readGroupProperty = new Property();
readGroupProperty.setUri(NodeProperties.GROUP_READ_URI);
readGroupProperty.setValue(group);
node.getProperties().add(readGroupProperty);
return node; return node;
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment