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 16c60270e RANGER-4820: Support authorization of multiple accesses 
grouped by access groups in one policy engine call
16c60270e is described below

commit 16c60270eafb9fda7ac8f784e43f6a96110c40e6
Author: Abhay Kulkarni <[email protected]>
AuthorDate: Mon Jun 17 16:00:34 2024 -0700

    RANGER-4820: Support authorization of multiple accesses grouped by access 
groups in one policy engine call
---
 .../policyengine/RangerPolicyEngineImpl.java       |  22 +-
 .../plugin/policyengine/gds/GdsPolicyEngine.java   |   7 +-
 .../RangerDefaultPolicyEvaluator.java              | 288 ++++++++++++++++-----
 .../plugin/util/RangerAccessRequestUtil.java       | 140 +++++++---
 .../plugin/policyengine/TestPolicyEngine.java      |  32 ++-
 .../policyengine/gds/TestGdsPolicyEngine.java      |  20 +-
 .../plugin/service/TestRangerBasePlugin.java       |  20 +-
 .../test_policyengine_hdfs_multiple_accesses.json  |  11 +-
 .../authorization/hadoop/RangerHdfsAuthorizer.java |  35 ++-
 9 files changed, 410 insertions(+), 165 deletions(-)

diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
index b0dc7a461..232ef90da 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
@@ -678,7 +678,8 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                                String requestedAccess = 
accessTypeDef.getName();
                                allRequestedAccesses.add(requestedAccess);
                        }
-                       
RangerAccessRequestUtil.setAllRequestedAccessTypes(request.getContext(), 
allRequestedAccesses, Boolean.TRUE);
+                       
RangerAccessRequestUtil.setAllRequestedAccessTypes(request.getContext(), 
allRequestedAccesses);
+                       
RangerAccessRequestUtil.setIsAnyAccessInContext(request.getContext(), 
Boolean.TRUE);
                }
 
                ret = evaluatePoliciesForOneAccessTypeNoAudit(request, 
policyType, zoneName, policyRepository, tagPolicyRepository);
@@ -768,22 +769,6 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                                }
                        }
 
-                       if (!request.isAccessTypeAny()) {
-                               Set<String> allRequestedAccesses = 
RangerAccessRequestUtil.getAllRequestedAccessTypes(request);
-                               if (CollectionUtils.size(allRequestedAccesses) 
> 1 && !RangerAccessRequestUtil.getIsAnyAccessInContext(request.getContext())) {
-                                       Map<String, RangerAccessResult> 
accessTypeResults = 
RangerAccessRequestUtil.getAccessTypeResults(request.getContext());
-                                       if (accessTypeResults != null) {
-                                               if 
(accessTypeResults.keySet().containsAll(allRequestedAccesses)) {
-                                                       // Allow
-                                                       RangerAccessResult 
result = accessTypeResults.values().iterator().next(); // Pick one result 
randomly
-                                                       
ret.setAccessResultFrom(result);
-                                                       
ret.setIsAccessDetermined(true);
-                                               }
-                                               
RangerAccessRequestUtil.setAccessTypeResults(request.getContext(), null);
-                                       }
-                               }
-                       }
-
                        if (!ret.getIsAccessDetermined()) {
                                if (isDeniedByTags) {
                                        ret.setIsAllowed(false);
@@ -801,6 +786,9 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                        if (ret.getIsAllowed()) {
                                ret.setIsAccessDetermined(true);
                        }
+                       
RangerAccessRequestUtil.setAccessTypeResults(request.getContext(), null);
+                       
RangerAccessRequestUtil.setAccessTypeACLResults(request.getContext(), null);
+                       
RangerAccessRequestUtil.setIsAnyAccessInContext(request.getContext(), null);
 
                        if (findAuditByResource && !foundInCache) {
                                
policyRepository.storeAuditEnabledInCache(request, ret);
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 6a6709254..53843136c 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
@@ -78,7 +78,8 @@ public class GdsPolicyEngine {
 
         try {
             if (isAnyAccess) {
-                
RangerAccessRequestUtil.setAllRequestedAccessTypes(request.getContext(), 
allAccessTypes, Boolean.TRUE);
+                
RangerAccessRequestUtil.setAllRequestedAccessTypes(request.getContext(), 
allAccessTypes);
+                
RangerAccessRequestUtil.setIsAnyAccessInContext(request.getContext(), 
Boolean.TRUE);
             }
 
             List<GdsDataShareEvaluator> dataShares = 
getDataShareEvaluators(request);
@@ -108,7 +109,9 @@ public class GdsPolicyEngine {
             }
         } finally {
             if (isAnyAccess) {
-                
RangerAccessRequestUtil.setAllRequestedAccessTypes(request.getContext(), null, 
Boolean.FALSE);
+                
RangerAccessRequestUtil.setAllRequestedAccessTypes(request.getContext(), null);
+                
RangerAccessRequestUtil.setIsAnyAccessInContext(request.getContext(), 
Boolean.FALSE);
+
             }
         }
 
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 c43ec4c2f..33d56ec57 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
@@ -830,6 +830,76 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                return ret;
        }
 
+       private Integer getAccessACLForOneGroup(RangerAccessRequest request, 
Set<String> accessesInGroup) {
+               Integer              ret               = null;
+               Map<String, Integer> accessTypeResults = 
RangerAccessRequestUtil.getAccessTypeACLResults(request);
+
+               boolean isAccessDetermined = true;
+               boolean isAccessDenied     = false;
+               Integer deniedAccessResult = null;
+
+               for (String accessType : accessesInGroup) {
+                       Integer accessResult = 
accessTypeResults.get(accessType);
+                       if (accessResult != null) {
+                               if (accessResult.equals(ACCESS_ALLOWED)) {
+                                       // Allow
+                                       isAccessDenied = false;
+                                       ret = accessResult;
+                                       break;
+                               } else {
+                                       isAccessDenied = true;
+                                       if (deniedAccessResult == null) {
+                                               deniedAccessResult = 
accessResult;
+                                       }
+                               }
+                       } else {
+                               isAccessDetermined = false;
+                       }
+               }
+               if (isAccessDetermined && isAccessDenied) {
+                       ret = deniedAccessResult;
+               }
+               return ret;
+       }
+
+       private Integer getCompositeACLResult(RangerAccessRequest request) {
+               Integer                         ret                             
= null;
+               Set<Set<String>>        allAccessTypeGroups = 
RangerAccessRequestUtil.getAllRequestedAccessTypeGroups(request);
+
+               if (CollectionUtils.isEmpty(allAccessTypeGroups)) {
+                       Set<String>                     allAccessTypes          
= RangerAccessRequestUtil.getAllRequestedAccessTypes(request);
+                       ret = getAccessACLForOneGroup(request, allAccessTypes);
+               } else {
+                       boolean                         isAccessDetermined      
= true;
+                       boolean                         isAccessAllowed         
= false;
+                       Integer                         allowResult             
        = null;
+
+                       for (Set<String> accessesInGroup : allAccessTypeGroups) 
{
+                               Integer groupResult = 
getAccessACLForOneGroup(request, accessesInGroup);
+                               if (groupResult != null) {
+                                       if 
(!groupResult.equals(ACCESS_ALLOWED)) {
+                                               // Deny
+                                               isAccessAllowed = false;
+                                               ret                             
= groupResult;
+                                               break;
+                                       } else {
+                                               isAccessAllowed = true;
+                                               if (allowResult == null) {
+                                                       allowResult = 
groupResult;
+                                               }
+                                       }
+                               } else {
+                                       // Some group is not completely 
authorized yet
+                                       isAccessDetermined = false;
+                               }
+                       }
+                       if (isAccessDetermined && isAccessAllowed) {
+                               ret = allowResult;
+                       }
+               }
+               return ret;
+       }
+
        protected void evaluatePolicyItems(RangerAccessRequest request, 
RangerPolicyResourceMatcher.MatchType matchType, RangerAccessResult result) {
                if(LOG.isDebugEnabled()) {
                        LOG.debug("==> 
RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + 
", " + matchType + ")");
@@ -843,42 +913,43 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                        if (request.isAccessTypeAny() || 
RangerAccessRequestUtil.getIsAnyAccessInContext(request.getContext())) {
                                accessResult = 
lookupPolicyACLSummary(request.getUser(), request.getUserGroups(), 
request.getUserRoles(), RangerPolicyEngine.ANY_ACCESS);
                        } else {
+                               Map<String, Integer> accessTypeACLResults = 
RangerAccessRequestUtil.getAccessTypeACLResults(request);
                                Set<String> allRequestedAccesses = 
RangerAccessRequestUtil.getAllRequestedAccessTypes(request);
 
-                               if (CollectionUtils.size(allRequestedAccesses) 
> 1) {
+                               if (allRequestedAccesses.size() > 1) {
                                        for (String accessType : 
allRequestedAccesses) {
+
+                                               Integer denyResult  = null;
+                                               Integer allowResult = null;
+
                                                Integer oneAccessResult = 
lookupPolicyACLSummary(request.getUser(), request.getUserGroups(), 
request.getUserRoles(), accessType);
                                                if (oneAccessResult != null) {
-                                                       if 
(oneAccessResult.equals(RangerPolicyEvaluator.ACCESS_DENIED)) {
-                                                               accessResult = 
oneAccessResult;
-                                                               
RangerAccessRequestUtil.setAccessTypeResults(request.getContext(), null);
-
-                                                               break;
+                                                       if 
(oneAccessResult.equals(ACCESS_DENIED)) {
+                                                               denyResult = 
oneAccessResult;
                                                        }
-                                                       if 
(oneAccessResult.equals(RangerPolicyEvaluator.ACCESS_ALLOWED)) {
-                                                               if 
(!result.getIsAllowed()) { // if access is not yet allowed by another policy
-                                                                       if 
(matchType != RangerPolicyResourceMatcher.MatchType.ANCESTOR) {
-                                                                               
RangerAccessResult oneResult = new RangerAccessResult(result.getPolicyType(), 
result.getServiceName(), result.getServiceDef(), result.getAccessRequest());
-                                                                               
oneResult.setPolicyPriority(getPolicyPriority());
-                                                                               
oneResult.setPolicyId(getPolicyId());
-                                                                               
oneResult.setPolicyVersion(getPolicy().getVersion());
-                                                                               
if (!oneResult.getIsAuditedDetermined()) {
-                                                                               
        oneResult.setAuditResultFrom(result);
-                                                                               
}
-
-                                                                               
RangerAccessRequestUtil.setAccessTypeResult(request.getContext(), accessType, 
oneResult);
+                                                       if 
(oneAccessResult.equals(ACCESS_ALLOWED)) {
+                                                               allowResult = 
oneAccessResult;
+                                                       }
+                                                       Integer oldResult = 
accessTypeACLResults.get(accessType);
+                                                       if (oldResult == null) {
+                                                               
accessTypeACLResults.put(accessType, allowResult != null ? allowResult : 
denyResult);
+                                                       } else {
+                                                               if 
(oldResult.equals(ACCESS_ALLOWED)) {
+                                                                       if 
(denyResult != null) {
+                                                                               
accessTypeACLResults.put(accessType, denyResult);
+                                                                       } else {
+                                                                               
accessTypeACLResults.put(accessType, allowResult);
                                                                        }
-                                                               }
-                                                               Map<String, 
RangerAccessResult> savedAccessResults = 
RangerAccessRequestUtil.getAccessTypeResults(request.getContext());
-                                                               int 
allowedAccessesCount = savedAccessResults == null ? 0 : 
savedAccessResults.size();
-                                                               if 
(allRequestedAccesses.size() == allowedAccessesCount) {
-                                                                       
RangerAccessRequestUtil.setAccessTypeResults(request.getContext(), null);
-                                                                       
result.setIsAllowed(true);
-                                                                       break;
+                                                               } else {
+                                                                       
accessTypeACLResults.put(accessType, denyResult);
                                                                }
                                                        }
                                                }
                                        }
+                                       Integer compositeACLResult = 
getCompositeACLResult(request);
+                                       if (compositeACLResult != null) {
+                                               accessResult = 
compositeACLResult;
+                                       }
                                } else {
                                        accessResult = 
lookupPolicyACLSummary(request.getUser(), request.getUserGroups(), 
request.getUserRoles(), request.getAccessType());
                                }
@@ -895,19 +966,20 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                        }
                        Set<String> allRequestedAccesses = 
RangerAccessRequestUtil.getAllRequestedAccessTypes(request);
 
-                       if (CollectionUtils.isNotEmpty(allRequestedAccesses)) {
-
-                               RangerAccessResult denyResult  = null;
-                               RangerAccessResult allowResult = null;
-                               boolean            noResult    = false;
+                       if (CollectionUtils.isNotEmpty(allRequestedAccesses) ) {
+                               Map<String, RangerAccessResult> 
accessTypeResults = RangerAccessRequestUtil.getAccessTypeResults(request);
 
                                for (String accessType : allRequestedAccesses) {
 
                                        if (LOG.isDebugEnabled()) {
                                                LOG.debug("Checking for 
accessType:[" + accessType + "]");
                                        }
-                                       RangerAccessRequestWrapper  oneRequest 
= new RangerAccessRequestWrapper(request, accessType);
-                                       RangerAccessResult          oneResult  
= new RangerAccessResult(result.getPolicyType(), result.getServiceName(), 
result.getServiceDef(), oneRequest);
+                                       RangerAccessResult denyResult  = null;
+                                       RangerAccessResult allowResult = null;
+                                       boolean            noResult    = false;
+
+                                       RangerAccessRequestWrapper oneRequest = 
new RangerAccessRequestWrapper(request, accessType);
+                                       RangerAccessResult         oneResult  = 
new RangerAccessResult(result.getPolicyType(), result.getServiceName(), 
result.getServiceDef(), oneRequest);
 
                                        oneResult.setAuditResultFrom(result);
 
@@ -919,55 +991,61 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                                                updateAccessResult(oneResult, 
matchType, false, "matched deny-all-else policy");
                                        }
 
-                                       if (request.isAccessTypeAny() || 
allRequestedAccesses.size() == 1 || 
RangerAccessRequestUtil.getIsAnyAccessInContext(request.getContext())) {
-                                               // Implement OR logic
-                                               if (oneResult.getIsAllowed()) {
-                                                       allowResult = oneResult;
-                                                       denyResult  = null;
+                                       if (oneResult.getIsAllowed()) {
+                                               allowResult = oneResult;
+                                       } else if 
(oneResult.getIsAccessDetermined()) {
+                                               denyResult = oneResult;
+                                       } else {
+                                               noResult = true;
+                                       }
 
-                                                       break;
-                                               } else if 
(oneResult.getIsAccessDetermined()) {
-                                                       if (!noResult) {
-                                                               if (denyResult 
== null) {
-                                                                       
denyResult = oneResult;
+                                       if (!noResult) {
+                                               RangerAccessResult oldResult = 
accessTypeResults.get(accessType);
+                                               if (oldResult == null) {
+                                                       
accessTypeResults.put(accessType, allowResult != null ? allowResult : 
denyResult);
+                                               } else {
+                                                       int oldPriority = 
oldResult.getPolicyPriority();
+                                                       if 
(oldResult.getIsAllowed()) {
+                                                               if (denyResult 
!= null) {
+                                                                       if 
(getPolicyPriority() >= oldPriority) {
+                                                                               
accessTypeResults.put(accessType, denyResult);
+                                                                       }
+                                                               } else {
+                                                                       if 
(getPolicy().getPolicyType() == null || getPolicy().getPolicyType() == 
RangerPolicy.POLICY_TYPE_ACCESS) {
+                                                                               
if (getPolicyPriority() > oldPriority) {
+                                                                               
        accessTypeResults.put(accessType, allowResult);
+                                                                               
}
+                                                                       } else {
+                                                                               
if (getPolicyPriority() >= oldPriority) {
+                                                                               
        accessTypeResults.put(accessType, allowResult);
+                                                                               
}
+                                                                       }
+                                                               }
+                                                       } else { // Earlier 
evaluator denied this access
+                                                               if 
(getPolicyPriority() >= oldPriority && allowResult != null && 
(oneRequest.isAccessTypeAny() || 
RangerAccessRequestUtil.getIsAnyAccessInContext(oneRequest.getContext()))) {
+                                                                       
accessTypeResults.put(accessType, allowResult);
+                                                               } else {
+                                                                       if 
(getPolicyPriority() > oldPriority && denyResult != null) {
+                                                                               
accessTypeResults.put(accessType, denyResult);
+                                                                       }
                                                                }
                                                        }
-                                               } else {
-                                                       noResult = true;
-                                                       denyResult = null;
                                                }
-                                       } else {
-                                               // Implement AND logic
-                                               if 
(oneResult.getIsAccessDetermined() && !oneResult.getIsAllowed()) {
-                                                       denyResult = oneResult;
-                                                       
RangerAccessRequestUtil.setAccessTypeResults(request.getContext(), null);
-
-                                                       break;
-                                               } else if 
(oneResult.getIsAllowed()) {
-                                                       
RangerAccessRequestUtil.setAccessTypeResult(request.getContext(), accessType, 
oneResult);
-
-                                                       // Check if all access 
requests are satisfied, if so, access is allowed
-                                                       if 
(allRequestedAccesses.size() == 
RangerAccessRequestUtil.getAccessTypeResults(request.getContext()).size()) {
-                                                               allowResult = 
oneResult;
-                                                               
RangerAccessRequestUtil.setAccessTypeResults(request.getContext(), null);
+                                               /* At least one access is 
allowed - this evaluator need not be checked for other accesses as the test 
below
+                                                * implies that there is only 
one access group in the request
+                                                */
+                                               if 
(oneRequest.isAccessTypeAny() || 
RangerAccessRequestUtil.getIsAnyAccessInContext(oneRequest.getContext())) {
+                                                       if (allowResult != 
null) {
                                                                break;
                                                        }
                                                }
                                        }
                                }
 
-                               if (LOG.isDebugEnabled()) {
-                                       LOG.debug("allowResult:[" + allowResult 
+ "], denyResult:[" + denyResult + "], noResult:[" + noResult + "]");
+                               RangerAccessResult compositeAccessResult = 
getCompositeAccessResult(request);
+                               if (compositeAccessResult != null) {
+                                       
result.setAccessResultFrom(compositeAccessResult);
                                }
-
-                               if (allowResult != null) {
-                                       if (!result.getIsAllowed() || 
result.getPolicyPriority() < allowResult.getPolicyPriority()) {
-                                               
result.setAccessResultFrom(allowResult);
-                                       }
-                               } else if (denyResult != null) {
-                                       result.setAccessResultFrom(denyResult);
-                               }
-
                        } else {
                                RangerPolicyItemEvaluator matchedPolicyItem = 
getMatchingPolicyItem(request, result);
                                if (matchedPolicyItem != null) {
@@ -983,6 +1061,76 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                }
        }
 
+       private RangerAccessResult 
deriveAccessResultFromGroup(RangerAccessRequest request, Set<String> 
accessesInGroup) {
+               RangerAccessResult                                      ret     
                        = null;
+               Map<String, RangerAccessResult>         accessTypeResults       
= RangerAccessRequestUtil.getAccessTypeResults(request);
+
+               boolean                                                         
isAccessDetermined      = true;
+               boolean                                                         
isAccessDenied          = false;
+               RangerAccessResult                                      
deniedAccessResult      = null;
+
+               for (String accessType : accessesInGroup) {
+                       RangerAccessResult accessResult = 
accessTypeResults.get(accessType);
+                       if (accessResult != null) {
+                               if (accessResult.getIsAllowed()) {
+                                       // Allow
+                                       isAccessDenied = false;
+                                       ret = accessResult;
+                                       break;
+                               } else {
+                                       isAccessDenied = true;
+                                       if (deniedAccessResult == null) {
+                                               deniedAccessResult = 
accessResult;
+                                       }
+                               }
+                       } else {
+                               isAccessDetermined = false;
+                       }
+               }
+               if (isAccessDetermined && isAccessDenied) {
+                       ret = deniedAccessResult;
+               }
+               return ret;
+       }
+
+       private RangerAccessResult getCompositeAccessResult(RangerAccessRequest 
request) {
+               RangerAccessResult      ret                             = null;
+               Set<Set<String>>        allAccessTypeGroups = 
RangerAccessRequestUtil.getAllRequestedAccessTypeGroups(request);
+               Set<String>             allAccessTypes      = 
RangerAccessRequestUtil.getAllRequestedAccessTypes(request);
+
+               if (CollectionUtils.isEmpty(allAccessTypeGroups)) {
+                       ret = deriveAccessResultFromGroup(request, 
allAccessTypes);
+               } else {
+                       boolean                         isAccessDetermined      
= true;
+                       boolean                         isAccessAllowed         
= false;
+                       RangerAccessResult      allowResult                     
= null;
+
+                       for (Set<String> accessesInGroup : allAccessTypeGroups) 
{
+                               RangerAccessResult groupResult = 
deriveAccessResultFromGroup(request, accessesInGroup);
+                               if (groupResult != null) {
+                                       if (!groupResult.getIsAllowed()) {
+                                               // Deny
+                                               isAccessAllowed = false;
+                                               ret                             
= groupResult;
+                                               break;
+                                       } else {
+                                               isAccessAllowed = true;
+                                               if (allowResult == null) {
+                                                       allowResult = 
groupResult;
+                                               }
+                                       }
+                               } else {
+                                       // Some group is not completely 
authorized yet
+                                       isAccessDetermined = false;
+                               }
+                       }
+                       if (isAccessDetermined && isAccessAllowed) {
+                               ret = allowResult;
+                       }
+               }
+               return ret;
+       }
+
        private Integer lookupPolicyACLSummary(String user, Set<String> 
userGroups, Set<String> userRoles, String accessType) {
                Integer accessResult = null;
 
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
index df0352ca9..de31737d6 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
@@ -19,10 +19,7 @@
 
 package org.apache.ranger.plugin.util;
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
@@ -37,23 +34,26 @@ import org.slf4j.LoggerFactory;
 public class RangerAccessRequestUtil {
        private static final Logger LOG = 
LoggerFactory.getLogger(RangerAccessRequestUtil.class);
 
-       public static final String KEY_CONTEXT_TAGS                = "TAGS";
-       public static final String KEY_CONTEXT_TAG_OBJECT          = 
"TAG_OBJECT";
-       public static final String KEY_CONTEXT_RESOURCE            = "RESOURCE";
-       public static final String KEY_CONTEXT_REQUESTED_RESOURCES = 
"REQUESTED_RESOURCES";
-       public static final String KEY_CONTEXT_USERSTORE           = 
"USERSTORE";
-       public static final String KEY_TOKEN_NAMESPACE = "token:";
-       public static final String KEY_USER = "USER";
-       public static final String KEY_OWNER = "OWNER";
-       public static final String KEY_ROLES = "ROLES";
-       public static final String KEY_CONTEXT_ACCESSTYPES = "ACCESSTYPES";
-       public static final String KEY_CONTEXT_IS_ANY_ACCESS = "ISANYACCESS";
-       public static final String KEY_CONTEXT_REQUEST       = "_REQUEST";
+       public static final String KEY_CONTEXT_TAGS                             
        = "TAGS";
+       public static final String KEY_CONTEXT_TAG_OBJECT                       
= "TAG_OBJECT";
+       public static final String KEY_CONTEXT_RESOURCE                         
= "RESOURCE";
+       public static final String KEY_CONTEXT_REQUESTED_RESOURCES      = 
"REQUESTED_RESOURCES";
+       public static final String KEY_CONTEXT_USERSTORE                        
= "USERSTORE";
+       public static final String KEY_TOKEN_NAMESPACE                          
= "token:";
+       public static final String KEY_USER                                     
        = "USER";
+       public static final String KEY_OWNER                                    
        = "OWNER";
+       public static final String KEY_ROLES                                    
        = "ROLES";
+       public static final String KEY_CONTEXT_IS_ANY_ACCESS            = 
"ISANYACCESS";
+       public static final String KEY_CONTEXT_ALL_ACCESSTYPE_GROUPS = 
"ALLACCESSTYPEGROUPS";
+       public static final String KEY_CONTEXT_ALL_ACCESSTYPES          = 
"ALLACCESSTYPES";
+       public static final String KEY_CONTEXT_ALL_ACCESS_TYPE_RESULTS  = 
"ALL_ACCESS_TYPE_RESULTS";
+       public static final String KEY_CONTEXT_ALL_ACCESS_TYPE_ACL_RESULTS      
= "ALL_ACCESS_TYPE_ACL_RESULTS";
+
+       public static final String KEY_CONTEXT_REQUEST                          
= "_REQUEST";
        public static final String KEY_CONTEXT_GDS_RESULT    = "_GDS_RESULT";
-       public static final String KEY_CONTEXT_IS_REQUEST_PREPROCESSED = 
"ISREQUESTPREPROCESSED";
-       public static final String KEY_CONTEXT_RESOURCE_ZONE_NAMES     = 
"RESOURCE_ZONE_NAMES";
-       public static final String KEY_CONTEXT_ACCESS_TYPE_RESULTS = 
"_ACCESS_TYPE_RESULTS";
-       public static final String KEY_CONTEXT_IS_SKIP_CHAINED_PLUGINS = 
"_IS_SKIP_CHAINED_PLUGINS";
+       public static final String KEY_CONTEXT_IS_REQUEST_PREPROCESSED  = 
"ISREQUESTPREPROCESSED";
+       public static final String KEY_CONTEXT_RESOURCE_ZONE_NAMES              
= "RESOURCE_ZONE_NAMES";
+       public static final String KEY_CONTEXT_IS_SKIP_CHAINED_PLUGINS  = 
"_IS_SKIP_CHAINED_PLUGINS";
 
        public static void setRequestTagsInContext(Map<String, Object> context, 
Set<RangerTagForEval> tags) {
                if(CollectionUtils.isEmpty(tags)) {
@@ -137,11 +137,13 @@ public class RangerAccessRequestUtil {
                        ret.remove(KEY_CONTEXT_TAGS);
                        ret.remove(KEY_CONTEXT_TAG_OBJECT);
                        ret.remove(KEY_CONTEXT_RESOURCE);
-                       ret.remove(KEY_CONTEXT_RESOURCE_ZONE_NAMES);
                        ret.remove(KEY_CONTEXT_REQUEST);
                        ret.remove(KEY_CONTEXT_GDS_RESULT);
-                       ret.remove(KEY_CONTEXT_ACCESSTYPES);
                        ret.remove(KEY_CONTEXT_IS_ANY_ACCESS);
+                       ret.remove(KEY_CONTEXT_ALL_ACCESSTYPES);
+                       ret.remove(KEY_CONTEXT_ALL_ACCESSTYPE_GROUPS);
+                       ret.remove(KEY_CONTEXT_ALL_ACCESS_TYPE_RESULTS);
+                       ret.remove(KEY_CONTEXT_ALL_ACCESS_TYPE_ACL_RESULTS);
                        ret.remove(KEY_CONTEXT_IS_REQUEST_PREPROCESSED);
                        // don't remove REQUESTED_RESOURCES
                }
@@ -169,15 +171,16 @@ public class RangerAccessRequestUtil {
                return MapUtils.isNotEmpty(context) ? 
context.get(tokenNameWithNamespace) : null;
        }
 
-       public static void setCurrentUserRolesInContext(Map<String, Object> 
context, Set<String> roles) {
-               setTokenInContext(context, KEY_ROLES, roles);
-       }
-       public static Set<String> getCurrentUserRolesFromContext(Map<String, 
Object> context) {
-               Object ret = getTokenFromContext(context, KEY_ROLES);
-               return ret != null ? (Set<String>) ret : Collections.EMPTY_SET;
-       }
+    public static void setCurrentUserRolesInContext(Map<String, Object> 
context, Set<String> roles) {
+        setTokenInContext(context, KEY_ROLES, roles);
+    }
+
+    public static Set<String> getCurrentUserRolesFromContext(Map<String, 
Object> context) {
+        Object ret = getTokenFromContext(context, KEY_ROLES);
+        return ret != null ? (Set<String>) ret : Collections.EMPTY_SET;
+    }
 
-       public static Set<String> getUserRoles(RangerAccessRequest request) {
+    public static Set<String> getUserRoles(RangerAccessRequest request) {
                Set<String> ret = Collections.EMPTY_SET;
 
                if (request != null) {
@@ -225,20 +228,65 @@ public class RangerAccessRequestUtil {
        }
 
        public static void setAllRequestedAccessTypes(Map<String, Object> 
context, Set<String> accessTypes) {
-               context.put(KEY_CONTEXT_ACCESSTYPES, accessTypes);
+               context.put(KEY_CONTEXT_ALL_ACCESSTYPES, accessTypes);
        }
 
-        public static void setAllRequestedAccessTypes(Map<String, Object> 
context, Set<String> accessTypes, Boolean isAny) {
-                context.put(KEY_CONTEXT_ACCESSTYPES, accessTypes);
-                               setIsAnyAccessInContext(context, isAny);
-        }
-
+       @SuppressWarnings("unchecked")
        public static Set<String> 
getAllRequestedAccessTypes(RangerAccessRequest request) {
-               Set<String> ret = (Set<String>) 
request.getContext().get(KEY_CONTEXT_ACCESSTYPES);
+               Set<String> ret = null;
+
+               Object val = 
request.getContext().get(KEY_CONTEXT_ALL_ACCESSTYPES);
+
+               if (val != null) {
+                       if (val instanceof Set<?>) {
+                               ret = (Set<String>) val;
+                       } else if (val instanceof List<?>) {
+                               ret = new TreeSet<>((List<String>) val);
+                       } else {
+                               LOG.error("getAllRequestedAccessTypes(): failed 
to get ALLACCESSTYPES from context");
+                       }
+               }
 
                return ret != null ? ret : 
Collections.singleton(request.getAccessType());
        }
 
+       public static Set<Set<String>> 
getAllRequestedAccessTypeGroups(RangerAccessRequest request) {
+               Object      val = 
request.getContext().get(KEY_CONTEXT_ALL_ACCESSTYPE_GROUPS);
+               return (Set<Set<String>>) val;
+       }
+
+       public static void setAllRequestedAccessTypeGroups(RangerAccessRequest 
request, Set<Set<String>> accessTypeGroups) {
+               if (accessTypeGroups == null || accessTypeGroups.isEmpty()) {
+                       
request.getContext().put(KEY_CONTEXT_ALL_ACCESSTYPE_GROUPS, new TreeSet<>());
+               } else {
+                       
request.getContext().put(KEY_CONTEXT_ALL_ACCESSTYPE_GROUPS, accessTypeGroups);
+               }
+       }
+
+       public static Map<String, RangerAccessResult> 
getAccessTypeResults(RangerAccessRequest request) {
+               Map<String, RangerAccessResult> ret;
+               Object      val = 
request.getContext().get(KEY_CONTEXT_ALL_ACCESS_TYPE_RESULTS);
+               if (val == null) {
+                       ret = new HashMap<>();
+                       
request.getContext().put(KEY_CONTEXT_ALL_ACCESS_TYPE_RESULTS, ret);
+               } else {
+                       ret = (Map<String, RangerAccessResult>) val;
+               }
+               return ret;
+       }
+
+       public static Map<String, Integer> 
getAccessTypeACLResults(RangerAccessRequest request) {
+               Map<String, Integer> ret;
+               Object      val = 
request.getContext().get(KEY_CONTEXT_ALL_ACCESS_TYPE_ACL_RESULTS);
+               if (val == null) {
+                       ret = new HashMap<>();
+                       
request.getContext().put(KEY_CONTEXT_ALL_ACCESS_TYPE_ACL_RESULTS, ret);
+               } else {
+                       ret = (Map<String, Integer>) val;
+               }
+               return ret;
+       }
+
        public static void setRequestInContext(RangerAccessRequest request) {
                Map<String, Object> context = request.getContext();
 
@@ -329,9 +377,19 @@ public class RangerAccessRequestUtil {
        public static void setAccessTypeResults(Map<String, Object> context, 
Map<String, RangerAccessResult> accessTypeResults) {
                if (context != null) {
                        if (accessTypeResults != null) {
-                               context.put(KEY_CONTEXT_ACCESS_TYPE_RESULTS, 
accessTypeResults);
+                               
context.put(KEY_CONTEXT_ALL_ACCESS_TYPE_RESULTS, accessTypeResults);
+                       } else {
+                               
context.remove(KEY_CONTEXT_ALL_ACCESS_TYPE_RESULTS);
+                       }
+               }
+       }
+
+       public static void setAccessTypeACLResults(Map<String, Object> context, 
Map<String, Integer> accessTypeResults) {
+               if (context != null) {
+                       if (accessTypeResults != null) {
+                               
context.put(KEY_CONTEXT_ALL_ACCESS_TYPE_ACL_RESULTS, accessTypeResults);
                        } else {
-                               context.remove(KEY_CONTEXT_ACCESS_TYPE_RESULTS);
+                               
context.remove(KEY_CONTEXT_ALL_ACCESS_TYPE_ACL_RESULTS);
                        }
                }
        }
@@ -340,7 +398,7 @@ public class RangerAccessRequestUtil {
                Map<String, RangerAccessResult> ret = null;
 
                if (context != null) {
-                       Object o = context.get(KEY_CONTEXT_ACCESS_TYPE_RESULTS);
+                       Object o = 
context.get(KEY_CONTEXT_ALL_ACCESS_TYPE_RESULTS);
                        if (o != null) {
                                ret = (Map<String, RangerAccessResult>)o;
                        }
@@ -356,7 +414,7 @@ public class RangerAccessRequestUtil {
                        if (results == null) {
                                results = new HashMap<>();
 
-                               setAccessTypeResults(context, results);
+                               
context.put(KEY_CONTEXT_ALL_ACCESS_TYPE_RESULTS, results);
                        }
 
                        results.putIfAbsent(accessType, result);
diff --git 
a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
 
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
index 64563b84e..d78084589 100644
--- 
a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
+++ 
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
@@ -67,17 +67,7 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Properties;
-import java.util.Set;
-import java.util.TimeZone;
+import java.util.*;
 
 import static org.junit.Assert.*;
 
@@ -961,11 +951,25 @@ public class TestPolicyEngine {
                                ret.setAccessTime(new Date());
                        }
                        Map<String, Object> reqContext = ret.getContext();
-                       Object accessTypes = reqContext.get("ACCESSTYPES");
+                       Object accessTypes = 
reqContext.get(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESSTYPES);
                        if (accessTypes != null) {
                                Collection<String> accessTypesCollection = 
(Collection<String>) accessTypes;
-                               Set<String> requestedAccesses = new 
HashSet<>(accessTypesCollection);
-                               ret.getContext().put("ACCESSTYPES", 
requestedAccesses);
+                               Set<String> requestedAccesses = new 
TreeSet<>(accessTypesCollection);
+                               
ret.getContext().put(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESSTYPES, 
requestedAccesses);
+                       }
+
+                       Object accessTypeGroups = 
reqContext.get(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESSTYPE_GROUPS);
+                       if (accessTypeGroups != null) {
+                               Set<Set<String>> setOfAccessTypeGroups = new 
HashSet<>();
+
+                               List<Object> listOfAccessTypeGroups = 
(List<Object>) accessTypeGroups;
+                               for (Object accessTypeGroup : 
listOfAccessTypeGroups) {
+                                       List<String> accesses = (List<String>) 
accessTypeGroup;
+                                       Set<String> setOfAccesses = new 
TreeSet<>(accesses);
+                                       
setOfAccessTypeGroups.add(setOfAccesses);
+                               }
+
+                               
reqContext.put(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESSTYPE_GROUPS, 
setOfAccessTypeGroups);
                        }
 
                        return ret;
diff --git 
a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/gds/TestGdsPolicyEngine.java
 
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/gds/TestGdsPolicyEngine.java
index 71880dabf..c3884f261 100644
--- 
a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/gds/TestGdsPolicyEngine.java
+++ 
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/gds/TestGdsPolicyEngine.java
@@ -185,11 +185,25 @@ public class TestGdsPolicyEngine {
                 ret.setAccessTime(new Date());
             }
             Map<String, Object> reqContext  = ret.getContext();
-            Object              accessTypes = reqContext.get("ACCESSTYPES");
+            Object accessTypes = 
reqContext.get(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESSTYPES);
             if (accessTypes != null) {
                 Collection<String> accessTypesCollection = 
(Collection<String>) accessTypes;
-                Set<String>        requestedAccesses     = new 
HashSet<>(accessTypesCollection);
-                ret.getContext().put("ACCESSTYPES", requestedAccesses);
+                Set<String> requestedAccesses = new 
TreeSet<>(accessTypesCollection);
+                
ret.getContext().put(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESSTYPES, 
requestedAccesses);
+            }
+
+            Object accessTypeGroups = 
reqContext.get(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESSTYPE_GROUPS);
+            if (accessTypeGroups != null) {
+                Set<Set<String>> setOfAccessTypeGroups = new HashSet<>();
+
+                List<Object> listOfAccessTypeGroups = (List<Object>) 
accessTypeGroups;
+                for (Object accessTypeGroup : listOfAccessTypeGroups) {
+                    List<String> accesses = (List<String>) accessTypeGroup;
+                    Set<String> setOfAccesses = new TreeSet<>(accesses);
+                    setOfAccessTypeGroups.add(setOfAccesses);
+                }
+
+                
reqContext.put(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESSTYPE_GROUPS, 
setOfAccessTypeGroups);
             }
 
             return ret;
diff --git 
a/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerBasePlugin.java
 
b/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerBasePlugin.java
index 9886f25c0..ff871a706 100644
--- 
a/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerBasePlugin.java
+++ 
b/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerBasePlugin.java
@@ -178,11 +178,25 @@ public class TestRangerBasePlugin {
                 ret.setAccessTime(new Date());
             }
             Map<String, Object> reqContext  = ret.getContext();
-            Object              accessTypes = reqContext.get("ACCESSTYPES");
+            Object accessTypes = 
reqContext.get(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESSTYPES);
             if (accessTypes != null) {
                 Collection<String> accessTypesCollection = 
(Collection<String>) accessTypes;
-                Set<String>        requestedAccesses     = new 
HashSet<>(accessTypesCollection);
-                ret.getContext().put("ACCESSTYPES", requestedAccesses);
+                Set<String> requestedAccesses = new 
TreeSet<>(accessTypesCollection);
+                
ret.getContext().put(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESSTYPES, 
requestedAccesses);
+            }
+
+            Object accessTypeGroups = 
reqContext.get(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESSTYPE_GROUPS);
+            if (accessTypeGroups != null) {
+                Set<Set<String>> setOfAccessTypeGroups = new HashSet<>();
+
+                List<Object> listOfAccessTypeGroups = (List<Object>) 
accessTypeGroups;
+                for (Object accessTypeGroup : listOfAccessTypeGroups) {
+                    List<String> accesses = (List<String>) accessTypeGroup;
+                    Set<String> setOfAccesses = new TreeSet<>(accesses);
+                    setOfAccessTypeGroups.add(setOfAccesses);
+                }
+
+                
reqContext.put(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESSTYPE_GROUPS, 
setOfAccessTypeGroups);
             }
 
             return ret;
diff --git 
a/agents-common/src/test/resources/policyengine/test_policyengine_hdfs_multiple_accesses.json
 
b/agents-common/src/test/resources/policyengine/test_policyengine_hdfs_multiple_accesses.json
index 8962c5a3f..1701f354f 100644
--- 
a/agents-common/src/test/resources/policyengine/test_policyengine_hdfs_multiple_accesses.json
+++ 
b/agents-common/src/test/resources/policyengine/test_policyengine_hdfs_multiple_accesses.json
@@ -48,9 +48,6 @@
       "resources":{"path":{"values":["/public/*"],"isRecursive":true}},
       "policyItems":[
         
{"accesses":[{"type":"execute","isAllowed":true}],"users":[],"groups":["public"],"delegateAdmin":false}
-      ],
-      "allowExceptions":[
-        
{"accesses":[{"type":"execute","isAllowed":true}],"users":["guest"],"groups":[],"delegateAdmin":false}
       ]
     }
   ,
@@ -85,7 +82,7 @@
       "request":{
         "resource":{"elements":{"path":"/public/finance"}},
         
"accessType":"read","user":"guest","userGroups":[],"requestData":"read_execute 
/public/finance",
-        "context": {"ACCESSTYPES": [ "read",  "execute" ]}
+        "context": {"ALLACCESSTYPEGROUPS": [ ["read"],  ["execute"] ], 
"ALLACCESSTYPES": [ "read", "execute"]}
       },
       "result":{"isAudited":true,"isAllowed":true,"policyId":6}
     },
@@ -114,7 +111,7 @@
       "request":{
         "resource":{"elements":{"path":"/public/finance"}},
         
"accessType":"write","user":"guest","userGroups":[],"requestData":"write_execute
 /public/finance",
-        "context": {"ACCESSTYPES": [ "write",  "execute" ]}
+        "context": {"ALLACCESSTYPEGROUPS": [ ["write"],  ["execute"] ], 
"ALLACCESSTYPES": [ "write", "execute"]}
       },
       "result":{"isAudited":true,"isAllowed":false,"policyId":4}
     },
@@ -122,7 +119,7 @@
       "request":{
         "resource":{"elements":{"path":"/public/finance"}},
         
"accessType":"read","user":"finance","userGroups":[],"requestData":"read_execute
 /public/finance",
-        "context": {"ACCESSTYPES": [ "read",  "execute" ]}
+        "context": {"ALLACCESSTYPEGROUPS": [ ["read"],  ["execute"] ], 
"ALLACCESSTYPES": [ "read", "execute"]}
 
       },
       "result":{"isAudited":true,"isAllowed":true,"policyId":3}
@@ -132,7 +129,7 @@
       "request":{
         "resource":{"elements":{"path":"/public/finance"}},
         
"accessType":"read","user":"hr","userGroups":[],"requestData":"read_execute 
/public/finance",
-        "context": {"ACCESSTYPES": [ "read",  "execute" ]}
+        "context": {"ALLACCESSTYPEGROUPS": [ ["read"],  ["execute"] ], 
"ALLACCESSTYPES": [ "read", "execute"]}
 
       },
       "result":{"isAudited":true,"isAllowed":false,"policyId":-1}
diff --git 
a/hdfs-agent/src/main/java/org/apache/ranger/authorization/hadoop/RangerHdfsAuthorizer.java
 
b/hdfs-agent/src/main/java/org/apache/ranger/authorization/hadoop/RangerHdfsAuthorizer.java
index c892bced3..e226da8a5 100644
--- 
a/hdfs-agent/src/main/java/org/apache/ranger/authorization/hadoop/RangerHdfsAuthorizer.java
+++ 
b/hdfs-agent/src/main/java/org/apache/ranger/authorization/hadoop/RangerHdfsAuthorizer.java
@@ -19,6 +19,7 @@
 
 package org.apache.ranger.authorization.hadoop;
 
+import static java.util.stream.Collectors.toSet;
 import static 
org.apache.ranger.authorization.hadoop.constants.RangerHadoopConstants.EXECUTE_ACCCESS_TYPE;
 import static 
org.apache.ranger.authorization.hadoop.constants.RangerHadoopConstants.HDFS_ROOT_FOLDER_PATH;
 import static 
org.apache.ranger.authorization.hadoop.constants.RangerHadoopConstants.READ_ACCCESS_TYPE;
@@ -32,13 +33,17 @@ import static 
org.apache.ranger.authorization.hadoop.constants.RangerHadoopConst
 
 import java.net.InetAddress;
 import java.security.SecureRandom;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.Stack;
+import java.util.TreeSet;
 import java.util.Objects;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.ArrayUtils;
@@ -143,14 +148,22 @@ public class RangerHdfsAuthorizer extends 
INodeAttributeProvider {
 
                LOG.info("Legacy way of authorizing sub-access requests will " 
+ (plugin.isUseLegacySubAccessAuthorization() ? "" : "not ") + "be used");
 
-               access2ActionListMapper.put(FsAction.NONE,          new 
HashSet<String>());
-               access2ActionListMapper.put(FsAction.ALL,           
Sets.newHashSet(READ_ACCCESS_TYPE, WRITE_ACCCESS_TYPE, EXECUTE_ACCCESS_TYPE));
-               access2ActionListMapper.put(FsAction.READ,          
Sets.newHashSet(READ_ACCCESS_TYPE));
-               access2ActionListMapper.put(FsAction.READ_WRITE,    
Sets.newHashSet(READ_ACCCESS_TYPE, WRITE_ACCCESS_TYPE));
-               access2ActionListMapper.put(FsAction.READ_EXECUTE,  
Sets.newHashSet(READ_ACCCESS_TYPE, EXECUTE_ACCCESS_TYPE));
-               access2ActionListMapper.put(FsAction.WRITE,         
Sets.newHashSet(WRITE_ACCCESS_TYPE));
-               access2ActionListMapper.put(FsAction.WRITE_EXECUTE, 
Sets.newHashSet(WRITE_ACCCESS_TYPE, EXECUTE_ACCCESS_TYPE));
-               access2ActionListMapper.put(FsAction.EXECUTE,       
Sets.newHashSet(EXECUTE_ACCCESS_TYPE));
+               access2ActionListMapper.put(FsAction.NONE,
+                                                                       new 
TreeSet<String>());
+               access2ActionListMapper.put(FsAction.ALL,
+                                                                       
Stream.of(READ_ACCCESS_TYPE, WRITE_ACCCESS_TYPE, 
EXECUTE_ACCCESS_TYPE).collect(Collectors.toCollection(() -> new 
TreeSet<>(String.CASE_INSENSITIVE_ORDER))));
+               access2ActionListMapper.put(FsAction.READ,
+                                                                       
Stream.of(READ_ACCCESS_TYPE).collect(Collectors.toCollection(() -> new 
TreeSet<>(String.CASE_INSENSITIVE_ORDER))));
+               access2ActionListMapper.put(FsAction.READ_WRITE,
+                                                                       
Stream.of(READ_ACCCESS_TYPE, 
WRITE_ACCCESS_TYPE).collect(Collectors.toCollection(() -> new 
TreeSet<>(String.CASE_INSENSITIVE_ORDER))));
+               access2ActionListMapper.put(FsAction.READ_EXECUTE,
+                                                                       
Stream.of(READ_ACCCESS_TYPE, 
EXECUTE_ACCCESS_TYPE).collect(Collectors.toCollection(() -> new 
TreeSet<>(String.CASE_INSENSITIVE_ORDER))));
+               access2ActionListMapper.put(FsAction.WRITE,
+                                                                       
Stream.of(WRITE_ACCCESS_TYPE).collect(Collectors.toCollection(() -> new 
TreeSet<>(String.CASE_INSENSITIVE_ORDER))));
+               access2ActionListMapper.put(FsAction.WRITE_EXECUTE,
+                                                                       
Stream.of(WRITE_ACCCESS_TYPE, 
EXECUTE_ACCCESS_TYPE).collect(Collectors.toCollection(() -> new 
TreeSet<>(String.CASE_INSENSITIVE_ORDER))));
+               access2ActionListMapper.put(FsAction.EXECUTE,
+                                                                       
Stream.of(EXECUTE_ACCCESS_TYPE).collect(Collectors.toCollection(() -> new 
TreeSet<>(String.CASE_INSENSITIVE_ORDER))));
 
                rangerPlugin = plugin;
 
@@ -882,6 +895,9 @@ public class RangerHdfsAuthorizer extends 
INodeAttributeProvider {
                                RangerHdfsAccessRequest request = new 
RangerHdfsAccessRequest(inode, path, pathOwner, access, 
accessTypes.iterator().next(), context.operationName, context.user, 
context.userGroups);
 
                                if (accessTypes.size() > 1) {
+                                       Set<Set<String>> allAccessTypeGroups = 
accessTypes.stream().map(Collections::singleton).collect(toSet());
+
+                                       
RangerAccessRequestUtil.setAllRequestedAccessTypeGroups(request, 
allAccessTypeGroups);
                                        
RangerAccessRequestUtil.setAllRequestedAccessTypes(request.getContext(), 
accessTypes);
                                }
 
@@ -959,6 +975,9 @@ public class RangerHdfsAuthorizer extends 
INodeAttributeProvider {
                                        RangerHdfsAccessRequest request = new 
RangerHdfsAccessRequest(null, subDirPath, pathOwner, access, 
accessTypes.iterator().next(), context.operationName, context.user, 
context.userGroups);
 
                                        if (accessTypes.size() > 1) {
+                                               Set<Set<String>> 
allAccessTypeGroups = 
accessTypes.stream().map(Collections::singleton).collect(toSet());
+
+                                               
RangerAccessRequestUtil.setAllRequestedAccessTypeGroups(request, 
allAccessTypeGroups);
                                                
RangerAccessRequestUtil.setAllRequestedAccessTypes(request.getContext(), 
accessTypes);
                                        }
 


Reply via email to