From 5c4d42c29b6a81c843018f3772a45e3c0ecd9a5d Mon Sep 17 00:00:00 2001 From: Sara Bertocco <sara.bertocco@inaf.it> Date: Tue, 2 Feb 2021 18:22:54 +0100 Subject: [PATCH] working on task #3635 - Refactoring: create NodeUtils class --- .../vospace/datamodel/NodeProperties.java | 74 ++++++++++ .../oats/vospace/datamodel/NodeUtils.java | 132 ++++++++++++++++++ 2 files changed, 206 insertions(+) create mode 100644 src/main/java/it/inaf/oats/vospace/datamodel/NodeProperties.java create mode 100644 src/main/java/it/inaf/oats/vospace/datamodel/NodeUtils.java diff --git a/src/main/java/it/inaf/oats/vospace/datamodel/NodeProperties.java b/src/main/java/it/inaf/oats/vospace/datamodel/NodeProperties.java new file mode 100644 index 0000000..c704b4a --- /dev/null +++ b/src/main/java/it/inaf/oats/vospace/datamodel/NodeProperties.java @@ -0,0 +1,74 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package it.inaf.oats.vospace.datamodel; + +import java.util.List; +import java.util.stream.Collectors; +import net.ivoa.xml.vospace.v2.Node; + +/** + * + * @author bertocco + */ +public class NodeProperties { + + + private NodeProperties() { } + + public static final String AVAILABLE_SPACE_URI = "ivo://ivoa.net/vospace/core#availableSpace"; // the amount of space available within a container + public static final String INITIAL_CREATION_TIME_URI = "ivo://ivoa.net/vospace/core#btime"; // the initial creation time + public static final String CONTRIBUTOR_URI = "ivo://ivoa.net/vospace/core#contributor"; // an entity responsible for making contributions to this resource + public static final String COVERAGE_URI = "ivo://ivoa.net/vospace/core#coverage"; // a spatial or temporal topic of the resource, the spatial applicability of the resource, or the jurisdiction under which the resource is relevant + public static final String CREATOR_URI = "ivo://ivoa.net/vospace/core#creator"; // an entity primarily responsible for making the resource + public static final String STATUS_CHANGE_TIME_URI = "ivo://ivoa.net/vospace/core#ctime"; // the status change (aka metadata modification) time + public static final String DATE_URI = "ivo://ivoa.net/vospace/core#date"; // a point or period of time associated with an event in the lifecycle of the resource + public static final String DESCRIPTION_URI = "ivo://ivoa.net/vospace/core#description"; // an account of the resource + public static final String FORMAT_URI = "ivo://ivoa.net/vospace/core#format"; // the file format, physical medium or dimensions of the resource + public static final String GROUP_READ_URI = "ivo://ivoa.net/vospace/core#groupread"; // the list of groups which can only read this resource delimiter-separated + public static final String GROUP_WRITE_URI = "ivo://ivoa.net/vospace/core#groupwrite"; // the list of groups which can read and write to this resource delimiter-separated + public static final String IDENTIFIER_URI = "ivo://ivoa.net/vospace/core#identifier"; // an unambiguous reference to the resource within a given context + public static final String LANGUAGE_URI = "ivo://ivoa.net/vospace/core#language"; // a language of the resource + public static final String CORE_URI = "ivo://ivoa.net/vospace/core#length"; // the length or size of a resource + public static final String MODIFICATION_TIME_URI = "ivo://ivoa.net/vospace/core#mtime"; // the data modification time + public static final String PUBLIC_READ_URI = "ivo://ivoa.net/vospace/core#publicread"; // whether this resource is world readable + public static final String PUBLISHER_URI = "ivo://ivoa.net/vospace/core#publisher"; // an entity responsible for making the resource available + public static final String QUOTA_URI = "ivo://ivoa.net/vospace/core#quota"; // the value of a system quota on the resource + public static final String RELATED_RESOURCE_URI = "ivo://ivoa.net/vospace/core#relation"; // a related resource + public static final String RIGHTS_ON_URI = "ivo://ivoa.net/vospace/core#rights"; // information about rights held in and over the resource + public static final String RESOURCE_RELATED_URI = "ivo://ivoa.net/vospace/core#source"; // a related resource from which the described resource is derived + public static final String SUBJECT_URI = "ivo://ivoa.net/vospace/core#subject"; // the topic of the resource + public static final String TITLE_URI = "ivo://ivoa.net/vospace/core#title"; // a name given to the resource + public static final String TYPE_URI = "ivo://ivoa.net/vospace/core#type"; // the nature or genre of the resource + + + // Returns all properties stored inside the node under the requested + // property URI. + public static List<String> getNodePropertyByURI(Node node, String propertyURI) { + + List<String> propertyList = node.getProperties().stream() + .filter((i) -> i.getUri() + .equals(propertyURI)) + .map((i) -> i.getValue()) + .collect(Collectors.toList()); + + return propertyList; + } + + public static 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)); + + } + +} diff --git a/src/main/java/it/inaf/oats/vospace/datamodel/NodeUtils.java b/src/main/java/it/inaf/oats/vospace/datamodel/NodeUtils.java new file mode 100644 index 0000000..853afb8 --- /dev/null +++ b/src/main/java/it/inaf/oats/vospace/datamodel/NodeUtils.java @@ -0,0 +1,132 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package it.inaf.oats.vospace.datamodel; + +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; +import net.ivoa.xml.vospace.v2.Node; + + +public class NodeUtils { + + + + /** + * Slash is a special character in defining REST endpoints and trying to + * define a PathVariable containing slashes doesn't work, so the endpoint + * has been defined using "/nodes/**" instead of "/nodes/{path}" and the + * path is extracted manually parsing the request URL. + */ + public static String getPathFromRequestURLString(String requestUrlString ) { + + String[] split = requestUrlString.split("/nodes/"); + + String path = "/"; + if (split.length == 2) { + path += split[1]; + } + return path; + } + + // This method assumes that URL is in the format /node1/node2/... + // multiple slashes as a single separator are allowed + // But the output has only single slash separators + public static String getParentPath(String path) { + + String[] parsedPath = path.split("[/]+"); + + if (parsedPath.length < 2 || !parsedPath[0].isEmpty()) { + throw new IllegalArgumentException(); + } + + StringBuilder sb = new StringBuilder(); + sb.append("/"); + + for (int i = 1; i < parsedPath.length - 1; i++) { + sb.append(parsedPath[i]); + if (i < parsedPath.length - 2) { + sb.append("/"); + } + } + + return sb.toString(); + } + + + public static List<String> subPathComponents(String path) { + + List resultList = new ArrayList<String>(); + + String[] pathComponents = path.split("[/]+"); + + if (pathComponents.length == 0) { + + // Manage root node + resultList.add("/"); + + } else { + + // Manage all precursors in full path + String parentPath="/"; + for (int i = 1; i < pathComponents.length; i++) { + parentPath = parentPath + pathComponents[i] + "/"; + // "I'm managing path = " + parentPath.substring(0, parentPath.length()-1)); + resultList.add(parentPath.substring(0, parentPath.length()-1)); + + } + + } + + return resultList; + + } + + public static boolean checkIfWritable(Node myNode, String userName, List<String> userGroups) { + + List<String> nodeOwner + = NodeProperties.getNodePropertyByURI(myNode, NodeProperties.CREATOR_URI); + //= getNodePropertyByURI( + // toBeDeletedNode, "ivo://ivoa.net/vospace/core#creator"); + + + if (nodeOwner == null + || nodeOwner.isEmpty() + || !nodeOwner.get(0).equals(userName)) { + // Node owner check has failed: let's check if user can write + // due to group privileges + + // If the user doesn't belong to any groups throw exception + if (userGroups == null || userGroups.isEmpty()) { + return false; + } + + List<String> groupWritePropValues + = NodeProperties.getNodePropertyByURI(myNode, + NodeProperties.GROUP_WRITE_URI); + + // If groupwrite property is absent in Parent Node throw exception + if (groupWritePropValues == null + || groupWritePropValues.isEmpty()) { + return false; + } + + List<String> nodeGroups + = NodeProperties.parsePropertyStringToList(groupWritePropValues.get(0)); + + if (nodeGroups.isEmpty() + || !nodeGroups.stream() + .anyMatch((i) -> userGroups.contains(i))) { + return false; + } + + } + + // DUPLICATED code from CreateNodeController - END + return true; + } + +} -- GitLab