You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ra...@apache.org on 2026/05/26 08:13:53 UTC
(ranger) branch ranger-2.9 updated: RANGER-3899: performance improvement for policies with many users/groups/roles (ranger-2.9) (#970)
This is an automated email from the ASF dual-hosted git repository.
ramackri pushed a commit to branch ranger-2.9
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/ranger-2.9 by this push:
new 4559d0a01 RANGER-3899: performance improvement for policies with many users/groups/roles (ranger-2.9) (#970)
4559d0a01 is described below
commit 4559d0a01186ea65dd0de7b53b0fca308d2f63bc
Author: Ramachandran Krishnan <ra...@gmail.com>
AuthorDate: Tue May 26 13:43:48 2026 +0530
RANGER-3899: performance improvement for policies with many users/groups/roles (ranger-2.9) (#970)
* RANGER-3899: performance improvement in create/update of policies referencing large number of users/groups/roles
Backport of apache/ranger@d1589d629 to ranger-2.9.
Co-authored-by: Cursor <cu...@cursor.com>
* RANGER-3899: fix TestServiceDBStore; omit JUnit5 TestPolicyRefUpdater on ranger-2.9
Update tess28updatePolicy mock for createNewPolMappingForRefTable(..., true).
Remove TestPolicyRefUpdater (JUnit 5) since ranger-2.9 security-admin uses
Surefire 2.18.1; production backport does not require Surefire/JUnit5 changes.
Co-authored-by: Cursor <cu...@cursor.com>
* RANGER-3899: trim DAO diffs to functional-only changes on ranger-2.9
Restore ranger-2.9 formatting and append only batch lookup/delete methods
from master (d1589d629), matching ~266 lines added instead of full-file
reformat churn.
Co-authored-by: Cursor <cu...@cursor.com>
* RANGER-3899: add TestPolicyRefUpdater using JUnit 4 on ranger-2.9
Restore policy ref updater unit tests adapted for batch DAO APIs and
5-arg createNewPolMappingForRefTable. Use JUnit 4 + MockitoJUnitRunner
so tests run under security-admin Surefire 2.18.1 without pom changes.
Co-authored-by: Cursor <cu...@cursor.com>
* RANGER-3899: drop GDS and master-only JPA queries from 2.9 backport
Align jpa_named_queries.xml with apache/ranger@d1589d629: keep only the
13 named queries required for policy ref updater performance work.
Remove XXGds* (GDS), XXPolicy.findByServiceType, and other queries not
present on ranger-2.9. Restore XXRMSResourceMapping.deleteByServiceResourceIds.
Co-authored-by: Cursor <cu...@cursor.com>
---------
Co-authored-by: ramk <ra...@cloudera.com>
Co-authored-by: Cursor <cu...@cursor.com>
---
dev-support/checks/coverage.sh | 4 +
.../org/apache/ranger/biz/PolicyRefUpdater.java | 1239 ++++++++++++--------
.../java/org/apache/ranger/biz/ServiceDBStore.java | 5 +-
.../org/apache/ranger/db/XXAccessTypeDefDao.java | 27 +
.../org/apache/ranger/db/XXDataMaskTypeDefDao.java | 27 +
.../main/java/org/apache/ranger/db/XXGroupDao.java | 21 +
.../apache/ranger/db/XXPolicyConditionDefDao.java | 28 +-
.../org/apache/ranger/db/XXPolicyRefGroupDao.java | 29 +
.../org/apache/ranger/db/XXPolicyRefRoleDao.java | 29 +
.../org/apache/ranger/db/XXPolicyRefUserDao.java | 29 +
.../org/apache/ranger/db/XXResourceDefDao.java | 27 +
.../main/java/org/apache/ranger/db/XXRoleDao.java | 25 +
.../main/java/org/apache/ranger/db/XXUserDao.java | 29 +-
.../main/resources/META-INF/jpa_named_queries.xml | 60 +
.../apache/ranger/biz/TestPolicyRefUpdater.java | 423 +++++++
.../org/apache/ranger/biz/TestServiceDBStore.java | 9 +-
16 files changed, 1531 insertions(+), 480 deletions(-)
diff --git a/dev-support/checks/coverage.sh b/dev-support/checks/coverage.sh
index eabf0a4a3..58a8a09bd 100755
--- a/dev-support/checks/coverage.sh
+++ b/dev-support/checks/coverage.sh
@@ -49,6 +49,10 @@ find . -type d -name 'target' -prune -exec find {} -type f \( -name 'ranger-*.ja
-or -name '*shim*' -prune \
| xargs -n1 unzip -o -q -d target/coverage-classes
+# Multi-release JARs (e.g. BouncyCastle) ship the same classes under
+# META-INF/versions/* and at the root; JaCoCo fails with duplicate class names.
+rm -rf target/coverage-classes/META-INF/versions || true
+
# get all source file paths
src=$(find . -path '*/src/main/java' -o -path './target' -prune | sed 's/^/--sourcefiles /g' | xargs echo)
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java b/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java
index ab7eb5f67..6c8ede470 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java
@@ -18,22 +18,18 @@
*/
package org.apache.ranger.biz;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ranger.common.RESTErrorUtil;
import org.apache.ranger.common.RangerCommonEnums;
+import org.apache.ranger.common.db.BaseDao;
import org.apache.ranger.common.db.RangerTransactionSynchronizationAdapter;
import org.apache.ranger.db.RangerDaoManager;
-import org.apache.ranger.entity.XXAccessTypeDef;
-import org.apache.ranger.entity.XXDataMaskTypeDef;
+import org.apache.ranger.db.XXPolicyRefGroupDao;
+import org.apache.ranger.db.XXPolicyRefRoleDao;
+import org.apache.ranger.db.XXPolicyRefUserDao;
import org.apache.ranger.entity.XXGroup;
import org.apache.ranger.entity.XXPolicy;
-import org.apache.ranger.entity.XXPolicyConditionDef;
import org.apache.ranger.entity.XXPolicyRefAccessType;
import org.apache.ranger.entity.XXPolicyRefCondition;
import org.apache.ranger.entity.XXPolicyRefDataMaskType;
@@ -41,7 +37,6 @@
import org.apache.ranger.entity.XXPolicyRefResource;
import org.apache.ranger.entity.XXPolicyRefRole;
import org.apache.ranger.entity.XXPolicyRefUser;
-import org.apache.ranger.entity.XXResourceDef;
import org.apache.ranger.entity.XXRole;
import org.apache.ranger.entity.XXServiceDef;
import org.apache.ranger.entity.XXUser;
@@ -64,473 +59,781 @@
import javax.servlet.http.HttpServletResponse;
-import static org.apache.ranger.service.RangerBaseModelService.OPERATION_CREATE_CONTEXT;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+import static org.apache.ranger.service.RangerBaseModelService.OPERATION_CREATE_CONTEXT;
@Component
public class PolicyRefUpdater {
+ private static final Logger LOG = LoggerFactory.getLogger(PolicyRefUpdater.class);
+
+ @Autowired
+ RangerDaoManager daoMgr;
+
+ @Autowired
+ XUserMgr xUserMgr;
+
+ @Autowired
+ RoleDBStore roleStore;
+
+ @Autowired
+ RangerBizUtil rangerBizUtil;
+
+ @Autowired
+ XGroupService xGroupService;
+
+ @Autowired
+ RangerTransactionSynchronizationAdapter rangerTransactionSynchronizationAdapter;
+
+ @Autowired
+ RESTErrorUtil restErrorUtil;
+
+ public static List<List<? extends RangerPolicyItem>> getAllPolicyItems(RangerPolicy policy) {
+ List<List<? extends RangerPolicyItem>> ret = new ArrayList<>();
+
+ if (CollectionUtils.isNotEmpty(policy.getPolicyItems())) {
+ ret.add(policy.getPolicyItems());
+ }
+
+ if (CollectionUtils.isNotEmpty(policy.getDenyPolicyItems())) {
+ ret.add(policy.getDenyPolicyItems());
+ }
+
+ if (CollectionUtils.isNotEmpty(policy.getAllowExceptions())) {
+ ret.add(policy.getAllowExceptions());
+ }
+
+ if (CollectionUtils.isNotEmpty(policy.getDenyExceptions())) {
+ ret.add(policy.getDenyExceptions());
+ }
+
+ if (CollectionUtils.isNotEmpty(policy.getDataMaskPolicyItems())) {
+ ret.add(policy.getDataMaskPolicyItems());
+ }
+
+ if (CollectionUtils.isNotEmpty(policy.getRowFilterPolicyItems())) {
+ ret.add(policy.getRowFilterPolicyItems());
+ }
+
+ return ret;
+ }
+
+ public void createNewPolMappingForRefTable(RangerPolicy policy, XXPolicy xPolicy, XXServiceDef xServiceDef, boolean createPrincipalsIfAbsent, boolean isCleanupRefTablesNeeded) throws Exception {
+ if (policy == null) {
+ return;
+ }
+
+ final Set<String> resourceNames = policy.getResources().keySet();
+ final Set<String> roleNames = new HashSet<>();
+ final Set<String> groupNames = new HashSet<>();
+ final Set<String> userNames = new HashSet<>();
+ final Set<String> accessTypes = new HashSet<>();
+ final Set<String> conditionTypes = new HashSet<>();
+ final Set<String> dataMaskTypes = new HashSet<>();
+ boolean oldBulkMode = RangerBizUtil.isBulkMode();
+ final Long policyId = policy.getId();
+
+ List<RangerPolicy.RangerPolicyItemCondition> rangerPolicyConditions = policy.getConditions();
+
+ if (CollectionUtils.isNotEmpty(rangerPolicyConditions)) {
+ for (RangerPolicy.RangerPolicyItemCondition condition : rangerPolicyConditions) {
+ conditionTypes.add(condition.getType());
+ }
+ }
+
+ for (List<? extends RangerPolicyItem> policyItems : getAllPolicyItems(policy)) {
+ if (CollectionUtils.isEmpty(policyItems)) {
+ continue;
+ }
+
+ for (RangerPolicyItem policyItem : policyItems) {
+ roleNames.addAll(policyItem.getRoles());
+ groupNames.addAll(policyItem.getGroups());
+ userNames.addAll(policyItem.getUsers());
+
+ if (CollectionUtils.isNotEmpty(policyItem.getAccesses())) {
+ for (RangerPolicyItemAccess access : policyItem.getAccesses()) {
+ accessTypes.add(access.getType());
+ }
+ }
+
+ if (CollectionUtils.isNotEmpty(policyItem.getConditions())) {
+ for (RangerPolicyItemCondition condition : policyItem.getConditions()) {
+ conditionTypes.add(condition.getType());
+ }
+ }
+
+ if (policyItem instanceof RangerDataMaskPolicyItem) {
+ RangerPolicyItemDataMaskInfo dataMaskInfo = ((RangerDataMaskPolicyItem) policyItem).getDataMaskInfo();
+
+ dataMaskTypes.add(dataMaskInfo.getDataMaskType());
+ }
+ }
+ }
+
+ if (isCleanupRefTablesNeeded) {
+ cleanupRefTablesForUpdate(policyId, userNames, roleNames, groupNames);
+ }
+
+ if (CollectionUtils.isNotEmpty(resourceNames)) {
+ List<XXPolicyRefResource> xPolResources = new ArrayList<>();
+ Map<String, Long> nameToId = daoMgr.getXXResourceDef().findResourceDefIdsByNameAndPolicyId(resourceNames, policy.getId());
+
+ for (String resource : resourceNames) {
+ Long resourceDefId = nameToId.get(resource);
+
+ if (resourceDefId == null) {
+ throw new Exception(resource + ": is not a valid resource-type. policy='" + policy.getName() + "' service='" + policy.getService() + "'");
+ }
+
+ XXPolicyRefResource xPolRes = new XXPolicyRefResource();
+
+ xPolRes.setPolicyId(policy.getId());
+ xPolRes.setResourceDefId(resourceDefId);
+ xPolRes.setResourceName(resource);
+
+ xPolResources.add(xPolRes);
+ }
+
+ batchInsert(xPolResources, daoMgr.getXXPolicyRefResource(), oldBulkMode);
+ }
+
+ if (createPrincipalsIfAbsent && !rangerBizUtil.checkAdminAccess()) {
+ LOG.warn("policy={}: createPrincipalIfAbsent=true, but current user does not have admin privileges!", policy.getName());
+
+ createPrincipalsIfAbsent = false;
+ }
+
+ if (CollectionUtils.isNotEmpty(roleNames)) {
+ LOG.debug("x_policy_ref_role - New role entries to insert for policy ID {}: {}", policyId, roleNames);
+
+ Set<String> filteredRoleNames = roleNames.stream()
+ .filter(StringUtils::isNotBlank)
+ .collect(Collectors.toSet());
+
+ List<XXPolicyRefRole> xPolRoles = new ArrayList<>();
+ Map<String, Long> nameToId = daoMgr.getXXRole().getIdsByRoleNames(filteredRoleNames);
+
+ for (String roleName : filteredRoleNames) {
+ Long roleId = nameToId.get(roleName);
+ PolicyRoleAssociator associator = new PolicyRoleAssociator(roleName, roleId, xPolicy);
+
+ if (roleId != null) {
+ XXPolicyRefRole roleRef = associator.getPolicyRef();
+
+ if (roleRef != null) {
+ xPolRoles.add(roleRef);
+ }
+ } else if (createPrincipalsIfAbsent) {
+ rangerTransactionSynchronizationAdapter.executeOnTransactionCommit(associator);
+ } else {
+ VXResponse gjResponse = new VXResponse();
+
+ gjResponse.setStatusCode(HttpServletResponse.SC_BAD_REQUEST);
+ gjResponse.setMsgDesc("Operation denied. Role name: " + roleName + " specified in policy does not exist in ranger admin.");
+
+ throw restErrorUtil.generateRESTException(gjResponse);
+ }
+ }
+
+ batchInsert(xPolRoles, daoMgr.getXXPolicyRefRole(), oldBulkMode);
+ }
+
+ if (CollectionUtils.isNotEmpty(groupNames)) {
+ LOG.debug("x_policy_ref_group - New group entries to insert for policy ID {}: {}", policyId, groupNames);
+
+ Set<String> filteredGroupNames = groupNames.stream()
+ .filter(StringUtils::isNotBlank)
+ .collect(Collectors.toSet());
+
+ List<XXPolicyRefGroup> xPolGroups = new ArrayList<>();
+ Map<String, Long> nameToId = daoMgr.getXXGroup().getIdsByGroupNames(filteredGroupNames);
+
+ for (String groupName : filteredGroupNames) {
+ Long groupId = nameToId.get(groupName);
+ PolicyGroupAssociator associator = new PolicyGroupAssociator(groupName, groupId, xPolicy);
+
+ if (groupId != null) {
+ XXPolicyRefGroup groupRef = associator.getPolicyRef();
+
+ if (groupRef != null) {
+ xPolGroups.add(groupRef);
+ }
+ } else if (createPrincipalsIfAbsent) {
+ rangerTransactionSynchronizationAdapter.executeOnTransactionCommit(associator);
+ } else {
+ VXResponse gjResponse = new VXResponse();
+
+ gjResponse.setStatusCode(HttpServletResponse.SC_BAD_REQUEST);
+ gjResponse.setMsgDesc("Operation denied. Group name: " + groupName + " specified in policy does not exist in ranger admin.");
+
+ throw restErrorUtil.generateRESTException(gjResponse);
+ }
+ }
+
+ batchInsert(xPolGroups, daoMgr.getXXPolicyRefGroup(), oldBulkMode);
+ }
+
+ if (CollectionUtils.isNotEmpty(userNames)) {
+ LOG.debug("x_policy_ref_user - New user entries to insert for policy ID {}: {}", policyId, userNames);
+
+ Set<String> filteredUserNames = userNames.stream()
+ .filter(StringUtils::isNotBlank)
+ .collect(Collectors.toSet());
+
+ List<XXPolicyRefUser> xPolUsers = new ArrayList<>();
+ Map<String, Long> nameToId = daoMgr.getXXUser().getIdsByUserNames(filteredUserNames);
+
+ for (String userName : filteredUserNames) {
+ Long userId = nameToId.get(userName);
+ PolicyUserAssociator associator = new PolicyUserAssociator(userName, userId, xPolicy);
+
+ if (userId != null) {
+ XXPolicyRefUser userRef = associator.getPolicyRef();
+
+ if (userRef != null) {
+ xPolUsers.add(userRef);
+ }
+ } else if (createPrincipalsIfAbsent) {
+ rangerTransactionSynchronizationAdapter.executeOnTransactionCommit(associator);
+ } else {
+ VXResponse gjResponse = new VXResponse();
+
+ gjResponse.setStatusCode(HttpServletResponse.SC_BAD_REQUEST);
+ gjResponse.setMsgDesc("Operation denied. User name: " + userName + " specified in policy does not exist in ranger admin.");
+
+ throw restErrorUtil.generateRESTException(gjResponse);
+ }
+ }
+
+ batchInsert(xPolUsers, daoMgr.getXXPolicyRefUser(), oldBulkMode);
+ }
+
+ // ignore built-in access-types while creating ref-table entries
+ accessTypes.removeAll(ServiceDefUtil.ACCESS_TYPE_MARKERS);
+
+ if (CollectionUtils.isNotEmpty(accessTypes)) {
+ List<XXPolicyRefAccessType> xPolAccesses = new ArrayList<>();
+ Map<String, Long> nameToId = daoMgr.getXXAccessTypeDef().findAccessTypeDefIdsByNamesAndServiceId(accessTypes, xPolicy.getService());
+
+ for (String accessType : accessTypes) {
+ Long accessDefId = nameToId.get(accessType);
+
+ if (accessDefId == null) {
+ throw new Exception(accessType + ": is not a valid access-type. policy='" + policy.getName() + "' service='" + policy.getService() + "'");
+ }
+
+ XXPolicyRefAccessType xPolAccess = new XXPolicyRefAccessType();
+
+ xPolAccess.setPolicyId(policy.getId());
+ xPolAccess.setAccessDefId(accessDefId);
+ xPolAccess.setAccessTypeName(accessType);
+
+ xPolAccesses.add(xPolAccess);
+ }
+
+ batchInsert(xPolAccesses, daoMgr.getXXPolicyRefAccessType(), oldBulkMode);
+ }
+
+ if (CollectionUtils.isNotEmpty(conditionTypes)) {
+ List<XXPolicyRefCondition> xPolConds = new ArrayList<>();
+ Map<String, Long> nameToId = daoMgr.getXXPolicyConditionDef().findConditionDefIdsByServiceDefIdAndNames(xServiceDef.getId(), conditionTypes);
+
+ for (String condition : conditionTypes) {
+ Long conditionDefId = nameToId.get(condition);
+
+ if (conditionDefId == null) {
+ if (StringUtils.equalsIgnoreCase(condition, ServiceDefUtil.IMPLICIT_CONDITION_EXPRESSION_NAME)) {
+ continue;
+ }
+
+ throw new Exception(condition + ": is not a valid condition-type. policy='" + xPolicy.getName() + "' service='" + xPolicy.getService() + "'");
+ }
+
+ XXPolicyRefCondition xPolCond = new XXPolicyRefCondition();
+
+ xPolCond.setPolicyId(policy.getId());
+ xPolCond.setConditionDefId(conditionDefId);
+ xPolCond.setConditionName(condition);
+
+ xPolConds.add(xPolCond);
+ }
+
+ batchInsert(xPolConds, daoMgr.getXXPolicyRefCondition(), oldBulkMode);
+ }
+
+ if (CollectionUtils.isNotEmpty(dataMaskTypes)) {
+ List<XXPolicyRefDataMaskType> xxDataMaskInfos = new ArrayList<>();
+ Map<String, Long> nameToId = daoMgr.getXXDataMaskTypeDef().findDataMaskTypeDefIdsByNamesAndServiceId(dataMaskTypes, xPolicy.getService());
+
+ for (String dataMaskType : dataMaskTypes) {
+ Long dataMaskDefId = nameToId.get(dataMaskType);
+
+ if (dataMaskDefId == null) {
+ throw new Exception(dataMaskType + ": is not a valid datamask-type. policy='" + policy.getName() + "' service='" + policy.getService() + "'");
+ }
+
+ XXPolicyRefDataMaskType xxDataMaskInfo = new XXPolicyRefDataMaskType();
+
+ xxDataMaskInfo.setPolicyId(policy.getId());
+ xxDataMaskInfo.setDataMaskDefId(dataMaskDefId);
+ xxDataMaskInfo.setDataMaskTypeName(dataMaskType);
+
+ xxDataMaskInfos.add(xxDataMaskInfo);
+ }
+
+ batchInsert(xxDataMaskInfos, daoMgr.getXXPolicyRefDataMaskType(), oldBulkMode);
+ }
+ }
+
+ public Boolean cleanupRefTables(RangerPolicy policy) {
+ final Long policyId = policy == null ? null : policy.getId();
+
+ if (policyId == null) {
+ return false;
+ }
+
+ daoMgr.getXXPolicyRefResource().deleteByPolicyId(policyId);
+ daoMgr.getXXPolicyRefRole().deleteByPolicyId(policyId);
+ daoMgr.getXXPolicyRefGroup().deleteByPolicyId(policyId);
+ daoMgr.getXXPolicyRefUser().deleteByPolicyId(policyId);
+ daoMgr.getXXPolicyRefAccessType().deleteByPolicyId(policyId);
+ daoMgr.getXXPolicyRefCondition().deleteByPolicyId(policyId);
+ daoMgr.getXXPolicyRefDataMaskType().deleteByPolicyId(policyId);
+
+ return true;
+ }
+
+ /**
+ * Cleans up reference tables for a given policy before updating it.
+ * This includes handling policy reference users, roles, and other
+ * associated reference entities like resources, groups, access types,
+ * conditions, and data mask types.
+ *
+ * @param policyId ID of the policy being updated.
+ * @param policyUsers Set of usernames associated with the updated policy.
+ * @param policyRoles Set of role names associated with the updated policy.
+ * @param policyGroups Set of group names associated with the updated policy.
+ * @return true if cleanup was successful.
+ */
+ public Boolean cleanupRefTablesForUpdate(Long policyId, Set<String> policyUsers, Set<String> policyRoles, Set<String> policyGroups) {
+ cleanupPolicyRefUsers(policyUsers, policyId, daoMgr.getXXPolicyRefUser());
+ cleanupPolicyRefRoles(policyRoles, policyId, daoMgr.getXXPolicyRefRole());
+ cleanupPolicyRefGroups(policyGroups, policyId, daoMgr.getXXPolicyRefGroup());
+
+ daoMgr.getXXPolicyRefResource().deleteByPolicyId(policyId);
+ daoMgr.getXXPolicyRefAccessType().deleteByPolicyId(policyId);
+ daoMgr.getXXPolicyRefCondition().deleteByPolicyId(policyId);
+ daoMgr.getXXPolicyRefDataMaskType().deleteByPolicyId(policyId);
+
+ return true;
+ }
+
+ /**
+ * Identifies and deletes outdated user references for a given policy,
+ * and prepares a list of new users that need to be inserted.
+ *
+ * @param policyUsers Set of usernames from the new policy.
+ * @param policyId The ID of the policy.
+ * @param dao DAO for policy reference users.
+ */
+ public void cleanupPolicyRefUsers(Set<String> policyUsers, Long policyId, XXPolicyRefUserDao dao) {
+ Map<String, Long> policyUserNameIdMap = dao.findUserNameIdByPolicyId(policyId);
+
+ if (policyUserNameIdMap != null && !policyUserNameIdMap.isEmpty()) {
+ Set<String> existingPolicyRefUsers = policyUserNameIdMap.keySet();
+ Set<String> toDeletePolicyRefUsers = new HashSet<>(existingPolicyRefUsers);
+ Set<String> commonUsers = new HashSet<>(policyUsers);
+
+ // Identify users present in both new and existing sets
+ commonUsers.retainAll(toDeletePolicyRefUsers);
+
+ // Identify users to delete (in DB but not in new set)
+ toDeletePolicyRefUsers.removeAll(commonUsers);
+
+ // Remove already existing users from the new set (they don’t need to be inserted again)
+ policyUsers.removeAll(commonUsers);
+
+ if (CollectionUtils.isNotEmpty(toDeletePolicyRefUsers)) {
+ List<Long> idsToDelete = toDeletePolicyRefUsers.stream()
+ .map(policyUserNameIdMap::get)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+
+ LOG.debug("Deleting user IDs from x_policy_ref_user table: {} for policy ID: {}", idsToDelete, policyId);
+
+ dao.deletePolicyRefUserByIds(idsToDelete);
+ }
+ }
+ }
+
+ /**
+ * Identifies and deletes outdated role references for a given policy,
+ * and prepares a list of new roles that need to be inserted.
+ *
+ * @param policyRoles Set of role names from the new policy.
+ * @param policyId The ID of the policy.
+ * @param dao DAO for policy reference roles.
+ */
+ public void cleanupPolicyRefRoles(Set<String> policyRoles, Long policyId, XXPolicyRefRoleDao dao) {
+ Map<String, Long> policyRoleNameIdMap = dao.findRoleNameIdByPolicyId(policyId);
+
+ if (policyRoleNameIdMap != null && !policyRoleNameIdMap.isEmpty()) {
+ Set<String> existingPolicyRefRoles = policyRoleNameIdMap.keySet();
+ Set<String> toDeletePolicyRefRoles = new HashSet<>(existingPolicyRefRoles);
+ Set<String> commonRoles = new HashSet<>(policyRoles);
+
+ // Identify roles present in both new and existing sets
+ commonRoles.retainAll(toDeletePolicyRefRoles);
+
+ // Identify roles to delete (in DB but not in new set)
+ toDeletePolicyRefRoles.removeAll(commonRoles);
+
+ // Remove already existing roles from the new set (they don’t need to be inserted again)
+ policyRoles.removeAll(commonRoles);
+
+ if (CollectionUtils.isNotEmpty(toDeletePolicyRefRoles)) {
+ List<Long> idsToDelete = toDeletePolicyRefRoles.stream()
+ .map(policyRoleNameIdMap::get)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+
+ LOG.debug("Deleting Role IDs from x_policy_ref_role: {} for policy ID: {}", idsToDelete, policyId);
+
+ dao.deletePolicyRefRoleByIds(idsToDelete);
+ }
+ }
+ }
+
+ /**
+ * Identifies and deletes outdated group references for a given policy,
+ * and prepares a list of new groups that need to be inserted.
+ *
+ * @param policyGroups Set of group names from the new policy.
+ * @param policyId The ID of the policy.
+ * @param dao DAO for policy reference groups.
+ */
+ public void cleanupPolicyRefGroups(Set<String> policyGroups, Long policyId, XXPolicyRefGroupDao dao) {
+ Map<String, Long> policyGroupNameIdMap = dao.findGroupNameByPolicyId(policyId);
+
+ if (policyGroupNameIdMap != null && !policyGroupNameIdMap.isEmpty()) {
+ Set<String> existingPolicyRefGroups = policyGroupNameIdMap.keySet();
+ Set<String> toDeletePolicyRefGroups = new HashSet<>(existingPolicyRefGroups);
+ Set<String> commonGroups = new HashSet<>(policyGroups);
+
+ // Identify groups present in both new and existing sets
+ commonGroups.retainAll(toDeletePolicyRefGroups);
+
+ // Identify groups to delete (in DB but not in new set)
+ toDeletePolicyRefGroups.removeAll(commonGroups);
+
+ // Remove already existing groups from the new set (they don’t need to be inserted again)
+ policyGroups.removeAll(commonGroups);
+
+ if (CollectionUtils.isNotEmpty(toDeletePolicyRefGroups)) {
+ List<Long> idsToDelete = toDeletePolicyRefGroups.stream()
+ .map(policyGroupNameIdMap::get)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+
+ LOG.debug("Deleting Group IDs from x_policy_ref_group: {} for policy ID: {}", idsToDelete, policyId);
+
+ dao.deletePolicyRefGroupByIds(idsToDelete);
+ }
+ }
+ }
+
+ public enum PRINCIPAL_TYPE { USER, GROUP, ROLE }
+
+ private boolean doesPolicyExist(XXPolicy policy) {
+ return daoMgr.getXXPolicy().getById(policy.getId()) != null;
+ }
+
+ private class PolicyRoleAssociator implements Runnable {
+ private final String name;
+ private final Long roleId;
+ private final XXPolicy xPolicy;
+
+ PolicyRoleAssociator(String name, Long roleId, XXPolicy xPolicy) {
+ this.name = name;
+ this.roleId = roleId;
+ this.xPolicy = xPolicy;
+ }
+
+ public XXPolicyRefRole getPolicyRef() {
+ Long id = resolveRoleId(false);
+
+ if (id != null && doesPolicyExist(xPolicy)) {
+ XXPolicyRefRole xPolRole = new XXPolicyRefRole();
+
+ xPolRole.setPolicyId(xPolicy.getId());
+ xPolRole.setRoleId(id);
+ xPolRole.setRoleName(name);
+
+ return xPolRole;
+ }
+
+ return null;
+ }
+
+ public void createPolicyRef(Long id) {
+ if (doesPolicyExist(xPolicy)) {
+ XXPolicyRefRole xPolRole = new XXPolicyRefRole();
+
+ xPolRole.setPolicyId(xPolicy.getId());
+ xPolRole.setRoleId(id);
+ xPolRole.setRoleName(name);
+
+ daoMgr.getXXPolicyRefRole().create(xPolRole);
+ } else {
+ LOG.info("Policy with id ={} does not exist, skipping policy association!", xPolicy.getId());
+ }
+ }
+
+ @Override
+ public void run() {
+ Long id = resolveRoleId(true);
+
+ if (id != null) {
+ createPolicyRef(id);
+
+ LOG.debug("Associated ROLE:{} with policy id:[{}]", name, xPolicy.getId());
+ } else {
+ throw new RuntimeException("Failed to associate ROLE:" + name + " with policy id:[" + xPolicy.getId() + "]");
+ }
+ }
+
+ private Long resolveRoleId(boolean createIfAbsent) {
+ Long ret = roleId;
+
+ if (ret == null) {
+ XXRole xRole = daoMgr.getXXRole().findByRoleName(name);
+
+ if (xRole != null) {
+ ret = xRole.getId();
+ } else if (createIfAbsent) {
+ RangerBizUtil.setBulkMode(false);
+
+ ret = createRole();
+ }
+ }
+
+ return ret;
+ }
+
+ private Long createRole() {
+ LOG.warn("Role specified in policy does not exist in ranger admin, creating new role, name = {}", name);
+
+ try {
+ RangerRole rRole = new RangerRole(name, null, null, null, null);
+ RangerRole createdRole = roleStore.createRole(rRole, false);
+
+ return createdRole.getId();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ }
+
+ private class PolicyGroupAssociator implements Runnable {
+ private final String name;
+ private final Long groupId;
+ private final XXPolicy xPolicy;
+
+ PolicyGroupAssociator(String name, Long groupId, XXPolicy xPolicy) {
+ this.name = name;
+ this.groupId = groupId;
+ this.xPolicy = xPolicy;
+ }
+
+ public XXPolicyRefGroup getPolicyRef() {
+ Long id = resolveGroupId(false);
+
+ if (id != null && doesPolicyExist(xPolicy)) {
+ XXPolicyRefGroup xPolGroup = new XXPolicyRefGroup();
+
+ xPolGroup.setPolicyId(xPolicy.getId());
+ xPolGroup.setGroupId(id);
+ xPolGroup.setGroupName(name);
+
+ return xPolGroup;
+ }
+
+ return null;
+ }
+
+ public void createPolicyRef(Long id) {
+ if (doesPolicyExist(xPolicy)) {
+ XXPolicyRefGroup xPolGroup = new XXPolicyRefGroup();
+
+ xPolGroup.setPolicyId(xPolicy.getId());
+ xPolGroup.setGroupId(id);
+ xPolGroup.setGroupName(name);
+
+ daoMgr.getXXPolicyRefGroup().create(xPolGroup);
+ } else {
+ LOG.info("Policy with id ={} does not exist, skipping policy association!", xPolicy.getId());
+ }
+ }
+
+ @Override
+ public void run() {
+ Long id = resolveGroupId(true);
+
+ if (id != null) {
+ createPolicyRef(id);
+
+ LOG.debug("Associated GROUP:{} with policy id:[{}]", name, xPolicy.getId());
+ } else {
+ throw new RuntimeException("Failed to associate GROUP:" + name + " with policy id:[" + xPolicy.getId() + "]");
+ }
+ }
+
+ private Long resolveGroupId(boolean createIfAbsent) {
+ Long ret = groupId;
+
+ if (ret == null) {
+ XXGroup xGroup = daoMgr.getXXGroup().findByGroupName(name);
+
+ if (xGroup != null) {
+ ret = xGroup.getId();
+ } else if (createIfAbsent) {
+ ret = createGroup();
+ }
+ }
+
+ return ret;
+ }
+
+ private Long createGroup() {
+ LOG.warn("Group specified in policy does not exist in ranger admin, creating new group, name = {}", name);
+
+ VXGroup vxGroup = new VXGroup();
+
+ vxGroup.setName(name);
+ vxGroup.setDescription(name);
+ vxGroup.setGroupSource(RangerCommonEnums.GROUP_EXTERNAL);
+
+ VXGroup vXGroup = xGroupService.createXGroupWithOutLogin(vxGroup);
+
+ if (vXGroup != null) {
+ xGroupService.createTransactionLog(vXGroup, null, OPERATION_CREATE_CONTEXT, xPolicy.getAddedByUserId());
+
+ return vXGroup.getId();
+ }
+
+ return null;
+ }
+ }
+
+ private class PolicyUserAssociator implements Runnable {
+ private final String name;
+ private final Long userId;
+ private final XXPolicy xPolicy;
+
+ PolicyUserAssociator(String name, Long userId, XXPolicy xPolicy) {
+ this.name = name;
+ this.userId = userId;
+ this.xPolicy = xPolicy;
+ }
+
+ public XXPolicyRefUser getPolicyRef() {
+ Long id = resolveUserId(false);
+
+ if (id != null && doesPolicyExist(xPolicy)) {
+ XXPolicyRefUser xPolUser = new XXPolicyRefUser();
+
+ xPolUser.setPolicyId(xPolicy.getId());
+ xPolUser.setUserId(id);
+ xPolUser.setUserName(name);
+
+ return xPolUser;
+ }
+
+ return null;
+ }
+
+ public void createPolicyRef(Long id) {
+ if (doesPolicyExist(xPolicy)) {
+ XXPolicyRefUser xPolUser = new XXPolicyRefUser();
+
+ xPolUser.setPolicyId(xPolicy.getId());
+ xPolUser.setUserId(id);
+ xPolUser.setUserName(name);
+
+ daoMgr.getXXPolicyRefUser().create(xPolUser);
+ } else {
+ LOG.info("Policy with id ={} does not exist, skipping policy association!", xPolicy.getId());
+ }
+ }
+
+ @Override
+ public void run() {
+ Long id = resolveUserId(true);
+
+ if (id != null) {
+ createPolicyRef(id);
+
+ LOG.debug("Associated USER:{} with policy id:[{}]", name, xPolicy.getId());
+ } else {
+ throw new RuntimeException("Failed to associate USER:" + name + " with policy id:[" + xPolicy.getId() + "]");
+ }
+ }
+
+ private Long resolveUserId(boolean createIfAbsent) {
+ Long ret = userId;
+
+ if (ret == null) {
+ XXUser xUser = daoMgr.getXXUser().findByUserName(name);
+
+ if (xUser != null) {
+ ret = xUser.getId();
+ } else if (createIfAbsent) {
+ return createUser();
+ }
+ }
+
+ return ret;
+ }
+
+ private Long createUser() {
+ LOG.warn("User specified in policy does not exist in ranger admin, creating new user, name = {}", name);
- private static final Logger LOG = LoggerFactory.getLogger(PolicyRefUpdater.class);
+ VXUser vXUser = xUserMgr.createServiceConfigUser(name);
- public enum PRINCIPAL_TYPE { USER, GROUP, ROLE }
+ if (vXUser != null) {
+ XXUser xUser = daoMgr.getXXUser().findByUserName(name);
- @Autowired
- RangerDaoManager daoMgr;
+ if (xUser == null) {
+ LOG.error("No User created!! Irrecoverable error! [{}]", name);
+ } else {
+ return xUser.getId();
+ }
+ } else {
+ LOG.warn("serviceConfigUser:[{}] creation failed. This may be a transient/spurious condition that may correct itself when transaction is committed", name);
+ }
- @Autowired
- XUserMgr xUserMgr;
+ return null;
+ }
+ }
- @Autowired
- RoleDBStore roleStore;
-
- @Autowired
- RangerBizUtil rangerBizUtil;
-
- @Autowired
- XGroupService xGroupService;
-
- @Autowired
- RangerTransactionSynchronizationAdapter rangerTransactionSynchronizationAdapter;
-
- @Autowired
- RESTErrorUtil restErrorUtil;
-
- public void createNewPolMappingForRefTable(RangerPolicy policy, XXPolicy xPolicy, XXServiceDef xServiceDef, boolean createPrincipalsIfAbsent) throws Exception {
- if(policy == null) {
- return;
- }
-
- cleanupRefTables(policy);
-
- final Set<String> resourceNames = policy.getResources().keySet();
- final Set<String> roleNames = new HashSet<>();
- final Set<String> groupNames = new HashSet<>();
- final Set<String> userNames = new HashSet<>();
- final Set<String> accessTypes = new HashSet<>();
- final Set<String> conditionTypes = new HashSet<>();
- final Set<String> dataMaskTypes = new HashSet<>();
- boolean oldBulkMode = RangerBizUtil.isBulkMode();
-
- List<RangerPolicy.RangerPolicyItemCondition> rangerPolicyConditions = policy.getConditions();
- if (CollectionUtils.isNotEmpty(rangerPolicyConditions)) {
- for (RangerPolicy.RangerPolicyItemCondition condition : rangerPolicyConditions) {
- conditionTypes.add(condition.getType());
- }
- }
-
- for (List<? extends RangerPolicyItem> policyItems : getAllPolicyItems(policy)) {
- if (CollectionUtils.isEmpty(policyItems)) {
- continue;
- }
-
- for (RangerPolicyItem policyItem : policyItems) {
- roleNames.addAll(policyItem.getRoles());
- groupNames.addAll(policyItem.getGroups());
- userNames.addAll(policyItem.getUsers());
-
- if (CollectionUtils.isNotEmpty(policyItem.getAccesses())) {
- for (RangerPolicyItemAccess access : policyItem.getAccesses()) {
- accessTypes.add(access.getType());
- }
- }
-
- if (CollectionUtils.isNotEmpty(policyItem.getConditions())) {
- for (RangerPolicyItemCondition condition : policyItem.getConditions()) {
- conditionTypes.add(condition.getType());
- }
- }
-
- if (policyItem instanceof RangerDataMaskPolicyItem) {
- RangerPolicyItemDataMaskInfo dataMaskInfo = ((RangerDataMaskPolicyItem) policyItem).getDataMaskInfo();
-
- dataMaskTypes.add(dataMaskInfo.getDataMaskType());
- }
- }
- }
-
- List<XXPolicyRefResource> xPolResources = new ArrayList<>();
- for (String resource : resourceNames) {
- XXResourceDef xResDef = daoMgr.getXXResourceDef().findByNameAndPolicyId(resource, policy.getId());
-
- if (xResDef == null) {
- throw new Exception(resource + ": is not a valid resource-type. policy='"+ policy.getName() + "' service='"+ policy.getService() + "'");
- }
-
- XXPolicyRefResource xPolRes = new XXPolicyRefResource();
-
- xPolRes.setPolicyId(policy.getId());
- xPolRes.setResourceDefId(xResDef.getId());
- xPolRes.setResourceName(resource);
-
- xPolResources.add(xPolRes);
- }
- daoMgr.getXXPolicyRefResource().batchCreate(xPolResources);
-
- if (createPrincipalsIfAbsent && !rangerBizUtil.checkAdminAccess()) {
- LOG.warn("policy=" + policy.getName() + ": createPrincipalIfAbsent=true, but current user does not have admin privileges!");
-
- createPrincipalsIfAbsent = false;
- }
-
- List<XXPolicyRefRole> xPolRoles = new ArrayList<>();
- for (String role : roleNames) {
- if (StringUtils.isBlank(role)) {
- continue;
- }
- PolicyPrincipalAssociator associator = new PolicyPrincipalAssociator(PRINCIPAL_TYPE.ROLE, role, xPolicy);
- if (!associator.doAssociate(false)) {
- if (createPrincipalsIfAbsent) {
- rangerTransactionSynchronizationAdapter.executeOnTransactionCommit(associator);
- } else {
- VXResponse gjResponse = new VXResponse();
- gjResponse.setStatusCode(HttpServletResponse.SC_BAD_REQUEST);
- gjResponse.setMsgDesc("Operation denied. Role name: " + role + " specified in policy does not exist in ranger admin.");
- throw restErrorUtil.generateRESTException(gjResponse);
- }
- }
- }
- RangerBizUtil.setBulkMode(oldBulkMode);
- daoMgr.getXXPolicyRefRole().batchCreate(xPolRoles);
-
- for (String group : groupNames) {
- if (StringUtils.isBlank(group)) {
- continue;
- }
-
- PolicyPrincipalAssociator associator = new PolicyPrincipalAssociator(PRINCIPAL_TYPE.GROUP, group, xPolicy);
- if (!associator.doAssociate(false)) {
- if (createPrincipalsIfAbsent) {
- rangerTransactionSynchronizationAdapter.executeOnTransactionCommit(associator);
- } else {
- VXResponse gjResponse = new VXResponse();
- gjResponse.setStatusCode(HttpServletResponse.SC_BAD_REQUEST);
- gjResponse.setMsgDesc("Operation denied. Group name: " + group + " specified in policy does not exist in ranger admin.");
- throw restErrorUtil.generateRESTException(gjResponse);
- }
- }
- }
-
- for (String user : userNames) {
- if (StringUtils.isBlank(user)) {
- continue;
- }
- PolicyPrincipalAssociator associator = new PolicyPrincipalAssociator(PRINCIPAL_TYPE.USER, user, xPolicy);
- if (!associator.doAssociate(false)) {
- if (createPrincipalsIfAbsent) {
- rangerTransactionSynchronizationAdapter.executeOnTransactionCommit(associator);
- } else {
- VXResponse gjResponse = new VXResponse();
- gjResponse.setStatusCode(HttpServletResponse.SC_BAD_REQUEST);
- gjResponse.setMsgDesc("Operation denied. User name: " + user + " specified in policy does not exist in ranger admin.");
- throw restErrorUtil.generateRESTException(gjResponse);
- }
- }
- }
-
- List<XXPolicyRefAccessType> xPolAccesses = new ArrayList<>();
-
- // ignore built-in access-types while creating ref-table entries
- accessTypes.removeAll(ServiceDefUtil.ACCESS_TYPE_MARKERS);
-
- for (String accessType : accessTypes) {
- XXAccessTypeDef xAccTypeDef = daoMgr.getXXAccessTypeDef().findByNameAndServiceId(accessType, xPolicy.getService());
-
- if (xAccTypeDef == null) {
- throw new Exception(accessType + ": is not a valid access-type. policy='" + policy.getName() + "' service='" + policy.getService() + "'");
- }
-
- XXPolicyRefAccessType xPolAccess = new XXPolicyRefAccessType();
-
- xPolAccess.setPolicyId(policy.getId());
- xPolAccess.setAccessDefId(xAccTypeDef.getId());
- xPolAccess.setAccessTypeName(accessType);
-
- xPolAccesses.add(xPolAccess);
- }
- daoMgr.getXXPolicyRefAccessType().batchCreate(xPolAccesses);
-
- List<XXPolicyRefCondition> xPolConds = new ArrayList<>();
- for (String condition : conditionTypes) {
- XXPolicyConditionDef xPolCondDef = daoMgr.getXXPolicyConditionDef().findByServiceDefIdAndName(xServiceDef.getId(), condition);
-
- if (xPolCondDef == null) {
- if (StringUtils.equalsIgnoreCase(condition, ServiceDefUtil.IMPLICIT_CONDITION_EXPRESSION_NAME)) {
- continue;
- }
-
- throw new Exception(condition + ": is not a valid condition-type. policy='"+ xPolicy.getName() + "' service='"+ xPolicy.getService() + "'");
- }
-
- XXPolicyRefCondition xPolCond = new XXPolicyRefCondition();
-
- xPolCond.setPolicyId(policy.getId());
- xPolCond.setConditionDefId(xPolCondDef.getId());
- xPolCond.setConditionName(condition);
-
- xPolConds.add(xPolCond);
- }
- daoMgr.getXXPolicyRefCondition().batchCreate(xPolConds);
-
- List<XXPolicyRefDataMaskType> xxDataMaskInfos = new ArrayList<>();
- for (String dataMaskType : dataMaskTypes ) {
- XXDataMaskTypeDef dataMaskDef = daoMgr.getXXDataMaskTypeDef().findByNameAndServiceId(dataMaskType, xPolicy.getService());
-
- if (dataMaskDef == null) {
- throw new Exception(dataMaskType + ": is not a valid datamask-type. policy='" + policy.getName() + "' service='" + policy.getService() + "'");
- }
-
- XXPolicyRefDataMaskType xxDataMaskInfo = new XXPolicyRefDataMaskType();
-
- xxDataMaskInfo.setPolicyId(policy.getId());
- xxDataMaskInfo.setDataMaskDefId(dataMaskDef.getId());
- xxDataMaskInfo.setDataMaskTypeName(dataMaskType);
-
- xxDataMaskInfos.add(xxDataMaskInfo);
- }
- daoMgr.getXXPolicyRefDataMaskType().batchCreate(xxDataMaskInfos);
- }
-
- private class PolicyPrincipalAssociator implements Runnable {
- final PRINCIPAL_TYPE type;
- final String name;
- final XXPolicy xPolicy;
-
- public PolicyPrincipalAssociator(PRINCIPAL_TYPE type, String name, XXPolicy xPolicy) {
- this.type = type;
- this.name = name;
- this.xPolicy = xPolicy;
- }
-
- @Override
- public void run() {
- if (doAssociate(true)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Associated " + type.name() + ":" + name + " with policy id:[" + xPolicy.getId() + "]");
- }
- } else {
- throw new RuntimeException("Failed to associate " + type.name() + ":" + name + " with policy id:[" + xPolicy.getId() + "]");
- }
- }
-
- boolean doAssociate(boolean isAdmin) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("===> PolicyPrincipalAssociator.doAssociate(" + isAdmin + ")");
- }
- final boolean ret;
-
- Long id = createOrGetPrincipal(isAdmin);
- if (id != null) {
- // associate with policy
- createPolicyAssociation(id, name);
- ret = true;
- } else {
- ret = false;
- }
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("<=== PolicyPrincipalAssociator.doAssociate(" + isAdmin + ") : " + ret);
- }
- return ret;
- }
-
- private Long createOrGetPrincipal(final boolean createIfAbsent) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("===> PolicyPrincipalAssociator.createOrGetPrincipal(" + createIfAbsent + ")");
- }
-
- Long ret = null;
-
- switch (type) {
- case USER: {
- XXUser xUser = daoMgr.getXXUser().findByUserName(name);
- if (xUser != null) {
- ret = xUser.getId();
- } else {
- if (createIfAbsent) {
- ret = createPrincipal(name);
- }
- }
- }
- break;
- case GROUP: {
- XXGroup xGroup = daoMgr.getXXGroup().findByGroupName(name);
-
- if (xGroup != null) {
- ret = xGroup.getId();
- } else {
- if (createIfAbsent) {
- ret = createPrincipal(name);
- }
- }
- }
- break;
- case ROLE: {
- XXRole xRole = daoMgr.getXXRole().findByRoleName(name);
- if (xRole != null) {
- ret = xRole.getId();
- } else {
- if (createIfAbsent) {
- RangerBizUtil.setBulkMode(false);
- ret = createPrincipal(name);
- }
- }
- }
- break;
- default:
- break;
- }
- if (LOG.isDebugEnabled()) {
- LOG.debug("<=== PolicyPrincipalAssociator.createOrGetPrincipal(" + createIfAbsent + ") : " + ret);
- }
- return ret;
- }
-
- private Long createPrincipal(String user) {
- LOG.warn("User specified in policy does not exist in ranger admin, creating new user, Type: " + type.name() + ", name = " + user);
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("===> PolicyPrincipalAssociator.createPrincipal(type=" + type.name() +", name=" + name + ")");
- }
-
- Long ret = null;
-
- switch (type) {
- case USER: {
- // Create External user
- VXUser vXUser = xUserMgr.createServiceConfigUser(name);
- if (vXUser != null) {
- XXUser xUser = daoMgr.getXXUser().findByUserName(name);
-
- if (xUser == null) {
- LOG.error("No User created!! Irrecoverable error! [" + name + "]");
- } else {
- ret = xUser.getId();
- }
- } else {
- LOG.warn("serviceConfigUser:[" + name + "] creation failed. This may be a transient/spurious condition that may correct itself when transaction is committed");
- }
- }
- break;
- case GROUP: {
- // Create group
- VXGroup vxGroup = new VXGroup();
- vxGroup.setName(name);
- vxGroup.setDescription(name);
- vxGroup.setGroupSource(RangerCommonEnums.GROUP_EXTERNAL);
- VXGroup vXGroup = xGroupService.createXGroupWithOutLogin(vxGroup);
- if (vXGroup != null) {
- xGroupService.createTransactionLog(vXGroup, null, OPERATION_CREATE_CONTEXT, xPolicy.getAddedByUserId());
-
- ret = vXGroup.getId();
- }
- }
- break;
- case ROLE: {
- try {
- RangerRole rRole = new RangerRole(name, null, null, null, null);
- RangerRole createdRole = roleStore.createRole(rRole, false);
- ret = createdRole.getId();
- } catch (Exception e) {
- // Ignore
- }
- }
- break;
- default:
- break;
- }
- if (LOG.isDebugEnabled()) {
- LOG.debug("<=== PolicyPrincipalAssociator.createPrincipal(type=" + type.name() + ", name=" + name + ") : " + ret);
- }
- return ret;
- }
-
- private void createPolicyAssociation(Long id, String name) {
- if(LOG.isDebugEnabled()) {
- LOG.debug("===> PolicyPrincipalAssociator.createPolicyAssociation(policyId=" + xPolicy.getId() + ", type=" + type.name() + ", name=" + name + ", id=" + id + ")");
- }
- switch (type) {
- case USER: {
- XXPolicyRefUser xPolUser = new XXPolicyRefUser();
-
- xPolUser.setPolicyId(xPolicy.getId());
- xPolUser.setUserId(id);
- xPolUser.setUserName(name);
- daoMgr.getXXPolicyRefUser().create(xPolUser);
- }
- break;
- case GROUP: {
- XXPolicyRefGroup xPolGroup = new XXPolicyRefGroup();
-
- xPolGroup.setPolicyId(xPolicy.getId());
- xPolGroup.setGroupId(id);
- xPolGroup.setGroupName(name);
- daoMgr.getXXPolicyRefGroup().create(xPolGroup);
- }
- break;
- case ROLE: {
- XXPolicyRefRole xPolRole = new XXPolicyRefRole();
-
- xPolRole.setPolicyId(xPolicy.getId());
- xPolRole.setRoleId(id);
- xPolRole.setRoleName(name);
- daoMgr.getXXPolicyRefRole().create(xPolRole);
- }
- break;
- default:
- break;
- }
- if(LOG.isDebugEnabled()) {
- LOG.debug("<=== PolicyPrincipalAssociator.createPolicyAssociation(policyId=" + xPolicy.getId() + ", type=" + type.name() + ", name=" + name + ", id=" + id + ")");
- }
- }
- }
-
- public Boolean cleanupRefTables(RangerPolicy policy) {
- final Long policyId = policy == null ? null : policy.getId();
-
- if (policyId == null) {
- return false;
- }
-
- daoMgr.getXXPolicyRefResource().deleteByPolicyId(policyId);
- daoMgr.getXXPolicyRefRole().deleteByPolicyId(policyId);
- daoMgr.getXXPolicyRefGroup().deleteByPolicyId(policyId);
- daoMgr.getXXPolicyRefUser().deleteByPolicyId(policyId);
- daoMgr.getXXPolicyRefAccessType().deleteByPolicyId(policyId);
- daoMgr.getXXPolicyRefCondition().deleteByPolicyId(policyId);
- daoMgr.getXXPolicyRefDataMaskType().deleteByPolicyId(policyId);
-
- return true;
- }
-
- public static List<List<? extends RangerPolicyItem>> getAllPolicyItems(RangerPolicy policy) {
- List<List<? extends RangerPolicyItem>> ret = new ArrayList<>();
-
- if (CollectionUtils.isNotEmpty(policy.getPolicyItems())) {
- ret.add(policy.getPolicyItems());
- }
-
- if (CollectionUtils.isNotEmpty(policy.getDenyPolicyItems())) {
- ret.add(policy.getDenyPolicyItems());
- }
-
- if (CollectionUtils.isNotEmpty(policy.getAllowExceptions())) {
- ret.add(policy.getAllowExceptions());
- }
-
- if (CollectionUtils.isNotEmpty(policy.getDenyExceptions())) {
- ret.add(policy.getDenyExceptions());
- }
-
- if (CollectionUtils.isNotEmpty(policy.getDataMaskPolicyItems())) {
- ret.add(policy.getDataMaskPolicyItems());
- }
-
- if (CollectionUtils.isNotEmpty(policy.getRowFilterPolicyItems())) {
- ret.add(policy.getRowFilterPolicyItems());
- }
-
- return ret;
- }
+ private <T> void batchInsert(List<T> entities, BaseDao<T> dao, boolean oldBulkMode) {
+ if (CollectionUtils.isNotEmpty(entities)) {
+ long startTimeMs = System.currentTimeMillis();
+ LOG.debug("Batch insert started for create/update {} with {} records.", dao.getClass().getSimpleName(), entities.size());
+
+ RangerBizUtil.setBulkMode(false);
+ dao.batchCreate(entities);
+ RangerBizUtil.setBulkMode(oldBulkMode);
+
+ LOG.debug("Batch insert completed for create/update {} with {} records in {} ms.", dao.getClass().getSimpleName(), entities.size(), (System.currentTimeMillis() - startTimeMs));
+ }
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
index dc3802748..501d3e454 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
@@ -2132,7 +2132,7 @@ public RangerPolicy createPolicy(RangerPolicy policy, boolean createPrincipalsIf
}
XXPolicy xCreatedPolicy = daoMgr.getXXPolicy().getById(policy.getId());
- policyRefUpdater.createNewPolMappingForRefTable(policy, xCreatedPolicy, xServiceDef, createPrincipalsIfAbsent);
+ policyRefUpdater.createNewPolMappingForRefTable(policy, xCreatedPolicy, xServiceDef, createPrincipalsIfAbsent, false);
createOrMapLabels(xCreatedPolicy, uniquePolicyLabels);
RangerPolicy createdPolicy = policyService.getPopulatedViewObject(xCreatedPolicy);
@@ -2315,10 +2315,9 @@ public RangerPolicy updatePolicy(RangerPolicy policy) throws Exception {
policy = policyService.update(policy);
XXPolicy newUpdPolicy = daoMgr.getXXPolicy().getById(policy.getId());
- policyRefUpdater.cleanupRefTables(policy);
deleteExistingPolicyLabel(policy);
- policyRefUpdater.createNewPolMappingForRefTable(policy, newUpdPolicy, xServiceDef, bizUtil.getCreatePrincipalsIfAbsent());
+ policyRefUpdater.createNewPolMappingForRefTable(policy, newUpdPolicy, xServiceDef, bizUtil.getCreatePrincipalsIfAbsent(), true);
createOrMapLabels(newUpdPolicy, uniquePolicyLabels);
RangerPolicy updPolicy = policyService.getPopulatedViewObject(newUpdPolicy);
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXAccessTypeDefDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXAccessTypeDefDao.java
index 8f5749854..3fba90df0 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXAccessTypeDefDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXAccessTypeDefDao.java
@@ -18,16 +18,25 @@
package org.apache.ranger.db;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
import javax.persistence.NoResultException;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.ranger.common.db.BaseDao;
import org.apache.ranger.entity.XXAccessTypeDef;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@Service
public class XXAccessTypeDefDao extends BaseDao<XXAccessTypeDef> {
+ private static final Logger logger = LoggerFactory.getLogger(XXAccessTypeDefDao.class);
public XXAccessTypeDefDao(RangerDaoManagerBase daoManager) {
super(daoManager);
@@ -60,4 +69,22 @@ public XXAccessTypeDef findByNameAndServiceId(String name, Long serviceId) {
return null;
}
}
+
+ public Map<String, Long> findAccessTypeDefIdsByNamesAndServiceId(Set<String> names, Long serviceId) {
+ if (serviceId != null && CollectionUtils.isNotEmpty(names)) {
+ try {
+ Collection<Object[]> result = getEntityManager()
+ .createNamedQuery("XXAccessTypeDef.findAccessTypeDefIdsByNamesAndServiceId", Object[].class)
+ .setParameter("names", names)
+ .setParameter("serviceId", serviceId)
+ .getResultList();
+
+ return result.stream().collect(Collectors.toMap(object -> (String) object[1], object -> (Long) object[0], (a, b) -> a));
+ } catch (NoResultException e) {
+ logger.debug(e.getMessage());
+ }
+ }
+
+ return Collections.emptyMap();
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXDataMaskTypeDefDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXDataMaskTypeDefDao.java
index 83c288127..b0fa07396 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXDataMaskTypeDefDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXDataMaskTypeDefDao.java
@@ -18,16 +18,25 @@
package org.apache.ranger.db;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
import javax.persistence.NoResultException;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.ranger.common.db.BaseDao;
import org.apache.ranger.entity.XXDataMaskTypeDef;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@Service
public class XXDataMaskTypeDefDao extends BaseDao<XXDataMaskTypeDef> {
+ private static final Logger logger = LoggerFactory.getLogger(XXDataMaskTypeDefDao.class);
public XXDataMaskTypeDefDao(RangerDaoManagerBase daoManager) {
super(daoManager);
@@ -60,4 +69,22 @@ public XXDataMaskTypeDef findByNameAndServiceId(String name, Long serviceId) {
return null;
}
}
+
+ public Map<String, Long> findDataMaskTypeDefIdsByNamesAndServiceId(Set<String> names, Long serviceId) {
+ if (serviceId != null && CollectionUtils.isNotEmpty(names)) {
+ try {
+ Collection<Object[]> result = getEntityManager()
+ .createNamedQuery("XXDataMaskTypeDef.findDataMaskTypeDefIdsByNamesAndServiceId", Object[].class)
+ .setParameter("names", names)
+ .setParameter("serviceId", serviceId)
+ .getResultList();
+
+ return result.stream().collect(Collectors.toMap(object -> (String) object[1], object -> (Long) object[0], (a, b) -> a));
+ } catch (NoResultException e) {
+ logger.debug(e.getMessage());
+ }
+ }
+
+ return Collections.emptyMap();
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXGroupDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXGroupDao.java
index 12708f6a3..df7a11216 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXGroupDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXGroupDao.java
@@ -21,10 +21,14 @@
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ranger.authorization.utils.JsonUtils;
import org.apache.ranger.common.RangerCommonEnums;
@@ -117,6 +121,23 @@ public List<GroupInfo> getAllGroupsInfo() {
return ret;
}
+ public Map<String, Long> getIdsByGroupNames(Collection<String> groupNames) {
+ if (CollectionUtils.isNotEmpty(groupNames)) {
+ try {
+ Collection<Object[]> result = getEntityManager()
+ .createNamedQuery("XXGroup.getIdsByGroupNames", Object[].class)
+ .setParameter("names", groupNames)
+ .getResultList();
+
+ return result.stream().collect(Collectors.toMap(object -> (String) (object[1]), object -> (Long) (object[0])));
+ } catch (NoResultException excp) {
+ logger.debug(excp.getMessage());
+ }
+ }
+
+ return Collections.emptyMap();
+ }
+
private GroupInfo toGroupInfo(Object[] row) {
String name = (String) row[0];
String description = (String) row[1];
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXPolicyConditionDefDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXPolicyConditionDefDao.java
index de2c47dc4..bae897a6c 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXPolicyConditionDefDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXPolicyConditionDefDao.java
@@ -18,16 +18,25 @@
package org.apache.ranger.db;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
import javax.persistence.NoResultException;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.ranger.common.db.BaseDao;
import org.apache.ranger.entity.XXPolicyConditionDef;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@Service
public class XXPolicyConditionDefDao extends BaseDao<XXPolicyConditionDef> {
+ private static final Logger logger = LoggerFactory.getLogger(XXPolicyConditionDefDao.class);
public XXPolicyConditionDefDao(RangerDaoManagerBase daoManager) {
super(daoManager);
@@ -61,5 +70,22 @@ public XXPolicyConditionDef findByServiceDefIdAndName(Long serviceDefId, String
return null;
}
}
-
+
+ public Map<String, Long> findConditionDefIdsByServiceDefIdAndNames(Long serviceDefId, Set<String> names) {
+ if (serviceDefId != null && CollectionUtils.isNotEmpty(names)) {
+ try {
+ Collection<Object[]> result = getEntityManager()
+ .createNamedQuery("XXPolicyConditionDef.findConditionDefIdsByServiceDefIdAndNames", Object[].class)
+ .setParameter("serviceDefId", serviceDefId)
+ .setParameter("names", names)
+ .getResultList();
+
+ return result.stream().collect(Collectors.toMap(object -> (String) object[1], object -> (Long) object[0], (a, b) -> a));
+ } catch (NoResultException e) {
+ logger.debug(e.getMessage());
+ }
+ }
+
+ return Collections.emptyMap();
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXPolicyRefGroupDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXPolicyRefGroupDao.java
index 3ce371306..8c5da614b 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXPolicyRefGroupDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXPolicyRefGroupDao.java
@@ -20,8 +20,11 @@
package org.apache.ranger.db;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
import javax.persistence.NoResultException;
@@ -115,4 +118,30 @@ public void deleteByPolicyId(Long policyId) {
batchDeleteByIds("XXPolicyRefGroup.deleteByIds", ids, "ids");
}
+
+ public Map<String, Long> findGroupNameByPolicyId(Long policyId) {
+ Map<String, Long> ret = Collections.emptyMap();
+ if (policyId != null) {
+ try {
+ Collection<Object[]> results = getEntityManager()
+ .createNamedQuery("XXPolicyRefGroup.findGroupNameByPolicyId", Object[].class)
+ .setParameter("policyId", policyId)
+ .getResultList();
+ ret = results.stream().collect(
+ Collectors.toMap(
+ object -> (String) object[0],
+ object -> (Long) object[1]));
+ } catch (NoResultException e) {
+ // ignore
+ }
+ }
+ return ret;
+ }
+
+ public void deletePolicyRefGroupByIds(List<Long> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ batchDeleteByIds("XXPolicyRefGroup.deletePolicyRefGroupByIds", ids, "ids");
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXPolicyRefRoleDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXPolicyRefRoleDao.java
index 29d2bc4c9..4dfe7372e 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXPolicyRefRoleDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXPolicyRefRoleDao.java
@@ -20,8 +20,11 @@
package org.apache.ranger.db;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
import javax.persistence.NoResultException;
@@ -127,5 +130,31 @@ public void deleteByPolicyId(Long policyId) {
batchDeleteByIds("XXPolicyRefRole.deleteByIds", ids, "ids");
}
+
+ public Map<String, Long> findRoleNameIdByPolicyId(Long policyId) {
+ Map<String, Long> ret = Collections.emptyMap();
+ if (policyId != null) {
+ try {
+ Collection<Object[]> results = getEntityManager()
+ .createNamedQuery("XXPolicyRefRole.findRoleNameIdByPolicyId", Object[].class)
+ .setParameter("policyId", policyId)
+ .getResultList();
+ ret = results.stream().collect(
+ Collectors.toMap(
+ object -> (String) object[0],
+ object -> (Long) object[1]));
+ } catch (NoResultException e) {
+ // ignore
+ }
+ }
+ return ret;
+ }
+
+ public void deletePolicyRefRoleByIds(List<Long> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ batchDeleteByIds("XXPolicyRefRole.deletePolicyRefRoleByIds", ids, "ids");
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXPolicyRefUserDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXPolicyRefUserDao.java
index 07d94ceb9..52543b2c3 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXPolicyRefUserDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXPolicyRefUserDao.java
@@ -20,8 +20,11 @@
package org.apache.ranger.db;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
import javax.persistence.NoResultException;
@@ -127,4 +130,30 @@ public void deleteByPolicyId(Long policyId) {
batchDeleteByIds("XXPolicyRefUser.deleteByIds", ids, "ids");
}
+
+ public Map<String, Long> findUserNameIdByPolicyId(Long policyId) {
+ Map<String, Long> ret = Collections.emptyMap();
+ if (policyId != null) {
+ try {
+ Collection<Object[]> results = getEntityManager()
+ .createNamedQuery("XXPolicyRefUser.findUserNameIdByPolicyId", Object[].class)
+ .setParameter("policyId", policyId)
+ .getResultList();
+ ret = results.stream().collect(
+ Collectors.toMap(
+ object -> (String) object[0],
+ object -> (Long) object[1]));
+ } catch (NoResultException e) {
+ // ignore
+ }
+ }
+ return ret;
+ }
+
+ public void deletePolicyRefUserByIds(List<Long> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ batchDeleteByIds("XXPolicyRefUser.deletePolicyRefUserByIds", ids, "ids");
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXResourceDefDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXResourceDefDao.java
index 56139027b..df5d104ff 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXResourceDefDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXResourceDefDao.java
@@ -18,16 +18,25 @@
package org.apache.ranger.db;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
import javax.persistence.NoResultException;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.ranger.common.db.BaseDao;
import org.apache.ranger.entity.XXResourceDef;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@Service
public class XXResourceDefDao extends BaseDao<XXResourceDef> {
+ private static final Logger logger = LoggerFactory.getLogger(XXResourceDefDao.class);
public XXResourceDefDao(RangerDaoManagerBase daoMgr) {
super(daoMgr);
@@ -99,4 +108,22 @@ public List<XXResourceDef> findByParentResId(Long parentId) {
return new ArrayList<XXResourceDef>();
}
}
+
+ public Map<String, Long> findResourceDefIdsByNameAndPolicyId(Set<String> names, Long policyId) {
+ if (policyId != null && CollectionUtils.isNotEmpty(names)) {
+ try {
+ Collection<Object[]> result = getEntityManager()
+ .createNamedQuery("XXResourceDef.findResourceDefIdsByNameAndPolicyId", Object[].class)
+ .setParameter("policyId", policyId)
+ .setParameter("names", names)
+ .getResultList();
+
+ return result.stream().collect(Collectors.toMap(object -> (String) object[1], object -> (Long) object[0], (a, b) -> a));
+ } catch (NoResultException e) {
+ logger.debug(e.getMessage());
+ }
+ }
+
+ return Collections.emptyMap();
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXRoleDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXRoleDao.java
index 03e966934..1fb54895e 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXRoleDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXRoleDao.java
@@ -17,18 +17,26 @@
package org.apache.ranger.db;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ranger.common.db.BaseDao;
import org.apache.ranger.entity.XXRole;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.persistence.NoResultException;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
@Service
public class XXRoleDao extends BaseDao<XXRole> {
+ private static final Logger logger = LoggerFactory.getLogger(XXRoleDao.class);
/**
* Default Constructor
*/
@@ -126,5 +134,22 @@ public List<XXRole> findByGroupId(Long groupId) {
}
return ret;
}
+
+ public Map<String, Long> getIdsByRoleNames(Collection<String> roleNames) {
+ if (CollectionUtils.isNotEmpty(roleNames)) {
+ try {
+ Collection<Object[]> result = getEntityManager()
+ .createNamedQuery("XXRole.getIdsByRoleNames", Object[].class)
+ .setParameter("roleNames", roleNames)
+ .getResultList();
+
+ return result.stream().collect(Collectors.toMap(object -> (String) (object[1]), object -> (Long) (object[0])));
+ } catch (NoResultException e) {
+ logger.debug(e.getMessage());
+ }
+ }
+
+ return Collections.emptyMap();
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXUserDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXUserDao.java
index 05c65322a..61121788d 100755
--- a/security-admin/src/main/java/org/apache/ranger/db/XXUserDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXUserDao.java
@@ -21,6 +21,7 @@
import javax.persistence.NoResultException;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ranger.authorization.utils.JsonUtils;
@@ -33,12 +34,15 @@
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
-import java.util.List;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Map;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
import static org.apache.ranger.plugin.util.RangerCommonConstants.*;
@@ -186,6 +190,23 @@ public List<UserInfo> getAllUsersInfo() {
return ret;
}
+ public Map<String, Long> getIdsByUserNames(Collection<String> names) {
+ if (CollectionUtils.isNotEmpty(names)) {
+ try {
+ Collection<Object[]> result = getEntityManager()
+ .createNamedQuery("XXUser.getIdsByUserNames", Object[].class)
+ .setParameter("names", names)
+ .getResultList();
+
+ return result.stream().collect(Collectors.toMap(object -> (String) (object[1]), object -> (Long) (object[0])));
+ } catch (NoResultException e) {
+ logger.debug(e.getMessage());
+ }
+ }
+
+ return Collections.emptyMap();
+ }
+
private UserInfo toUserInfo(Object[] row) {
String name = (String) row[0];
String description = (String) row[1];
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 9db7bf1ca..42d497792 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
@@ -176,6 +176,10 @@
</query>
</named-query>
+ <named-query name="XXGroup.getIdsByGroupNames">
+ <query>SELECT obj.id, obj.name FROM XXGroup obj WHERE obj.name IN :names</query>
+ </named-query>
+
<!-- XXGroup -->
<named-query name="XXUser.findGroupsByUserIds">
<query>SELECT user.name, group.name FROM XXUser user, XXGroup group, XXGroupUser groupUser
@@ -193,12 +197,17 @@
</query>
</named-query>
+ <named-query name="XXUser.getIdsByUserNames">
+ <query>SELECT obj.id, obj.name FROM XXUser obj WHERE obj.name IN :names</query>
+ </named-query>
+
<named-query name="VXXPrincipal.lookupByName">
<query>SELECT p.principalName, p.principalType FROM VXXPrincipal p
WHERE p.principalName LIKE :principalName
AND p.isVisible = 1
ORDER BY p.principalName</query>
</named-query>
+
<named-query name="XXUser.getAllUsersInfo">
<query>SELECT user.name, user.description, user.otherAttributes, user.syncSource, pUser.userSource, pUser.emailAddress
FROM XXUser user LEFT OUTER JOIN XXPortalUser pUser ON pUser.loginId = user.name
@@ -582,6 +591,15 @@
and xSvc.id = xPol.service and xPol.id = :policyId and obj.name = :name order by obj.level</query>
</named-query>
+ <named-query name="XXResourceDef.findResourceDefIdsByNameAndPolicyId">
+ <query>SELECT obj.id, obj.name FROM XXResourceDef obj
+ WHERE obj.name IN :names AND obj.defId IN
+ (SELECT xSvcDef.id FROM XXServiceDef xSvcDef, XXService xSvc, XXPolicy xPol
+ WHERE xSvcDef.id = xSvc.type AND xSvc.id = xPol.service AND xPol.id = :policyId)
+ ORDER BY obj.level
+ </query>
+ </named-query>
+
<named-query name="XXResourceDef.findByParentResId">
<query>
select obj from XXResourceDef obj where obj.parent = :parentId
@@ -635,6 +653,11 @@
obj.name = :name and xSvc.id = :serviceId and obj.defId = xSvc.type</query>
</named-query>
+ <named-query name="XXAccessTypeDef.findAccessTypeDefIdsByNamesAndServiceId">
+ <query>SELECT obj.id, obj.name FROM XXAccessTypeDef obj
+ WHERE obj.name IN :names AND obj.defId IN (SELECT xSvc.type FROM XXService xSvc WHERE xSvc.id = :serviceId)</query>
+ </named-query>
+
<!-- XXPolicyConditionDef -->
<named-query name="XXPolicyConditionDef.findByServiceDefId">
<query>select obj from XXPolicyConditionDef obj where obj.defId = :serviceDefId order by obj.order</query>
@@ -644,6 +667,10 @@
<query>select obj from XXPolicyConditionDef obj where obj.defId = :serviceDefId and obj.name = :name order by obj.order</query>
</named-query>
+ <named-query name="XXPolicyConditionDef.findConditionDefIdsByServiceDefIdAndNames">
+ <query>select obj.id, obj.name from XXPolicyConditionDef obj where obj.defId = :serviceDefId and obj.name IN :names order by obj.order</query>
+ </named-query>
+
<!-- XXContextEnricherDef -->
<named-query name="XXContextEnricherDef.findByServiceDefId">
<query>select obj from XXContextEnricherDef obj where obj.defId = :serviceDefId order by obj.order</query>
@@ -669,6 +696,10 @@
obj.name = :name and xSvc.id = :serviceId and obj.defId = xSvc.type</query>
</named-query>
+ <named-query name="XXDataMaskTypeDef.findDataMaskTypeDefIdsByNamesAndServiceId">
+ <query>select obj.id, obj.name from XXDataMaskTypeDef obj, XXService xSvc where obj.name IN :names and xSvc.id = :serviceId and obj.defId = xSvc.type</query>
+ </named-query>
+
<!-- XXServiceConfigMap -->
<named-query name="XXServiceConfigMap.findByServiceId">
<query>select obj from XXServiceConfigMap obj where obj.serviceId = :serviceId</query>
@@ -897,6 +928,14 @@
<query>select obj from XXPolicyRefGroup obj where obj.groupName = :groupName</query>
</named-query>
+ <named-query name="XXPolicyRefGroup.findGroupNameByPolicyId">
+ <query>select obj.groupName, obj.id from XXPolicyRefGroup obj where obj.policyId = :policyId</query>
+ </named-query>
+
+ <named-query name="XXPolicyRefGroup.deletePolicyRefGroupByIds">
+ <query>DELETE FROM XXPolicyRefGroup obj WHERE obj.id IN :ids </query>
+ </named-query>
+
<!-- new queries -->
<named-query name="XXPolicyRefGroup.findByGroupIdAndPolicyId">
<query>select obj from XXPolicyRefGroup obj where obj.groupId = :groupId and obj.policyId = :policyId </query>
@@ -1103,6 +1142,14 @@
<query>DELETE FROM XXPolicyRefUser obj WHERE obj.id IN :ids</query>
</named-query>
+ <named-query name="XXPolicyRefUser.findUserNameIdByPolicyId">
+ <query>SELECT obj.userName, obj.id FROM XXPolicyRefUser obj WHERE obj.policyId = :policyId</query>
+ </named-query>
+
+ <named-query name="XXPolicyRefUser.deletePolicyRefUserByIds">
+ <query>DELETE FROM XXPolicyRefUser obj WHERE obj.id IN :ids </query>
+ </named-query>
+
<!-- XXPolicyItemCondition -->
<named-query name="XXPolicyItemCondition.findByPolicyId">
@@ -1927,6 +1974,10 @@
<query>select obj.name from XXRole obj</query>
</named-query>
+ <named-query name="XXRole.getIdsByRoleNames">
+ <query>SELECT obj.id, obj.name FROM XXRole obj WHERE obj.name IN :roleNames</query>
+ </named-query>
+
<!-- XXRoleRef* -->
<named-query name="XXRoleRefUser.findByRoleId">
@@ -1997,6 +2048,14 @@
<query>select obj from XXPolicyRefRole obj where obj.policyId = :policyId </query>
</named-query>
+ <named-query name="XXPolicyRefRole.findRoleNameIdByPolicyId">
+ <query>SELECT obj.roleName, obj.id FROM XXPolicyRefRole obj WHERE obj.policyId = :policyId</query>
+ </named-query>
+
+ <named-query name="XXPolicyRefRole.deletePolicyRefRoleByIds">
+ <query>DELETE FROM XXPolicyRefRole obj WHERE obj.id IN :ids </query>
+ </named-query>
+
<named-query name="XXPolicyRefRole.findIdsByPolicyId">
<query>select obj.id from XXPolicyRefRole obj where obj.policyId = :policyId </query>
</named-query>
@@ -2172,4 +2231,5 @@
<named-query name="XXPolicy.findByZoneId">
<query>select obj from XXPolicy obj where obj.zoneId = :zoneId</query>
</named-query>
+
</entity-mappings>
diff --git a/security-admin/src/test/java/org/apache/ranger/biz/TestPolicyRefUpdater.java b/security-admin/src/test/java/org/apache/ranger/biz/TestPolicyRefUpdater.java
new file mode 100644
index 000000000..f84be0025
--- /dev/null
+++ b/security-admin/src/test/java/org/apache/ranger/biz/TestPolicyRefUpdater.java
@@ -0,0 +1,423 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.biz;
+
+import org.apache.ranger.common.RESTErrorUtil;
+import org.apache.ranger.common.db.RangerTransactionSynchronizationAdapter;
+import org.apache.ranger.db.RangerDaoManager;
+import org.apache.ranger.db.XXAccessTypeDefDao;
+import org.apache.ranger.db.XXDataMaskTypeDefDao;
+import org.apache.ranger.db.XXGroupDao;
+import org.apache.ranger.db.XXPolicyConditionDefDao;
+import org.apache.ranger.db.XXPolicyRefAccessTypeDao;
+import org.apache.ranger.db.XXPolicyRefConditionDao;
+import org.apache.ranger.db.XXPolicyRefDataMaskTypeDao;
+import org.apache.ranger.db.XXPolicyRefGroupDao;
+import org.apache.ranger.db.XXPolicyRefResourceDao;
+import org.apache.ranger.db.XXPolicyRefRoleDao;
+import org.apache.ranger.db.XXPolicyRefUserDao;
+import org.apache.ranger.db.XXResourceDefDao;
+import org.apache.ranger.db.XXRoleDao;
+import org.apache.ranger.db.XXUserDao;
+import org.apache.ranger.entity.XXPolicy;
+import org.apache.ranger.entity.XXPolicyRefGroup;
+import org.apache.ranger.entity.XXPolicyRefRole;
+import org.apache.ranger.entity.XXPolicyRefUser;
+import org.apache.ranger.entity.XXServiceDef;
+import org.apache.ranger.entity.XXUser;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem;
+import org.apache.ranger.plugin.model.RangerRole;
+import org.apache.ranger.service.RangerAuditFields;
+import org.apache.ranger.service.XGroupService;
+import org.apache.ranger.view.VXGroup;
+import org.apache.ranger.view.VXUser;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+* @generated by Cursor
+* @description <Unit Test for TestPolicyRefUpdater class>
+*/
+@RunWith(MockitoJUnitRunner.class)
+public class TestPolicyRefUpdater {
+ @InjectMocks
+ PolicyRefUpdater updater;
+
+ @Mock
+ RangerDaoManager daoMgr;
+ @Mock
+ RangerAuditFields<?> rangerAuditFields;
+ @Mock
+ XUserMgr xUserMgr;
+ @Mock
+ RoleDBStore roleStore;
+ @Mock
+ RangerBizUtil rangerBizUtil;
+ @Mock
+ XGroupService xGroupService;
+ @Mock
+ RangerTransactionSynchronizationAdapter rangerTransactionSynchronizationAdapter;
+ @Mock
+ RESTErrorUtil restErrorUtil;
+
+ @Test
+ public void testGetAllPolicyItemsAggregates() {
+ RangerPolicy p = new RangerPolicy();
+ p.setPolicyItems(Arrays.asList(new RangerPolicyItem()));
+ p.setDenyPolicyItems(Arrays.asList(new RangerPolicyItem()));
+ p.setAllowExceptions(Arrays.asList(new RangerPolicyItem()));
+ p.setDenyExceptions(Arrays.asList(new RangerPolicyItem()));
+ p.setDataMaskPolicyItems(Arrays.asList(new RangerDataMaskPolicyItem()));
+ p.setRowFilterPolicyItems(Arrays.asList(new RangerRowFilterPolicyItem()));
+ List<List<? extends RangerPolicyItem>> items = PolicyRefUpdater.getAllPolicyItems(p);
+ Assert.assertEquals(6, items.size());
+ }
+
+ @Test
+ public void testCreateNewPolMappingForRefTable_NullPolicyNoop() throws Exception {
+ updater.createNewPolMappingForRefTable(null, null, null, false, false);
+ }
+
+ @Test
+ public void testCreateNewPolMappingForRefTable_ValidEverything() throws Exception {
+ // Prepare policy with resources and items
+ RangerPolicy policy = new RangerPolicy();
+ policy.setId(5L);
+ policy.setName("p");
+ policy.setService("svc");
+ policy.setResources(Collections.singletonMap("db",
+ new RangerPolicy.RangerPolicyResource(Collections.singletonList("db1"), false, false)));
+ RangerPolicyItem item = new RangerPolicyItem();
+ item.setUsers(Arrays.asList("u1"));
+ item.setGroups(Arrays.asList("g1"));
+ item.setRoles(Arrays.asList("r1"));
+ RangerPolicyItemAccess acc = new RangerPolicyItemAccess();
+ acc.setType("select");
+ item.setAccesses(Collections.singletonList(acc));
+ RangerPolicyItemCondition cond = new RangerPolicyItemCondition();
+ cond.setType("time");
+ item.setConditions(Collections.singletonList(cond));
+ RangerDataMaskPolicyItem dmItem = new RangerDataMaskPolicyItem();
+ RangerPolicyItemDataMaskInfo dm = new RangerPolicyItemDataMaskInfo();
+ dm.setDataMaskType("MASK");
+ dmItem.setDataMaskInfo(dm);
+ policy.setPolicyItems(Arrays.asList(item));
+ policy.setDataMaskPolicyItems(Arrays.asList(dmItem));
+ policy.setConditions(Collections.singletonList(cond));
+
+ XXPolicy xPolicy = new XXPolicy();
+ xPolicy.setId(5L);
+ xPolicy.setName("p");
+ xPolicy.setService(9L);
+ XXServiceDef xSvc = new XXServiceDef();
+ xSvc.setId(9L);
+
+ // Stubs for DAO lookups and batch create calls
+ XXResourceDefDao resDefDao = mock(XXResourceDefDao.class);
+ when(daoMgr.getXXResourceDef()).thenReturn(resDefDao);
+ Map<String, Long> xxResourceDefIdMap = new HashMap<>();
+ xxResourceDefIdMap.put("db", 1L);
+ when(resDefDao.findResourceDefIdsByNameAndPolicyId(Mockito.anySet(), Mockito.eq(5L))).thenReturn(xxResourceDefIdMap);
+ Mockito.lenient().when(rangerAuditFields.populateAuditFields(Mockito.any(), Mockito.any()))
+ .thenAnswer(inv -> inv.getArgument(0));
+ XXPolicyRefResourceDao polResDao = mock(XXPolicyRefResourceDao.class);
+ when(daoMgr.getXXPolicyRefResource()).thenReturn(polResDao);
+ XXPolicyRefRoleDao polRoleDao = mock(XXPolicyRefRoleDao.class);
+ when(daoMgr.getXXPolicyRefRole()).thenReturn(polRoleDao);
+ XXPolicyRefGroupDao polGroupDao = mock(XXPolicyRefGroupDao.class);
+ when(daoMgr.getXXPolicyRefGroup()).thenReturn(polGroupDao);
+ XXPolicyRefUserDao polUserDao = mock(XXPolicyRefUserDao.class);
+ when(daoMgr.getXXPolicyRefUser()).thenReturn(polUserDao);
+ XXAccessTypeDefDao accDefDao = mock(XXAccessTypeDefDao.class);
+ when(daoMgr.getXXAccessTypeDef()).thenReturn(accDefDao);
+ Map<String, Long> xAccMap = new HashMap<>();
+ xAccMap.put("select", 2L);
+ when(accDefDao.findAccessTypeDefIdsByNamesAndServiceId(Mockito.anySet(), Mockito.eq(9L))).thenReturn(xAccMap);
+ XXPolicyRefAccessTypeDao polAccDao = mock(XXPolicyRefAccessTypeDao.class);
+ when(daoMgr.getXXPolicyRefAccessType()).thenReturn(polAccDao);
+ XXPolicyConditionDefDao condDefDao = mock(XXPolicyConditionDefDao.class);
+ when(daoMgr.getXXPolicyConditionDef()).thenReturn(condDefDao);
+ Map<String, Long> xCondMap = new HashMap<>();
+ xCondMap.put("time", 3L);
+ when(condDefDao.findConditionDefIdsByServiceDefIdAndNames(Mockito.eq(9L), Mockito.anySet())).thenReturn(xCondMap);
+ XXPolicyRefConditionDao polCondDao = mock(XXPolicyRefConditionDao.class);
+ when(daoMgr.getXXPolicyRefCondition()).thenReturn(polCondDao);
+ XXDataMaskTypeDefDao dmDefDao = mock(XXDataMaskTypeDefDao.class);
+ when(daoMgr.getXXDataMaskTypeDef()).thenReturn(dmDefDao);
+ Map<String, Long> xxDataMaskTypeDefIdMap = new HashMap<>();
+ xxDataMaskTypeDefIdMap.put("MASK", 4L);
+ when(dmDefDao.findDataMaskTypeDefIdsByNamesAndServiceId(Mockito.anySet(), Mockito.eq(9L))).thenReturn(xxDataMaskTypeDefIdMap);
+ XXPolicyRefDataMaskTypeDao polDmDao = mock(XXPolicyRefDataMaskTypeDao.class);
+ when(daoMgr.getXXPolicyRefDataMaskType()).thenReturn(polDmDao);
+ when(rangerBizUtil.checkAdminAccess()).thenReturn(true);
+
+ org.apache.ranger.db.XXPolicyDao policyDao = mock(org.apache.ranger.db.XXPolicyDao.class);
+ when(daoMgr.getXXPolicy()).thenReturn(policyDao);
+ when(policyDao.getById(xPolicy.getId())).thenReturn(xPolicy);
+
+ XXUserDao userDao = mock(XXUserDao.class);
+ when(daoMgr.getXXUser()).thenReturn(userDao);
+ when(userDao.getIdsByUserNames(Mockito.anySet())).thenReturn(Collections.singletonMap("u1", 30L));
+
+ XXGroupDao groupDao = mock(XXGroupDao.class);
+ when(daoMgr.getXXGroup()).thenReturn(groupDao);
+ when(groupDao.getIdsByGroupNames(Mockito.anySet())).thenReturn(Collections.singletonMap("g1", 20L));
+
+ XXRoleDao roleDao = mock(XXRoleDao.class);
+ when(daoMgr.getXXRole()).thenReturn(roleDao);
+ when(roleDao.getIdsByRoleNames(Mockito.anySet())).thenReturn(Collections.singletonMap("r1", 10L));
+
+ updater.createNewPolMappingForRefTable(policy, xPolicy, xSvc, true, false);
+ // no exceptions indicates success across branches
+ }
+
+ @Test
+ public void testCreateNewPolMappingForRefTable_InvalidResourceDef() throws Exception {
+ RangerPolicy policy = new RangerPolicy();
+ policy.setId(6L);
+ policy.setName("p2");
+ policy.setService("svc");
+ policy.setResources(Collections.singletonMap("invalid",
+ new RangerPolicy.RangerPolicyResource(Collections.singletonList("v"), false, false)));
+ XXPolicy xPolicy = new XXPolicy();
+ xPolicy.setId(6L);
+ XXServiceDef xSvc = new XXServiceDef();
+ xSvc.setId(9L);
+ XXResourceDefDao resDefDao = mock(XXResourceDefDao.class);
+ when(daoMgr.getXXResourceDef()).thenReturn(resDefDao);
+ when(resDefDao.findResourceDefIdsByNameAndPolicyId(Mockito.anySet(), Mockito.eq(6L))).thenReturn(Collections.emptyMap());
+ try {
+ updater.createNewPolMappingForRefTable(policy, xPolicy, xSvc, false, false);
+ Assert.fail("Expected exception");
+ } catch (Exception expected) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testCleanupRefTablesForUpdate_SelectivePrincipalCleanup() {
+ final Long policyId = 100L;
+
+ Set<String> policyUsers = new HashSet<>(Arrays.asList("alice", "bob", "carol"));
+ Set<String> policyRoles = new HashSet<>(Arrays.asList("roleA", "roleB", "roleNew"));
+ Set<String> policyGroups = new HashSet<>(Arrays.asList("grp1", "grp2", "grpNew"));
+
+ Map<String, Long> existingUsers = new HashMap<>();
+ existingUsers.put("alice", 1L);
+ existingUsers.put("bob", 2L);
+ existingUsers.put("dave", 4L);
+
+ Map<String, Long> existingRoles = new HashMap<>();
+ existingRoles.put("roleA", 10L);
+ existingRoles.put("roleOld", 12L);
+
+ Map<String, Long> existingGroups = new HashMap<>();
+ existingGroups.put("grp1", 20L);
+ existingGroups.put("grpOld", 22L);
+
+ XXPolicyRefUserDao userDao = mock(XXPolicyRefUserDao.class);
+ XXPolicyRefRoleDao roleDao = mock(XXPolicyRefRoleDao.class);
+ XXPolicyRefGroupDao groupDao = mock(XXPolicyRefGroupDao.class);
+ XXPolicyRefResourceDao resourceDao = mock(XXPolicyRefResourceDao.class);
+ XXPolicyRefAccessTypeDao accessDao = mock(XXPolicyRefAccessTypeDao.class);
+ XXPolicyRefConditionDao conditionDao = mock(XXPolicyRefConditionDao.class);
+ XXPolicyRefDataMaskTypeDao dataMaskDao = mock(XXPolicyRefDataMaskTypeDao.class);
+
+ when(daoMgr.getXXPolicyRefUser()).thenReturn(userDao);
+ when(daoMgr.getXXPolicyRefRole()).thenReturn(roleDao);
+ when(daoMgr.getXXPolicyRefGroup()).thenReturn(groupDao);
+ when(daoMgr.getXXPolicyRefResource()).thenReturn(resourceDao);
+ when(daoMgr.getXXPolicyRefAccessType()).thenReturn(accessDao);
+ when(daoMgr.getXXPolicyRefCondition()).thenReturn(conditionDao);
+ when(daoMgr.getXXPolicyRefDataMaskType()).thenReturn(dataMaskDao);
+
+ when(userDao.findUserNameIdByPolicyId(policyId)).thenReturn(existingUsers);
+ when(roleDao.findRoleNameIdByPolicyId(policyId)).thenReturn(existingRoles);
+ when(groupDao.findGroupNameByPolicyId(policyId)).thenReturn(existingGroups);
+
+ Assert.assertTrue(updater.cleanupRefTablesForUpdate(policyId, policyUsers, policyRoles, policyGroups));
+
+ verify(userDao).deletePolicyRefUserByIds(Collections.singletonList(4L));
+ Assert.assertEquals(Collections.singleton("carol"), policyUsers);
+
+ verify(roleDao).deletePolicyRefRoleByIds(Collections.singletonList(12L));
+ Assert.assertEquals(new HashSet<>(Arrays.asList("roleB", "roleNew")), policyRoles);
+
+ verify(groupDao).deletePolicyRefGroupByIds(Collections.singletonList(22L));
+ Assert.assertEquals(new HashSet<>(Arrays.asList("grp2", "grpNew")), policyGroups);
+
+ verify(resourceDao).deleteByPolicyId(policyId);
+ verify(accessDao).deleteByPolicyId(policyId);
+ verify(conditionDao).deleteByPolicyId(policyId);
+ verify(dataMaskDao).deleteByPolicyId(policyId);
+
+ verify(userDao, never()).deleteByPolicyId(policyId);
+ verify(roleDao, never()).deleteByPolicyId(policyId);
+ verify(groupDao, never()).deleteByPolicyId(policyId);
+ }
+
+ @Test
+ public void testCleanupRefTables() {
+ when(daoMgr.getXXPolicyRefResource()).thenReturn(mock(XXPolicyRefResourceDao.class));
+ when(daoMgr.getXXPolicyRefRole()).thenReturn(mock(XXPolicyRefRoleDao.class));
+ when(daoMgr.getXXPolicyRefGroup()).thenReturn(mock(XXPolicyRefGroupDao.class));
+ when(daoMgr.getXXPolicyRefUser()).thenReturn(mock(XXPolicyRefUserDao.class));
+ when(daoMgr.getXXPolicyRefAccessType()).thenReturn(mock(XXPolicyRefAccessTypeDao.class));
+ when(daoMgr.getXXPolicyRefCondition()).thenReturn(mock(XXPolicyRefConditionDao.class));
+ when(daoMgr.getXXPolicyRefDataMaskType()).thenReturn(mock(XXPolicyRefDataMaskTypeDao.class));
+
+ RangerPolicy p = new RangerPolicy();
+ p.setId(77L);
+ Assert.assertEquals(true, updater.cleanupRefTables(p));
+ Assert.assertEquals(false, updater.cleanupRefTables(null));
+ }
+
+ @Test
+ public void testCreatePrincipal_User_Group_Role_Paths() throws Exception {
+ // Common setup: policy and xPolicy for audit fields
+ XXPolicy xPolicy = new XXPolicy();
+ xPolicy.setId(10L);
+ xPolicy.setService(100L);
+
+ // FIX: Mock policy DAO hierarchy to satisfy doesPolicyExist(xPolicy) checks
+ org.apache.ranger.db.XXPolicyDao policyDao = mock(org.apache.ranger.db.XXPolicyDao.class);
+ when(daoMgr.getXXPolicy()).thenReturn(policyDao);
+ when(policyDao.getById(xPolicy.getId())).thenReturn(xPolicy);
+
+ // Mock audit population to be identity
+ Mockito.lenient().when(rangerAuditFields.populateAuditFields(Mockito.any(), Mockito.any()))
+ .thenAnswer(inv -> inv.getArgument(0));
+
+ // USER path: user not found, xUserMgr creates, then XXUser lookup returns id
+ XXUserDao userDao = mock(XXUserDao.class);
+ when(daoMgr.getXXUser()).thenReturn(userDao);
+ when(userDao.findByUserName("uNew")).thenReturn(null).thenReturn(new XXUser() {
+ {
+ setId(11L);
+ }
+ });
+ VXUser createdVX = new VXUser();
+ when(xUserMgr.createServiceConfigUser("uNew")).thenReturn(createdVX);
+ XXPolicyRefUserDao polUserDao = mock(XXPolicyRefUserDao.class);
+ when(daoMgr.getXXPolicyRefUser()).thenReturn(polUserDao);
+
+ // Reflectively construct inner class PolicyUserAssociator for USER
+ Class<?> userAssociatorClass = null;
+ for (Class<?> c : PolicyRefUpdater.class.getDeclaredClasses()) {
+ if (c.getSimpleName().equals("PolicyUserAssociator")) {
+ userAssociatorClass = c;
+ break;
+ }
+ }
+ Assert.assertNotNull(userAssociatorClass);
+ Constructor<?> userCtor = userAssociatorClass.getDeclaredConstructor(
+ PolicyRefUpdater.class, String.class, Long.class, XXPolicy.class);
+ userCtor.setAccessible(true);
+ Object associatorUser = userCtor.newInstance(updater, "uNew", null, xPolicy);
+ Method runUser = userAssociatorClass.getDeclaredMethod("run");
+ runUser.setAccessible(true);
+ runUser.invoke(associatorUser);
+ verify(daoMgr.getXXPolicyRefUser(), Mockito.times(1))
+ .create(Mockito.any(XXPolicyRefUser.class));
+
+ // GROUP path: group not found, xGroupService creates and logs, verify ref
+ // created
+ XXGroupDao groupDao = mock(XXGroupDao.class);
+ when(daoMgr.getXXGroup()).thenReturn(groupDao);
+ when(groupDao.findByGroupName("gNew")).thenReturn(null);
+ VXGroup vXGroup = new VXGroup();
+ vXGroup.setId(22L);
+ when(xGroupService.createXGroupWithOutLogin(Mockito.any(VXGroup.class))).thenReturn(vXGroup);
+ XXPolicyRefGroupDao polGroupDao = mock(XXPolicyRefGroupDao.class);
+ when(daoMgr.getXXPolicyRefGroup()).thenReturn(polGroupDao);
+
+ Class<?> groupAssociatorClass = null;
+ for (Class<?> c : PolicyRefUpdater.class.getDeclaredClasses()) {
+ if (c.getSimpleName().equals("PolicyGroupAssociator")) {
+ groupAssociatorClass = c;
+ break;
+ }
+ }
+ Assert.assertNotNull(groupAssociatorClass);
+ Constructor<?> groupCtor = groupAssociatorClass.getDeclaredConstructor(
+ PolicyRefUpdater.class, String.class, Long.class, XXPolicy.class);
+ groupCtor.setAccessible(true);
+ Object associatorGroup = groupCtor.newInstance(updater, "gNew", null, xPolicy);
+ Method runGroup = groupAssociatorClass.getDeclaredMethod("run");
+ runGroup.setAccessible(true);
+ runGroup.invoke(associatorGroup);
+ verify(daoMgr.getXXPolicyRefGroup(), Mockito.times(1))
+ .create(Mockito.any(XXPolicyRefGroup.class));
+
+ // ROLE path: role not found, roleStore.createRole returns id, verify ref
+ // created
+ XXRoleDao roleDao = mock(XXRoleDao.class);
+ when(daoMgr.getXXRole()).thenReturn(roleDao);
+ when(roleDao.findByRoleName("rNew")).thenReturn(null);
+ RangerRole createdRole = new RangerRole("rNew", null, null, null, null);
+ createdRole.setId(33L);
+ when(roleStore.createRole(Mockito.any(RangerRole.class), Mockito.eq(false))).thenReturn(createdRole);
+ XXPolicyRefRoleDao polRoleDao = mock(XXPolicyRefRoleDao.class);
+ when(daoMgr.getXXPolicyRefRole()).thenReturn(polRoleDao);
+
+ Class<?> roleAssociatorClass = null;
+ for (Class<?> c : PolicyRefUpdater.class.getDeclaredClasses()) {
+ if (c.getSimpleName().equals("PolicyRoleAssociator")) {
+ roleAssociatorClass = c;
+ break;
+ }
+ }
+ Assert.assertNotNull(roleAssociatorClass);
+ Constructor<?> roleCtor = roleAssociatorClass.getDeclaredConstructor(
+ PolicyRefUpdater.class, String.class, Long.class, XXPolicy.class);
+ roleCtor.setAccessible(true);
+ Object associatorRole = roleCtor.newInstance(updater, "rNew", null, xPolicy);
+ Method runRole = roleAssociatorClass.getDeclaredMethod("run");
+ runRole.setAccessible(true);
+ runRole.invoke(associatorRole);
+ verify(daoMgr.getXXPolicyRefRole(), Mockito.times(1)).create(Mockito.any(XXPolicyRefRole.class));
+ }
+}
diff --git a/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java b/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java
index 9238122f5..434a64ee7 100644
--- a/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java
+++ b/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java
@@ -1688,7 +1688,7 @@ public void test26createPolicy() throws Exception {
Mockito.when(daoManager.getXXPolicy()).thenReturn(xPolicyDao);
Mockito.when(xPolicyDao.getById(Id)).thenReturn(xPolicy);
- Mockito.doNothing().when(policyRefUpdater).createNewPolMappingForRefTable(rangerPolicy, xPolicy, xServiceDef, false);
+ Mockito.doNothing().when(policyRefUpdater).createNewPolMappingForRefTable(rangerPolicy, xPolicy, xServiceDef, false, false);
Mockito.when(policyService.getPopulatedViewObject(xPolicy)).thenReturn(rangerPolicy);
Mockito.when(daoManager.getXXService()).thenReturn(xServiceDao);
@@ -1835,10 +1835,11 @@ public void tess28updatePolicy() throws Exception {
Mockito.when(factory.createPolicyResourceSignature(rangerPolicy))
.thenReturn(signature);
Mockito.when(!bizUtil.hasAccess(xService, null)).thenReturn(true);
- Mockito.when(policyRefUpdater.cleanupRefTables(rangerPolicy)).thenReturn(true);
-
+ Mockito.doNothing().when(policyRefUpdater).createNewPolMappingForRefTable(
+ Mockito.eq(rangerPolicy), Mockito.eq(xPolicy), Mockito.eq(xServiceDef),
+ Mockito.anyBoolean(), Mockito.eq(true));
- RangerPolicy dbRangerPolicy = serviceDBStore.updatePolicy(rangerPolicy);
+ RangerPolicy dbRangerPolicy = serviceDBStore.updatePolicy(rangerPolicy);
Assert.assertNotNull(dbRangerPolicy);
Assert.assertEquals(dbRangerPolicy, rangerPolicy);
Assert.assertEquals(dbRangerPolicy.getId(), rangerPolicy.getId());