package it.inaf.oats.vospace; import it.inaf.ia2.aa.data.User; import it.inaf.oats.vospace.datamodel.NodeUtils; import it.inaf.oats.vospace.exception.LinkFoundException; import it.inaf.oats.vospace.exception.NodeNotFoundException; import it.inaf.oats.vospace.exception.PermissionDeniedException; import it.inaf.oats.vospace.persistence.NodeDAO; import java.util.List; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.vospace.v2.Node; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController public class SetNodeController extends BaseNodeController { @Autowired private NodeDAO nodeDao; @Value("${vospace-authority}") private String authority; @PostMapping(value = {"/nodes", "/nodes/**"}, 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 setNode(@RequestBody Node node, User principal, HttpServletRequest request) { String path = getPath(); //The service SHALL throw a HTTP 404 status code including a NodeNotFound //fault in the entity-body if the target Node does not exist Node toBeModifiedNode = nodeDao.listNode(path) .orElseThrow(() -> new NodeNotFoundException(path)); // The service SHALL throw a HTTP 403 status code including a PermissionDenied fault // in the entity-body if the user does not have permissions to perform the operation if(!NodeUtils.checkIfWritable(toBeModifiedNode, principal.getName(), principal.getGroups())) { throw new PermissionDeniedException(path); } // The service SHALL throw a HTTP 403 status code including a PermissionDenied fault // in the entity-body if the request attempts to modify a read-only Property. // This method cannot be used to modify the Node type. // This method cannot be used to modify the accepts or provides list of Views for the Node. // This method cannot be used to create children of a container Node. // If a parent node in the URI path does not exist then the service SHALL throw a // HTTP 404 status code including a ContainerNotFound fault in the entity-body // For example, given the URI path /a/b/c, the service must throw a HTTP 404 status // code including a ContainerNotFound fault in the entity-body if either /a or /a/b // do not exist. List pathComponents = NodeUtils.subPathComponents(path); if (pathComponents.size() == 0) { // Manage root node throw new PermissionDeniedException("root"); } else { // Manage all precursors in full path for (int i = 0; i < pathComponents.size(); i++) { String tmpPath = pathComponents.get(i); Node mynode = nodeDao.listNode(tmpPath) .orElseThrow(() -> new NodeNotFoundException(tmpPath)); if (mynode.getType().equals("vos:LinkNode") && i < pathComponents.size()-1) // a LinkNode leaf can be deleted throw new LinkFoundException(tmpPath); } } //The service SHOULD throw a HTTP 500 status code including an InternalFault fault // in the entity-body if the operation fails // to be fixed // A HTTP 200 status code and a Node representation in the entity-body The full // expanded record for the node SHALL be returned, including any xsi:type // specific extensions. return node; } }