Commit eeca6aa0 authored by Nicola Fulvio Calabria's avatar Nicola Fulvio Calabria
Browse files

#3619: if group Write or group Read properties are not set in payload

then inherit them from parent node, if not null.
parent 9eef9cbe
Loading
Loading
Loading
Loading
+42 −13
Original line number Diff line number Diff line
@@ -73,21 +73,50 @@ public class CreateNodeController extends BaseNodeController {
        // Check if node creator property is set. If not set it according to 
        // token. In case of creator mistmatch between node and token throw
        // exception
        
        String creator = NodeProperties.getNodePropertyByURI(
                node, NodeProperties.CREATOR_URI);

        if(creator == null)
        {
        if (creator == null) {
            Property creatorProperty = new Property();
            creatorProperty.setUri(NodeProperties.CREATOR_URI);
            creatorProperty.setValue(principal.getName());
            node.getProperties().add(creatorProperty);
        } else {
            if(!creator.equals(principal.getName()))
                // maybe a more specific exception would be more appropriate?
            if (!creator.equals(principal.getName())) // maybe a more specific exception would be more appropriate?
            {
                throw new PermissionDeniedException(path);
            }
        }

        // If payload has no read groups specified, inherit from parent node
        String payloadReadGroups = NodeProperties.getNodePropertyByURI(
                node, NodeProperties.GROUP_READ_URI);

        if (payloadReadGroups == null) {
            String parentNodeReadGroups = NodeProperties.getNodePropertyByURI(
                    parentNode, NodeProperties.GROUP_READ_URI);
            if (parentNodeReadGroups != null) {
                Property readGroups = new Property();
                readGroups.setUri(NodeProperties.GROUP_READ_URI);
                readGroups.setValue(parentNodeReadGroups);
                node.getProperties().add(readGroups);
            }
        }

        // If payload has no write groups specified, inherit from parent node
        String payloadWriteGroups = NodeProperties.getNodePropertyByURI(
                node, NodeProperties.GROUP_WRITE_URI);

        if (payloadWriteGroups == null) {
            String parentNodeWriteGroups = NodeProperties.getNodePropertyByURI(
                    parentNode, NodeProperties.GROUP_WRITE_URI);
            if (parentNodeWriteGroups != null) {
                Property writeGroups = new Property();
                writeGroups.setUri(NodeProperties.GROUP_WRITE_URI);
                writeGroups.setValue(parentNodeWriteGroups);
                node.getProperties().add(writeGroups);
            }
        }

        nodeDao.createNode(node);

+0 −18
Original line number Diff line number Diff line
@@ -7,7 +7,6 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.http.ResponseEntity;

import net.ivoa.xml.vospace.v2.Node;
import net.ivoa.xml.vospace.v2.ContainerNode;

import it.inaf.oats.vospace.persistence.NodeDAO;
import javax.servlet.http.HttpServletRequest;
@@ -18,8 +17,6 @@ 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;
import java.util.stream.Collectors;
import java.util.List;

@RestController
public class ListNodeController extends BaseNodeController {
@@ -46,21 +43,6 @@ public class ListNodeController extends BaseNodeController {
            }
        }

        Node node = optNode.get();
        
        if(node instanceof ContainerNode)
        {
            ContainerNode cnd = (ContainerNode) node;
            List<Node> children = 
                    cnd.getNodes().stream().filter(
                            (n)->NodeUtils.checkIfReadable(
                                        n, principal.getName(), 
                                        principal.getGroups()))
                            .collect(Collectors.toList());
            cnd.setNodes(children);
            optNode = Optional.of(cnd);            
        }

        return ResponseEntity.ok(optNode.get());
    }
}
+113 −83
Original line number Diff line number Diff line
@@ -275,14 +275,13 @@ public class CreateNodeControllerTest {
    
    @Test
    public void testWriteOwnerAbsent() throws Exception {
         String requestBody = 
                 getResourceFileContent("create-unstructured-data-node.xml");
        String requestBody
                = getResourceFileContent("create-unstructured-data-node.xml");
        
        when(nodeDao.listNode(eq("/")))
                .thenReturn(Optional.of(getContainerParentNodeWithCreator("/")));

        // no node creator specified in xml file
         
        mockMvc.perform(put("/nodes/mydata1")
                .header("Authorization", "Bearer user2_token")
                .content(requestBody)
@@ -302,16 +301,47 @@ public class CreateNodeControllerTest {
        
    }
    
    @Test
    public void testGroupPropertiesAbsent() throws Exception {
        String requestBody
                = getResourceFileContent("create-unstructured-data-node.xml");
        
        ContainerNode cdn = getContainerParentNode("/");
        
        when(nodeDao.listNode(eq("/")))
                .thenReturn(Optional.of(cdn));

        // no node creator specified in xml file
        mockMvc.perform(put("/nodes/mydata1")
                .header("Authorization", "Bearer user2_token")
                .content(requestBody)
                .contentType(MediaType.APPLICATION_XML)
                .accept(MediaType.APPLICATION_XML))
                .andDo(print())
                .andExpect(status().is2xxSuccessful());

        // assert creator properties now matches user2
        verify(nodeDao, times(1)).createNode(argThat(node -> {
            UnstructuredDataNode udn = (UnstructuredDataNode) node;
            String groupRead = NodeProperties.getNodePropertyByURI(
                    udn, NodeProperties.GROUP_READ_URI);
            String groupWrite = NodeProperties.getNodePropertyByURI(
                    udn, NodeProperties.GROUP_WRITE_URI);
            return (groupRead == null && groupWrite.equals("group1 group2"));            
        }
        ));
        
    }
    
    @Test
    public void testWriteOwnerMismatch() throws Exception {
         String requestBody = 
                 getResourceFileContent("create-unstructured-data-node-user1.xml");
        String requestBody
                = getResourceFileContent("create-unstructured-data-node-user1.xml");
        
        when(nodeDao.listNode(eq("/")))
                .thenReturn(Optional.of(getContainerParentNodeWithCreator("/")));

        // no node creator specified in xml file
         
        mockMvc.perform(put("/nodes/mydata1")
                .header("Authorization", "Bearer user2_token")
                .content(requestBody)
+18 −60
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

@SpringBootTest
@AutoConfigureMockMvc
@@ -109,48 +108,6 @@ public class ListNodeControllerTest {
                .andExpect(status().is2xxSuccessful());       
    }

    @Test
    public void testRemoveUnreadable() throws Exception {
        // Create container node
        ContainerNode root = (ContainerNode) getRootNode().get();

        Node node1 = getDataNodeByOwnership("user1", "group10");
        node1.setUri(URI_PREFIX + "/mynode1");
        root.getNodes().add(node1);

        Node node2 = getDataNodeByOwnership("user1", "group10");
        node2.setUri(URI_PREFIX + "/mynode2");
        root.getNodes().add(node2);

        Node node3 = getDataNodeByOwnership("user2", "group10");
        node3.setUri(URI_PREFIX + "/mynode3");
        root.getNodes().add(node3);

        Node node4 = getDataNodeByOwnership("user3", "group10");
        node4.setUri(URI_PREFIX + "/mynode4");
        root.getNodes().add(node4);

        when(dao.listNode(eq("/"))).thenReturn(Optional.of(root));

        String xml = mockMvc.perform(get("/nodes/")
                .header("Authorization", "Bearer user2_token")
                .accept(MediaType.APPLICATION_XML))
                .andExpect(status().is2xxSuccessful())
                .andDo(print())
                .andReturn().getResponse().getContentAsString();
        
        Document doc = loadDocument(xml);
        assertEquals("vos:node", doc.getDocumentElement().getNodeName());
        assertEquals("vos:ContainerNode", doc.getDocumentElement().getAttribute("xsi:type"));
        NodeList nl = doc.getDocumentElement().getElementsByTagName("vos:nodes");        
        
        assertEquals(1, nl.getLength());
        NodeList children = nl.item(0).getChildNodes();
        assertEquals(2, children.getLength());
        verify(dao, times(1)).listNode(eq("/"));

    }

    private Optional<Node> getRootNode() {
        ContainerNode root = new ContainerNode();
        root.setUri(URI_PREFIX + "/");
@@ -174,7 +131,8 @@ public class ListNodeControllerTest {
        return node;
    }
    
    private Node getDataNodeByOwnership(String ownerID, String group) {
    private Node getDataNodeByOwnership(String ownerID, String group)
    {
        DataNode node = new DataNode();
        node.setUri(URI_PREFIX + "/mynode");
        // Set owner