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 b8190999814713677945a5179c68d9e28d8cbb86..c412581c9c91bdd73b76adc54970693812fff9ca 100644 --- a/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java +++ b/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java @@ -460,8 +460,8 @@ public class NodeDAO { String sql = "SELECT COUNT(c.node_id) = 0 " + "FROM node n " + "JOIN node c ON c.path <@ n.path " - + "WHERE n.node_id = ? " - + "(NOT COALESCE(c.is_public, FALSE) " + + "WHERE n.node_id = ? AND " + + "NOT COALESCE(c.is_public, FALSE) " + "AND (SELECT COUNT(*) FROM (SELECT UNNEST(?) INTERSECT SELECT UNNEST(c.group_read)) AS allowed_groups) = 0 " + "AND c.creator_id <> ?"; diff --git a/src/test/java/it/inaf/oats/vospace/NodeBranchServiceTest.java b/src/test/java/it/inaf/oats/vospace/NodeBranchServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..69d342c85e97a9b94972f4955e9262b01d2f13bf --- /dev/null +++ b/src/test/java/it/inaf/oats/vospace/NodeBranchServiceTest.java @@ -0,0 +1,78 @@ +/* + * 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.exception.NodeBusyException; +import it.inaf.oats.vospace.exception.NodeNotFoundException; +import it.inaf.oats.vospace.exception.PermissionDeniedException; +import it.inaf.oats.vospace.persistence.DataSourceConfigSingleton; +import it.inaf.oats.vospace.persistence.NodeDAO; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import net.ivoa.xml.vospace.v2.Transfer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.ContextConfiguration; + +@SpringBootTest +@AutoConfigureMockMvc +@ContextConfiguration(classes = {DataSourceConfigSingleton.class}) +@TestPropertySource(locations = "classpath:test.properties", properties = {"vospace-authority=example.com!vospace", "file-service-url=http://file-service"}) +@TestMethodOrder(OrderAnnotation.class) +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) +public class NodeBranchServiceTest { + + @Value("${vospace-authority}") + private String authority; + + @Autowired + private MoveService moveService; + + @Autowired + private NodeDAO nodeDao; + + @Test + @Order(1) + public void moveRootTest() { + + assertThrows(IllegalArgumentException.class, () -> { + moveService.processMoveJob(getTransfer("/", "/pippo"), getAnonymousUser()); + } + ); + + assertThrows(IllegalArgumentException.class, () -> { + moveService.processMoveJob(getTransfer("/pippo", "/"), getAnonymousUser()); + } + ); + + } + + private Transfer getTransfer(String vosTarget, String vosDestination) { + Transfer transfer = new Transfer(); + transfer.setTarget(Arrays.asList("vos://" + this.authority + vosTarget)); + transfer.setDirection("vos://" + this.authority + vosDestination); + return transfer; + } + + private User getAnonymousUser() { + return new User().setUserId("anonymous"); + } +} diff --git a/src/test/java/it/inaf/oats/vospace/persistence/NodeDAOTest.java b/src/test/java/it/inaf/oats/vospace/persistence/NodeDAOTest.java index 1f0be586a6098ab148cee0ea3f3d367ac6ea413f..eae2766d31afcb6b31b11e1ed07e6f92a113f1bc 100644 --- a/src/test/java/it/inaf/oats/vospace/persistence/NodeDAOTest.java +++ b/src/test/java/it/inaf/oats/vospace/persistence/NodeDAOTest.java @@ -49,7 +49,7 @@ public class NodeDAOTest { ReflectionTestUtils.setField(dao, "authority", AUTHORITY); } - //@Test + @Test public void testCreateNode() { DataNode dataNode = new DataNode(); @@ -66,7 +66,7 @@ public class NodeDAOTest { assertEquals(retrievedNode.getProvides().get(0).getUri(), dataNode.getProvides().get(0).getUri()); } - //@Test + @Test public void testListNode() { ContainerNode root = (ContainerNode) dao.listNode("/").get(); assertEquals(4, root.getNodes().size()); @@ -81,7 +81,7 @@ public class NodeDAOTest { assertEquals(bTime, NodeProperties.getNodePropertyByURI(root.getNodes().get(0), NodeProperties.DATE_URI)); } - //@Test + @Test public void testListNodeChildren() { assertTrue(dao.listNodeChildren("/test4").isEmpty()); List<String> children = dao.listNodeChildren("/test2"); @@ -90,7 +90,7 @@ public class NodeDAOTest { assertTrue(children.containsAll(List.of("f4", "f5"))); } - //@Test + @Test public void testGetNodeId() { Optional<Long> id1 = dao.getNodeId("/test1"); assertTrue(id1.isPresent()); @@ -104,7 +104,7 @@ public class NodeDAOTest { assertTrue(id3.isEmpty()); } - //@Test + @Test public void testGetShortNodeDescriptor() { String userName = "user3"; List<String> userGroups = List.of(); @@ -176,7 +176,7 @@ public class NodeDAOTest { assertFalse(snd1.isPermissionDenied()); } - //@Test + @Test public void testIsBranchBusy() { Optional<Long> optId = dao.getNodeId("/test3/m1"); assertTrue(optId.isPresent()); @@ -190,7 +190,7 @@ public class NodeDAOTest { } - //@Test + @Test public void testIsBranchWritable() { List<String> userGroups = List.of("group1"); @@ -210,8 +210,52 @@ public class NodeDAOTest { assertTrue(optId.isPresent()); assertFalse(dao.isBranchWritable(optId.get(), "user1", List.of("group99"))); } + + @Test + public void testIsBranchReadable() { + + List<String> userGroups = List.of("group1"); + Optional<Long> optId = dao.getNodeId("/test3/m1"); + assertTrue(optId.isPresent()); + assertTrue(dao.isBranchReadable(optId.get(), "user3", userGroups)); - //@Test + optId = dao.getNodeId("/test3"); + assertTrue(optId.isPresent()); + assertFalse(dao.isBranchReadable(optId.get(), "user2", userGroups)); + + optId = dao.getNodeId("/test3/group1"); + assertTrue(optId.isPresent()); + assertTrue(dao.isBranchReadable(optId.get(), "user2", userGroups)); + + optId = dao.getNodeId("/test3/group1"); + assertTrue(optId.isPresent()); + assertFalse(dao.isBranchWritable(optId.get(), "user1", List.of("group99"))); + } + + @Test + public void testSetJobId(){ + Optional<Long> optId = dao.getNodeId("/test3/m1"); + assertTrue(optId.isPresent()); + + assertFalse(dao.isBranchBusy(optId.get())); + + dao.setBranchJobId(optId.get(), "pippo1"); + + assertTrue(dao.isBranchBusy(optId.get())); + + Optional<Long> childId = dao.getNodeId("/test3/m1/m2"); + assertTrue(childId.isPresent()); + + assertTrue(dao.isBranchBusy(childId.get())); + + dao.setBranchJobId(optId.get(), null); + + assertFalse(dao.isBranchBusy(optId.get())); + assertFalse(dao.isBranchBusy((childId.get()))); + + } + + @Test public void testMoveNodeBranch() { // Let's move /test3/m1 to /test3/group1 Optional<Long> optSourceId = dao.getNodeId("/test3/m1"); @@ -272,7 +316,7 @@ public class NodeDAOTest { } - //@Test + @Test public void testRenameNode() { String oldPath = "/test1/f1"; String newPath = "/test1/f_pippo"; @@ -304,7 +348,7 @@ public class NodeDAOTest { assertEquals("f1", dao.getNodeOsName("/test1/f_pippo_second_rename")); } - //@Test + @Test public void testCountNodeWithPath() { assertEquals(1, dao.countNodesWithPath("/")); assertEquals(1, dao.countNodesWithPath("/test1"), "Test db has been changed"); @@ -320,7 +364,7 @@ public class NodeDAOTest { assertEquals(0, dao.countNodesWithPath("/pippooo"), "Test db has been changed"); } - //@Test + @Test public void testDeleteNode() { assertEquals(1, dao.countNodesWithPath("/test1/f1/f2_renamed/f3"), "Test db has been changed"); @@ -333,7 +377,7 @@ public class NodeDAOTest { } - //@Test + @Test public void testSetNodeLocation() { DataNode dataNode = new DataNode(); @@ -343,7 +387,7 @@ public class NodeDAOTest { dao.setNodeLocation("/mydata2", 1, "mydata2"); } - //@Test + @Test public void testSetNodeLocationFailure() { boolean exception = false; try { @@ -354,7 +398,7 @@ public class NodeDAOTest { assertTrue(exception); } - //@Test + @Test public void testSetNode() { Property publicReadProperty = getProperty(NodeProperties.PUBLIC_READ_URI, String.valueOf(false)); @@ -377,7 +421,7 @@ public class NodeDAOTest { assertEquals("true", NodeProperties.getNodePropertyByURI(node, NodeProperties.PUBLIC_READ_URI)); } - //@Test + @Test public void testSetNodeRecursiveGroup() { Property parentGroupRead = getProperty(NodeProperties.GROUP_READ_URI, "group1 group2"); @@ -421,7 +465,7 @@ public class NodeDAOTest { checkGroups(NodeProperties.getNodePropertyAsListByURI(child2, NodeProperties.GROUP_WRITE_URI), "group6"); } - //@Test + @Test public void testGetNodeOsName() { assertEquals("f2", dao.getNodeOsName("/test1/f1/f2_renamed")); assertEquals("f4", dao.getNodeOsName("/test2/f4")); diff --git a/src/test/resources/test-data.sql b/src/test/resources/test-data.sql index 3872174c43e0b3270918bd90c8a849657ed0e9da..4b0af3bd45cb04a2b2f1d4739741f3bae4cec594 100644 --- a/src/test/resources/test-data.sql +++ b/src/test/resources/test-data.sql @@ -33,7 +33,7 @@ INSERT INTO node (parent_path, parent_relative_path, name, sticky, type, creator INSERT INTO node (parent_path, parent_relative_path, name, job_id, type, creator_id, is_public, location_id) VALUES ('9', '', 'mbusy', 'job1234', 'container', 'user3', false, 3); -- /test3/mbusy INSERT INTO node (parent_path, parent_relative_path, name, async_trans, type, creator_id, is_public, location_id) VALUES ('9', '', 'masynctrans', true, 'container', 'user3', false, 3); -- /test3/masynctrans INSERT INTO node (parent_path, parent_relative_path, name, type, creator_id, is_public, location_id) VALUES ('9', '', 'asyncloc', 'container', 'user3', false, 1); -- /test3/asyncloc -INSERT INTO node (parent_path, parent_relative_path, name, type, creator_id, group_write, is_public, location_id) VALUES ('9', '', 'group1', 'container', 'user3','{"group1"}', false, 3); -- /test3/group1 +INSERT INTO node (parent_path, parent_relative_path, name, type, creator_id, group_write, group_read, is_public, location_id) VALUES ('9', '', 'group1', 'container', 'user3', '{"group1"}', '{"group1"}', false, 3); -- /test3/group1 DELETE FROM job;