Skip to content
CreateNodeService.java 4.66 KiB
Newer Older
/*
 * This file is part of vospace-rest
 * Copyright (C) 2021 Istituto Nazionale di Astrofisica
 * SPDX-License-Identifier: GPL-3.0-or-later
 */
package it.inaf.oats.vospace;

import it.inaf.ia2.aa.data.User;
import it.inaf.oats.vospace.datamodel.NodeProperties;
import it.inaf.oats.vospace.datamodel.NodeUtils;
import it.inaf.oats.vospace.exception.ContainerNotFoundException;
import it.inaf.oats.vospace.exception.DuplicateNodeException;
import it.inaf.oats.vospace.exception.LinkFoundException;
import it.inaf.oats.vospace.exception.PermissionDeniedException;
import it.inaf.oats.vospace.persistence.NodeDAO;
import net.ivoa.xml.vospace.v2.Node;
import net.ivoa.xml.vospace.v2.Property;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Service
@EnableTransactionManagement
public class CreateNodeService {

    @Autowired
    private NodeDAO nodeDao;

    private static final Logger LOG = LoggerFactory.getLogger(CreateNodeService.class);

    public Node createNode(Node node, String path, User principal) {
        
        LOG.debug("createNodeService called for node with URI {} and PATH {}", 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 PermissionDeniedException.forPath(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 PermissionDeniedException.forPath(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);
    private String getParentPath(String path) {
        return NodeUtils.getParentPath(path);
    }    
}