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

BugFix #3613 - Fixed CreateNodeController: if userId matches parent node

creator property write is allowed. 
parent 5700e878
Loading
Loading
Loading
Loading
+54 −26
Original line number Diff line number Diff line
@@ -12,7 +12,6 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PutMapping;
import it.inaf.oats.vospace.exception.*;
import java.util.stream.Collectors;
import java.util.Arrays;

@RestController
public class CreateNodeController extends BaseNodeController {
@@ -30,8 +29,6 @@ public class CreateNodeController extends BaseNodeController {

        String path = getPath();

        List<String> userGroups = principal.getGroups();

        // Validate payload node URI
        if (!isValidURI(node.getUri())) {
            throw new InvalidURIException(node.getUri());
@@ -52,37 +49,53 @@ public class CreateNodeController extends BaseNodeController {
        Node parentNode = nodeDao.listNode(getParentPath(path))
                .orElseThrow(() -> new ContainerNotFoundException(getParentPath(path)));

        // Check user write/ownership privilege against parent node
        List<String> groupWritePropValues
                = getNodePropertyByURI(parentNode, "ivo://ivoa.net/vospace/core#groupwrite");

        if (groupWritePropValues.isEmpty()) {
            throw new PermissionDeniedException(path);
        // Check if parent node is not a Container node and in case throw
        // appropriate exception
        if (!parentNode.getType().equals("vos:ContainerNode")) {
            if (parentNode.getType().equals("vos:LinkNode")) {
                throw new LinkFoundException(getParentPath(path));
            } else {
                throw new ContainerNotFoundException(getParentPath(path));
            }
        }

        List<String> nodeGroups
                = Arrays.asList(groupWritePropValues.get(0).split(" ", -1));

        if (userGroups == null
                || !nodeGroups.stream().anyMatch((i) -> userGroups.contains(i))) {
            // If groups don't match check ownership at least
        // First check if parent node creator is == userid
        List<String> nodeOwner
                    = getNodePropertyByURI(parentNode, "ivo://ivoa.net/vospace/core#creator");
                = getNodePropertyByURI(
                        parentNode, "ivo://ivoa.net/vospace/core#creator");

            if (nodeOwner.isEmpty()
        if (nodeOwner == null
                || nodeOwner.isEmpty()
                || !nodeOwner.get(0).equals(principal.getName())) {
            // Node owner check has failed: let's check if user can write
            // due to group privileges
            
            List<String> userGroups = principal.getGroups();

            // If the user doesn't belong to any groups throw exception
            if (userGroups == null || userGroups.isEmpty()) {
                throw new PermissionDeniedException(path);
            }         
            
            List<String> groupWritePropValues
                    = getNodePropertyByURI(parentNode,
                            "ivo://ivoa.net/vospace/core#groupwrite");

            // If groupwrite property is absent in Parent Node throw exception
            if (groupWritePropValues == null
                    || groupWritePropValues.isEmpty()) {
                throw new PermissionDeniedException(path);
            }

        // Check if parent node is not a Container node and in case throw
        // appropriate exception
        if (!parentNode.getType().equals("vos:ContainerNode")) {
            if (parentNode.getType().equals("vos:LinkNode")) {
                throw new LinkFoundException(getParentPath(path));
            } else {
                throw new ContainerNotFoundException(getParentPath(path));
            List<String> nodeGroups
                    = parsePropertyStringToList(groupWritePropValues.get(0));

            if (nodeGroups.isEmpty()
                    || !nodeGroups.stream()
                            .anyMatch((i) -> userGroups.contains(i))) {
                throw new PermissionDeniedException(path);
            }

        }

        return node;
@@ -151,4 +164,19 @@ public class CreateNodeController extends BaseNodeController {

        return propertyList;
    }

    private List<String> parsePropertyStringToList(String property) {
        // If separator changes, this method should remain consistent
        // For now it assumes that " " is the separator        
        String separator = " ";

        String trimmedProperty = property.trim();
        if (trimmedProperty.isEmpty()) {
            return List.of();
        }

        return List.of(trimmedProperty.split(separator));

    }

}
+1 −5
Original line number Diff line number Diff line
@@ -64,14 +64,10 @@ public class CreateNodeControllerTest {
        ContainerNode parentNode = new ContainerNode();
        // Set parent node address at /
        parentNode.setUri("vos://example.com!vospace" + path);
        // Set groupwrite property
        Property groups = new Property();
        groups.setUri("ivo://ivoa.net/vospace/core#groupwrite");
        groups.setValue("group3");
        Property creator = new Property();
        creator.setUri("ivo://ivoa.net/vospace/core#creator");
        creator.setValue("user2");        
        parentNode.setProperties(List.of(groups,creator));
        parentNode.setProperties(List.of(creator));
        return parentNode;
    }