RANGER-4651: update GDS objects ACL for deletion of Ranger user/group/roles
Signed-off-by: Madhan Neethiraj <madhan@apache.org>
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/GdsDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/GdsDBStore.java
index a696479..69b43f2 100755
--- a/security-admin/src/main/java/org/apache/ranger/biz/GdsDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/GdsDBStore.java
@@ -22,6 +22,7 @@
import org.apache.http.HttpStatus;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.ranger.biz.ServiceDBStore.REMOVE_REF_TYPE;
import org.apache.ranger.common.*;
import org.apache.ranger.common.db.RangerTransactionSynchronizationAdapter;
import org.apache.ranger.db.*;
@@ -1339,6 +1340,48 @@
return ret;
}
+ public void deletePrincipalFromGdsAcl(String principalType, String principalName) {
+ Map<Long, RangerGdsObjectACL> datsetAcls = daoMgr.getXXGdsDataset().getDatasetIdsAndACLs();
+ Map<Long, RangerGdsObjectACL> dataShareAcls = daoMgr.getXXGdsDataShare().getDataShareIdsAndACLs();
+ Map<Long, RangerGdsObjectACL> projectAcls = daoMgr.getXXGdsProject().getProjectIdsAndACLs();
+
+ for (Map.Entry<Long, RangerGdsObjectACL> entry : datsetAcls.entrySet()) {
+ Long id = entry.getKey();
+ RangerGdsObjectACL acl = entry.getValue();
+
+ if (deletePrincipalFromAcl(acl, principalName, principalType) != null) {
+ RangerDataset dataset = datasetService.read(id);
+
+ dataset.setAcl(acl);
+ datasetService.update(dataset);
+ }
+ }
+
+ for (Map.Entry<Long, RangerGdsObjectACL> entry : dataShareAcls.entrySet()) {
+ Long id = entry.getKey();
+ RangerGdsObjectACL acl = entry.getValue();
+
+ if (deletePrincipalFromAcl(acl, principalName, principalType) != null) {
+ RangerDataShare dataShare = dataShareService.read(id);
+
+ dataShare.setAcl(acl);
+ dataShareService.update(dataShare);
+ }
+ }
+
+ for (Map.Entry<Long, RangerGdsObjectACL> entry : projectAcls.entrySet()) {
+ Long id = entry.getKey();
+ RangerGdsObjectACL acl = entry.getValue();
+
+ if (deletePrincipalFromAcl(acl, principalName, principalType) != null) {
+ RangerProject project = projectService.read(id);
+
+ project.setAcl(acl);
+ projectService.update(project);
+ }
+ }
+ }
+
private List<DataShareInDatasetSummary> getDshInDsSummary(List<RangerDataShare> dataShares, List<RangerDataset> datasets, RangerDataShareInDatasetList dshInDsList) {
Set<DataShareInDatasetSummary> ret = new LinkedHashSet<>();
Map<Long, RangerDataset> datasetMap = toMap(datasets);
@@ -2136,6 +2179,22 @@
}
}
+ private GdsPermission deletePrincipalFromAcl(RangerGdsObjectACL acl, String principalName, String principalType) {
+ final Map<String, GdsPermission> principalAcls;
+
+ if (principalType.equalsIgnoreCase(REMOVE_REF_TYPE.USER.toString())) {
+ principalAcls = acl.getUsers();
+ } else if (principalType.equalsIgnoreCase(REMOVE_REF_TYPE.GROUP.toString())) {
+ principalAcls = acl.getGroups();
+ } else if (principalType.equalsIgnoreCase(REMOVE_REF_TYPE.ROLE.toString())) {
+ principalAcls = acl.getRoles();
+ } else {
+ principalAcls = null;
+ }
+
+ return principalAcls != null ? principalAcls.remove(principalName) : null;
+ }
+
private void copyExistingBaseFields(RangerGdsBaseModelObject objToUpdate, RangerGdsBaseModelObject existingObj) {
if (objToUpdate != null && existingObj != null) {
// retain existing values for: guid, createdBy, createTime
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/RoleDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/RoleDBStore.java
index abf2b0c..0aa03e7 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/RoleDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/RoleDBStore.java
@@ -86,6 +86,9 @@
@Autowired
ServiceDBStore svcStore;
+ @Autowired
+ GdsDBStore gdsStore;
+
RangerAdminConfig config;
private Boolean populateExistingBaseFields = false;
@@ -200,19 +203,7 @@
throw restErrorUtil.createRESTException("Role with name: " + roleName + " does not exist");
}
- ensureRoleDeleteAllowed(roleName);
-
- Runnable roleVersionUpdater = new RoleVersionUpdater(daoMgr);
- transactionSynchronizationAdapter.executeOnTransactionCommit(roleVersionUpdater);
-
- RangerRole role = roleService.read(xxRole.getId());
- roleRefUpdater.cleanupRefTables(role);
- // delete role from audit filter configs
- svcStore.updateServiceAuditConfig(role.getName(), REMOVE_REF_TYPE.ROLE);
- roleService.delete(role);
-
- List<XXTrxLog> trxLogList = roleService.getTransactionLog(role, null, "delete");
- bizUtil.createTrxLog(trxLogList);
+ deleteRole(xxRole.getId());
}
@Override
@@ -227,6 +218,10 @@
roleRefUpdater.cleanupRefTables(role);
// delete role from audit filter configs
svcStore.updateServiceAuditConfig(role.getName(), REMOVE_REF_TYPE.ROLE);
+
+ // delete gdsObject mapping of role
+ gdsStore.deletePrincipalFromGdsAcl(REMOVE_REF_TYPE.ROLE.toString(), role.getName());
+
roleService.delete(role);
List<XXTrxLog> trxLogList = roleService.getTransactionLog(role, null, "delete");
bizUtil.createTrxLog(trxLogList);
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
index d961bc5..2874002 100755
--- a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
@@ -166,6 +166,9 @@
RangerTransactionSynchronizationAdapter transactionSynchronizationAdapter;
@Autowired
+ GdsDBStore gdsStore;
+
+ @Autowired
@Qualifier(value = "transactionManager")
PlatformTransactionManager txManager;
@@ -2169,6 +2172,8 @@
}
//delete group from audit filter configs
svcStore.updateServiceAuditConfig(vXGroup.getName(), REMOVE_REF_TYPE.GROUP);
+ // delete group from dataset,datashare,project
+ gdsStore.deletePrincipalFromGdsAcl(REMOVE_REF_TYPE.GROUP.toString(), vXGroup.getName());
//delete XXGroup
xXGroupDao.remove(id);
//Create XXTrxLog
@@ -2396,6 +2401,8 @@
}
//delete user from audit filter configs
svcStore.updateServiceAuditConfig(vXUser.getName(), REMOVE_REF_TYPE.USER);
+ //delete gdsObject mapping of user
+ gdsStore.deletePrincipalFromGdsAcl(REMOVE_REF_TYPE.USER.toString(),vXUser.getName());
//delete XXUser entry of user
xXUserDao.remove(id);
//delete XXPortal entry of user
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXGdsDataShareDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXGdsDataShareDao.java
index 8acca8f..20084bc 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXGdsDataShareDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXGdsDataShareDao.java
@@ -20,15 +20,19 @@
package org.apache.ranger.db;
import org.apache.commons.lang.StringUtils;
+import org.apache.ranger.authorization.utils.JsonUtils;
import org.apache.ranger.common.db.BaseDao;
import org.apache.ranger.entity.XXGdsDataShare;
+import org.apache.ranger.plugin.model.RangerGds.RangerGdsObjectACL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.persistence.NoResultException;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
@Service
@@ -144,4 +148,27 @@
return ret != null ? ret : Collections.emptyList();
}
+
+ public Map<Long, RangerGdsObjectACL> getDataShareIdsAndACLs() {
+ Map<Long, RangerGdsObjectACL> ret = new HashMap<>();
+
+ try {
+ List<Object[]> rows = getEntityManager().createNamedQuery("XXGdsDataShare.getDataShareIdsAndACLs", Object[].class).getResultList();
+
+ if (rows != null) {
+ for (Object[] row : rows) {
+ Long id = (Long) row[0];
+ RangerGdsObjectACL acl = JsonUtils.jsonToObject((String) row[1], RangerGdsObjectACL.class);
+
+ if (acl != null) {
+ ret.put(id, acl);
+ }
+ }
+ }
+ } catch (NoResultException e) {
+ LOG.debug("getDataShareIdsAndACLs()", e);
+ }
+
+ return ret;
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetDao.java
index 5743ad7..4661b41 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetDao.java
@@ -20,6 +20,7 @@
package org.apache.ranger.db;
import org.apache.commons.lang.StringUtils;
+import org.apache.ranger.authorization.utils.JsonUtils;
import org.apache.ranger.common.db.BaseDao;
import org.apache.ranger.entity.XXGdsDataset;
import org.slf4j.Logger;
@@ -28,8 +29,11 @@
import javax.persistence.NoResultException;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import org.apache.ranger.plugin.model.RangerGds.RangerGdsObjectACL;
@Service
public class XXGdsDatasetDao extends BaseDao<XXGdsDataset> {
@@ -113,4 +117,27 @@
return ret != null ? ret : Collections.emptyList();
}
+
+ public Map<Long, RangerGdsObjectACL> getDatasetIdsAndACLs() {
+ Map<Long, RangerGdsObjectACL> ret = new HashMap<>();
+
+ try {
+ List<Object[]> rows = getEntityManager().createNamedQuery("XXGdsDataset.getDatasetIdsAndACLs", Object[].class).getResultList();
+
+ if (rows != null) {
+ for (Object[] row : rows) {
+ Long id = (Long) row[0];
+ RangerGdsObjectACL acl = JsonUtils.jsonToObject((String) row[1], RangerGdsObjectACL.class);
+
+ if (acl != null) {
+ ret.put(id, acl);
+ }
+ }
+ }
+ } catch (NoResultException e) {
+ LOG.debug("getDatasetIdsAndACLs()", e);
+ }
+
+ return ret;
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectDao.java
index 76bab86..ba8f6c6 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectDao.java
@@ -20,15 +20,19 @@
package org.apache.ranger.db;
import org.apache.commons.lang.StringUtils;
+import org.apache.ranger.authorization.utils.JsonUtils;
import org.apache.ranger.common.db.BaseDao;
import org.apache.ranger.entity.XXGdsProject;
+import org.apache.ranger.plugin.model.RangerGds.RangerGdsObjectACL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.persistence.NoResultException;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
@Service
@@ -98,4 +102,27 @@
return ret != null ? ret : Collections.emptyList();
}
+
+ public Map<Long, RangerGdsObjectACL> getProjectIdsAndACLs() {
+ Map<Long, RangerGdsObjectACL> ret = new HashMap<>();
+
+ try {
+ List<Object[]> rows = getEntityManager().createNamedQuery("XXGdsProject.getProjectIdsAndACLs", Object[].class).getResultList();
+
+ if (rows != null) {
+ for (Object[] row : rows) {
+ Long id = (Long) row[0];
+ RangerGdsObjectACL acl = JsonUtils.jsonToObject((String) row[1], RangerGdsObjectACL.class);
+
+ if (acl != null) {
+ ret.put(id, acl);
+ }
+ }
+ }
+ } catch (NoResultException e) {
+ LOG.debug("getProjectIdsAndACLs()", e);
+ }
+
+ return ret;
+ }
}
diff --git a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
index 52ecf8a..b3557d5 100755
--- a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
+++ b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
@@ -2178,6 +2178,11 @@
</query>
</named-query>
+ <named-query name="XXGdsDataset.getAlldatasetIdsAndACLs">
+ <query>select obj.id, obj.acl from XXGdsDataset obj where obj.id is NOT null
+ </query>
+ </named-query>
+
<named-query name="XXGdsProject.findByGuid">
<query>select obj from XXGdsProject obj where obj.guid = :guid</query>
</named-query>
@@ -2200,6 +2205,11 @@
</query>
</named-query>
+ <named-query name="XXGdsProject.getAllProjectIdsAndACLs">
+ <query>select obj.id, obj.acl from XXGdsProject obj where obj.id is NOT null
+ </query>
+ </named-query>
+
<named-query name="XXGdsDataShare.findByGuid">
<query>select obj from XXGdsDataShare obj where obj.guid = :guid</query>
</named-query>
@@ -2227,6 +2237,11 @@
</query>
</named-query>
+<named-query name="XXGdsDataShare.getAlldataShareIdsAndACLs">
+ <query>select obj.id, obj.acl from XXGdsDataShare obj where obj.id is NOT null
+ </query>
+ </named-query>
+
<named-query name="XXGdsSharedResource.findByGuid">
<query>select obj from XXGdsSharedResource obj where obj.guid = :guid</query>
</named-query>
diff --git a/security-admin/src/test/java/org/apache/ranger/biz/TestRoleDBStore.java b/security-admin/src/test/java/org/apache/ranger/biz/TestRoleDBStore.java
index 6d340f2..6df1f73 100644
--- a/security-admin/src/test/java/org/apache/ranger/biz/TestRoleDBStore.java
+++ b/security-admin/src/test/java/org/apache/ranger/biz/TestRoleDBStore.java
@@ -78,6 +78,9 @@
RoleDBStore roleDBStore = new RoleDBStore();
@Mock
+ GdsDBStore gdsStore;
+
+ @Mock
RangerBizUtil bizUtil;
@Mock
@@ -482,14 +485,11 @@
@Test
public void testDeleteRoleByValidRoleNameWhenRoleIsAssociatedWithOneOrMorePolices() throws Exception {
- XXRole xxRole = getTestRole();
- XXRoleDao xxRoleDao = Mockito.mock(XXRoleDao.class);
- XXPolicyRefRoleDao xxPolicyRefRoleDao = Mockito.mock(XXPolicyRefRoleDao.class);
+ XXRole xxRole = getTestRole();
+ XXRoleDao xxRoleDao = Mockito.mock(XXRoleDao.class);
Mockito.when(xxRoleDao.findByRoleName(roleName)).thenReturn(xxRole);
- Mockito.when(daoMgr.getXXPolicyRefRole()).thenReturn(xxPolicyRefRoleDao);
Mockito.when(daoMgr.getXXRole()).thenReturn(xxRoleDao);
- Mockito.when(xxPolicyRefRoleDao.findRoleRefPolicyCount(roleName)).thenReturn(1L);
thrown.expect(Exception.class);
roleDBStore.deleteRole(roleName);
@@ -497,17 +497,11 @@
@Test
public void testDeleteRoleByValidRoleNameWhenRoleIsAssociatedWithOneOrMoreRoles() throws Exception {
- XXRole xxRole = getTestRole();
- XXRoleDao xxRoleDao = Mockito.mock(XXRoleDao.class);
- XXPolicyRefRoleDao xxPolicyRefRoleDao = Mockito.mock(XXPolicyRefRoleDao.class);
- XXRoleRefRoleDao xxRoleRefRoleDao = Mockito.mock(XXRoleRefRoleDao.class);
+ XXRole xxRole = getTestRole();
+ XXRoleDao xxRoleDao = Mockito.mock(XXRoleDao.class);
Mockito.when(daoMgr.getXXRole()).thenReturn(xxRoleDao);
Mockito.when(xxRoleDao.findByRoleName(roleName)).thenReturn(xxRole);
- Mockito.when(daoMgr.getXXPolicyRefRole()).thenReturn(xxPolicyRefRoleDao);
- Mockito.when(xxPolicyRefRoleDao.findRoleRefPolicyCount(roleName)).thenReturn(0L);
- Mockito.when(daoMgr.getXXRoleRefRole()).thenReturn(xxRoleRefRoleDao);
- Mockito.when(xxRoleRefRoleDao.findRoleRefRoleCount(roleName)).thenReturn(1L);
thrown.expect(Exception.class);
roleDBStore.deleteRole(roleName);
@@ -515,20 +509,11 @@
@Test
public void testDeleteRoleByValidRoleNameWhenRoleIsAssociatedWithOneOrMoreSecurityZones() throws Exception {
- XXRole xxRole = getTestRole();
- XXRoleDao xxRoleDao = Mockito.mock(XXRoleDao.class);
- XXPolicyRefRoleDao xxPolicyRefRoleDao = Mockito.mock(XXPolicyRefRoleDao.class);
- XXRoleRefRoleDao xxRoleRefRoleDao = Mockito.mock(XXRoleRefRoleDao.class);
- XXSecurityZoneRefRoleDao xxSzRefRoleDao = Mockito.mock(XXSecurityZoneRefRoleDao.class);
+ XXRole xxRole = getTestRole();
+ XXRoleDao xxRoleDao = Mockito.mock(XXRoleDao.class);
Mockito.when(daoMgr.getXXRole()).thenReturn(xxRoleDao);
Mockito.when(xxRoleDao.findByRoleName(roleName)).thenReturn(xxRole);
- Mockito.when(daoMgr.getXXPolicyRefRole()).thenReturn(xxPolicyRefRoleDao);
- Mockito.when(xxPolicyRefRoleDao.findRoleRefPolicyCount(roleName)).thenReturn(0L);
- Mockito.when(daoMgr.getXXRoleRefRole()).thenReturn(xxRoleRefRoleDao);
- Mockito.when(xxRoleRefRoleDao.findRoleRefRoleCount(roleName)).thenReturn(0L);
- Mockito.when(daoMgr.getXXSecurityZoneRefRole()).thenReturn(xxSzRefRoleDao);
- Mockito.when(xxSzRefRoleDao.findRoleRefZoneCount(roleName)).thenReturn(1L);
thrown.expect(Exception.class);
roleDBStore.deleteRole(roleName);
diff --git a/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java b/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java
index 601dbe9..ce48c82 100644
--- a/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java
+++ b/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java
@@ -220,6 +220,9 @@
ServiceDBStore svcStore;
@Mock
+ GdsDBStore gdsStore;
+
+ @Mock
XGroupGroupService xGroupGroupService;
@Mock