This is an automated email from the ASF dual-hosted git repository.

machristie pushed a commit to branch custos-integration
in repository https://gitbox.apache.org/repos/asf/airavata-data-catalog.git

commit 032c659769b4e78d199ee67a03e2dc402fa8cb89
Author: Marcus Christie <[email protected]>
AuthorDate: Tue Apr 25 15:41:21 2023 -0400

    Simple implementation of hierarchical sharing of data products
---
 .../server/src/main/resources/schema.sql           |  31 +++++--
 .../api/sharing/SimpleSharingManagerImplTest.java  | 103 +++++++++++++++++++++
 2 files changed, 128 insertions(+), 6 deletions(-)

diff --git a/data-catalog-api/server/src/main/resources/schema.sql 
b/data-catalog-api/server/src/main/resources/schema.sql
index faad468..162f1af 100644
--- a/data-catalog-api/server/src/main/resources/schema.sql
+++ b/data-catalog-api/server/src/main/resources/schema.sql
@@ -1,8 +1,26 @@
 -- TODO: move this to Liquibase or some other schema migration management tool
 CREATE
-OR REPLACE VIEW simple_data_product_sharing_view AS
+OR REPLACE VIEW simple_data_product_sharing_view AS --
+WITH recursive data_product_hierarchy(data_product_id, root) AS (
+    SELECT
+        -- include self with the root
+        dp.data_product_id,
+        dp.data_product_id AS root
+    FROM
+        data_product dp
+    UNION
+    ALL
+    SELECT
+        dp.data_product_id,
+        h.root
+    FROM
+        data_product_hierarchy h,
+        data_product dp
+    WHERE
+        dp.parent_data_product_id = h.data_product_id
+)
 SELECT
-    s.data_product_id AS data_product_id,
+    dph.data_product_id AS data_product_id,
     su.user_id AS user_id,
     CASE
         WHEN s.permission_id = 'OWNER' THEN 0
@@ -15,10 +33,11 @@ SELECT
     END AS permission_id
 FROM
     simple_user_sharing s
-    INNER JOIN simple_user su ON su.simple_user_id = s.simple_user_id -- INNER 
JOIN user_table u ON u.user_id = su.user_id
+    INNER JOIN simple_user su ON su.simple_user_id = s.simple_user_id
+    INNER JOIN data_product_hierarchy dph ON dph.root = s.data_product_id
 UNION
 SELECT
-    s.data_product_id AS data_product_id,
+    dph.data_product_id AS data_product_id,
     su.user_id AS user_id,
     CASE
         WHEN s.permission_id = 'OWNER' THEN 0
@@ -32,5 +51,5 @@ SELECT
 FROM
     simple_group_sharing s
     INNER JOIN simple_group_membership gm ON gm.simple_group_id = 
s.simple_group_id
-    INNER JOIN simple_user su ON su.simple_user_id = gm.simple_user_id -- 
INNER JOIN user_table u ON u.user_id = su.user_id
-;
+    INNER JOIN simple_user su ON su.simple_user_id = gm.simple_user_id
+    INNER JOIN data_product_hierarchy dph ON dph.root = s.data_product_id;
diff --git 
a/data-catalog-api/server/src/test/java/org/apache/airavata/datacatalog/api/sharing/SimpleSharingManagerImplTest.java
 
b/data-catalog-api/server/src/test/java/org/apache/airavata/datacatalog/api/sharing/SimpleSharingManagerImplTest.java
index 6fe117f..74df1c4 100644
--- 
a/data-catalog-api/server/src/test/java/org/apache/airavata/datacatalog/api/sharing/SimpleSharingManagerImplTest.java
+++ 
b/data-catalog-api/server/src/test/java/org/apache/airavata/datacatalog/api/sharing/SimpleSharingManagerImplTest.java
@@ -320,4 +320,107 @@ public class SimpleSharingManagerImplTest {
 
         assertFalse(simpleSharingManagerImpl.hasPublicAccess(dataProduct, 
Permission.READ));
     }
+
+    @Test
+    public void testUserHasAccessViaCascade() throws SharingException {
+
+        UserInfo userA = 
UserInfo.newBuilder().setTenantId("tenantId").setUserId("userA").build();
+        UserEntity testUserA = simpleSharingManagerImpl.resolveUser(userA);
+        UserInfo userB = 
UserInfo.newBuilder().setTenantId("tenantId").setUserId("userB").build();
+
+        DataProductEntity dp1 = new DataProductEntity();
+        dp1.setExternalId(UUID.randomUUID().toString());
+        dp1.setOwner(testUserA);
+        dp1.setName("test data product 1");
+        dataProductRepository.save(dp1);
+
+        DataProductEntity dp2 = new DataProductEntity();
+        dp2.setExternalId(UUID.randomUUID().toString());
+        dp2.setOwner(testUserA);
+        dp2.setName("test data product 2");
+        dp2.setParentDataProductEntity(dp1);
+        dataProductRepository.save(dp2);
+
+        DataProductEntity dp3 = new DataProductEntity();
+        dp3.setExternalId(UUID.randomUUID().toString());
+        dp3.setOwner(testUserA);
+        dp3.setName("test data product 3");
+        dp3.setParentDataProductEntity(dp2);
+        dataProductRepository.save(dp3);
+
+        // Check that userB doesn't have READ access to the data products 1, 2 
or 3
+        DataProduct dataProduct = DataProduct.newBuilder()
+                .setDataProductId(dp1.getExternalId()) // only need the data 
product id
+                .build();
+        assertFalse(simpleSharingManagerImpl.userHasAccess(userB, dataProduct, 
Permission.READ));
+
+        // Grant READ access to userB for the data product
+        simpleSharingManagerImpl.grantPermissionToUser(userB, dataProduct, 
Permission.READ, userA);
+
+        // Check that userB does now have READ access to the data product 1, 2 
and 3
+        assertTrue(simpleSharingManagerImpl.userHasAccess(userB, dataProduct, 
Permission.READ));
+        assertTrue(simpleSharingManagerImpl.userHasAccess(userB,
+                
DataProduct.newBuilder().setDataProductId(dp2.getExternalId()).build(), 
Permission.READ));
+        assertTrue(simpleSharingManagerImpl.userHasAccess(userB,
+                
DataProduct.newBuilder().setDataProductId(dp3.getExternalId()).build(), 
Permission.READ));
+    }
+
+    @Test
+    public void testUserHasAccessViaGroupMembershipAndCascade() throws 
SharingException {
+
+        UserInfo userA = 
UserInfo.newBuilder().setTenantId("tenantId").setUserId("userA").build();
+        UserEntity testUserA = simpleSharingManagerImpl.resolveUser(userA);
+        UserInfo userB = 
UserInfo.newBuilder().setTenantId("tenantId").setUserId("userB").build();
+
+        GroupInfo testGroup = 
GroupInfo.newBuilder().setGroupId("groupId").setTenantId("tenantId").build();
+
+        // Create data products
+        DataProductEntity dp1 = new DataProductEntity();
+        dp1.setExternalId(UUID.randomUUID().toString());
+        dp1.setOwner(testUserA);
+        dp1.setName("test data product 1");
+        dataProductRepository.save(dp1);
+
+        DataProductEntity dp2 = new DataProductEntity();
+        dp2.setExternalId(UUID.randomUUID().toString());
+        dp2.setOwner(testUserA);
+        dp2.setName("test data product 2");
+        dp2.setParentDataProductEntity(dp1);
+        dataProductRepository.save(dp2);
+
+        DataProductEntity dp3 = new DataProductEntity();
+        dp3.setExternalId(UUID.randomUUID().toString());
+        dp3.setOwner(testUserA);
+        dp3.setName("test data product 3");
+        dp3.setParentDataProductEntity(dp2);
+        dataProductRepository.save(dp3);
+
+        // Add user B to the testGroup
+        simpleSharingManagerImpl.resolveUser(userB);
+        Optional<SimpleUserEntity> userBEntity = simpleUserRepository
+                .findByExternalIdAndSimpleTenant_ExternalId(userB.getUserId(), 
userB.getTenantId());
+        assertTrue(userBEntity.isPresent());
+        SimpleGroupEntity testGroupEntity = new SimpleGroupEntity();
+        testGroupEntity.setName(testGroup.getGroupId());
+        testGroupEntity.setExternalId(testGroup.getGroupId());
+        
testGroupEntity.getMemberUsers().addAll(Arrays.asList(userBEntity.get()));
+        testGroupEntity.setSimpleTenant(userBEntity.get().getSimpleTenant());
+        simpleGroupRepository.save(testGroupEntity);
+
+        // Check that user B doesn't have READ access to the data product
+        DataProduct dataProduct = DataProduct.newBuilder()
+                .setDataProductId(dp1.getExternalId()) // only need the data 
product id
+                .build();
+        assertFalse(simpleSharingManagerImpl.userHasAccess(userB, dataProduct, 
Permission.READ));
+
+        // Grant READ access to testGroup for the data product
+        simpleSharingManagerImpl.grantPermissionToGroup(testGroup, 
dataProduct, Permission.READ, userA);
+
+        // Check that users B now has READ access to the data products 1, 2, 
and 3
+        assertTrue(simpleSharingManagerImpl.userHasAccess(userB, dataProduct, 
Permission.READ));
+        assertTrue(simpleSharingManagerImpl.userHasAccess(userB,
+                
DataProduct.newBuilder().setDataProductId(dp2.getExternalId()).build(), 
Permission.READ));
+        assertTrue(simpleSharingManagerImpl.userHasAccess(userB,
+                
DataProduct.newBuilder().setDataProductId(dp3.getExternalId()).build(), 
Permission.READ));
+    }
 }

Reply via email to