Skip to content

Commit

Permalink
RANGER-4651: update GDS objects ACL for deletion of Ranger user/group…
Browse files Browse the repository at this point in the history
…/roles

Signed-off-by: Madhan Neethiraj <[email protected]>
  • Loading branch information
prashantdev88 authored and mneethiraj committed Jan 13, 2024
1 parent c4e6e94 commit 42bbf5c
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 37 deletions.
59 changes: 59 additions & 0 deletions security-admin/src/main/java/org/apache/ranger/biz/GdsDBStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.*;
Expand Down Expand Up @@ -1339,6 +1340,48 @@ public PList<DataShareInDatasetSummary> getDshInDsSummary(SearchFilter filter) {
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);
Expand Down Expand Up @@ -2136,6 +2179,22 @@ private void updateGdsVersionForDataShare(Long dataShareId) {
}
}

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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ public class RoleDBStore implements RoleStore {
@Autowired
ServiceDBStore svcStore;

@Autowired
GdsDBStore gdsStore;

RangerAdminConfig config;

private Boolean populateExistingBaseFields = false;
Expand Down Expand Up @@ -200,19 +203,7 @@ public void deleteRole(String roleName) throws Exception {
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
Expand All @@ -227,6 +218,10 @@ public void deleteRole(Long roleId) throws Exception {
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ public class XUserMgr extends XUserMgrBase {
@Autowired
RangerTransactionSynchronizationAdapter transactionSynchronizationAdapter;

@Autowired
GdsDBStore gdsStore;

@Autowired
@Qualifier(value = "transactionManager")
PlatformTransactionManager txManager;
Expand Down Expand Up @@ -2169,6 +2172,8 @@ public void deleteXGroup(Long id, boolean force) {
}
//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
Expand Down Expand Up @@ -2396,6 +2401,8 @@ public synchronized void deleteXUser(Long id, boolean force) {
}
//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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -144,4 +148,27 @@ public List<Long> findServiceIdsForDataShareId(Long dataShareId) {

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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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> {
Expand Down Expand Up @@ -113,4 +117,27 @@ public List<Long> findServiceIdsForDataset(Long datasetId) {

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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -98,4 +102,27 @@ public List<Long> findServiceIdsForProject(Long projectId) {

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;
}
}
15 changes: 15 additions & 0 deletions security-admin/src/main/resources/META-INF/jpa_named_queries.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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>
Expand Down Expand Up @@ -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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ public class TestRoleDBStore {
@InjectMocks
RoleDBStore roleDBStore = new RoleDBStore();

@Mock
GdsDBStore gdsStore;

@Mock
RangerBizUtil bizUtil;

Expand Down Expand Up @@ -482,53 +485,35 @@ public void testDeleteRoleByRoleId() throws Exception {

@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);
}

@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);
}

@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);
Expand Down
Loading

0 comments on commit 42bbf5c

Please sign in to comment.