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);
}