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 }
+    },
 
 
     {

Reply via email to