This is an automated email from the ASF dual-hosted git repository.

abhay pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/master by this push:
     new 696d4340b RANGER-4378: Expand implied grants in the policy-items for 
being able to compare policy-cache dumps from server and client
696d4340b is described below

commit 696d4340bfdf6c38f7cb4f53fc31b14e1ffaa0e7
Author: Abhay Kulkarni <ab...@apache.org>
AuthorDate: Mon Sep 25 09:01:33 2023 -0700

    RANGER-4378: Expand implied grants in the policy-items for being able to 
compare policy-cache dumps from server and client
---
 .../apache/ranger/plugin/model/RangerPolicy.java   |   4 +
 .../ranger/plugin/policyengine/PolicyEngine.java   |  44 +++++++++
 .../RangerAbstractPolicyItemEvaluator.java         |  59 ++++++++++++
 .../RangerAuditPolicyEvaluator.java                |   2 +-
 .../RangerDefaultPolicyEvaluator.java              |  51 ++++------
 .../RangerDefaultPolicyItemEvaluator.java          | 107 ++++++++++++---------
 .../RangerOptimizedPolicyEvaluator.java            | 106 ++++++++++++++------
 .../policyevaluator/RangerPolicyEvaluator.java     |  43 +++++++--
 .../policyevaluator/RangerPolicyItemEvaluator.java |   1 +
 9 files changed, 298 insertions(+), 119 deletions(-)

diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
index 9e5a94b1a..ec0618421 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
@@ -959,6 +959,10 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
                        this(null, null, null, null, null, null);
                }
 
+                public RangerPolicyItem(RangerPolicyItem other) {
+                        this(other.accesses, other.users, other.groups, 
other.roles, other.conditions, other.delegateAdmin);
+                }
+
                public RangerPolicyItem(List<RangerPolicyItemAccess> 
accessTypes, List<String> users, List<String> groups, List<String> roles, 
List<RangerPolicyItemCondition> conditions, Boolean delegateAdmin) {
                        setAccesses(accessTypes);
                        setUsers(users);
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
index 1e99b5824..4a5406301 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
@@ -71,6 +71,13 @@ public class PolicyEngine {
 
     private final RangerReadWriteLock                 lock;
 
+    static private Map<String, Map<String, Collection<String>>> 
impliedAccessGrants = null;
+
+    static public Map<String, Collection<String>> 
getImpliedAccessGrants(RangerServiceDef serviceDef) {
+        return impliedAccessGrants == null ? null : 
impliedAccessGrants.get(serviceDef.getName());
+    }
+
+
     public RangerReadWriteLock.RangerLock getReadLock() {
         return lock.getReadLock();
     }
@@ -197,6 +204,8 @@ public class PolicyEngine {
             PERF_POLICYENGINE_INIT_LOG.debug("In-Use memory: " + (totalMemory 
- freeMemory) + ", Free memory:" + freeMemory);
         }
 
+        buildImpliedAccessGrants(servicePolicies);
+
         this.pluginContext = pluginContext;
         this.lock          = new RangerReadWriteLock(isUseReadWriteLock);
 
@@ -471,6 +480,41 @@ public class PolicyEngine {
         }
     }
 
+    synchronized static private void buildImpliedAccessGrants(ServicePolicies 
servicePolicies) {
+        buildImpliedAccessGrants(servicePolicies.getServiceDef());
+        if (servicePolicies.getTagPolicies() != null) {
+            
buildImpliedAccessGrants(servicePolicies.getTagPolicies().getServiceDef());
+        }
+    }
+
+    static private void buildImpliedAccessGrants(RangerServiceDef serviceDef) {
+        Map<String, Collection<String>> ret = null;
+
+        if (serviceDef != null && 
!CollectionUtils.isEmpty(serviceDef.getAccessTypes())) {
+            for (RangerServiceDef.RangerAccessTypeDef accessTypeDef : 
serviceDef.getAccessTypes()) {
+                if 
(!CollectionUtils.isEmpty(accessTypeDef.getImpliedGrants())) {
+                    if (ret == null) {
+                        ret = new HashMap<>();
+                    }
+
+                    Collection<String> impliedGrants = 
ret.get(accessTypeDef.getName());
+
+                    if (impliedGrants == null) {
+                        impliedGrants = new HashSet<>();
+
+                        ret.put(accessTypeDef.getName(), impliedGrants);
+                    }
+
+                    impliedGrants.addAll(accessTypeDef.getImpliedGrants());
+                }
+            }
+
+            if (impliedAccessGrants == null) {
+                impliedAccessGrants = Collections.synchronizedMap(new 
HashMap<>());
+            }
+            impliedAccessGrants.put(serviceDef.getName(), ret);
+        }
+    }
     private Set<String> getMatchedZonesForResourceAndChildren(Map<String, ?> 
resource, RangerAccessResource accessResource) {
         if (LOG.isDebugEnabled()) {
             LOG.debug("==> 
PolicyEngine.getMatchedZonesForResourceAndChildren(" + resource + ", " + 
accessResource + ")");
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
index 0f09952f7..a3e3806ec 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
@@ -19,14 +19,17 @@
 package org.apache.ranger.plugin.policyevaluator;
 
 
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator;
 import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
 import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.policyengine.PolicyEngine;
 import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
 import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
 
@@ -50,6 +53,7 @@ public abstract class RangerAbstractPolicyItemEvaluator 
implements RangerPolicyI
        final int                       evalOrder;
 
        List<RangerConditionEvaluator> conditionEvaluators = 
Collections.<RangerConditionEvaluator>emptyList();
+       RangerPolicyItem withImpliedGrants;
 
        RangerAbstractPolicyItemEvaluator(RangerServiceDef serviceDef, 
RangerPolicy policy, RangerPolicyItem policyItem, int policyItemType, int 
policyItemIndex, RangerPolicyEngineOptions options) {
                this.serviceDef     = serviceDef;
@@ -100,6 +104,61 @@ public abstract class RangerAbstractPolicyItemEvaluator 
implements RangerPolicyI
                return options != null && options.disableCustomConditions;
        }
 
+       @Override
+       public RangerPolicyItem getWithImpliedGrants() {
+               return withImpliedGrants;
+       }
+
+       protected RangerPolicyItem computeWithImpliedGrants() {
+
+               final RangerPolicyItem ret;
+
+               if (withImpliedGrants == null) {
+                       if (CollectionUtils.isEmpty(policyItem.getAccesses())) {
+                               ret = policyItem;
+                       } else {
+                               // Compute implied-accesses
+                               Map<String, Collection<String>> 
impliedAccessGrants = PolicyEngine.getImpliedAccessGrants(serviceDef);
+
+                               if (impliedAccessGrants != null && 
!impliedAccessGrants.isEmpty()) {
+                                       ret = new RangerPolicyItem(policyItem);
+
+                                       // Only one round of 'expansion' is 
done; multi-level impliedGrants (like shown below) are not handled for now
+                                       // multi-level impliedGrants: given 
admin=>write; write=>read: must imply admin=>read,write
+                                       for (Map.Entry<String, 
Collection<String>> e : impliedAccessGrants.entrySet()) {
+                                               String implyingAccessType = 
e.getKey();
+                                               Collection<String> 
impliedGrants = e.getValue();
+
+                                               
RangerPolicy.RangerPolicyItemAccess access = 
RangerDefaultPolicyEvaluator.getAccess(ret, implyingAccessType);
+
+                                               if (access == null) {
+                                                       continue;
+                                               }
+
+                                               for (String impliedGrant : 
impliedGrants) {
+                                                       
RangerPolicy.RangerPolicyItemAccess impliedAccess = 
RangerDefaultPolicyEvaluator.getAccess(ret, impliedGrant);
+
+                                                       if (impliedAccess == 
null) {
+                                                               impliedAccess = 
new RangerPolicy.RangerPolicyItemAccess(impliedGrant, access.getIsAllowed());
+
+                                                               
ret.getAccesses().add(impliedAccess);
+                                                       } else {
+                                                               if 
(!impliedAccess.getIsAllowed()) {
+                                                                       
impliedAccess.setIsAllowed(access.getIsAllowed());
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               } else {
+                                       ret = policyItem;
+                               }
+                       }
+               } else {
+                       ret = withImpliedGrants;
+               }
+               return ret;
+       }
+
        private int computeEvalOrder() {
                int evalOrder = RANGER_POLICY_ITEM_EVAL_ORDER_DEFAULT;
 
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java
index ba24b8c3e..9051a8ce4 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java
@@ -103,7 +103,7 @@ public class RangerAuditPolicyEvaluator extends 
RangerDefaultPolicyEvaluator {
     protected void preprocessPolicy(RangerPolicy policy, RangerServiceDef 
serviceDef) {
         super.preprocessPolicy(policy, serviceDef);
 
-        Map<String, Collection<String>> impliedAccessGrants = 
getImpliedAccessGrants(serviceDef);
+        Map<String, Collection<String>> impliedAccessGrants = 
PolicyEngine.getImpliedAccessGrants(serviceDef);
 
         if (impliedAccessGrants == null || impliedAccessGrants.isEmpty()) {
             return;
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
index 4ad2944a8..bf7ebe86a 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
@@ -42,6 +42,7 @@ import 
org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
 import org.apache.ranger.plugin.model.RangerValiditySchedule;
+import org.apache.ranger.plugin.policyengine.PolicyEngine;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequestWrapper;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
@@ -80,6 +81,15 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
        private boolean          useAclSummaryForEvaluation = false;
        private boolean          disableRoleResolution      = true;
 
+       List<RangerPolicyItemEvaluator> getAllowEvaluators() { return 
allowEvaluators; }
+       List<RangerPolicyItemEvaluator> getAllowExceptionEvaluators() { return 
allowExceptionEvaluators; }
+       List<RangerPolicyItemEvaluator> getDenyEvaluators() { return 
denyEvaluators; }
+       List<RangerPolicyItemEvaluator> getDenyExceptionEvaluators() { return 
denyExceptionEvaluators; }
+       List<RangerDataMaskPolicyItemEvaluator> getDataMaskEvaluators() { 
return dataMaskEvaluators; }
+       List<RangerRowFilterPolicyItemEvaluator> getRowFilterEvaluators() { 
return rowFilterEvaluators; }
+
+       boolean isUseAclSummaryForEvaluation() { return 
useAclSummaryForEvaluation; }
+
        @Override
        public int getCustomConditionsCount() {
                return customConditionsCount;
@@ -610,24 +620,26 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
 
                if (isUsableForEvaluation || isCreationForced) {
                        ret = new PolicyACLSummary();
+                       Map<String, Collection<String>> impliedAccessGrants = 
PolicyEngine.getImpliedAccessGrants(getServiceDef());
+
 
                        for (RangerPolicyItem policyItem : 
policy.getDenyPolicyItems()) {
-                               ret.processPolicyItem(policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY, 
hasNonPublicGroupOrConditionsInDenyExceptions || 
hasPublicGroupInDenyAndUsersInDenyExceptions);
+                               ret.processPolicyItem(policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY, 
hasNonPublicGroupOrConditionsInDenyExceptions || 
hasPublicGroupInDenyAndUsersInDenyExceptions, impliedAccessGrants);
                        }
 
                        if (!hasNonPublicGroupOrConditionsInDenyExceptions && 
!hasPublicGroupInDenyAndUsersInDenyExceptions) {
                                for (RangerPolicyItem policyItem : 
policy.getDenyExceptions()) {
-                                       ret.processPolicyItem(policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS, false);
+                                       ret.processPolicyItem(policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS, false, 
impliedAccessGrants);
                                }
                        }
 
                        for (RangerPolicyItem policyItem : 
policy.getPolicyItems()) {
-                               ret.processPolicyItem(policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW, 
hasNonPublicGroupOrConditionsInAllowExceptions || 
hasPublicGroupInAllowAndUsersInAllowExceptions);
+                               ret.processPolicyItem(policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW, 
hasNonPublicGroupOrConditionsInAllowExceptions || 
hasPublicGroupInAllowAndUsersInAllowExceptions, impliedAccessGrants);
                        }
 
                        if (!hasNonPublicGroupOrConditionsInAllowExceptions && 
!hasPublicGroupInAllowAndUsersInAllowExceptions) {
                                for (RangerPolicyItem policyItem : 
policy.getAllowExceptions()) {
-                                       ret.processPolicyItem(policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS, false);
+                                       ret.processPolicyItem(policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS, false, 
impliedAccessGrants);
                                }
                        }
 
@@ -1153,6 +1165,7 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                if(policy == null || (!hasAllow() && !hasDeny()) || serviceDef 
== null) {
                        return;
                }
+               /*
 
                Map<String, Collection<String>> impliedAccessGrants = 
getImpliedAccessGrants(serviceDef);
 
@@ -1166,6 +1179,8 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                preprocessPolicyItems(policy.getDenyExceptions(), 
impliedAccessGrants);
                preprocessPolicyItems(policy.getDataMaskPolicyItems(), 
impliedAccessGrants);
                preprocessPolicyItems(policy.getRowFilterPolicyItems(), 
impliedAccessGrants);
+
+                */
        }
 
        protected void preprocessPolicyItems(List<? extends RangerPolicyItem> 
policyItems, Map<String, Collection<String>> impliedAccessGrants) {
@@ -1203,33 +1218,7 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                }
        }
 
-       protected Map<String, Collection<String>> 
getImpliedAccessGrants(RangerServiceDef serviceDef) {
-               Map<String, Collection<String>> ret = null;
-
-               if(serviceDef != null && 
!CollectionUtils.isEmpty(serviceDef.getAccessTypes())) {
-                       for(RangerAccessTypeDef accessTypeDef : 
serviceDef.getAccessTypes()) {
-                               
if(!CollectionUtils.isEmpty(accessTypeDef.getImpliedGrants())) {
-                                       if(ret == null) {
-                                               ret = new HashMap<>();
-                                       }
-
-                                       Collection<String> impliedAccessGrants 
= ret.get(accessTypeDef.getName());
-
-                                       if(impliedAccessGrants == null) {
-                                               impliedAccessGrants = new 
HashSet<>();
-
-                                               
ret.put(accessTypeDef.getName(), impliedAccessGrants);
-                                       }
-
-                                       
impliedAccessGrants.addAll(accessTypeDef.getImpliedGrants());
-                               }
-                       }
-               }
-
-               return ret;
-       }
-
-       private RangerPolicyItemAccess getAccess(RangerPolicyItem policyItem, 
String accessType) {
+       static RangerPolicyItemAccess getAccess(RangerPolicyItem policyItem, 
String accessType) {
                RangerPolicyItemAccess ret = null;
 
                if(policyItem != null && 
CollectionUtils.isNotEmpty(policyItem.getAccesses())) {
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
index 3510ad144..2528aeafa 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
@@ -57,26 +57,26 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
        }
 
        public void init() {
-               if(LOG.isDebugEnabled()) {
+               if (LOG.isDebugEnabled()) {
                        LOG.debug("==> 
RangerDefaultPolicyItemEvaluator(policyId=" + policyId + ", policyItem=" + 
policyItem + ", serviceType=" + getServiceType() + ", conditionsDisabled=" + 
getConditionsDisabledOption() + ")");
                }
 
                RangerCustomConditionEvaluator rangerCustomConditionEvaluator = 
new RangerCustomConditionEvaluator();
 
-               conditionEvaluators = 
rangerCustomConditionEvaluator.getPolicyItemConditionEvaluator(policy,policyItem,serviceDef,options,policyItemIndex);
+               conditionEvaluators = 
rangerCustomConditionEvaluator.getPolicyItemConditionEvaluator(policy, 
policyItem, serviceDef, options, policyItemIndex);
 
                List<String> users = policyItem.getUsers();
                this.hasCurrentUser = CollectionUtils.isNotEmpty(users) && 
users.contains(RangerPolicyEngine.USER_CURRENT);
                this.hasResourceOwner = CollectionUtils.isNotEmpty(users) && 
users.contains(RangerPolicyEngine.RESOURCE_OWNER);
 
-               if(LOG.isDebugEnabled()) {
+               if (LOG.isDebugEnabled()) {
                        LOG.debug("<== 
RangerDefaultPolicyItemEvaluator(policyId=" + policyId + ", conditionsCount=" + 
getConditionEvaluators().size() + ")");
                }
        }
 
        @Override
        public boolean isMatch(RangerAccessRequest request) {
-               if(LOG.isDebugEnabled()) {
+               if (LOG.isDebugEnabled()) {
                        LOG.debug("==> 
RangerDefaultPolicyItemEvaluator.isMatch(" + request + ")");
                }
 
@@ -84,29 +84,35 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
 
                RangerPerfTracer perf = null;
 
-               
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYITEM_REQUEST_LOG)) {
-                       perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICYITEM_REQUEST_LOG, 
"RangerPolicyItemEvaluator.isMatch(resource=" + 
request.getResource().getAsString()  + ")");
+               if 
(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYITEM_REQUEST_LOG)) {
+                       perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICYITEM_REQUEST_LOG, 
"RangerPolicyItemEvaluator.isMatch(resource=" + 
request.getResource().getAsString() + ")");
                }
 
-               if(policyItem != null) {
-                       if(matchUserGroupAndOwner(request)) {
+               if (policyItem != null) {
+                       if (matchUserGroupAndOwner(request)) {
                                if (request.isAccessTypeDelegatedAdmin()) { // 
used only in grant/revoke scenario
                                        if (policyItem.getDelegateAdmin()) {
                                                ret = true;
                                        }
-                               } else if 
(CollectionUtils.isNotEmpty(policyItem.getAccesses())) {
-                                       boolean isAccessTypeMatched = false;
+                               } else {
+                                       if (withImpliedGrants == null) {
+                                               withImpliedGrants = 
computeWithImpliedGrants();
+                                       }
 
-                                       for 
(RangerPolicy.RangerPolicyItemAccess access : policyItem.getAccesses()) {
-                                               if (access.getIsAllowed() && 
StringUtils.equalsIgnoreCase(access.getType(), request.getAccessType())) {
-                                                       isAccessTypeMatched = 
true;
-                                                       break;
+                                       if (withImpliedGrants != null && 
CollectionUtils.isNotEmpty(withImpliedGrants.getAccesses())) {
+                                               boolean isAccessTypeMatched = 
false;
+
+                                               for 
(RangerPolicy.RangerPolicyItemAccess access : withImpliedGrants.getAccesses()) {
+                                                       if 
(access.getIsAllowed() && StringUtils.equalsIgnoreCase(access.getType(), 
request.getAccessType())) {
+                                                               
isAccessTypeMatched = true;
+                                                               break;
+                                                       }
                                                }
-                                       }
 
-                                       if(isAccessTypeMatched) {
-                                               
if(matchCustomConditions(request)) {
-                                                       ret = true;
+                                               if (isAccessTypeMatched) {
+                                                       if 
(matchCustomConditions(request)) {
+                                                               ret = true;
+                                                       }
                                                }
                                        }
                                }
@@ -115,7 +121,7 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
 
                RangerPerfTracer.log(perf);
 
-               if(LOG.isDebugEnabled()) {
+               if (LOG.isDebugEnabled()) {
                        LOG.debug("<== 
RangerDefaultPolicyItemEvaluator.isMatch(" + request + "): " + ret);
                }
 
@@ -124,17 +130,17 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
 
        @Override
        public boolean matchUserGroupAndOwner(String user, Set<String> 
userGroups, Set<String> roles, String owner) {
-               if(LOG.isDebugEnabled()) {
+               if (LOG.isDebugEnabled()) {
                        LOG.debug("==> 
RangerDefaultPolicyItemEvaluator.matchUserGroup(" + policyItem + ", " + user + 
", " + userGroups + ", " + roles + ", " + owner + ")");
                }
 
                boolean ret = false;
 
-               if(policyItem != null) {
-                       if(!ret && user != null && policyItem.getUsers() != 
null) {
+               if (policyItem != null) {
+                       if (!ret && user != null && policyItem.getUsers() != 
null) {
                                ret = hasCurrentUser || 
policyItem.getUsers().contains(user);
                        }
-                       if(!ret && userGroups != null && policyItem.getGroups() 
!= null) {
+                       if (!ret && userGroups != null && 
policyItem.getGroups() != null) {
                                ret = 
policyItem.getGroups().contains(RangerPolicyEngine.GROUP_PUBLIC) ||
                                                
!Collections.disjoint(policyItem.getGroups(), userGroups);
                        }
@@ -146,7 +152,7 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
                        }
                }
 
-               if(LOG.isDebugEnabled()) {
+               if (LOG.isDebugEnabled()) {
                        LOG.debug("<== 
RangerDefaultPolicyItemEvaluator.matchUserGroup(" + policyItem + ", " + user + 
", " + userGroups + ", " + roles + ", " + owner + "): " + ret);
                }
 
@@ -154,7 +160,7 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
        }
 
        private boolean matchUserGroupAndOwner(RangerAccessRequest request) {
-               if(LOG.isDebugEnabled()) {
+               if (LOG.isDebugEnabled()) {
                        LOG.debug("==> 
RangerDefaultPolicyItemEvaluator.matchUserGroupAndOwner(" + request + ")");
                }
 
@@ -174,39 +180,44 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
                        ret = matchUserGroupAndOwner(user, userGroups, roles, 
resourceOwner);
                }
 
-               if(LOG.isDebugEnabled()) {
+               if (LOG.isDebugEnabled()) {
                        LOG.debug("<== 
RangerDefaultPolicyItemEvaluator.matchUserGroupAndOwner(" + request + "): " + 
ret);
                }
 
                return ret;
        }
+
        @Override
        public boolean matchAccessType(String accessType) {
-               if(LOG.isDebugEnabled()) {
+               if (LOG.isDebugEnabled()) {
                        LOG.debug("==> 
RangerDefaultPolicyItemEvaluator.matchAccessType(" + accessType + ")");
                }
 
                boolean ret = false;
 
-               if(policyItem != null) {
+               if (policyItem != null) {
                        boolean isAdminAccess = StringUtils.equals(accessType, 
RangerPolicyEngine.ADMIN_ACCESS);
 
-                       if(isAdminAccess) {
+                       if (isAdminAccess) {
                                ret = policyItem.getDelegateAdmin();
                        } else {
-                               
if(CollectionUtils.isNotEmpty(policyItem.getAccesses())) {
+                               if (withImpliedGrants == null) {
+                                       withImpliedGrants = 
computeWithImpliedGrants();
+                               }
+
+                               if 
(CollectionUtils.isNotEmpty(withImpliedGrants.getAccesses())) {
                                        boolean isAnyAccess = 
StringUtils.equals(accessType, RangerPolicyEngine.ANY_ACCESS);
 
-                                       for(RangerPolicyItemAccess itemAccess : 
policyItem.getAccesses()) {
-                                               if(! itemAccess.getIsAllowed()) 
{
+                                       for (RangerPolicyItemAccess itemAccess 
: withImpliedGrants.getAccesses()) {
+                                               if (!itemAccess.getIsAllowed()) 
{
                                                        continue;
                                                }
 
-                                               if(isAnyAccess) {
+                                               if (isAnyAccess) {
                                                        ret = true;
 
                                                        break;
-                                               } else 
if(StringUtils.equalsIgnoreCase(itemAccess.getType(), accessType)) {
+                                               } else if 
(StringUtils.equalsIgnoreCase(itemAccess.getType(), accessType)) {
                                                        ret = true;
 
                                                        break;
@@ -217,8 +228,8 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
                                }
                        }
                }
-               
-               if(LOG.isDebugEnabled()) {
+
+               if (LOG.isDebugEnabled()) {
                        LOG.debug("<== 
RangerDefaultPolicyItemEvaluator.matchAccessType(" + accessType + "): " + ret);
                }
 
@@ -227,27 +238,27 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
 
        @Override
        public boolean matchCustomConditions(RangerAccessRequest request) {
-               if(LOG.isDebugEnabled()) {
+               if (LOG.isDebugEnabled()) {
                        LOG.debug("==> 
RangerDefaultPolicyItemEvaluator.matchCustomConditions(" + request + ")");
                }
 
                boolean ret = true;
 
                if (CollectionUtils.isNotEmpty(conditionEvaluators)) {
-                       if(LOG.isDebugEnabled()) {
+                       if (LOG.isDebugEnabled()) {
                                
LOG.debug("RangerDefaultPolicyItemEvaluator.matchCustomConditions(): 
conditionCount=" + conditionEvaluators.size());
                        }
-                       for(RangerConditionEvaluator conditionEvaluator : 
conditionEvaluators) {
-                               if(LOG.isDebugEnabled()) {
+                       for (RangerConditionEvaluator conditionEvaluator : 
conditionEvaluators) {
+                               if (LOG.isDebugEnabled()) {
                                        LOG.debug("evaluating condition: " + 
conditionEvaluator);
                                }
                                RangerPerfTracer perf = null;
 
-                               
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYCONDITION_REQUEST_LOG)) {
+                               if 
(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYCONDITION_REQUEST_LOG)) {
 
                                        String conditionType = null;
                                        if (conditionEvaluator instanceof 
RangerAbstractConditionEvaluator) {
-                                               conditionType = 
((RangerAbstractConditionEvaluator)conditionEvaluator).getPolicyItemCondition().getType();
+                                               conditionType = 
((RangerAbstractConditionEvaluator) 
conditionEvaluator).getPolicyItemCondition().getType();
                                        }
 
                                        perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICYCONDITION_REQUEST_LOG, 
"RangerConditionEvaluator.matchCondition(policyId=" + policyId + 
",policyItemIndex=" + getPolicyItemIndex() + ",policyConditionType=" + 
conditionType + ")");
@@ -258,7 +269,7 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
                                RangerPerfTracer.log(perf);
 
                                if (!conditionEvalResult) {
-                                       if(LOG.isDebugEnabled()) {
+                                       if (LOG.isDebugEnabled()) {
                                                LOG.debug(conditionEvaluator + 
" returned false");
                                        }
 
@@ -269,7 +280,7 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
                        }
                }
 
-               if(LOG.isDebugEnabled()) {
+               if (LOG.isDebugEnabled()) {
                        LOG.debug("<== 
RangerDefaultPolicyItemEvaluator.matchCustomConditions(" + request + "): " + 
ret);
                }
 
@@ -282,15 +293,15 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
        }
 
        RangerPolicyConditionDef getConditionDef(String conditionName) {
-               if(LOG.isDebugEnabled()) {
+               if (LOG.isDebugEnabled()) {
                        LOG.debug("==> 
RangerDefaultPolicyItemEvaluator.getConditionDef(" + conditionName + ")");
                }
 
                RangerPolicyConditionDef ret = null;
 
                if (serviceDef != null && 
CollectionUtils.isNotEmpty(serviceDef.getPolicyConditions())) {
-                       for(RangerPolicyConditionDef conditionDef : 
serviceDef.getPolicyConditions()) {
-                               if(StringUtils.equals(conditionName, 
conditionDef.getName())) {
+                       for (RangerPolicyConditionDef conditionDef : 
serviceDef.getPolicyConditions()) {
+                               if (StringUtils.equals(conditionName, 
conditionDef.getName())) {
                                        ret = conditionDef;
 
                                        break;
@@ -298,7 +309,7 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
                        }
                }
 
-               if(LOG.isDebugEnabled()) {
+               if (LOG.isDebugEnabled()) {
                        LOG.debug("<== 
RangerDefaultPolicyItemEvaluator.getConditionDef(" + conditionName + "): " + 
ret);
                }
 
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
index e50eb5f54..6d6169309 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
@@ -45,6 +45,7 @@ public class RangerOptimizedPolicyEvaluator extends 
RangerDefaultPolicyEvaluator
     private boolean     hasPublicGroup;
     private boolean     hasCurrentUser;
     private boolean     hasResourceOwner;
+    private boolean     hasAllEvaluatorsInitialized;
 
     // For computation of priority
     private static final String RANGER_POLICY_EVAL_MATCH_ANY_PATTERN_STRING   
= "*";
@@ -252,23 +253,29 @@ public class RangerOptimizedPolicyEvaluator extends 
RangerDefaultPolicyEvaluator
     protected boolean hasMatchablePolicyItem(RangerAccessRequest request) {
         boolean ret = false;
 
-        if (hasPublicGroup || hasCurrentUser || isOwnerMatch(request) || 
users.contains(request.getUser()) || CollectionUtils.containsAny(groups, 
request.getUserGroups()) || (CollectionUtils.isNotEmpty(roles) && 
CollectionUtils.containsAny(roles, 
RangerAccessRequestUtil.getCurrentUserRolesFromContext(request.getContext())))) 
{
-           if (hasAllPerms || request.isAccessTypeAny()) {
-                ret = true;
-            } else {
-               ret = accessPerms.contains(request.getAccessType());
-
-               if (!ret) {
-                   Set<String> allRequestedAccesses = 
RangerAccessRequestUtil.getAllRequestedAccessTypes(request);
-                   ret = CollectionUtils.containsAny(accessPerms, 
allRequestedAccesses);
-               }
-
-               if (!ret) {
-                   if (request.isAccessTypeDelegatedAdmin()) {
-                       ret = delegateAdmin;
-                   }
-               }
-           }
+        if (isUseAclSummaryForEvaluation()) {
+            ret = true;
+        } else if (checkIfAllEvaluatorsInitialized()) {
+            if (hasPublicGroup || hasCurrentUser || isOwnerMatch(request) || 
users.contains(request.getUser()) || CollectionUtils.containsAny(groups, 
request.getUserGroups()) || (CollectionUtils.isNotEmpty(roles) && 
CollectionUtils.containsAny(roles, 
RangerAccessRequestUtil.getCurrentUserRolesFromContext(request.getContext())))) 
{
+                if (hasAllPerms || request.isAccessTypeAny()) {
+                    ret = true;
+                } else {
+                    ret = accessPerms.contains(request.getAccessType());
+
+                    if (!ret) {
+                        Set<String> allRequestedAccesses = 
RangerAccessRequestUtil.getAllRequestedAccessTypes(request);
+                        ret = CollectionUtils.containsAny(accessPerms, 
allRequestedAccesses);
+                    }
+
+                    if (!ret) {
+                        if (request.isAccessTypeDelegatedAdmin()) {
+                            ret = delegateAdmin;
+                        }
+                    }
+                }
+            }
+        } else {
+            ret = true;
         }
 
         return ret;
@@ -293,26 +300,32 @@ public class RangerOptimizedPolicyEvaluator extends 
RangerDefaultPolicyEvaluator
     private boolean hasMatchablePolicyItem(String user, Set<String> 
userGroups, Set<String> rolesFromContext, String owner, String accessType) {
         boolean ret = false;
 
-        boolean hasRole = false;
-        if (CollectionUtils.isNotEmpty(roles)) {
-            if (CollectionUtils.isNotEmpty(rolesFromContext)) {
-                hasRole = CollectionUtils.containsAny(roles, rolesFromContext);
+        if (isUseAclSummaryForEvaluation()) {
+            ret = true;
+        } else if (checkIfAllEvaluatorsInitialized()) {
+            boolean hasRole = false;
+            if (CollectionUtils.isNotEmpty(roles)) {
+                if (CollectionUtils.isNotEmpty(rolesFromContext)) {
+                    hasRole = CollectionUtils.containsAny(roles, 
rolesFromContext);
+                }
             }
-        }
-
-        if (hasPublicGroup || hasCurrentUser || users.contains(user) || 
CollectionUtils.containsAny(groups, userGroups) || hasRole || (hasResourceOwner 
&& StringUtils.equals(user, owner))) {
-            if (hasAllPerms) {
-                ret = true;
-            } else {
-                boolean isAccessTypeAny = StringUtils.isEmpty(accessType) || 
StringUtils.equals(accessType, RangerPolicyEngine.ANY_ACCESS);
-                ret = isAccessTypeAny || accessPerms.contains(accessType);
 
-                if (!ret) {
-                    if (StringUtils.equals(accessType, 
RangerPolicyEngine.ADMIN_ACCESS)) {
-                        ret = delegateAdmin;
+            if (hasPublicGroup || hasCurrentUser || users.contains(user) || 
CollectionUtils.containsAny(groups, userGroups) || hasRole || (hasResourceOwner 
&& StringUtils.equals(user, owner))) {
+                if (hasAllPerms) {
+                    ret = true;
+                } else {
+                    boolean isAccessTypeAny = StringUtils.isEmpty(accessType) 
|| StringUtils.equals(accessType, RangerPolicyEngine.ANY_ACCESS);
+                    ret = isAccessTypeAny || accessPerms.contains(accessType);
+
+                    if (!ret) {
+                        if (StringUtils.equals(accessType, 
RangerPolicyEngine.ADMIN_ACCESS)) {
+                            ret = delegateAdmin;
+                        }
                     }
                 }
             }
+        } else {
+            ret = true;
         }
 
         return ret;
@@ -365,4 +378,33 @@ public class RangerOptimizedPolicyEvaluator extends 
RangerDefaultPolicyEvaluator
         return result;
     }
 
+    private boolean checkIfAllEvaluatorsInitialized() {
+        if (!hasAllEvaluatorsInitialized) {
+            hasAllEvaluatorsInitialized = checkIfWithImpliedGrantsInitialized 
(getAllowEvaluators()) &&
+                    
checkIfWithImpliedGrantsInitialized(getAllowExceptionEvaluators()) &&
+                    checkIfWithImpliedGrantsInitialized(getDenyEvaluators()) &&
+                    
checkIfWithImpliedGrantsInitialized(getDenyExceptionEvaluators()) &&
+                    
checkIfWithImpliedGrantsInitialized(getDataMaskEvaluators()) &&
+                    
checkIfWithImpliedGrantsInitialized(getRowFilterEvaluators());
+        }
+        return hasAllEvaluatorsInitialized;
+    }
+
+    private boolean checkIfWithImpliedGrantsInitialized(List<? extends 
RangerPolicyItemEvaluator> evaluators) {
+        boolean ret = true;
+        for (RangerPolicyItemEvaluator evaluator: evaluators) {
+            if (evaluator.getWithImpliedGrants() == null) {
+                ret = false;
+                break;
+            } else {
+                for (RangerPolicy.RangerPolicyItemAccess access : 
evaluator.getWithImpliedGrants().getAccesses()) {
+                    if (access.getIsAllowed()) {
+                        accessPerms.add(access.getType());
+                    }
+                }
+            }
+        }
+        return ret;
+    }
+
 }
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
index f130e2491..dcaae9ff1 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
@@ -22,6 +22,7 @@ package org.apache.ranger.plugin.policyevaluator;
 
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Comparator;
 import java.util.Date;
 import java.util.HashMap;
@@ -308,7 +309,7 @@ public interface RangerPolicyEvaluator {
 
                public List<DataMaskResult> getDataMasks() { return dataMasks; }
 
-               void processPolicyItem(RangerPolicyItem policyItem, int 
policyItemType, boolean isConditional) {
+               void processPolicyItem(RangerPolicyItem policyItem, int 
policyItemType, boolean isConditional, Map<String, Collection<String>> 
impliedAccessGrants) {
                        final Integer result;
                        final boolean hasContextSensitiveSpecification = 
CollectionUtils.isNotEmpty(policyItem.getConditions());
 
@@ -335,15 +336,43 @@ public interface RangerPolicyEvaluator {
                        }
 
                        if (result != null) {
-                               final List<RangerPolicyItemAccess> accesses;
+                               List<RangerPolicyItemAccess> accesses = new 
ArrayList<>();
+                               accesses.addAll(policyItem.getAccesses());
 
                                if (policyItem.getDelegateAdmin()) {
-                                       accesses = new ArrayList<>();
-
                                        accesses.add(new 
RangerPolicyItemAccess(RangerPolicyEngine.ADMIN_ACCESS, 
policyItem.getDelegateAdmin()));
-                                       
accesses.addAll(policyItem.getAccesses());
-                               } else {
-                                       accesses = policyItem.getAccesses();
+                               }
+
+                               if(impliedAccessGrants != null && 
!impliedAccessGrants.isEmpty()) {
+                                       if 
(CollectionUtils.isNotEmpty(policyItem.getAccesses())) {
+
+                                               // Only one round of 
'expansion' is done; multi-level impliedGrants (like shown below) are not 
handled for now
+                                               // multi-level impliedGrants: 
given admin=>write; write=>read: must imply admin=>read,write
+                                               for (Map.Entry<String, 
Collection<String>> e : impliedAccessGrants.entrySet()) {
+                                                       String 
implyingAccessType = e.getKey();
+                                                       Collection<String> 
impliedGrants = e.getValue();
+
+                                                       RangerPolicyItemAccess 
access = RangerDefaultPolicyEvaluator.getAccess(policyItem, implyingAccessType);
+
+                                                       if (access == null) {
+                                                               continue;
+                                                       }
+
+                                                       for (String 
impliedGrant : impliedGrants) {
+                                                               
RangerPolicyItemAccess impliedAccess = 
RangerDefaultPolicyEvaluator.getAccess(policyItem, impliedGrant);
+
+                                                               if 
(impliedAccess == null) {
+                                                                       
impliedAccess = new RangerPolicyItemAccess(impliedGrant, access.getIsAllowed());
+
+                                                                       
accesses.add(impliedAccess);
+                                                               } else {
+                                                                       if 
(!impliedAccess.getIsAllowed()) {
+                                                                               
impliedAccess.setIsAllowed(access.getIsAllowed());
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
                                }
 
                                final List<String> groups         = 
policyItem.getGroups();
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
index 1a2ea4c9e..38d2129df 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
@@ -66,4 +66,5 @@ public interface RangerPolicyItemEvaluator {
                }
        }
        void updateAccessResult(RangerPolicyEvaluator policyEvaluator, 
RangerAccessResult result, RangerPolicyResourceMatcher.MatchType matchType);
+       RangerPolicyItem getWithImpliedGrants();
 }


Reply via email to