diff --git a/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java b/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java index 467a0eee12c51877db3d1db08e87427a419386e6..b4b3356276876caf282bb4b0136ff723789a342f 100644 --- a/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java +++ b/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java @@ -12,8 +12,11 @@ import java.sql.SQLException; import java.sql.Types; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; import javax.sql.DataSource; @@ -147,6 +150,9 @@ public class NodeDAO { return ps; }); + if (recursive == true) + updatePermissionsRecursively(newNode, vosPath); + return newNode; } @@ -366,6 +372,79 @@ public class NodeDAO { } } + + /* + Map contains: + Key column + column name value + column name value + and value is a String containing comma separated groups having permissions + */ + private Map getPermissionsFromDB(String vosPath) { + + String sql = "SELECT group_read, group_write " + + "FROM node n JOIN node_vos_path p ON n.node_id = p.node_id " + + "WHERE p.vos_path = ?"; + + Map<String, Object> result = (Map<String, Object>) jdbcTemplate + .queryForMap(sql, new Object[] {vosPath}); + + return result; + + } + + private void updatePermissionsRecursively(Node newNode, String vosPath) { + + Map permissions = getPermissionsFromDB(vosPath); + String existingGroupReadStr = (String)permissions.get("group_read"); + String existingGroupWriteStr = (String)permissions.get("group_write"); + + List<String> existingGroupReadList = NodeProperties.parsePropertyStringToList(existingGroupReadStr); + List<String> existingGroupWriteList = NodeProperties.parsePropertyStringToList(existingGroupWriteStr); + + List<String> newGroupReadList = NodeProperties.getNodePropertyAsListByURI(newNode, NodeProperties.GROUP_READ_URI); + List<String> newGroupWriteList = NodeProperties.getNodePropertyAsListByURI(newNode, NodeProperties.GROUP_WRITE_URI); + + Set<String> existingGroupRead = new HashSet<>(existingGroupReadList); + Set<String> existingGroupWrite = new HashSet<>(existingGroupWriteList); + + Set<String> newGroupRead = new HashSet<>(newGroupReadList); + Set<String> newGroupWrite = new HashSet<>(newGroupWriteList); + + Set<String> groupReadToAdd = differenceBetweenSets(newGroupRead, existingGroupRead) ; + Set<String> groupReadToRemove = differenceBetweenSets(existingGroupRead, newGroupRead) ; + + Set<String> groupWriteToAdd = differenceBetweenSets(newGroupWrite, existingGroupWrite) ; + Set<String> groupWriteToRemove = differenceBetweenSets(existingGroupWrite, newGroupWrite) ; + + String sql = "UPDATE node SET " + + "group_read = update_array(group_read, " + groupReadToAdd + ", " + groupReadToRemove + "), " + + "group_write = update_array(group_write, " + groupWriteToAdd + ", " + groupWriteToRemove + "), " + + "is_public = ? " + + "WHERE path <@ (SELECT path FROM node n " + + "JOIN node_vos_path p ON n.node_id = p.node_id " + + "AND p.vos_path = ?)"; + + + jdbcTemplate.update(conn -> { + PreparedStatement ps = conn.prepareStatement(sql); + int i = 0; + ps.setBoolean(++i, Boolean.valueOf(NodeProperties.getNodePropertyByURI(newNode, NodeProperties.PUBLIC_READ_URI))); + ps.setString(++i, vosPath); + return ps; + }); + + } + + // Returns the difference a minus b + private Set<String> differenceBetweenSets(Set<String> a, Set<String> b) { + + Set<String> diff = new HashSet<>(a); + diff.removeAll(b); + + return diff; + + } private List<NodePaths> getNodePathsFromDB(String nodeURI) { @@ -411,5 +490,6 @@ public class NodeDAO { return this.relativePath; } - } + } + }