You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ab...@apache.org on 2021/09/04 00:33:42 UTC
[ranger] branch ranger-2.2 updated: RANGER-3397: Update ACL
computation to (optionally) expand Ranger Roles to users and groups and
include chained-plugins in ACL computation
This is an automated email from the ASF dual-hosted git repository.
abhay pushed a commit to branch ranger-2.2
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/ranger-2.2 by this push:
new 218c06f RANGER-3397: Update ACL computation to (optionally) expand Ranger Roles to users and groups and include chained-plugins in ACL computation
218c06f is described below
commit 218c06ff54f389a2ee57d80e156ecbf7364a51ec
Author: Abhay Kulkarni <ab...@apache.org>
AuthorDate: Fri Sep 3 16:50:29 2021 -0700
RANGER-3397: Update ACL computation to (optionally) expand Ranger Roles to users and groups and include chained-plugins in ACL computation
---
.../plugin/policyengine/RangerPolicyEngine.java | 2 +
.../policyengine/RangerPolicyEngineImpl.java | 23 ++--
.../policyengine/RangerPolicyEngineOptions.java | 11 +-
.../RangerDefaultPolicyEvaluator.java | 131 ++++++++++++++++---
.../policyevaluator/RangerPolicyEvaluator.java | 8 +-
.../ranger/plugin/service/RangerBasePlugin.java | 127 +++++++++++++++++-
.../ranger/plugin/service/RangerChainedPlugin.java | 7 +
.../apache/ranger/plugin/util/RangerRolesUtil.java | 64 ++++++----
.../ranger/plugin/policyengine/TestPolicyACLs.java | 14 +-
.../policyengine/test_aclprovider_hdfs.json | 131 +++++++++++++++++++
.../aclprovider/test_aclprovider_default.json | 142 +++++++++++++++++++++
11 files changed, 597 insertions(+), 63 deletions(-)
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
index 7a4bb12..7bf8c7c 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
@@ -70,6 +70,8 @@ public interface RangerPolicyEngine {
RangerResourceACLs getResourceACLs(RangerAccessRequest request);
+ RangerResourceACLs getResourceACLs(RangerAccessRequest request, Integer requestedPolicyType);
+
Set<String> getRolesFromUserAndGroups(String user, Set<String> groups);
RangerRoles getRangerRoles();
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 9e0a89e..c92b550 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
@@ -243,8 +243,13 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
@Override
public RangerResourceACLs getResourceACLs(RangerAccessRequest request) {
+ return getResourceACLs(request, null);
+ }
+
+ @Override
+ public RangerResourceACLs getResourceACLs(RangerAccessRequest request, Integer requestedPolicyType) {
if (LOG.isDebugEnabled()) {
- LOG.debug("==> RangerPolicyEngineImpl.getResourceACLs(request=" + request + ")");
+ LOG.debug("==> RangerPolicyEngineImpl.getResourceACLs(request=" + request + ", policyType=" + requestedPolicyType + ")");
}
RangerResourceACLs ret = new RangerResourceACLs();
@@ -269,7 +274,10 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
LOG.debug("zoneName:[" + zoneName + "]");
}
- for (int policyType : RangerPolicy.POLICY_TYPES) {
+ int[] policyTypes = requestedPolicyType == null ? RangerPolicy.POLICY_TYPES : new int[] { requestedPolicyType };
+
+
+ for (int policyType : policyTypes) {
List<RangerPolicyEvaluator> allEvaluators = new ArrayList<>();
Map<Long, MatchType> tagMatchTypeMap = new HashMap<>();
Set<Long> policyIdForTemporalTags = new HashSet<>();
@@ -331,7 +339,7 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
RangerPerfTracer.logAlways(perf);
if (LOG.isDebugEnabled()) {
- LOG.debug("<== RangerPolicyEngineImpl.getResourceACLs(request=" + request + ") : ret=" + ret);
+ LOG.debug("<== RangerPolicyEngineImpl.getResourceACLs(request=" + request + ", policyType=" + requestedPolicyType + ") : ret=" + ret);
}
return ret;
@@ -773,7 +781,6 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
if (ret.getIsAuditedDetermined() && ret.getIsAccessDetermined()) {
break; // Break out of policy-evaluation loop
}
-
}
if (!ret.getIsAccessDetermined()) {
@@ -1136,6 +1143,10 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
return ret;
}
+ private boolean getIsFallbackSupported() {
+ return policyEngine.getPluginContext().getConfig().getIsFallbackSupported();
+ }
+
private void updateFromPolicyACLs(RangerPolicyEvaluator evaluator, Set<Long> policyIdForTemporalTags, RangerResourceACLs resourceACLs) {
PolicyACLSummary aclSummary = evaluator.getPolicyACLSummary();
@@ -1248,10 +1259,6 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
}
}
- private boolean getIsFallbackSupported() {
- return policyEngine.getPluginContext().getConfig().getIsFallbackSupported();
- }
-
private static class ServiceConfig {
private final Set<String> auditExcludedUsers;
private final Set<String> auditExcludedGroups;
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineOptions.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineOptions.java
index 0816ec1..07d0a39 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineOptions.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineOptions.java
@@ -36,6 +36,7 @@ public class RangerPolicyEngineOptions {
public boolean enableTagEnricherWithLocalRefresher = false;
public boolean disableAccessEvaluationWithPolicyACLSummary = true;
public boolean optimizeTrieForRetrieval = false;
+ public boolean disableRoleResolution = true;
private RangerServiceDefHelper serviceDefHelper;
@@ -53,6 +54,7 @@ public class RangerPolicyEngineOptions {
this.enableTagEnricherWithLocalRefresher = other.enableTagEnricherWithLocalRefresher;
this.disableAccessEvaluationWithPolicyACLSummary = other.disableAccessEvaluationWithPolicyACLSummary;
this.optimizeTrieForRetrieval = other.optimizeTrieForRetrieval;
+ this.disableRoleResolution = other.disableRoleResolution;
this.serviceDefHelper = null;
}
@@ -73,6 +75,7 @@ public class RangerPolicyEngineOptions {
enableTagEnricherWithLocalRefresher = false;
disableAccessEvaluationWithPolicyACLSummary = conf.getBoolean(propertyPrefix + ".policyengine.option.disable.access.evaluation.with.policy.acl.summary", true);
optimizeTrieForRetrieval = conf.getBoolean(propertyPrefix + ".policyengine.option.optimize.trie.for.retrieval", false);
+ disableRoleResolution = conf.getBoolean(propertyPrefix + ".policyengine.option.disable.role.resolution", true);
}
@@ -89,6 +92,7 @@ public class RangerPolicyEngineOptions {
enableTagEnricherWithLocalRefresher = false;
disableAccessEvaluationWithPolicyACLSummary = conf.getBoolean(propertyPrefix + ".policyengine.option.disable.access.evaluation.with.policy.acl.summary", true);
optimizeTrieForRetrieval = conf.getBoolean(propertyPrefix + ".policyengine.option.optimize.trie.for.retrieval", false);
+ disableRoleResolution = conf.getBoolean(propertyPrefix + ".policyengine.option.disable.role.resolution", true);
}
@@ -150,7 +154,8 @@ public class RangerPolicyEngineOptions {
&& this.cacheAuditResults == that.cacheAuditResults
&& this.evaluateDelegateAdminOnly == that.evaluateDelegateAdminOnly
&& this.enableTagEnricherWithLocalRefresher == that.enableTagEnricherWithLocalRefresher
- && this.optimizeTrieForRetrieval == that.optimizeTrieForRetrieval;
+ && this.optimizeTrieForRetrieval == that.optimizeTrieForRetrieval
+ && this.disableRoleResolution == that.disableRoleResolution;
}
return ret;
}
@@ -178,7 +183,8 @@ public class RangerPolicyEngineOptions {
ret *= 2;
ret += optimizeTrieForRetrieval ? 1 : 0;
ret *= 2;
- return ret;
+ ret += disableRoleResolution ? 1 : 0;
+ ret *= 2; return ret;
}
@Override
@@ -195,6 +201,7 @@ public class RangerPolicyEngineOptions {
", disableTrieLookupPrefilter: " + disableTrieLookupPrefilter +
", optimizeTrieForRetrieval: " + optimizeTrieForRetrieval +
", cacheAuditResult: " + cacheAuditResults +
+ ", disableRoleResolution: " + disableRoleResolution +
" }";
}
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 8c08d0e..8471918 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
@@ -81,6 +81,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
private String perfTag;
private PolicyACLSummary aclSummary = null;
private boolean useAclSummaryForEvaluation = false;
+ private boolean disableRoleResolution = true;
protected boolean needsDynamicEval() { return resourceMatcher != null && resourceMatcher.getNeedsDynamicEval(); }
@@ -160,7 +161,6 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
allowExceptionEvaluators = Collections.<RangerPolicyItemEvaluator>emptyList();
denyExceptionEvaluators = Collections.<RangerPolicyItemEvaluator>emptyList();
}
-
}
dataMaskEvaluators = createDataMaskPolicyItemEvaluators(policy, serviceDef, options, policy.getDataMaskPolicyItems());
@@ -544,51 +544,58 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
perf = RangerPerfTracer.getPerfTracer(PERF_POLICY_INIT_ACLSUMMARY_LOG, "RangerPolicyEvaluator.init.ACLSummary(" + perfTag + ")");
}
- final boolean hasNonPublicGroupOrConditionsInAllowExceptions = hasNonPublicGroupOrConditions(getPolicy().getAllowExceptions());
- final boolean hasNonPublicGroupOrConditionsInDenyExceptions = hasNonPublicGroupOrConditions(getPolicy().getDenyExceptions());
- final boolean hasPublicGroupInAllowAndUsersInAllowExceptions = hasPublicGroupAndUserInException(getPolicy().getPolicyItems(), getPolicy().getAllowExceptions());
- final boolean hasPublicGroupInDenyAndUsersInDenyExceptions = hasPublicGroupAndUserInException(getPolicy().getDenyPolicyItems(), getPolicy().getDenyExceptions());
+ RangerPolicy policy;
+ if (!disableRoleResolution && hasRoles(getPolicy())) {
+ policy = getPolicyWithRolesResolved(getPolicy());
+ } else {
+ policy = getPolicy();
+ }
+
+ final boolean hasNonPublicGroupOrConditionsInAllowExceptions = hasNonPublicGroupOrConditions(policy.getAllowExceptions());
+ final boolean hasNonPublicGroupOrConditionsInDenyExceptions = hasNonPublicGroupOrConditions(policy.getDenyExceptions());
+ final boolean hasPublicGroupInAllowAndUsersInAllowExceptions = hasPublicGroupAndUserInException(policy.getPolicyItems(), policy.getAllowExceptions());
+ final boolean hasPublicGroupInDenyAndUsersInDenyExceptions = hasPublicGroupAndUserInException(policy.getDenyPolicyItems(), policy.getDenyExceptions());
final boolean hasContextSensitiveSpecification = hasContextSensitiveSpecification();
- final boolean hasRoles = hasRoles();
+ final boolean hasRoles = hasRoles(policy);
final boolean isUsableForEvaluation = !hasNonPublicGroupOrConditionsInAllowExceptions
&& !hasNonPublicGroupOrConditionsInDenyExceptions
&& !hasPublicGroupInAllowAndUsersInAllowExceptions
&& !hasPublicGroupInDenyAndUsersInDenyExceptions
- && !hasContextSensitiveSpecification
- && !hasRoles;
+ && !hasContextSensitiveSpecification
+ && !hasRoles;
if (isUsableForEvaluation || isCreationForced) {
ret = new PolicyACLSummary();
- for (RangerPolicyItem policyItem : getPolicy().getDenyPolicyItems()) {
+ for (RangerPolicyItem policyItem : policy.getDenyPolicyItems()) {
ret.processPolicyItem(policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY, hasNonPublicGroupOrConditionsInDenyExceptions || hasPublicGroupInDenyAndUsersInDenyExceptions);
}
if (!hasNonPublicGroupOrConditionsInDenyExceptions && !hasPublicGroupInDenyAndUsersInDenyExceptions) {
- for (RangerPolicyItem policyItem : getPolicy().getDenyExceptions()) {
+ for (RangerPolicyItem policyItem : policy.getDenyExceptions()) {
ret.processPolicyItem(policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS, false);
}
}
- for (RangerPolicyItem policyItem : getPolicy().getPolicyItems()) {
+ for (RangerPolicyItem policyItem : policy.getPolicyItems()) {
ret.processPolicyItem(policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW, hasNonPublicGroupOrConditionsInAllowExceptions || hasPublicGroupInAllowAndUsersInAllowExceptions);
}
if (!hasNonPublicGroupOrConditionsInAllowExceptions && !hasPublicGroupInAllowAndUsersInAllowExceptions) {
- for (RangerPolicyItem policyItem : getPolicy().getAllowExceptions()) {
+ for (RangerPolicyItem policyItem : policy.getAllowExceptions()) {
ret.processPolicyItem(policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS, false);
}
}
- for (RangerRowFilterPolicyItem policyItem : getPolicy().getRowFilterPolicyItems()) {
+ for (RangerRowFilterPolicyItem policyItem : policy.getRowFilterPolicyItems()) {
ret.processRowFilterPolicyItem(policyItem);
}
- for (RangerDataMaskPolicyItem policyItem : getPolicy().getDataMaskPolicyItems()) {
+ for (RangerDataMaskPolicyItem policyItem : policy.getDataMaskPolicyItems()) {
ret.processDataMaskPolicyItem(policyItem);
}
- final boolean isDenyAllElse = Boolean.TRUE.equals(getPolicy().getIsDenyAllElse());
+ final boolean isDenyAllElse = Boolean.TRUE.equals(policy.getIsDenyAllElse());
final Set<String> allAccessTypeNames;
@@ -612,6 +619,100 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
return ret;
}
+ private RangerPolicy getPolicyWithRolesResolved(final RangerPolicy policy) {
+ // Create new policy with no roles in it
+ // For each policyItem, expand roles into users and groups; and replace all policyItems with expanded roles - TBD
+
+ RangerPolicy ret = new RangerPolicy();
+ ret.updateFrom(policy);
+ ret.setId(policy.getId());
+ ret.setGuid(policy.getGuid());
+ ret.setVersion(policy.getVersion());
+
+ List<RangerPolicyItem> policyItems = new ArrayList<>();
+ List<RangerPolicyItem> denyPolicyItems = new ArrayList<>();
+ List<RangerPolicyItem> allowExceptions = new ArrayList<>();
+ List<RangerPolicyItem> denyExceptions = new ArrayList<>();
+ List<RangerDataMaskPolicyItem> dataMaskPolicyItems = new ArrayList<>();
+ List<RangerRowFilterPolicyItem> rowFilterPolicyItems = new ArrayList<>();
+
+ for (RangerPolicyItem policyItem : policy.getPolicyItems()) {
+ RangerPolicyItem newPolicyItem = new RangerPolicyItem(policyItem.getAccesses(), policyItem.getUsers(), policyItem.getGroups(), policyItem.getRoles(), policyItem.getConditions(), policyItem.getDelegateAdmin());
+ getPolicyItemWithRolesResolved(newPolicyItem, policyItem);
+
+ policyItems.add(newPolicyItem);
+ }
+ ret.setPolicyItems(policyItems);
+
+ for (RangerPolicyItem policyItem : policy.getDenyPolicyItems()) {
+ RangerPolicyItem newPolicyItem = new RangerPolicyItem(policyItem.getAccesses(), policyItem.getUsers(), policyItem.getGroups(), policyItem.getRoles(), policyItem.getConditions(), policyItem.getDelegateAdmin());
+ getPolicyItemWithRolesResolved(newPolicyItem, policyItem);
+
+ denyPolicyItems.add(newPolicyItem);
+ }
+ ret.setDenyPolicyItems(denyPolicyItems);
+
+ for (RangerPolicyItem policyItem : policy.getAllowExceptions()) {
+ RangerPolicyItem newPolicyItem = new RangerPolicyItem(policyItem.getAccesses(), policyItem.getUsers(), policyItem.getGroups(), policyItem.getRoles(), policyItem.getConditions(), policyItem.getDelegateAdmin());
+ getPolicyItemWithRolesResolved(newPolicyItem, policyItem);
+
+ allowExceptions.add(newPolicyItem);
+ }
+ ret.setAllowExceptions(allowExceptions);
+
+ for (RangerPolicyItem policyItem : policy.getDenyExceptions()) {
+ RangerPolicyItem newPolicyItem = new RangerPolicyItem(policyItem.getAccesses(), policyItem.getUsers(), policyItem.getGroups(), policyItem.getRoles(), policyItem.getConditions(), policyItem.getDelegateAdmin());
+ getPolicyItemWithRolesResolved(newPolicyItem, policyItem);
+
+ denyExceptions.add(newPolicyItem);
+ }
+ ret.setDenyExceptions(denyExceptions);
+
+ for (RangerDataMaskPolicyItem policyItem : policy.getDataMaskPolicyItems()) {
+ RangerDataMaskPolicyItem newPolicyItem = new RangerDataMaskPolicyItem(policyItem.getAccesses(), policyItem.getDataMaskInfo(), policyItem.getUsers(), policyItem.getGroups(), policyItem.getRoles(), policyItem.getConditions(), policyItem.getDelegateAdmin());
+ getPolicyItemWithRolesResolved(newPolicyItem, policyItem);
+
+ dataMaskPolicyItems.add(newPolicyItem);
+ }
+ ret.setDataMaskPolicyItems(dataMaskPolicyItems);
+
+ for (RangerRowFilterPolicyItem policyItem : policy.getRowFilterPolicyItems()) {
+ RangerRowFilterPolicyItem newPolicyItem = new RangerRowFilterPolicyItem(policyItem.getRowFilterInfo(), policyItem.getAccesses(), policyItem.getUsers(), policyItem.getGroups(), policyItem.getRoles(), policyItem.getConditions(), policyItem.getDelegateAdmin());
+ getPolicyItemWithRolesResolved(newPolicyItem, policyItem);
+
+ rowFilterPolicyItems.add(newPolicyItem);
+ }
+ ret.setRowFilterPolicyItems(rowFilterPolicyItems);
+
+ return ret;
+ }
+
+ private void getPolicyItemWithRolesResolved(RangerPolicyItem newPolicyItem, final RangerPolicyItem policyItem) {
+ Set<String> usersFromRoles = new HashSet<>();
+ Set<String> groupsFromRoles = new HashSet<>();
+
+ List<String> roles = policyItem.getRoles();
+
+ for (String role : roles) {
+ Set<String> users = getPluginContext().getAuthContext().getRangerRolesUtil().getRoleToUserMapping().get(role);
+ Set<String> groups = getPluginContext().getAuthContext().getRangerRolesUtil().getRoleToGroupMapping().get(role);
+ if (CollectionUtils.isNotEmpty(users)) {
+ usersFromRoles.addAll(users);
+ }
+ if (CollectionUtils.isNotEmpty(groups)) {
+ groupsFromRoles.addAll(groups);
+ }
+ if (CollectionUtils.isNotEmpty(usersFromRoles) || CollectionUtils.isNotEmpty(groupsFromRoles)) {
+ usersFromRoles.addAll(policyItem.getUsers());
+ groupsFromRoles.addAll(policyItem.getGroups());
+
+ newPolicyItem.setUsers(new ArrayList<>(usersFromRoles));
+ newPolicyItem.setGroups(new ArrayList<>(groupsFromRoles));
+ newPolicyItem.setRoles(null);
+ }
+ }
+ }
+
private boolean hasPublicGroupAndUserInException(List<RangerPolicyItem> grants, List<RangerPolicyItem> exceptionItems) {
boolean ret = false;
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
index 0157c00..15a6465 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
@@ -55,8 +55,10 @@ import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatche
import static org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW;
import static org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS;
+import static org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATAMASK;
import static org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY;
import static org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS;
+import static org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ROWFILTER;
public interface RangerPolicyEvaluator extends RangerPolicyResourceEvaluator {
Comparator<RangerPolicyEvaluator> EVAL_ORDER_COMPARATOR = new RangerPolicyEvaluator.PolicyEvalOrderComparator();
@@ -140,9 +142,7 @@ public interface RangerPolicyEvaluator extends RangerPolicyResourceEvaluator {
return false;
}
- default boolean hasRoles() {
- RangerPolicy policy = getPolicy();
-
+ default boolean hasRoles(final RangerPolicy policy) {
for (RangerPolicyItem policyItem : policy.getPolicyItems()) {
if (hasRoles(policyItem)) {
return true;
@@ -297,7 +297,7 @@ public interface RangerPolicyEvaluator extends RangerPolicyResourceEvaluator {
void processPolicyItem(RangerPolicyItem policyItem, int policyItemType, boolean isConditional) {
final Integer result;
- final boolean hasContextSensitiveSpecification = RangerPolicyEvaluator.hasContextSensitiveSpecification(policyItem);
+ final boolean hasContextSensitiveSpecification = CollectionUtils.isNotEmpty(policyItem.getConditions());
switch (policyItemType) {
case POLICY_ITEM_TYPE_ALLOW:
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
index 7e0894d..3ad74e5 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
@@ -49,6 +49,7 @@ import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngineImpl;
import org.apache.ranger.plugin.policyengine.RangerResourceACLs;
import org.apache.ranger.plugin.policyengine.RangerResourceAccessInfo;
+import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.plugin.util.*;
@@ -539,13 +540,43 @@ public class RangerBasePlugin {
}
public RangerResourceACLs getResourceACLs(RangerAccessRequest request) {
+ return getResourceACLs(request, null);
+ }
+
+ public RangerResourceACLs getResourceACLs(RangerAccessRequest request, Integer policyType) {
+ RangerResourceACLs ret = null;
RangerPolicyEngine policyEngine = this.policyEngine;
if(policyEngine != null) {
- return policyEngine.getResourceACLs(request);
+ ret = policyEngine.getResourceACLs(request, policyType);
}
- return null;
+ for (RangerChainedPlugin chainedPlugin : chainedPlugins) {
+ RangerResourceACLs chainedResourceACLs = chainedPlugin.getResourceACLs(request, policyType);
+
+ if (chainedResourceACLs != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Chained-plugin returned non-null ACLs!!");
+ }
+ if (chainedPlugin.isAuthorizeOnlyWithChainedPlugin()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Chained-plugin is configured to ignore Base-plugin's ACLs");
+ }
+ ret = chainedResourceACLs;
+ break;
+ } else {
+ if (ret != null) {
+ ret = getMergedResourceACLs(ret, chainedResourceACLs);
+ }
+ }
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Chained-plugin returned null ACLs!!");
+ }
+ }
+ }
+
+ return ret;
}
public Set<String> getRolesFromUserAndGroups(String user, Set<String> groups) {
@@ -1035,6 +1066,98 @@ public class RangerBasePlugin {
}
}
+ private RangerResourceACLs getMergedResourceACLs(RangerResourceACLs baseACLs, RangerResourceACLs chainedACLs) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerBasePlugin.getMergedResourceACLs()");
+ LOG.debug("baseACLs:[" + baseACLs + "]");
+ LOG.debug("chainedACLS:[" + chainedACLs + "]");
+ }
+
+ overrideACLs(chainedACLs, baseACLs, RangerRolesUtil.ROLES_FOR.USER);
+ overrideACLs(chainedACLs, baseACLs, RangerRolesUtil.ROLES_FOR.GROUP);
+ overrideACLs(chainedACLs, baseACLs, RangerRolesUtil.ROLES_FOR.ROLE);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerBasePlugin.getMergedResourceACLs() : ret:[" + baseACLs + "]");
+ }
+ return baseACLs;
+ }
+
+ private void overrideACLs(final RangerResourceACLs chainedResourceACLs, RangerResourceACLs baseResourceACLs, final RangerRolesUtil.ROLES_FOR userType) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerBasePlugin.overrideACLs(isUser=" + userType.name() + ")");
+ }
+ Map<String, Map<String, RangerResourceACLs.AccessResult>> chainedACLs = null;
+ Map<String, Map<String, RangerResourceACLs.AccessResult>> baseACLs = null;
+
+ switch (userType) {
+ case USER:
+ chainedACLs = chainedResourceACLs.getUserACLs();
+ baseACLs = baseResourceACLs.getUserACLs();
+ break;
+ case GROUP:
+ chainedACLs = chainedResourceACLs.getGroupACLs();
+ baseACLs = baseResourceACLs.getGroupACLs();
+ break;
+ case ROLE:
+ chainedACLs = chainedResourceACLs.getRoleACLs();
+ baseACLs = baseResourceACLs.getRoleACLs();
+ break;
+ default:
+ break;
+ }
+
+ for (Map.Entry<String, Map<String, RangerResourceACLs.AccessResult>> chainedPermissionsMap : chainedACLs.entrySet()) {
+ String name = chainedPermissionsMap.getKey();
+ Map<String, RangerResourceACLs.AccessResult> chainedPermissions = chainedPermissionsMap.getValue();
+ Map<String, RangerResourceACLs.AccessResult> basePermissions = baseACLs.get(name);
+
+ for (Map.Entry<String, RangerResourceACLs.AccessResult> chainedPermission : chainedPermissions.entrySet()) {
+ String chainedAccessType = chainedPermission.getKey();
+ RangerResourceACLs.AccessResult chainedAccessResult = chainedPermission.getValue();
+ RangerResourceACLs.AccessResult baseAccessResult = basePermissions == null ? null : basePermissions.get(chainedAccessType);
+
+ final boolean useChainedAccessResult;
+
+ if (baseAccessResult == null) {
+ useChainedAccessResult = true;
+ } else {
+ if (chainedAccessResult.getPolicy().getPolicyPriority() > baseAccessResult.getPolicy().getPolicyPriority()) {
+ useChainedAccessResult = true;
+ } else if (chainedAccessResult.getPolicy().getPolicyPriority().equals(baseAccessResult.getPolicy().getPolicyPriority())) {
+ if (chainedAccessResult.getResult() == baseAccessResult.getResult()) {
+ useChainedAccessResult = true;
+ } else {
+ useChainedAccessResult = chainedAccessResult.getResult() == RangerPolicyEvaluator.ACCESS_DENIED;
+ }
+ } else { // chainedAccessResult.getPolicy().getPolicyPriority() < baseAccessResult.getPolicy().getPolicyPriority()
+ useChainedAccessResult = false;
+ }
+ }
+
+ final RangerResourceACLs.AccessResult finalAccessResult = useChainedAccessResult ? chainedAccessResult : baseAccessResult;
+
+ switch (userType) {
+ case USER:
+ baseResourceACLs.setUserAccessInfo(name, chainedAccessType, finalAccessResult.getResult(), finalAccessResult.getPolicy());
+ break;
+ case GROUP:
+ baseResourceACLs.setGroupAccessInfo(name, chainedAccessType, finalAccessResult.getResult(), finalAccessResult.getPolicy());
+ break;
+ case ROLE:
+ baseResourceACLs.setRoleAccessInfo(name, chainedAccessType, finalAccessResult.getResult(), finalAccessResult.getPolicy());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerBasePlugin.mergeACLsOneWay(isUser=" + userType.name() + ")");
+ }
+ }
+
private static AuditProviderFactory getAuditProviderFactory(String serviceName) {
AuditProviderFactory ret = AuditProviderFactory.getInstance();
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerChainedPlugin.java b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerChainedPlugin.java
index 0fca2d9..7a48a09 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerChainedPlugin.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerChainedPlugin.java
@@ -23,6 +23,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+import org.apache.ranger.plugin.policyengine.RangerResourceACLs;
import java.util.Collection;
@@ -59,4 +60,10 @@ public abstract class RangerChainedPlugin {
public abstract Collection<RangerAccessResult> isAccessAllowed(Collection<RangerAccessRequest> requests);
+ public abstract RangerResourceACLs getResourceACLs(RangerAccessRequest request);
+
+ public abstract RangerResourceACLs getResourceACLs(RangerAccessRequest request, Integer policyType);
+
+ public boolean isAuthorizeOnlyWithChainedPlugin() { return false; }
+
}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRolesUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRolesUtil.java
index a6e461c..f785e11 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRolesUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRolesUtil.java
@@ -34,8 +34,12 @@ public class RangerRolesUtil {
private final Map<String, Set<String>> userRoleMapping = new HashMap<>();
private final Map<String, Set<String>> groupRoleMapping = new HashMap<>();
private final Map<String, Set<String>> roleRoleMapping = new HashMap<>();
+
+ private final Map<String, Set<String>> roleToUserMapping = new HashMap<>();
+ private final Map<String, Set<String>> roleToGroupMapping = new HashMap<>();
+
private RangerRoles roles = null;
- private enum ROLES_FOR {USER, GROUP, ROLE};
+ public enum ROLES_FOR {USER, GROUP, ROLE}
public RangerRolesUtil(RangerRoles roles) {
if (roles != null) {
@@ -49,7 +53,22 @@ public class RangerRolesUtil {
buildMap(userRoleMapping, role, containedRoles, ROLES_FOR.USER);
buildMap(groupRoleMapping, role, containedRoles, ROLES_FOR.GROUP);
buildMap(roleRoleMapping, role, containedRoles, ROLES_FOR.ROLE);
+
+ Set<String> roleUsers = new HashSet<>();
+ Set<String> roleGroups = new HashSet<>();
+
+ addMemberNames(role.getUsers(), roleUsers);
+ addMemberNames(role.getGroups(), roleGroups);
+
+ for (RangerRole containedRole : containedRoles) {
+ addMemberNames(containedRole.getUsers(), roleUsers);
+ addMemberNames(containedRole.getGroups(), roleGroups);
+ }
+
+ roleToUserMapping.put(role.getName(), roleUsers);
+ roleToGroupMapping.put(role.getName(), roleGroups);
}
+
}
} else {
roleVersion = -1L;
@@ -74,6 +93,14 @@ public class RangerRolesUtil {
return this.roleRoleMapping;
}
+ public Map<String, Set<String>> getRoleToUserMapping() {
+ return this.roleToUserMapping;
+ }
+
+ public Map<String, Set<String>> getRoleToGroupMapping() {
+ return this.roleToGroupMapping;
+ }
+
private Set<RangerRole> getAllContainedRoles(Set<RangerRole> roles, RangerRole role) {
Set<RangerRole> allRoles = new HashSet<>();
@@ -104,22 +131,6 @@ public class RangerRolesUtil {
}
}
- private void buildMap(Map<String, Set<String>> map, RangerRole role, String roleName, boolean isUser) {
- for (RangerRole.RoleMember userOrGroup : isUser ? role.getUsers() : role.getGroups()) {
- if (StringUtils.isNotEmpty(userOrGroup.getName())) {
- Set<String> roleNames = map.get(userOrGroup.getName());
-
- if (roleNames == null) {
- roleNames = new HashSet<>();
-
- map.put(userOrGroup.getName(), roleNames);
- }
-
- roleNames.add(roleName);
- }
- }
- }
-
private void buildMap(Map<String, Set<String>> map, RangerRole role, String roleName, ROLES_FOR roles_for) {
List<RangerRole.RoleMember> userOrGroupOrRole = null;
switch(roles_for) {
@@ -141,23 +152,20 @@ public class RangerRolesUtil {
private void getRoleMap(Map<String, Set<String>> map, String roleName, List<RangerRole.RoleMember> userOrGroupOrRole) {
for (RangerRole.RoleMember roleMember : userOrGroupOrRole) {
if (StringUtils.isNotEmpty(roleMember.getName())) {
- Set<String> roleNames = map.get(roleMember.getName());
- if (roleNames == null) {
- roleNames = new HashSet<>();
-
- map.put(roleMember.getName(), roleNames);
- }
+ Set<String> roleNames = map.computeIfAbsent(roleMember.getName(), k -> new HashSet<>());
roleNames.add(roleName);
}
}
}
private RangerRole getContainedRole(Set<RangerRole> roles, String role) {
- return (roles
- .stream()
- .filter(containedRole -> role.equals(containedRole.getName()))
- .findAny()
- .orElse(null));
+ return (roles.stream().filter(containedRole -> role.equals(containedRole.getName())).findAny().orElse(null));
+ }
+
+ private void addMemberNames(List<RangerRole.RoleMember> members, Set<String> names) {
+ for (RangerRole.RoleMember member : members) {
+ names.add(member.getName());
+ }
}
}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyACLs.java b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyACLs.java
index d2983a2..b6135b0 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyACLs.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyACLs.java
@@ -86,6 +86,13 @@ public class TestPolicyACLs {
runTestsFromResourceFiles(tests);
}
+ @Test
+ public void testResourceACLs_hdfs() throws Exception {
+ String[] tests = {"/policyengine/test_aclprovider_hdfs.json"};
+
+ runTestsFromResourceFiles(tests);
+ }
+
private void runTestsFromResourceFiles(String[] resourceNames) throws Exception {
for(String resourceName : resourceNames) {
InputStream inStream = this.getClass().getResourceAsStream(resourceName);
@@ -101,8 +108,9 @@ public class TestPolicyACLs {
assertTrue("invalid input: " + testName, testCases != null && testCases.testCases != null);
for(PolicyACLsTests.TestCase testCase : testCases.testCases) {
+ String serviceType = testCase.servicePolicies.getServiceDef().getName();
RangerPolicyEngineOptions policyEngineOptions = new RangerPolicyEngineOptions();
- RangerPluginContext pluginContext = new RangerPluginContext(new RangerPluginConfig("hive", null, "test-policy-acls", "cl1", "on-prem", policyEngineOptions));
+ RangerPluginContext pluginContext = new RangerPluginContext(new RangerPluginConfig(serviceType, null, "test-policy-acls", "cl1", "on-prem", policyEngineOptions));
RangerPolicyEngine policyEngine = new RangerPolicyEngineImpl(testCase.servicePolicies, pluginContext, null);
for(PolicyACLsTests.TestCase.OneTest oneTest : testCase.tests) {
@@ -259,9 +267,7 @@ public class TestPolicyACLs {
} else if (!(MapUtils.isEmpty(acls.getRoleACLs()) && MapUtils.isEmpty(oneTest.rolePermissions))) {
roleACLsMatched = false;
}
-
- assertTrue("getResourceACLs() failed! " + testCase.name + ":" + oneTest.name + " - userACLsMatched=" + userACLsMatched + "; groupACLsMatched=" + groupACLsMatched + "; roleACLsMatched=" + roleACLsMatched + "; rowFiltersMatched=" + rowFiltersMatched + "; dataMaskingMatched=" + dataMaskingMatched,
- userACLsMatched && groupACLsMatched && roleACLsMatched && rowFiltersMatched && dataMaskingMatched);
+ assertTrue("getResourceACLs() failed! " + testCase.name + ":" + oneTest.name, userACLsMatched && groupACLsMatched && roleACLsMatched && rowFiltersMatched && dataMaskingMatched);
}
}
}
diff --git a/agents-common/src/test/resources/policyengine/test_aclprovider_hdfs.json b/agents-common/src/test/resources/policyengine/test_aclprovider_hdfs.json
new file mode 100644
index 0000000..9526763
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/test_aclprovider_hdfs.json
@@ -0,0 +1,131 @@
+{
+ "testCases": [
+ {
+ "name": "Test-ACL-Provider-for-HDFS",
+
+ "servicePolicies": {
+ "serviceName": "hivedev",
+ "serviceDef": {
+ "name": "hdfs",
+ "id": 1,
+ "resources": [
+ {
+ "name": "path",
+ "type": "path",
+ "level": 1,
+ "mandatory": true,
+ "lookupSupported": true,
+ "matcher": "org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher",
+ "matcherOptions": {
+ "wildCard": true,
+ "ignoreCase": true
+ },
+ "label": "Resource Path",
+ "description": "HDFS file or directory path"
+ }
+ ],
+ "accessTypes": [
+ {
+ "name": "read",
+ "label": "Read"
+ },
+ {
+ "name": "write",
+ "label": "Write"
+ },
+ {
+ "name": "execute",
+ "label": "Execute"
+ }
+ ],
+ "contextEnrichers": [
+ {
+ "itemId": 1,
+ "name": "GeolocationEnricher",
+ "enricher": "org.apache.ranger.plugin.contextenricher.RangerFileBasedGeolocationProvider",
+ "enricherOptions": {
+ "FilePath": "/etc/ranger/geo/geo.txt",
+ "ForceRead": "false",
+ "IPInDotFormat": "true",
+ "geolocation.meta.prefix": "TEST_"
+ }
+ }
+ ],
+ "policyConditions": [
+ {
+ "itemId": 1,
+ "name": "ScriptConditionEvaluator",
+ "evaluator": "org.apache.ranger.plugin.conditionevaluator.RangerScriptConditionEvaluator",
+ "evaluatorOptions": {
+ "engineName": "JavaScript"
+ },
+ "label": "Script",
+ "description": "Script to execute"
+ }
+ ]
+ },
+ "policies": [
+ {
+ "id": 1, "name": "audit-all-access under /finance/restricted/",
+ "resources": {
+ "path": {"values": ["/finance/restricted/"], "isRecursive": true}
+ },
+ "policyItems": [
+ {"accesses": [], "users": [], "groups": [ "public"]}
+ ]
+ },
+ {
+ "id": 2, "name": "allow-read-to-all under /public/",
+ "resources": {
+ "path": {"values": [ "/public/*" ], "isRecursive": true}
+ },
+ "policyItems": [
+ {"accesses": [{"type": "read", "isAllowed": true},{"type": "execute", "isAllowed": true}], "users": [], "groups": ["public"]}
+ ]
+ },
+ {
+ "id": 3, "name": "allow-read-to-finance under /finance/restricted",
+ "resources": {
+ "path": {"values": [ "/finance/restricted" ], "isRecursive": true}
+ },
+ "policyItems": [
+ {"accesses": [{"type": "read", "isAllowed": true}], "users": [], "groups": ["finance"]}
+ ]
+ },
+ {
+ "id": 4, "name": "allow-read-to-finance under /finance/limited",
+ "resources": {
+ "path": {"values": [ "/finance/limited"], "isRecursive": true}
+ },
+ "policyItems": [
+ {"accesses": [{"type": "read", "isAllowed": true}], "users": [], "groups": ["stewards"]}
+ ]
+ }
+ ]
+ },
+ "tests": [
+ {
+ "name": "test-finance-restricted",
+ "resource": {"elements":{"path":"/finance/restricted"}},
+ "userPermissions": {},
+ "groupPermissions": {"finance": {"read": {"result": 1, "isFinal": true}}},
+ "rolePermissions": {}
+ },
+ {
+ "name": "test-finance-limited",
+ "resource": {"elements":{"path":"/finance/limited"}},
+ "userPermissions": {},
+ "groupPermissions": {"stewards": {"read": {"result": 1, "isFinal": true}}},
+ "rolePermissions": {}
+ },
+ {
+ "name": "test-anything-under-public",
+ "resource": {"elements":{"path":"/public/anything"}},
+ "userPermissions": {},
+ "groupPermissions": {"public": {"read": {"result": 1, "isFinal": true}, "execute": {"result": 1, "isFinal": true}}},
+ "rolePermissions": {}
+ }
+ ]
+ }
+ ]
+}
diff --git a/hdfs-agent/src/test/resources/aclprovider/test_aclprovider_default.json b/hdfs-agent/src/test/resources/aclprovider/test_aclprovider_default.json
new file mode 100644
index 0000000..c345ec6
--- /dev/null
+++ b/hdfs-agent/src/test/resources/aclprovider/test_aclprovider_default.json
@@ -0,0 +1,142 @@
+{
+ "testCases": [
+ {
+ "name": "Test-ACL-Provider",
+ "roles" : { "serviceName": "hdfsdev", "roleVersion": 1,
+ "rangerRoles": [ { "name": "admin", "users": [{"name":"admin-1","isAdmin": false}, {"name":"admin-2", "isAdmin": false}], "groups" : [{"name":"admin-group-1", "isAdmin":false}, {"name":"admin-group-2", "isAdmin": false}], "roles": [{"name": "sub-admin-1","isAdmin":false}, {"name":"sub-admin-2", "isAdmin": false}] },
+ { "name": "sub-admin-1", "users": [{"name":"sub-admin-user-1", "isAdmin": false}], "groups" : [], "roles": [] },
+ { "name": "sub-admin-2", "users": [], "groups" : [{"name":"sub-admin-group-2", "isAdmin":false}], "roles": [] }
+ ]
+ },
+ "servicePolicies": {
+ "serviceName": "hdfsdev",
+ "serviceDef": {
+ "name": "hdfs", "id": 1,
+ "resources": [
+ {"name": "path", "type": "path", "level": 1, "mandatory": true, "lookupSupported": true,
+ "matcher": "org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher",
+ "matcherOptions": {"wildCard": true, "ignoreCase": true},
+ "label": "Resource Path", "description": "HDFS file or directory path"
+ }
+ ],
+ "accessTypes": [
+ {"name": "read", "label": "Read"},
+ {"name": "write", "label": "Write"},
+ {"name": "execute", "label": "Execute"}
+ ],
+ "contextEnrichers": [
+ {
+ "itemId": 1,
+ "name": "GeolocationEnricher",
+ "enricher": "org.apache.ranger.plugin.contextenricher.RangerFileBasedGeolocationProvider",
+ "enricherOptions": {"FilePath": "/etc/ranger/geo/geo.txt", "ForceRead": "false", "IPInDotFormat": "true", "geolocation.meta.prefix": "TEST_"}
+ }
+ ],
+ "policyConditions": [
+ {
+ "itemId": 1,
+ "name": "ScriptConditionEvaluator",
+ "evaluator": "org.apache.ranger.plugin.conditionevaluator.RangerScriptConditionEvaluator",
+ "evaluatorOptions": {"engineName": "JavaScript"},
+ "label": "Script",
+ "description": "Script to execute"
+ }
+ ]
+ },
+ "serviceConfig": {"ranger.plugin.hdfs.chained.service" : "mapped_hive", "ranger.plugin.hdfs.chained.service.mapped_hive.impl": "org.apache.ranger.chainedplugin.hdfs.hive.RangerHdfsHiveChainedPlugin"},
+ "policies": [
+ {
+ "id": 10,
+ "name": "allow-read-to-user1,user3 /test/restricted",
+ "isEnabled": true, "isAuditEnabled": true, "isDenyAllElse": true,
+ "resources": {"path": {"values": ["/test/restricted"], "isRecursive": true}},
+ "policyItems": [
+ { "accesses": [{"type": "read", "isAllowed": true}], "users": ["user1", "user2", "user3"], "groups": [], "roles":["sub-admin-1"],"delegateAdmin": false }
+ ],
+ "allowExceptions": [
+ { "accesses": [{"type": "read", "isAllowed": true}], "users": ["user2"], "groups": [], "delegateAdmin": false }
+ ]
+ },
+ {
+ "id": 20,
+ "name": "allow-read-to-user2 /test/restricted/a",
+ "isEnabled": true, "isAuditEnabled": true,
+ "resources": {"path": {"values": ["/test/restricted/a"],"isRecursive": true}},
+ "policyItems": [
+ { "accesses": [ {"type": "read", "isAllowed": true}, {"type": "write", "isAllowed": true} ], "users": ["user2", "non-user1", "non-user2", "non-user3"], "groups": ["public"], "delegateAdmin": false }
+ ],
+ "denyPolicyItems": [
+ { "accesses": [ {"type": "read", "isAllowed": true} ], "users": ["non-user4"], "groups": [], "delegateAdmin": false }
+ ]
+ },
+ {
+ "id": 30,
+ "name": "deny-read-to-user3 /test/restricted/b",
+ "isEnabled": true, "isAuditEnabled": true,
+ "resources": {"path": {"values": ["/test/restricted/b"], "isRecursive": true} },
+ "policyItems": [
+ { "accesses": [ {"type": "read", "isAllowed": true} ], "users": ["non-user5", "non-user6", "non-user7", "non-user8"], "groups": ["public"], "delegateAdmin": false, "conditions": [ { "type": "ScriptConditionEvaluator", "values": [ "var country_code = ctx.getRequestContextAttribute('LOCATION_TEST_COUNTRY_CODE'); ctx.result = !!country_code;" ] } ] }
+ ],
+ "denyPolicyItems": [
+ { "accesses": [ { "type": "read", "isAllowed": true } ], "users": [ "user3", "non-user9" ], "groups": [], "delegateAdmin": false }
+ ]
+ },
+ {
+ "id": 1,
+ "name": "audit-all-access under /finance/restricted",
+ "isEnabled": true, "isAuditEnabled": true,
+ "resources": { "path": { "values": [ "/finance/restricted" ], "isRecursive": true } },
+ "policyItems": [
+ { "accesses": [], "users": [], "groups": [ "public" ], "delegateAdmin": false }
+ ]
+ },
+ {
+ "id": 2,
+ "name": "allow-read-to-all under /public/*",
+ "isEnabled": true, "isAuditEnabled": false,
+ "resources": { "path": { "values": [ "/public/*" ], "isRecursive": true } },
+ "policyItems": [
+ { "accesses": [ { "type": "read", "isAllowed": true }, { "type": "execute", "isAllowed": true } ], "users": [], "groups": [ "public" ], "delegateAdmin": false }
+ ]
+ },
+ {
+ "id": 3,
+ "name": "allow-read-to-finance under /finance/restricted",
+ "isEnabled": true, "isAuditEnabled": true,
+ "resources": { "path": { "values": [ "/finance/restricted" ], "isRecursive": true } },
+ "policyItems": [
+ { "accesses": [ { "type": "read", "isAllowed": true } ], "users": [], "groups": [ "finance" ], "delegateAdmin": false, "conditions": [ { "type": "ScriptConditionEvaluator", "values": [ "var country_code = ctx.getRequestContextAttribute('LOCATION_TEST_COUNTRY_CODE'); ctx.result = !!country_code;" ] } ] }
+ ]
+ },
+ {
+ "id": 4,
+ "name": "No access for /forbidden",
+ "isEnabled": true, "isAuditEnabled": true,
+ "isDenyAllElse": true,
+ "resources": { "path": { "values": [ "/forbidden" ], "isRecursive": true } },
+ "policyItems": [
+ { "accesses": [ { "type": "read", "isAllowed": true }, { "type": "read", "isAllowed": true }, { "type": "write", "isAllowed": true },{ "type": "execute", "isAllowed": true } ], "users": [], "groups": [ "public" ], "delegateAdmin": false }
+ ]
+ }
+ ]
+ }
+ ,
+ "tests": [
+ {
+ "name": "/test/restricted access",
+ "resource": {"elements":{"path":"/test/restricted" }},
+ "userPermissions": {"user1": {"read": {"result":-1, "isFinal" : true}, "write": {"result":-1,"isFinal":true}, "execute":{"result":-1, "isFinal": true}}, "user2": {"read": {"result":-1, "isFinal" : true}, "write": {"result":-1,"isFinal":true}, "execute":{"result":-1, "isFinal": true}},"user3": {"read": {"result":0, "isFinal" : true}, "write": {"result":0,"isFinal":true}, "execute":{"result":0, "isFinal": true}}, "sub-admin-user-1": {"read": {"result":1, "isFinal" : true}, "write [...]
+ "groupPermissions": {"public": {"read": {"result":2, "isFinal" : true},"write": {"result":-1,"isFinal":true}, "execute":{"result":-1, "isFinal": true}}}
+ },
+ {
+ "name": "all-deny-test",
+ "resource": {"elements":{"path":"/forbidden" }},
+ "userPermissions": {},
+ "groupPermissions": {"public": {"read": {"result":1, "isFinal" : true},"write": {"result":1,"isFinal":true}, "execute":{"result":1, "isFinal": true}},
+ "other": {"read": {"result":-1, "isFinal" : true},"write": {"result":-1,"isFinal":true}, "execute":{"result":-1, "isFinal": true}}}
+ }
+ ]
+ }
+ ]
+}
+