Skip to content
CreateNodeController.java 4.51 KiB
Newer Older
Sara Bertocco's avatar
Sara Bertocco committed
package it.inaf.oats.vospace;

import it.inaf.oats.vospace.datamodel.NodeProperties;
import it.inaf.oats.vospace.datamodel.NodeUtils;
Sara Bertocco's avatar
Sara Bertocco committed
import net.ivoa.xml.vospace.v2.Node;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Autowired;
import it.inaf.oats.vospace.persistence.NodeDAO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PutMapping;
import it.inaf.oats.vospace.exception.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.ivoa.xml.vospace.v2.Property;
Sara Bertocco's avatar
Sara Bertocco committed

@RestController
public class CreateNodeController extends BaseNodeController {
Sara Bertocco's avatar
Sara Bertocco committed

    private static final Logger LOG = LoggerFactory.getLogger(CreateNodeController.class);
    
    @Value("${vospace-authority}")
    private String authority;

            consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE},
            produces = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})
    public Node createNode(@RequestBody Node node, User principal) {

        String path = getPath();
        
        LOG.debug("createNode called for path {}", path);
Sara Bertocco's avatar
Sara Bertocco committed

            throw new InvalidURIException(node.getUri());
        // Check if payload URI is consistent with http request
        if (!isUrlConsistentWithPayloadURI(node.getUri(), path)) {
            throw new InvalidURIException(node.getUri(), path);
        }

        // Check if another node is already present at specified path
        // This checks if the user is trying to insert the root node at "/" too
        if (nodeDao.listNode(path).isPresent()) {
            throw new DuplicateNodeException(path);
        }

        // Retrieve parent node 
        Node parentNode = nodeDao.listNode(getParentPath(path))
                .orElseThrow(() -> new ContainerNotFoundException(getParentPath(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));
            }
        }              
        
        if(!NodeUtils.checkIfWritable(parentNode, principal.getName(), principal.getGroups())) {
            throw new PermissionDeniedException(path);
        
        // 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)
        {
            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?
                throw new PermissionDeniedException(path);
        }       
        nodeDao.createNode(node);

Sara Bertocco's avatar
Sara Bertocco committed
    }
    // Assuming that this service implementation uses only ! as a separator
    // in the authority part of the URI
    private boolean isValidURI(String nodeURI) {
            parsedAuthority = nodeURI.replaceAll("vos://", "").split("/", -1)[0];

        if (parsedAuthority.isEmpty()
                || !parsedAuthority.replace("~", "!").equals(authority)) {
    }

    private boolean isUrlConsistentWithPayloadURI(String nodeURI, String path) {
        // It's assumed that nodeURI has been validated to be in the expected 
        // form vos://authority[!~]somepath/mynode..."

        return nodeURI.replaceAll("vos://[^/]+", "").equals(path);
    }
Sara Bertocco's avatar
Sara Bertocco committed
}