This is an automated email from the ASF dual-hosted git repository. madhan pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ranger.git
commit 7dd8d5d274f6d09039fc6e9609350511f3c576fb Author: Madhan Neethiraj <[email protected]> AuthorDate: Tue Jan 16 18:15:17 2024 -0800 RANGER-4658: updated GDS policy evaluation to fix handling of _any access --- .../plugin/policyengine/gds/GdsPolicyEngine.java | 57 +++++++++++++++------- .../gds/GdsSharedResourceEvaluator.java | 21 +++++++- .../gds/test_gds_policy_engine_hive.json | 40 +++++++++++++++ 3 files changed, 99 insertions(+), 19 deletions(-) diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsPolicyEngine.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsPolicyEngine.java index dd1184a0b..6a6709254 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsPolicyEngine.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsPolicyEngine.java @@ -50,6 +50,7 @@ public class GdsPolicyEngine { public static final String RESOURCE_NAME_PROJECT_ID = "project-id"; private final ServiceGdsInfo gdsInfo; + private final Set<String> allAccessTypes; private final Map<String, List<GdsDataShareEvaluator>> zoneDataShares = new HashMap<>(); private final Map<Long, GdsDatasetEvaluator> datasets = new HashMap<>(); private final Map<Long, GdsProjectEvaluator> projects = new HashMap<>(); @@ -57,7 +58,8 @@ public class GdsPolicyEngine { public GdsPolicyEngine(ServiceGdsInfo gdsInfo, RangerServiceDefHelper serviceDefHelper, RangerPluginContext pluginContext) { LOG.debug("==> RangerGdsPolicyEngine()"); - this.gdsInfo = gdsInfo; + this.gdsInfo = gdsInfo; + this.allAccessTypes = Collections.unmodifiableSet(getAllAccessTypes(serviceDefHelper)); init(serviceDefHelper, pluginContext); @@ -71,31 +73,43 @@ public class GdsPolicyEngine { public GdsAccessResult evaluate(RangerAccessRequest request) { LOG.debug("==> RangerGdsPolicyEngine.evaluate({})", request); - GdsAccessResult ret = null; - List<GdsDataShareEvaluator> dataShares = getDataShareEvaluators(request); - - if (!dataShares.isEmpty()) { - ret = new GdsAccessResult(); + GdsAccessResult ret = null; + boolean isAnyAccess = request.isAccessTypeAny(); - if (dataShares.size() > 1) { - dataShares.sort(GdsDataShareEvaluator.EVAL_ORDER_COMPARATOR); + try { + if (isAnyAccess) { + RangerAccessRequestUtil.setAllRequestedAccessTypes(request.getContext(), allAccessTypes, Boolean.TRUE); } - Set<Long> datasetIds = new HashSet<>(); + List<GdsDataShareEvaluator> dataShares = getDataShareEvaluators(request); - for (GdsDataShareEvaluator dshEvaluator : dataShares) { - dshEvaluator.evaluate(request, ret, datasetIds); - } + if (!dataShares.isEmpty()) { + ret = new GdsAccessResult(); - if (!datasetIds.isEmpty()) { - Set<Long> projectIds = new HashSet<>(); + if (dataShares.size() > 1) { + dataShares.sort(GdsDataShareEvaluator.EVAL_ORDER_COMPARATOR); + } - evaluateDatasetPolicies(datasetIds, request, ret, projectIds); + Set<Long> datasetIds = new HashSet<>(); - if (!projectIds.isEmpty()) { - evaluateProjectPolicies(projectIds, request, ret); + for (GdsDataShareEvaluator dshEvaluator : dataShares) { + dshEvaluator.evaluate(request, ret, datasetIds); + } + + if (!datasetIds.isEmpty()) { + Set<Long> projectIds = new HashSet<>(); + + evaluateDatasetPolicies(datasetIds, request, ret, projectIds); + + if (!projectIds.isEmpty()) { + evaluateProjectPolicies(projectIds, request, ret); + } } } + } finally { + if (isAnyAccess) { + RangerAccessRequestUtil.setAllRequestedAccessTypes(request.getContext(), null, Boolean.FALSE); + } } LOG.debug("<== RangerGdsPolicyEngine.evaluate({}): {}", request, ret); @@ -502,7 +516,16 @@ public class GdsPolicyEngine { } } } + } + private Set<String> getAllAccessTypes(RangerServiceDefHelper serviceDefHelper) { + Set<String> ret = new HashSet<>(); + + for (RangerAccessTypeDef accessTypeDef : serviceDefHelper.getServiceDef().getAccessTypes()) { + ret.add(accessTypeDef.getName()); + } + + return ret; } static class SharedResourceIter implements Iterator<GdsSharedResourceEvaluator> { diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsSharedResourceEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsSharedResourceEvaluator.java index 2e073bb1c..9785d4b25 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsSharedResourceEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsSharedResourceEvaluator.java @@ -33,6 +33,7 @@ import org.apache.ranger.plugin.policyengine.RangerResourceACLs; import org.apache.ranger.plugin.policyevaluator.RangerCustomConditionEvaluator; import org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher; import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher; +import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher.MatchType; import org.apache.ranger.plugin.policyresourcematcher.RangerResourceEvaluator; import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher; import org.apache.ranger.plugin.util.ServiceDefUtil; @@ -120,7 +121,15 @@ public class GdsSharedResourceEvaluator implements RangerResourceEvaluator { ret = request.isAccessTypeAny() ? !allowedAccessTypes.isEmpty() : allowedAccessTypes.contains(request.getAccessType()); if (ret) { - ret = policyResourceMatcher.isMatch(request.getResource(), request.getResourceElementMatchingScopes(), request.getContext()); + MatchType matchType = policyResourceMatcher.getMatchType(request.getResource(), request.getResourceElementMatchingScopes(), request.getContext()); + + if (request.isAccessTypeAny()) { + ret = matchType != RangerPolicyResourceMatcher.MatchType.NONE; + } else if (request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) { + ret = matchType != RangerPolicyResourceMatcher.MatchType.NONE; + } else { + ret = matchType == RangerPolicyResourceMatcher.MatchType.SELF || matchType == RangerPolicyResourceMatcher.MatchType.SELF_AND_ALL_DESCENDANTS; + } if (!ret) { LOG.debug("GdsSharedResourceEvaluator.evaluate({}): not matched for resource {}", request, request.getResource()); @@ -179,7 +188,7 @@ public class GdsSharedResourceEvaluator implements RangerResourceEvaluator { int ret = 0; if (me != null && other != null) { - ret = StringUtils.compare(me.resource.getName(), other.resource.getName()); + ret = compareStrings(me.resource.getName(), other.resource.getName()); if (ret == 0) { ret = Integer.compare(me.resource.getResource().size(), other.resource.getResource().size()); @@ -196,5 +205,13 @@ public class GdsSharedResourceEvaluator implements RangerResourceEvaluator { return ret; } + + static int compareStrings(String str1, String str2) { + if (str1 == null) { + return str2 == null ? 0 : -1; + } else { + return str2 == null ? 1 : str1.compareTo(str2); + } + } } } diff --git a/agents-common/src/test/resources/policyengine/gds/test_gds_policy_engine_hive.json b/agents-common/src/test/resources/policyengine/gds/test_gds_policy_engine_hive.json index 71ecd225a..75eed6ddf 100644 --- a/agents-common/src/test/resources/policyengine/gds/test_gds_policy_engine_hive.json +++ b/agents-common/src/test/resources/policyengine/gds/test_gds_policy_engine_hive.json @@ -50,6 +50,14 @@ }, "result": { "datasets": [ "dataset-1" ], "projects": [ "project-1" ], "isAllowed": true, "isAudited": true, "policyId": 2001 } }, + { + "name": "database: sales, user: ds-user, access: _any", + "request": { + "resource": { "elements": { "database": "sales" } }, + "accessType": "", "user": "ds-user", "userGroups": [] + }, + "result": { "datasets": [ "dataset-1" ], "projects": [ "project-1" ], "isAllowed": true, "isAudited": true, "policyId": 2001 } + }, { "name": "table: finance.invoices, user: ds-user, access: select", "request": { @@ -66,6 +74,14 @@ }, "result": { "datasets": [ "dataset-1", "dataset-2" ], "projects": [ "project-1" ], "isAllowed": true, "isAudited": true, "policyId": 2001 } }, + { + "name": "database: finance, user: ds-user, access: _any", + "request": { + "resource": { "elements": { "database": "finance" } }, + "accessType": "", "user": "ds-user", "userGroups": [] + }, + "result": { "datasets": [ "dataset-1", "dataset-2" ], "projects": [ "project-1" ], "isAllowed": true, "isAudited": true, "policyId": 2001 } + }, { "name": "table: shipping.shipments, user: ds-user, access: select", "request": { @@ -74,6 +90,14 @@ }, "result": { "datasets": [ "dataset-2" ], "projects": [ "project-1" ], "isAllowed": true, "isAudited": true, "policyId": 2002 } }, + { + "name": "database: shipping, user: ds-user, access: _any", + "request": { + "resource": { "elements": { "database": "shipping" } }, + "accessType": "", "user": "ds-user", "userGroups": [] + }, + "result": { "datasets": [ "dataset-2" ], "projects": [ "project-1" ], "isAllowed": true, "isAudited": true, "policyId": 2002 } + }, { "name": "table: customers.contact_info, user: ds-user, access: select", "request": { @@ -82,6 +106,14 @@ }, "result": { "datasets": [ "dataset-3" ], "projects": [ "project-2" ], "isAllowed": true, "isAudited": true, "policyId": 2003 } }, + { + "name": "database: customers, user: ds-user, access: _any", + "request": { + "resource": { "elements": { "database": "customers" } }, + "accessType": "", "user": "ds-user", "userGroups": [] + }, + "result": { "datasets": [ "dataset-3" ], "projects": [ "project-2" ], "isAllowed": true, "isAudited": true, "policyId": 2003 } + }, { "name": "table: operations.facilities, user: ds-user, access: select", "request": { @@ -90,6 +122,14 @@ }, "result": { "datasets": [ "dataset-4" ], "projects": null, "isAllowed": true, "isAudited": true, "policyId": 2004 } }, + { + "name": "database: operations, user: ds-user, access: _any", + "request": { + "resource": { "elements": { "database": "operations" } }, + "accessType": "", "user": "ds-user", "userGroups": [] + }, + "result": { "datasets": [ "dataset-4" ], "projects": null, "isAllowed": true, "isAudited": true, "policyId": 2004 } + }, {
