You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2023/06/06 03:42:33 UTC
[ranger] branch master updated: RANGER-4165: support SELF_OR_PREFIX resource matching scope
This is an automated email from the ASF dual-hosted git repository.
madhan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new f33a88a90 RANGER-4165: support SELF_OR_PREFIX resource matching scope
f33a88a90 is described below
commit f33a88a90318ecd06fbdfeea10f65d709c3b9100
Author: Madhan Neethiraj <ma...@apache.org>
AuthorDate: Sun May 14 15:51:06 2023 -0700
RANGER-4165: support SELF_OR_PREFIX resource matching scope
---
.../RangerServiceResourceMatcher.java | 5 +-
.../plugin/contextenricher/RangerTagEnricher.java | 7 +-
.../plugin/policyengine/RangerAccessRequest.java | 13 +-
.../policyengine/RangerAccessRequestImpl.java | 11 ++
.../policyengine/RangerAccessRequestReadOnly.java | 3 +
.../policyengine/RangerAccessRequestWrapper.java | 3 +
.../policyengine/RangerPolicyEngineImpl.java | 4 +-
.../policyengine/RangerPolicyRepository.java | 2 +-
.../plugin/policyengine/RangerResourceTrie.java | 88 +++++++--
.../RangerAuditPolicyEvaluator.java | 2 +-
.../RangerDefaultPolicyEvaluator.java | 8 +-
.../RangerDefaultPolicyResourceMatcher.java | 39 +++-
.../RangerPolicyResourceMatcher.java | 11 ++
.../RangerAbstractResourceMatcher.java | 69 ++++---
.../RangerDefaultResourceMatcher.java | 20 +-
.../resourcematcher/RangerPathResourceMatcher.java | 215 +++++++++++++--------
.../resourcematcher/RangerResourceMatcher.java | 3 +-
.../resourcematcher/RangerURLResourceMatcher.java | 20 +-
.../plugin/resourcematcher/ResourceMatcher.java | 53 +++--
.../util/RangerResourceEvaluatorsRetriever.java | 12 +-
.../plugin/policyengine/TestPathResourceTrie.java | 22 ++-
.../plugin/policyengine/TestPolicyEngine.java | 14 ++
.../RangerAbstractResourceMatcherTest.java | 3 +-
.../RangerDefaultResourceMatcherTest.java | 3 +-
.../RangerPathResourceMatcherTest.java | 7 +-
.../RangerURLResourceMatcherTest.java | 3 +-
.../resourcematcher/TestResourceMatcher.java | 3 +-
.../test/resources/policyengine/aws_s3_tags.json | 33 ++++
.../policyengine/test_policyengine_aws.json | 24 +--
.../policyengine/test_policyengine_aws_s3.json | 211 ++++++++++++++++++++
.../policyengine/test_policyengine_kafka.json | 157 +++++++++++++++
31 files changed, 873 insertions(+), 195 deletions(-)
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
index 465d7d375..e696db518 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
@@ -22,6 +22,7 @@ package org.apache.ranger.plugin.contextenricher;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.model.RangerServiceResource;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceElementMatchingScope;
import org.apache.ranger.plugin.policyengine.RangerAccessResource;
import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
import org.apache.ranger.plugin.policyresourcematcher.RangerResourceEvaluator;
@@ -70,8 +71,8 @@ public class RangerServiceResourceMatcher implements RangerResourceEvaluator {
return ServiceDefUtil.isAncestorOf(policyResourceMatcher.getServiceDef(), leafResourceDef, resourceDef);
}
- public RangerPolicyResourceMatcher.MatchType getMatchType(RangerAccessResource requestedResource, Map<String, Object> evalContext) {
- return policyResourceMatcher != null ? policyResourceMatcher.getMatchType(requestedResource, evalContext) : RangerPolicyResourceMatcher.MatchType.NONE;
+ public RangerPolicyResourceMatcher.MatchType getMatchType(RangerAccessResource requestedResource, Map<String, ResourceElementMatchingScope> scopes, Map<String, Object> evalContext) {
+ return policyResourceMatcher != null ? policyResourceMatcher.getMatchType(requestedResource, scopes, evalContext) : RangerPolicyResourceMatcher.MatchType.NONE;
}
static class IdComparator implements Comparator<RangerServiceResourceMatcher>, Serializable {
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
index e0a86c398..b5428cfdf 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
@@ -564,7 +564,7 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
List<RangerServiceResourceMatcher> notMatched = new ArrayList<>();
for (RangerServiceResourceMatcher resourceMatcher : oldMatchers) {
- final RangerPolicyResourceMatcher.MatchType matchType = resourceMatcher.getMatchType(accessResource, request.getContext());
+ final RangerPolicyResourceMatcher.MatchType matchType = resourceMatcher.getMatchType(accessResource, request.getResourceElementMatchingScopes(), request.getContext());
if (LOG.isDebugEnabled()) {
LOG.debug("resource:[" + accessResource + ", MatchType:[" + matchType + "]");
@@ -703,10 +703,9 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
final Collection<RangerServiceResourceMatcher> serviceResourceMatchers = getEvaluators(request, enrichedServiceTags);
if (CollectionUtils.isNotEmpty(serviceResourceMatchers)) {
-
for (RangerServiceResourceMatcher resourceMatcher : serviceResourceMatchers) {
- final RangerPolicyResourceMatcher.MatchType matchType = resourceMatcher.getMatchType(resource, request.getContext());
+ final RangerPolicyResourceMatcher.MatchType matchType = resourceMatcher.getMatchType(resource, request.getResourceElementMatchingScopes(), request.getContext());
if (LOG.isDebugEnabled()) {
LOG.debug("resource:[" + resource + ", MatchType:[" + matchType + "]");
@@ -771,7 +770,7 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
perf = RangerPerfTracer.getPerfTracer(PERF_TRIE_OP_LOG, "RangerTagEnricher.getEvaluators(resource=" + resource.getAsString() + ")");
}
- ret = RangerResourceEvaluatorsRetriever.getEvaluators(serviceResourceTrie, resource.getAsMap(), request.getResourceMatchingScope());
+ ret = RangerResourceEvaluatorsRetriever.getEvaluators(serviceResourceTrie, resource.getAsMap(), request.getResourceElementMatchingScopes());
RangerPerfTracer.logAlways(perf);
}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java
index 6a38747f4..01848df76 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java
@@ -19,14 +19,13 @@
package org.apache.ranger.plugin.policyengine;
+import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
public interface RangerAccessRequest {
- String RANGER_ACCESS_REQUEST_SCOPE_STRING = "Scope";
-
RangerAccessResource getResource();
String getAccessType();
@@ -67,5 +66,13 @@ public interface RangerAccessRequest {
ResourceMatchingScope getResourceMatchingScope();
- enum ResourceMatchingScope {SELF, SELF_OR_DESCENDANTS, SELF_OR_CHILD}
+ default Map<String, ResourceElementMatchingScope> getResourceElementMatchingScopes() {
+ return Collections.emptyMap();
+ }
+
+ enum ResourceMatchingScope { SELF, SELF_OR_DESCENDANTS }
+
+ enum ResourceElementMatchingScope { SELF, SELF_OR_CHILD, SELF_OR_PREFIX }
+
+ enum ResourceElementMatchType { NONE, SELF, CHILD, PREFIX }
}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java
index e561c4c7c..019a0d893 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java
@@ -20,6 +20,7 @@
package org.apache.ranger.plugin.policyengine;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -56,6 +57,7 @@ public class RangerAccessRequestImpl implements RangerAccessRequest {
private boolean isAccessTypeAny;
private boolean isAccessTypeDelegatedAdmin;
private ResourceMatchingScope resourceMatchingScope = ResourceMatchingScope.SELF;
+ private Map<String, ResourceElementMatchingScope> resourceElementMatchingScopes = Collections.emptyMap();
public RangerAccessRequestImpl() {
this(null, null, null, null, null);
@@ -96,6 +98,7 @@ public class RangerAccessRequestImpl implements RangerAccessRequest {
setContext(request.getContext());
setClusterName(request.getClusterName());
setResourceMatchingScope(request.getResourceMatchingScope());
+ setResourceElementMatchingScopes(request.getResourceElementMatchingScopes());
setClientIPAddress(request.getClientIPAddress());
setClusterType(request.getClusterType());
}
@@ -171,6 +174,9 @@ public class RangerAccessRequestImpl implements RangerAccessRequest {
return resourceMatchingScope;
}
+ @Override
+ public Map<String, ResourceElementMatchingScope> getResourceElementMatchingScopes() { return this.resourceElementMatchingScopes; }
+
@Override
public boolean isAccessTypeAny() {
return isAccessTypeAny;
@@ -265,6 +271,10 @@ public class RangerAccessRequestImpl implements RangerAccessRequest {
}
}
+ public void setResourceElementMatchingScopes(Map<String, ResourceElementMatchingScope> resourceElementMatchingScopes) {
+ this.resourceElementMatchingScopes = resourceElementMatchingScopes == null ? Collections.emptyMap() : resourceElementMatchingScopes;
+ }
+
public void setContext(Map<String, Object> context) {
if (context == null) {
this.context = new HashMap<>();
@@ -358,6 +368,7 @@ public class RangerAccessRequestImpl implements RangerAccessRequest {
sb.append("requestData={").append(requestData).append("} ");
sb.append("sessionId={").append(sessionId).append("} ");
sb.append("resourceMatchingScope={").append(resourceMatchingScope).append("} ");
+ sb.append("resourceElementMatchingScopes={").append(resourceElementMatchingScopes).append("} ");
sb.append("clusterName={").append(clusterName).append("} ");
sb.append("clusterType={").append(clusterType).append("} ");
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestReadOnly.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestReadOnly.java
index 4887c0112..b732dfab6 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestReadOnly.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestReadOnly.java
@@ -98,6 +98,9 @@ public class RangerAccessRequestReadOnly implements RangerAccessRequest {
@Override
public ResourceMatchingScope getResourceMatchingScope() { return source.getResourceMatchingScope(); }
+ @Override
+ public Map<String, ResourceElementMatchingScope> getResourceElementMatchingScopes() { return source.getResourceElementMatchingScopes(); }
+
@Override
public String getClusterName() { return source.getClusterName(); }
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestWrapper.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestWrapper.java
index 6aec330d7..96f851e9a 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestWrapper.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestWrapper.java
@@ -101,5 +101,8 @@ public class RangerAccessRequestWrapper implements RangerAccessRequest {
@Override
public ResourceMatchingScope getResourceMatchingScope() { return request.getResourceMatchingScope(); }
+ @Override
+ public Map<String, ResourceElementMatchingScope> getResourceElementMatchingScopes() { return request.getResourceElementMatchingScopes(); }
+
}
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 e75bb722c..8ba0b1a7f 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
@@ -318,7 +318,7 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
for (RangerPolicyResourceEvaluator resourceEvaluator : evaluator.getResourceEvaluators()) {
RangerPolicyResourceMatcher matcher = resourceEvaluator.getPolicyResourceMatcher();
- matchType = matcher.getMatchType(request.getResource(), request.getContext());
+ matchType = matcher.getMatchType(request.getResource(), request.getResourceElementMatchingScopes(), request.getContext());
isMatched = isMatch(matchType, request.getResourceMatchingScope());
if (isMatched) {
@@ -326,7 +326,7 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
break;
} else if (matcher.getNeedsDynamicEval() && !isConditionalMatch) {
- MatchType dynWildCardMatch = resourceEvaluator.getMacrosReplaceWithWildcardMatcher(policyEngine).getMatchType(request.getResource(), request.getContext());
+ MatchType dynWildCardMatch = resourceEvaluator.getMacrosReplaceWithWildcardMatcher(policyEngine).getMatchType(request.getResource(), request.getResourceElementMatchingScopes(), request.getContext());
isConditionalMatch = isMatch(dynWildCardMatch, request.getResourceMatchingScope());
}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
index b5b26702c..68f4b5dfd 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
@@ -719,7 +719,7 @@ public class RangerPolicyRepository {
perf = RangerPerfTracer.getPerfTracer(PERF_TRIE_OP_LOG, "RangerPolicyRepository.getLikelyMatchEvaluators(resource=" + resource.getAsString() + ")");
}
- Collection<RangerPolicyResourceEvaluator> smallestList = RangerResourceEvaluatorsRetriever.getEvaluators(resourceTrie, resource.getAsMap(), request.getResourceMatchingScope());
+ Collection<RangerPolicyResourceEvaluator> smallestList = RangerResourceEvaluatorsRetriever.getEvaluators(resourceTrie, resource.getAsMap(), request.getResourceElementMatchingScopes());
if (smallestList != null) {
if (smallestList.size() == 0) {
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceTrie.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceTrie.java
index f89d51e35..07eb5815c 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceTrie.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceTrie.java
@@ -25,6 +25,7 @@ import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceElementMatchingScope;
import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
import org.apache.ranger.plugin.policyresourcematcher.RangerResourceEvaluator;
import org.apache.ranger.plugin.resourcematcher.RangerAbstractResourceMatcher;
@@ -44,6 +45,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.Stack;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@@ -184,10 +186,10 @@ public class RangerResourceTrie<T extends RangerResourceEvaluator> {
}
public Set<T> getEvaluatorsForResource(Object resource) {
- return getEvaluatorsForResource(resource, RangerAccessRequest.ResourceMatchingScope.SELF);
+ return getEvaluatorsForResource(resource, ResourceElementMatchingScope.SELF);
}
- public Set<T> getEvaluatorsForResource(Object resource, RangerAccessRequest.ResourceMatchingScope scope) {
+ public Set<T> getEvaluatorsForResource(Object resource, ResourceElementMatchingScope scope) {
if (resource instanceof String) {
return getEvaluatorsForResource((String) resource, scope);
} else if (resource instanceof Collection) {
@@ -576,7 +578,7 @@ public class RangerResourceTrie<T extends RangerResourceEvaluator> {
return str.substring(0, minIndex);
}
- private Set<T> getEvaluatorsForResource(String resource, RangerAccessRequest.ResourceMatchingScope scope) {
+ private Set<T> getEvaluatorsForResource(String resource, ResourceElementMatchingScope scope) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerResourceTrie.getEvaluatorsForResource(" + resource + ", " + scope + ")");
}
@@ -643,10 +645,10 @@ public class RangerResourceTrie<T extends RangerResourceEvaluator> {
ret = accumulatedEvaluators;
}
- boolean includeEvaluatorsOfChildResources = scope == RangerAccessRequest.ResourceMatchingScope.SELF_OR_CHILD;
+ final boolean includeChildEvaluators = scope == ResourceElementMatchingScope.SELF_OR_CHILD || scope == ResourceElementMatchingScope.SELF_OR_PREFIX;
+ final Set<T> childEvalautors = includeChildEvaluators ? new HashSet<>() : null;
- if (includeEvaluatorsOfChildResources) {
- final Set<T> childEvalautors = new HashSet<>();
+ if (scope == ResourceElementMatchingScope.SELF_OR_CHILD) {
final boolean resourceEndsWithSep = resource.charAt(resource.length() - 1) == separatorChar;
if (isSelfMatch) { // resource == path(curr)
@@ -671,14 +673,16 @@ public class RangerResourceTrie<T extends RangerResourceEvaluator> {
}
}
}
+ } else if (scope == ResourceElementMatchingScope.SELF_OR_PREFIX) {
+ curr.collectChildEvaluators(resource, i, childEvalautors);
+ }
- if (CollectionUtils.isNotEmpty(childEvalautors)) {
- if (CollectionUtils.isNotEmpty(ret)) {
- childEvalautors.addAll(ret);
- }
-
- ret = childEvalautors;
+ if (CollectionUtils.isNotEmpty(childEvalautors)) {
+ if (CollectionUtils.isNotEmpty(ret)) {
+ childEvalautors.addAll(ret);
}
+
+ ret = childEvalautors;
}
RangerPerfTracer.logAlways(perf);
@@ -731,7 +735,7 @@ public class RangerResourceTrie<T extends RangerResourceEvaluator> {
return curr;
}
- private Set<T> getEvaluatorsForResources(Collection<String> resources, RangerAccessRequest.ResourceMatchingScope scope) {
+ private Set<T> getEvaluatorsForResources(Collection<String> resources, ResourceElementMatchingScope scope) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerResourceTrie.getEvaluatorsForResources(" + resources + ")");
}
@@ -1228,6 +1232,64 @@ public class RangerResourceTrie<T extends RangerResourceEvaluator> {
}
}
+ void collectChildEvaluators(String resource, int startIndex, Set<U> childEvaluators) {
+ if (startIndex == resource.length()) {
+ collectChildEvaluators(childEvaluators);
+ } else if (startIndex < resource.length()) {
+ Character startChar = getLookupChar(resource, startIndex);
+ TrieNode<U> childNode = children.get(startChar);
+
+ if (childNode != null) {
+ if (!isOptimizedForSpace) {
+ childNode.setupIfNeeded(childNode.getParent());
+ }
+
+ String childStr = childNode.getStr();
+ int lenToMatch = Math.min(resource.length() - startIndex, childStr.length());
+
+ if (resource.regionMatches(optIgnoreCase, startIndex, childStr, 0, lenToMatch)) {
+ if (childNode.wildcardEvaluators != null) {
+ childEvaluators.addAll(childNode.wildcardEvaluators);
+ }
+
+ if (childNode.evaluators != null) {
+ childEvaluators.addAll(childNode.evaluators);
+ }
+
+ if (resource.length() == (startIndex + lenToMatch)) {
+ childNode.collectChildEvaluators(childEvaluators);
+ } else {
+ childNode.children.values().stream().forEach(c -> c.collectChildEvaluators(resource, startIndex + childStr.length(), childEvaluators));
+ }
+ }
+ }
+ }
+ }
+
+ private void collectChildEvaluators(Set<U> childEvaluators) {
+ Stack<TrieNode<U>> nodes = new Stack<>();
+
+ nodes.addAll(children.values());
+
+ while (!nodes.isEmpty()) {
+ TrieNode<U> childNode = nodes.pop();
+
+ if (!isOptimizedForSpace) {
+ childNode.setupIfNeeded(childNode.getParent());
+ }
+
+ if (childNode.wildcardEvaluators != null) {
+ childEvaluators.addAll(childNode.wildcardEvaluators);
+ }
+
+ if (childNode.evaluators != null) {
+ childEvaluators.addAll(childNode.evaluators);
+ }
+
+ nodes.addAll(childNode.children.values());
+ }
+ }
+
private void removeEvaluatorFromSubtree(U evaluator) {
if (CollectionUtils.isNotEmpty(wildcardEvaluators) && wildcardEvaluators.contains(evaluator)) {
undoSetup();
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java
index 1c46f184c..ba24b8c3e 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java
@@ -129,7 +129,7 @@ public class RangerAuditPolicyEvaluator extends RangerDefaultPolicyEvaluator {
RangerPolicyResourceMatcher resourceMatcher = resourceEvaluator.getPolicyResourceMatcher();
if (resourceMatcher != null) {
- matchType = resourceMatcher.getMatchType(request.getResource(), request.getContext());
+ matchType = resourceMatcher.getMatchType(request.getResource(), request.getResourceElementMatchingScopes(), request.getContext());
} else {
matchType = RangerPolicyResourceMatcher.MatchType.NONE;
}
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 eee1e1f1b..4ad2944a8 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
@@ -233,11 +233,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
matchType = RangerPolicyResourceMatcher.MatchType.SELF;
}
} else {
- if (request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_CHILD) {
- request.getContext().put(RangerAccessRequest.RANGER_ACCESS_REQUEST_SCOPE_STRING, RangerAccessRequest.ResourceMatchingScope.SELF_OR_CHILD);
- }
- matchType = resourceMatcher != null ? resourceMatcher.getMatchType(request.getResource(), request.getContext()) : RangerPolicyResourceMatcher.MatchType.NONE;
- request.getContext().remove(RangerAccessRequest.RANGER_ACCESS_REQUEST_SCOPE_STRING);
+ matchType = resourceMatcher != null ? resourceMatcher.getMatchType(request.getResource(), request.getResourceElementMatchingScopes(), request.getContext()) : RangerPolicyResourceMatcher.MatchType.NONE;
}
final boolean isMatched;
@@ -473,7 +469,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
if (RangerTagAccessRequest.class.isInstance(request)) {
matchType = ((RangerTagAccessRequest) request).getMatchType();
} else {
- matchType = resourceMatcher != null ? resourceMatcher.getMatchType(request.getResource(), request.getContext()) : RangerPolicyResourceMatcher.MatchType.NONE;
+ matchType = resourceMatcher != null ? resourceMatcher.getMatchType(request.getResource(), request.getResourceElementMatchingScopes(), request.getContext()) : RangerPolicyResourceMatcher.MatchType.NONE;
}
final boolean isMatched = matchType != RangerPolicyResourceMatcher.MatchType.NONE;
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
index e887730c9..f16157ce6 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
@@ -20,6 +20,7 @@
package org.apache.ranger.plugin.policyresourcematcher;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@@ -33,6 +34,7 @@ import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceElementMatchingScope;
import org.apache.ranger.plugin.policyengine.RangerAccessResource;
import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
import org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher;
@@ -378,6 +380,11 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
@Override
public boolean isMatch(RangerPolicy policy, MatchScope scope, Map<String, Object> evalContext) {
+ return isMatch(policy, Collections.emptyMap(), scope, evalContext);
+ }
+
+ @Override
+ public boolean isMatch(RangerPolicy policy, Map<String, ResourceElementMatchingScope> scopes, MatchScope scope, Map<String, Object> evalContext) {
boolean ret = false;
RangerPerfTracer perf = null;
@@ -428,7 +435,7 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
for (String value : policyResource.getValues()) {
accessResource.setValue(name, value);
- matchType = getMatchType(accessResource, evalContext);
+ matchType = getMatchType(accessResource, scopes, evalContext);
if (matchType != MatchType.NONE) { // One value for this resourceDef matched
ret = true;
@@ -458,6 +465,11 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
@Override
public boolean isMatch(RangerAccessResource resource, Map<String, Object> evalContext) {
+ return isMatch(resource, Collections.emptyMap(), evalContext);
+ }
+
+ @Override
+ public boolean isMatch(RangerAccessResource resource, Map<String, ResourceElementMatchingScope> scopes, Map<String, Object> evalContext) {
RangerPerfTracer perf = null;
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_RESOURCE_MATCHER_MATCH_LOG)) {
@@ -487,7 +499,7 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
break;
}
}
- final boolean ret = MapUtils.isNotEmpty(policyResources) && isMatch(policyResources, evalContext);
+ final boolean ret = MapUtils.isNotEmpty(policyResources) && isMatch(policyResources, scopes, evalContext);
RangerPerfTracer.log(perf);
@@ -496,6 +508,11 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
@Override
public boolean isMatch(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext) {
+ return isMatch(resources, Collections.emptyMap(), evalContext);
+ }
+
+ @Override
+ public boolean isMatch(Map<String, RangerPolicyResource> resources, Map<String, ResourceElementMatchingScope> scopes, Map<String, Object> evalContext) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerDefaultPolicyResourceMatcher.isMatch(" + resources + ", " + evalContext + ")");
}
@@ -524,7 +541,8 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
if (matcher != null) {
if (CollectionUtils.isNotEmpty(values)) {
for (String value : values) {
- ret = matcher.isMatch(value, evalContext);
+ ret = matcher.isMatch(value, scopes.get(resourceName), evalContext);
+
if (!ret) {
break;
}
@@ -558,12 +576,22 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
@Override
public boolean isMatch(RangerAccessResource resource, MatchScope scope, Map<String, Object> evalContext) {
- MatchType matchType = getMatchType(resource, evalContext);
+ return isMatch(resource, Collections.emptyMap(), scope, evalContext);
+ }
+
+ @Override
+ public boolean isMatch(RangerAccessResource resource, Map<String, ResourceElementMatchingScope> scopes, MatchScope scope, Map<String, Object> evalContext) {
+ MatchType matchType = getMatchType(resource, scopes, evalContext);
return isMatch(scope, matchType);
}
@Override
public MatchType getMatchType(RangerAccessResource resource, Map<String, Object> evalContext) {
+ return getMatchType(resource, Collections.emptyMap(), evalContext);
+ }
+
+ @Override
+ public MatchType getMatchType(RangerAccessResource resource, Map<String, ResourceElementMatchingScope> scopes, Map<String, Object> evalContext) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerDefaultPolicyResourceMatcher.getMatchType(" + resource + evalContext + ")");
}
@@ -582,6 +610,7 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
ret = MatchType.SELF;
} else {
List<RangerResourceDef> hierarchy = getMatchingHierarchy(resource);
+
if (CollectionUtils.isNotEmpty(hierarchy)) {
int lastNonAnyMatcherIndex = -1;
@@ -610,7 +639,7 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
if (matcher != null) {
if (resourceValue != null || matcher.isMatchAny()) {
- if (matcher.isMatch(resourceValue, evalContext)) {
+ if (matcher.isMatch(resourceValue, scopes.get(resourceDef.getName()), evalContext)) {
ret = MatchType.SELF;
} else {
ret = MatchType.NONE;
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
index 0220feba7..052e2df78 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
@@ -25,6 +25,7 @@ import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceElementMatchingScope;
import org.apache.ranger.plugin.policyengine.RangerAccessResource;
import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher;
@@ -50,14 +51,24 @@ public interface RangerPolicyResourceMatcher {
boolean isMatch(RangerAccessResource resource, Map<String, Object> evalContext);
+ boolean isMatch(RangerAccessResource resource, Map<String, ResourceElementMatchingScope> scopes, Map<String, Object> evalContext);
+
boolean isMatch(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext);
+ boolean isMatch(Map<String, RangerPolicyResource> resources, Map<String, ResourceElementMatchingScope> scopes, Map<String, Object> evalContext);
+
boolean isMatch(RangerAccessResource resource, MatchScope scope, Map<String, Object> evalContext);
+ boolean isMatch(RangerAccessResource resource, Map<String, ResourceElementMatchingScope> scopes, MatchScope scope, Map<String, Object> evalContext);
+
boolean isMatch(RangerPolicy policy, MatchScope scope, Map<String, Object> evalContext);
+ boolean isMatch(RangerPolicy policy, Map<String, ResourceElementMatchingScope> scopes, MatchScope scope, Map<String, Object> evalContext);
+
MatchType getMatchType(RangerAccessResource resource, Map<String, Object> evalContext);
+ MatchType getMatchType(RangerAccessResource resource, Map<String, ResourceElementMatchingScope> scopes, Map<String, Object> evalContext);
+
boolean isCompleteMatch(RangerAccessResource resource, Map<String, Object> evalContext);
boolean isCompleteMatch(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext);
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
index 032d4487c..cb8d46adf 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
@@ -390,9 +390,30 @@ public abstract class RangerAbstractResourceMatcher implements RangerResourceMat
}
}
-final class CaseSensitiveStringMatcher extends ResourceMatcher {
- CaseSensitiveStringMatcher(String value, Map<String, String> options) {
+abstract class AbstractStringResourceMatcher extends ResourceMatcher {
+ private final boolean isCaseSensitive;
+
+ protected AbstractStringResourceMatcher(String value, Map<String, String> options, boolean isCaseSensitive) {
super(value, options);
+
+ this.isCaseSensitive = isCaseSensitive;
+ }
+
+ @Override
+ public boolean isPrefixMatch(String resourceValue, Map<String, Object> evalContext) {
+ return isCaseSensitive ? StringUtils.startsWith(getExpandedValue(evalContext), resourceValue)
+ : StringUtils.startsWithIgnoreCase(getExpandedValue(evalContext), resourceValue);
+ }
+
+ @Override
+ public boolean isChildMatch(String resourceValue, Map<String, Object> evalContext) {
+ return false; // child-match is applicable only for path resource
+ }
+}
+
+final class CaseSensitiveStringMatcher extends AbstractStringResourceMatcher {
+ CaseSensitiveStringMatcher(String value, Map<String, String> options) {
+ super(value, options, true);
}
@Override
@@ -402,8 +423,8 @@ final class CaseSensitiveStringMatcher extends ResourceMatcher {
int getPriority() { return 1 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0);}
}
-final class CaseInsensitiveStringMatcher extends ResourceMatcher {
- CaseInsensitiveStringMatcher(String value, Map<String, String> options) { super(value, options); }
+final class CaseInsensitiveStringMatcher extends AbstractStringResourceMatcher {
+ CaseInsensitiveStringMatcher(String value, Map<String, String> options) { super(value, options, false); }
@Override
boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
@@ -412,11 +433,11 @@ final class CaseInsensitiveStringMatcher extends ResourceMatcher {
int getPriority() {return 2 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0); }
}
-final class QuotedCaseSensitiveStringMatcher extends ResourceMatcher {
+final class QuotedCaseSensitiveStringMatcher extends AbstractStringResourceMatcher {
private final String quoteChars;
QuotedCaseSensitiveStringMatcher(String value, Map<String, String> options, String quoteChars) {
- super(value, options);
+ super(value, options, true);
this.quoteChars = quoteChars;
}
@@ -433,9 +454,9 @@ final class QuotedCaseSensitiveStringMatcher extends ResourceMatcher {
int getPriority() {return 2 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0); }
}
-final class CaseSensitiveStartsWithMatcher extends ResourceMatcher {
+final class CaseSensitiveStartsWithMatcher extends AbstractStringResourceMatcher {
CaseSensitiveStartsWithMatcher(String value, Map<String, String> options) {
- super(value, options);
+ super(value, options, true);
}
@Override
@@ -445,8 +466,8 @@ final class CaseSensitiveStartsWithMatcher extends ResourceMatcher {
int getPriority() { return 3 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0);}
}
-final class CaseInsensitiveStartsWithMatcher extends ResourceMatcher {
- CaseInsensitiveStartsWithMatcher(String value, Map<String, String> options) { super(value, options); }
+final class CaseInsensitiveStartsWithMatcher extends AbstractStringResourceMatcher {
+ CaseInsensitiveStartsWithMatcher(String value, Map<String, String> options) { super(value, options, false); }
@Override
boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
@@ -455,11 +476,11 @@ final class CaseInsensitiveStartsWithMatcher extends ResourceMatcher {
int getPriority() { return 4 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0); }
}
-final class QuotedCaseSensitiveStartsWithMatcher extends ResourceMatcher {
+final class QuotedCaseSensitiveStartsWithMatcher extends AbstractStringResourceMatcher {
private final String quoteChars;
QuotedCaseSensitiveStartsWithMatcher(String value, Map<String, String> options, String quoteChars) {
- super(value, options);
+ super(value, options, true);
this.quoteChars = quoteChars;
}
@@ -476,9 +497,9 @@ final class QuotedCaseSensitiveStartsWithMatcher extends ResourceMatcher {
int getPriority() { return 4 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0); }
}
-final class CaseSensitiveEndsWithMatcher extends ResourceMatcher {
+final class CaseSensitiveEndsWithMatcher extends AbstractStringResourceMatcher {
CaseSensitiveEndsWithMatcher(String value, Map<String, String> options) {
- super(value, options);
+ super(value, options, true);
}
@Override
@@ -488,9 +509,9 @@ final class CaseSensitiveEndsWithMatcher extends ResourceMatcher {
int getPriority() { return 3 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0); }
}
-final class CaseInsensitiveEndsWithMatcher extends ResourceMatcher {
+final class CaseInsensitiveEndsWithMatcher extends AbstractStringResourceMatcher {
CaseInsensitiveEndsWithMatcher(String value, Map<String, String> options) {
- super(value, options);
+ super(value, options, false);
}
@Override
@@ -500,11 +521,11 @@ final class CaseInsensitiveEndsWithMatcher extends ResourceMatcher {
int getPriority() { return 4 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0); }
}
-final class QuotedCaseSensitiveEndsWithMatcher extends ResourceMatcher {
+final class QuotedCaseSensitiveEndsWithMatcher extends AbstractStringResourceMatcher {
private final String quoteChars;
QuotedCaseSensitiveEndsWithMatcher(String value, Map<String, String> options, String quoteChars) {
- super(value, options);
+ super(value, options, true);
this.quoteChars = quoteChars;
}
@@ -521,9 +542,9 @@ final class QuotedCaseSensitiveEndsWithMatcher extends ResourceMatcher {
int getPriority() { return 4 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0); }
}
-final class CaseSensitiveWildcardMatcher extends ResourceMatcher {
+final class CaseSensitiveWildcardMatcher extends AbstractStringResourceMatcher {
CaseSensitiveWildcardMatcher(String value, Map<String, String> options) {
- super(value, options);
+ super(value, options, true);
}
@Override
@@ -534,9 +555,9 @@ final class CaseSensitiveWildcardMatcher extends ResourceMatcher {
}
-final class CaseInsensitiveWildcardMatcher extends ResourceMatcher {
+final class CaseInsensitiveWildcardMatcher extends AbstractStringResourceMatcher {
CaseInsensitiveWildcardMatcher(String value, Map<String, String> options) {
- super(value, options);
+ super(value, options, false);
}
@Override
@@ -546,11 +567,11 @@ final class CaseInsensitiveWildcardMatcher extends ResourceMatcher {
int getPriority() {return 6 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0); }
}
-final class QuotedCaseSensitiveWildcardMatcher extends ResourceMatcher {
+final class QuotedCaseSensitiveWildcardMatcher extends AbstractStringResourceMatcher {
private final String quoteChars;
QuotedCaseSensitiveWildcardMatcher(String value, Map<String, String> options, String quoteChars) {
- super(value, options);
+ super(value, options, true);
this.quoteChars = quoteChars;
}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java
index c421388e7..702cb272f 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java
@@ -20,6 +20,7 @@
package org.apache.ranger.plugin.resourcematcher;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceElementMatchingScope;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,38 +32,45 @@ public class RangerDefaultResourceMatcher extends RangerAbstractResourceMatcher
private static final Logger LOG = LoggerFactory.getLogger(RangerDefaultResourceMatcher.class);
@Override
- public boolean isMatch(Object resource, Map<String, Object> evalContext) {
+ public boolean isMatch(Object resource, ResourceElementMatchingScope matchingScope, Map<String, Object> evalContext) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerDefaultResourceMatcher.isMatch(" + resource + ", " + evalContext + ")");
}
boolean ret = false;
boolean allValuesRequested = isAllValuesRequested(resource);
+ boolean isPrefixMatch = matchingScope == ResourceElementMatchingScope.SELF_OR_PREFIX;
- if(allValuesRequested || isMatchAny) {
+ if (isMatchAny || (allValuesRequested && !isPrefixMatch)) {
ret = isMatchAny;
} else {
if (resource instanceof String) {
String strValue = (String) resource;
for (ResourceMatcher resourceMatcher : resourceMatchers.getResourceMatchers()) {
- ret = resourceMatcher.isMatch(strValue, evalContext);
+ ret = resourceMatcher.isMatch(strValue, matchingScope, evalContext);
+
if (ret) {
break;
}
}
} else if (resource instanceof Collection) {
@SuppressWarnings("unchecked")
- Collection<String> collValue = (Collection<String>) resource;
+ Collection<String> resourceValues = (Collection<String>) resource;
for (ResourceMatcher resourceMatcher : resourceMatchers.getResourceMatchers()) {
- ret = resourceMatcher.isMatchAny(collValue, evalContext);
+ for (String resourceValue : resourceValues) {
+ ret = resourceMatcher.isMatch(resourceValue, matchingScope, evalContext);
+
+ if (ret) {
+ break;
+ }
+ }
if (ret) {
break;
}
}
}
-
}
ret = applyExcludes(allValuesRequested, ret);
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java
index 5fa5b68d4..1af967fbd 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java
@@ -20,7 +20,6 @@
package org.apache.ranger.plugin.resourcematcher;
import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.collections.MapUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOCase;
import org.apache.commons.lang.ArrayUtils;
@@ -261,15 +260,15 @@ public class RangerPathResourceMatcher extends RangerDefaultResourceMatcher {
if (needWildcardMatch) { // test?, test*a*, test*a*b, *test*a
ret = new WildcardResourceMatcher(policyValue, getOptions(), pathSeparatorChar, optIgnoreCase, FilenameUtils::wildcardMatch, 6);
} else if (wildcardStartIdx == -1) { // test, testa, testab
- ret = new StringResourceMatcher(policyValue, getOptions(), pathSeparatorChar, optIgnoreCase ? StringUtils::equalsIgnoreCase : StringUtils::equals, optIgnoreCase ? 2 : 1);
+ ret = new PathResourceMatcher(policyValue, getOptions(), pathSeparatorChar, optIgnoreCase ? StringUtils::equalsIgnoreCase : StringUtils::equals, optIgnoreCase ? 2 : 1, !optIgnoreCase);
} else if (wildcardStartIdx == 0) { // *test, **test, *testa, *testab
String matchStr = policyValue.substring(wildcardEndIdx + 1);
- ret = new StringResourceMatcher(matchStr, getOptions(), pathSeparatorChar, optIgnoreCase ? StringUtils::endsWithIgnoreCase : StringUtils::endsWith, optIgnoreCase ? 4 : 3);
+ ret = new PathResourceMatcher(matchStr, getOptions(), pathSeparatorChar, optIgnoreCase ? StringUtils::endsWithIgnoreCase : StringUtils::endsWith, optIgnoreCase ? 4 : 3, !optIgnoreCase);
} else if (wildcardEndIdx != (len - 1)) { // test*a, test*ab
ret = new WildcardResourceMatcher(policyValue, getOptions(), pathSeparatorChar, optIgnoreCase, FilenameUtils::wildcardMatch, 6);
} else { // test*, test**, testa*, testab*
String matchStr = policyValue.substring(0, wildcardStartIdx);
- ret = new StringResourceMatcher(matchStr, getOptions(), pathSeparatorChar, optIgnoreCase ? StringUtils::startsWithIgnoreCase : StringUtils::startsWith, optIgnoreCase ? 4 : 3);
+ ret = new PathResourceMatcher(matchStr, getOptions(), pathSeparatorChar, optIgnoreCase ? StringUtils::startsWithIgnoreCase : StringUtils::startsWith, optIgnoreCase ? 4 : 3, !optIgnoreCase);
}
if (optReplaceTokens) {
@@ -291,99 +290,132 @@ public class RangerPathResourceMatcher extends RangerDefaultResourceMatcher {
R apply(T t, U u, V v, W w, X x);
}
- static abstract class PathResourceMatcher extends ResourceMatcher {
+ static abstract class AbstractPathResourceMatcher extends ResourceMatcher {
final char pathSeparatorChar;
final int priority;
+ final boolean isCaseSensitive;
- PathResourceMatcher(String value, Map<String, String> options, char pathSeparatorChar, int priority) {
+ AbstractPathResourceMatcher(String value, Map<String, String> options, char pathSeparatorChar, int priority, boolean isCaseSensitive) {
super(value, options);
- this.pathSeparatorChar = pathSeparatorChar;
- this.priority = priority;
+
+ this.pathSeparatorChar = pathSeparatorChar;
+ this.priority = priority;
+ this.isCaseSensitive = isCaseSensitive;
}
int getPriority() {
return priority + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0);
}
+
+ @Override
+ public boolean isPrefixMatch(String resourceValue, Map<String, Object> evalContext) {
+ return isCaseSensitive ? StringUtils.startsWith(getExpandedValue(evalContext), resourceValue)
+ : StringUtils.startsWithIgnoreCase(getExpandedValue(evalContext), resourceValue);
+ }
}
- static class StringResourceMatcher extends PathResourceMatcher {
+ static class PathResourceMatcher extends AbstractPathResourceMatcher {
final BiFunction<String, String, Boolean> function;
- StringResourceMatcher(String value, Map<String, String> options, char pathSeparatorChar, BiFunction<String, String, Boolean> function, int priority) {
- super(value, options, pathSeparatorChar, priority);
+
+ PathResourceMatcher(String value, Map<String, String> options, char pathSeparatorChar, BiFunction<String, String, Boolean> function, int priority, boolean isCaseSensitive) {
+ super(value, options, pathSeparatorChar, priority, isCaseSensitive);
+
this.function = function;
}
+
@Override
boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
if (LOG.isDebugEnabled()) {
- LOG.debug("==> StringResourceMatcher.isMatch(resourceValue=" + resourceValue + ", evalContext=" + evalContext + ")");
- }
- String expandedValue = getExpandedValue(evalContext);
- boolean ret = function.apply(resourceValue, expandedValue);
- if (!ret) {
- RangerAccessRequest.ResourceMatchingScope scope = MapUtils.isNotEmpty(evalContext) ? (RangerAccessRequest.ResourceMatchingScope) evalContext.get(RangerAccessRequest.RANGER_ACCESS_REQUEST_SCOPE_STRING) : null;
- if (scope == RangerAccessRequest.ResourceMatchingScope.SELF_OR_CHILD) {
- int lastLevelSeparatorIndex = expandedValue.lastIndexOf(pathSeparatorChar);
- if (lastLevelSeparatorIndex != -1) {
- String shorterExpandedValue = expandedValue.substring(0, lastLevelSeparatorIndex);
- if (resourceValue.charAt(resourceValue.length()-1) == pathSeparatorChar) {
- resourceValue = resourceValue.substring(0, resourceValue.length()-1);
- }
- ret = function.apply(resourceValue, shorterExpandedValue);
- }
- }
+ LOG.debug("==> PathResourceMatcher.isMatch(resourceValue=" + resourceValue + ", evalContext=" + evalContext + ")");
}
+
+ String expandedValue = getExpandedValue(evalContext);
+ boolean ret = function.apply(resourceValue, expandedValue);
+
if (LOG.isDebugEnabled()) {
- LOG.debug("<== StringResourceMatcher.isMatch(resourceValue=" + resourceValue + ", expandedValue=" + expandedValue + ") : result:[" + ret + "]");
+ LOG.debug("<== PathResourceMatcher.isMatch(resourceValue=" + resourceValue + ", expandedValue=" + expandedValue + ") : result:[" + ret + "]");
}
+
+ return ret;
+ }
+
+ @Override
+ public boolean isChildMatch(String resourceValue, Map<String, Object> evalContext) {
+ boolean ret = false;
+ String expandedValue = getExpandedValue(evalContext);
+ int lastLevelSeparatorIndex = expandedValue.lastIndexOf(pathSeparatorChar);
+
+ if (lastLevelSeparatorIndex != -1) {
+ String shorterExpandedValue = expandedValue.substring(0, lastLevelSeparatorIndex);
+
+ if (resourceValue.charAt(resourceValue.length()-1) == pathSeparatorChar) {
+ resourceValue = resourceValue.substring(0, resourceValue.length()-1);
+ }
+
+ ret = function.apply(resourceValue, shorterExpandedValue);
+ }
+
return ret;
}
}
- static class WildcardResourceMatcher extends PathResourceMatcher {
+ static class WildcardResourceMatcher extends AbstractPathResourceMatcher {
final TriFunction<String, String, IOCase, Boolean> function;
- final IOCase ioCase;
+ final IOCase ioCase;
WildcardResourceMatcher(String value, Map<String, String> options, char pathSeparatorChar, boolean optIgnoreCase, TriFunction<String, String, IOCase, Boolean> function, int priority) {
- super(value, options, pathSeparatorChar, priority);
+ super(value, options, pathSeparatorChar, priority, !optIgnoreCase);
+
this.function = function;
this.ioCase = optIgnoreCase ? IOCase.INSENSITIVE : IOCase.SENSITIVE;
}
+
@Override
boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> WildcardResourceMatcher.isMatch(resourceValue=" + resourceValue + ", evalContext=" + evalContext + ")");
}
- String expandedValue = getExpandedValue(evalContext);
- boolean ret = function.apply(resourceValue, expandedValue, ioCase);
- if (!ret) {
- RangerAccessRequest.ResourceMatchingScope scope = MapUtils.isNotEmpty(evalContext) ? (RangerAccessRequest.ResourceMatchingScope) evalContext.get(RangerAccessRequest.RANGER_ACCESS_REQUEST_SCOPE_STRING) : null;
- if (scope == RangerAccessRequest.ResourceMatchingScope.SELF_OR_CHILD) {
- int lastLevelSeparatorIndex = expandedValue.lastIndexOf(pathSeparatorChar);
- if (lastLevelSeparatorIndex != -1) {
- String shorterExpandedValue = expandedValue.substring(0, lastLevelSeparatorIndex);
- if (resourceValue.charAt(resourceValue.length()-1) == pathSeparatorChar) {
- resourceValue = resourceValue.substring(0, resourceValue.length()-1);
- }
- ret = function.apply(resourceValue, shorterExpandedValue, ioCase);
- }
- }
- }
+
+ String expandedValue = getExpandedValue(evalContext);
+ boolean ret = function.apply(resourceValue, expandedValue, ioCase);
+
if (LOG.isDebugEnabled()) {
LOG.debug("<== WildcardResourceMatcher.isMatch(resourceValue=" + resourceValue + ", expandedValue=" + expandedValue + ") : result:[" + ret + "]");
}
return ret;
}
+
+ @Override
+ public boolean isChildMatch(String resourceValue, Map<String, Object> evalContext) {
+ boolean ret = false;
+ String expandedValue = getExpandedValue(evalContext);
+ int lastLevelSeparatorIndex = expandedValue.lastIndexOf(pathSeparatorChar);
+
+ if (lastLevelSeparatorIndex != -1) {
+ String shorterExpandedValue = expandedValue.substring(0, lastLevelSeparatorIndex);
+
+ if (resourceValue.charAt(resourceValue.length()-1) == pathSeparatorChar) {
+ resourceValue = resourceValue.substring(0, resourceValue.length()-1);
+ }
+
+ ret = function.apply(resourceValue, shorterExpandedValue, ioCase);
+ }
+
+ return ret;
+ }
}
- static class RecursiveWildcardResourceMatcher extends PathResourceMatcher {
+ static class RecursiveWildcardResourceMatcher extends AbstractPathResourceMatcher {
final QuintFunction<String, String, Character, IOCase, Boolean, String[]> function;
final IOCase ioCase;
String[] wildcardPathElements;
RecursiveWildcardResourceMatcher(String value, Map<String, String> options, char pathSeparatorChar, boolean optIgnoreCase, QuintFunction<String, String, Character, IOCase, Boolean, String[]> function, int priority) {
- super(value, options, pathSeparatorChar, priority);
+ super(value, options, pathSeparatorChar, priority, !optIgnoreCase);
+
this.function = function;
this.ioCase = optIgnoreCase ? IOCase.INSENSITIVE : IOCase.SENSITIVE;
+
if (!getNeedsDynamicEval()) {
wildcardPathElements = StringUtils.split(value, pathSeparatorChar);
}
@@ -402,28 +434,36 @@ public class RangerPathResourceMatcher extends RangerDefaultResourceMatcher {
}
boolean ret = function.apply(resourceValue, expandedValue, pathSeparatorChar, ioCase, wildcardPathElements);
- if (!ret) {
- RangerAccessRequest.ResourceMatchingScope scope = MapUtils.isNotEmpty(evalContext) ? (RangerAccessRequest.ResourceMatchingScope) evalContext.get(RangerAccessRequest.RANGER_ACCESS_REQUEST_SCOPE_STRING) : null;
- if (scope == RangerAccessRequest.ResourceMatchingScope.SELF_OR_CHILD) {
- int lastLevelSeparatorIndex = expandedValue.lastIndexOf(pathSeparatorChar);
- if (lastLevelSeparatorIndex != -1) {
- String shorterExpandedValue = expandedValue.substring(0, lastLevelSeparatorIndex);
- if (resourceValue.charAt(resourceValue.length()-1) == pathSeparatorChar) {
- resourceValue = resourceValue.substring(0, resourceValue.length()-1);
- }
- String[] shorterWildCardPathElements = StringUtils.split(shorterExpandedValue, pathSeparatorChar);
- ret = function.apply(resourceValue, shorterExpandedValue, pathSeparatorChar, ioCase, shorterWildCardPathElements);
- }
- }
- }
+
if (LOG.isDebugEnabled()) {
LOG.debug("<== RecursiveWildcardResourceMatcher.isMatch(resourceValue=" + resourceValue + ", expandedValue=" + expandedValue + ") : result:[" + ret + "]");
}
return ret;
}
+
+ @Override
+ public boolean isChildMatch(String resourceValue, Map<String, Object> evalContext) {
+ boolean ret = false;
+ String expandedValue = getExpandedValue(evalContext);
+ int lastLevelSeparatorIndex = expandedValue.lastIndexOf(pathSeparatorChar);
+
+ if (lastLevelSeparatorIndex != -1) {
+ String shorterExpandedValue = expandedValue.substring(0, lastLevelSeparatorIndex);
+
+ if (resourceValue.charAt(resourceValue.length() - 1) == pathSeparatorChar) {
+ resourceValue = resourceValue.substring(0, resourceValue.length() - 1);
+ }
+
+ String[] shorterWildCardPathElements = StringUtils.split(shorterExpandedValue, pathSeparatorChar);
+
+ ret = function.apply(resourceValue, shorterExpandedValue, pathSeparatorChar, ioCase, shorterWildCardPathElements);
+ }
+
+ return ret;
+ }
}
- static class RecursivePathResourceMatcher extends PathResourceMatcher {
+ static class RecursivePathResourceMatcher extends AbstractPathResourceMatcher {
String valueWithoutSeparator;
String valueWithSeparator;
@@ -431,7 +471,8 @@ public class RangerPathResourceMatcher extends RangerDefaultResourceMatcher {
final BiFunction<String, String, Boolean> fallbackFunction;
RecursivePathResourceMatcher(String value, Map<String, String> options, char pathSeparatorChar, BiFunction<String, String, Boolean> primaryFunction, BiFunction<String, String, Boolean> fallbackFunction, int priority) {
- super(value, options, pathSeparatorChar, priority);
+ super(value, options, pathSeparatorChar, priority, true);
+
this.primaryFunction = primaryFunction;
this.fallbackFunction = fallbackFunction;
}
@@ -465,28 +506,44 @@ public class RangerPathResourceMatcher extends RangerDefaultResourceMatcher {
if (!ret && noSeparator != null) {
final String withSeparator = getNeedsDynamicEval() ? noSeparator + pathSeparatorChar : valueWithSeparator;
- ret = fallbackFunction.apply(resourceValue, withSeparator);
- if (!ret) {
- RangerAccessRequest.ResourceMatchingScope scope = MapUtils.isNotEmpty(evalContext) ? (RangerAccessRequest.ResourceMatchingScope) evalContext.get(RangerAccessRequest.RANGER_ACCESS_REQUEST_SCOPE_STRING) : null;
- if (scope == RangerAccessRequest.ResourceMatchingScope.SELF_OR_CHILD) {
- final int lastLevelSeparatorIndex = noSeparator.lastIndexOf(pathSeparatorChar);
- if (lastLevelSeparatorIndex != -1) {
- final String shorterExpandedValue = noSeparator.substring(0, lastLevelSeparatorIndex);
- if (resourceValue.charAt(resourceValue.length() - 1) == pathSeparatorChar) {
- resourceValue = resourceValue.substring(0, resourceValue.length() - 1);
- }
- ret = primaryFunction.apply(resourceValue, shorterExpandedValue);
- }
- }
- }
+ ret = fallbackFunction.apply(resourceValue, withSeparator);
}
+
if (LOG.isDebugEnabled()) {
LOG.debug("<== RecursivePathResourceMatcher.isMatch(resourceValue=" + resourceValue + ", expandedValueWithoutTrailingSeparatorChar=" + noSeparator + ") : result:[" + ret + "]");
}
return ret;
}
- }
+ @Override
+ public boolean isChildMatch(String resourceValue, Map<String, Object> evalContext) {
+ boolean ret = false;
+ final String noSeparator;
+ if (getNeedsDynamicEval()) {
+ String expandedPolicyValue = getExpandedValue(evalContext);
+ noSeparator = expandedPolicyValue != null ? getStringToCompare(expandedPolicyValue) : null;
+ } else {
+ if (valueWithoutSeparator == null && value != null) {
+ valueWithoutSeparator = getStringToCompare(value);
+ valueWithSeparator = valueWithoutSeparator + pathSeparatorChar;
+ }
+ noSeparator = valueWithoutSeparator;
+ }
+ final int lastLevelSeparatorIndex = noSeparator.lastIndexOf(pathSeparatorChar);
+
+ if (lastLevelSeparatorIndex != -1) {
+ final String shorterExpandedValue = noSeparator.substring(0, lastLevelSeparatorIndex);
+
+ if (resourceValue.charAt(resourceValue.length() - 1) == pathSeparatorChar) {
+ resourceValue = resourceValue.substring(0, resourceValue.length() - 1);
+ }
+
+ ret = primaryFunction.apply(resourceValue, shorterExpandedValue);
+ }
+
+ return ret;
+ }
+ }
}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java
index 0cb3e0fed..c4ce30d36 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java
@@ -21,6 +21,7 @@ package org.apache.ranger.plugin.resourcematcher;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceElementMatchingScope;
import java.util.Map;
@@ -33,7 +34,7 @@ public interface RangerResourceMatcher {
boolean isMatchAny();
- boolean isMatch(Object resource, Map<String, Object> evalContext);
+ boolean isMatch(Object resource, ResourceElementMatchingScope matchingScope, Map<String, Object> evalContext);
boolean isCompleteMatch(String resource, Map<String, Object> evalContext);
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerURLResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerURLResourceMatcher.java
index ee2fff3ed..ce73b3006 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerURLResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerURLResourceMatcher.java
@@ -234,10 +234,10 @@ public class RangerURLResourceMatcher extends RangerDefaultResourceMatcher {
}
}
-final class CaseSensitiveURLRecursiveWildcardMatcher extends ResourceMatcher {
+final class CaseSensitiveURLRecursiveWildcardMatcher extends AbstractStringResourceMatcher {
private final char levelSeparatorChar;
CaseSensitiveURLRecursiveWildcardMatcher(String value, Map<String, String> options, char levelSeparatorChar) {
- super(value, options);
+ super(value, options, true);
this.levelSeparatorChar = levelSeparatorChar;
}
@@ -248,10 +248,10 @@ final class CaseSensitiveURLRecursiveWildcardMatcher extends ResourceMatcher {
int getPriority() { return 7 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0);}
}
-final class CaseInsensitiveURLRecursiveWildcardMatcher extends ResourceMatcher {
+final class CaseInsensitiveURLRecursiveWildcardMatcher extends AbstractStringResourceMatcher {
private final char levelSeparatorChar;
CaseInsensitiveURLRecursiveWildcardMatcher(String value, Map<String, String> options, char levelSeparatorChar) {
- super(value, options);
+ super(value, options, false);
this.levelSeparatorChar = levelSeparatorChar;
}
@@ -263,13 +263,13 @@ final class CaseInsensitiveURLRecursiveWildcardMatcher extends ResourceMatcher {
}
-abstract class RecursiveMatcher extends ResourceMatcher {
+abstract class RecursiveMatcher extends AbstractStringResourceMatcher {
final char levelSeparatorChar;
String valueWithoutSeparator;
String valueWithSeparator;
- RecursiveMatcher(String value, Map<String, String> options, char levelSeparatorChar) {
- super(value, options);
+ RecursiveMatcher(String value, Map<String, String> options, char levelSeparatorChar, boolean isCaseSensitive) {
+ super(value, options, isCaseSensitive);
this.levelSeparatorChar = levelSeparatorChar;
}
@@ -284,7 +284,7 @@ abstract class RecursiveMatcher extends ResourceMatcher {
final class CaseSensitiveURLRecursiveMatcher extends RecursiveMatcher {
CaseSensitiveURLRecursiveMatcher(String value, Map<String, String> options, char levelSeparatorChar) {
- super(value, options, levelSeparatorChar);
+ super(value, options, levelSeparatorChar, true);
}
@Override
@@ -316,7 +316,7 @@ final class CaseSensitiveURLRecursiveMatcher extends RecursiveMatcher {
final class CaseInsensitiveURLRecursiveMatcher extends RecursiveMatcher {
CaseInsensitiveURLRecursiveMatcher(String value, Map<String, String> options, char levelSeparatorChar) {
- super(value, options, levelSeparatorChar);
+ super(value, options, levelSeparatorChar, false);
}
@Override
@@ -345,4 +345,4 @@ final class CaseInsensitiveURLRecursiveMatcher extends RecursiveMatcher {
}
int getPriority() { return 8 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0);}
-}
\ No newline at end of file
+}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ResourceMatcher.java
index 5df4f1e3a..ad0942fbe 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ResourceMatcher.java
@@ -21,6 +21,8 @@ package org.apache.ranger.plugin.resourcematcher;
import org.apache.commons.lang.StringUtils;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceElementMatchType;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceElementMatchingScope;
import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
import org.apache.ranger.plugin.util.RangerRequestExprResolver;
import org.apache.ranger.plugin.util.StringTokenReplacer;
@@ -28,7 +30,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
-import java.util.Collection;
import java.util.Comparator;
import java.util.Map;
@@ -52,24 +53,54 @@ abstract class ResourceMatcher {
}
abstract boolean isMatch(String resourceValue, Map<String, Object> evalContext);
- abstract int getPriority();
- boolean isMatchAny() { return value != null && value.length() == 0; }
+ abstract boolean isPrefixMatch(String resourceValue, Map<String, Object> evalContext);
- boolean getNeedsDynamicEval() {
- return exprResolver != null || tokenReplacer != null;
+ abstract boolean isChildMatch(String resourceValue, Map<String, Object> evalContext);
+
+ final boolean isMatch(String resourceValue, ResourceElementMatchingScope matchingScope, Map<String, Object> evalContext) {
+ final ResourceElementMatchType matchType = getMatchType(resourceValue, matchingScope, evalContext);
+ final boolean ret;
+
+ if (matchType == ResourceElementMatchType.SELF) {
+ ret = true;
+ } else if (matchType == ResourceElementMatchType.PREFIX) {
+ ret = matchingScope == ResourceElementMatchingScope.SELF_OR_PREFIX;
+ } else if (matchType == ResourceElementMatchType.CHILD) {
+ ret = matchingScope == ResourceElementMatchingScope.SELF_OR_CHILD;
+ } else {
+ ret = false;
+ }
+
+ return ret;
}
- public boolean isMatchAny(Collection<String> resourceValues, Map<String, Object> evalContext) {
- if (resourceValues != null) {
- for (String resourceValue : resourceValues) {
- if (isMatch(resourceValue, evalContext)) {
- return true;
+ final ResourceElementMatchType getMatchType(String resourceValue, ResourceElementMatchingScope matchingScope, Map<String, Object> evalContext) {
+ ResourceElementMatchType ret = ResourceElementMatchType.NONE;
+
+ if (isMatch(resourceValue, evalContext)) {
+ ret = ResourceElementMatchType.SELF;
+ } else {
+ if (matchingScope == ResourceElementMatchingScope.SELF_OR_PREFIX) {
+ if (isPrefixMatch(resourceValue, evalContext)) {
+ ret = ResourceElementMatchType.PREFIX;
+ }
+ } else if (matchingScope == ResourceElementMatchingScope.SELF_OR_CHILD) {
+ if (isChildMatch(resourceValue, evalContext)) {
+ ret = ResourceElementMatchType.CHILD;
}
}
}
- return false;
+ return ret;
+ }
+
+ abstract int getPriority();
+
+ boolean isMatchAny() { return value != null && value.length() == 0; }
+
+ boolean getNeedsDynamicEval() {
+ return exprResolver != null || tokenReplacer != null;
}
@Override
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerResourceEvaluatorsRetriever.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerResourceEvaluatorsRetriever.java
index e60fe055b..2ba8135b1 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerResourceEvaluatorsRetriever.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerResourceEvaluatorsRetriever.java
@@ -21,7 +21,7 @@ package org.apache.ranger.plugin.util;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
-import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceElementMatchingScope;
import org.apache.ranger.plugin.policyengine.RangerResourceTrie;
import org.apache.ranger.plugin.policyresourcematcher.RangerResourceEvaluator;
import org.slf4j.Logger;
@@ -39,15 +39,19 @@ public class RangerResourceEvaluatorsRetriever {
private static final Logger LOG = LoggerFactory.getLogger(RangerResourceEvaluatorsRetriever.class);
public static <T extends RangerResourceEvaluator> Collection<T> getEvaluators(Map<String, RangerResourceTrie<T>> resourceTrie, Map<String, ?> resource) {
- return getEvaluators(resourceTrie, resource, RangerAccessRequest.ResourceMatchingScope.SELF);
+ return getEvaluators(resourceTrie, resource, null);
}
- public static <T extends RangerResourceEvaluator> Collection<T> getEvaluators(Map<String, RangerResourceTrie<T>> resourceTrie, Map<String, ?> resource, RangerAccessRequest.ResourceMatchingScope scope) {
+ public static <T extends RangerResourceEvaluator> Collection<T> getEvaluators(Map<String, RangerResourceTrie<T>> resourceTrie, Map<String, ?> resource, Map<String, ResourceElementMatchingScope> scopes) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyResourceEvaluatorsRetriever.getEvaluators(" + resource + ")");
}
Set<T> ret = null;
+ if (scopes == null) {
+ scopes = Collections.emptyMap();
+ }
+
if (MapUtils.isNotEmpty(resourceTrie) && MapUtils.isNotEmpty(resource)) {
Set<String> resourceKeys = resource.keySet();
@@ -63,7 +67,7 @@ public class RangerResourceEvaluatorsRetriever {
Object resourceValues = resource.get(resourceDefName);
Set<T> inheritedMatchers = trie.getInheritedEvaluators();
- Set<T> matchersForResource = trie.getEvaluatorsForResource(resourceValues, scope);
+ Set<T> matchersForResource = trie.getEvaluatorsForResource(resourceValues, scopes.get(resourceDefName));
if (LOG.isDebugEnabled()) {
LOG.debug("ResourceDefName:[" + resourceDefName + "], values:[" + resourceValues + "], resource-matchers:[" + matchersForResource + "], inherited-matchers:[" + inheritedMatchers + "]");
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPathResourceTrie.java b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPathResourceTrie.java
index 30a7215a6..d23509f86 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPathResourceTrie.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPathResourceTrie.java
@@ -21,6 +21,7 @@ package org.apache.ranger.plugin.policyengine;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceElementMatchingScope;
import org.apache.ranger.plugin.policyresourcematcher.RangerResourceEvaluator;
import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
import org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher;
@@ -71,7 +72,7 @@ public class TestPathResourceTrie {
@Test
public void testChildrenScope() {
- final RangerAccessRequest.ResourceMatchingScope scope = RangerAccessRequest.ResourceMatchingScope.SELF_OR_CHILD;
+ final ResourceElementMatchingScope scope = ResourceElementMatchingScope.SELF_OR_CHILD;
verifyEvaluators("/", scope, EVAL_, EVAL_nr, EVAL_HOME, EVAL_HOME_, EVAL_TMPnr, EVAL_TMP_nr, EVAL_TMPFILE, EVAL_TMPdTXT);
verifyEvaluators("/tmp", scope, EVAL_, EVAL_TMPnr, EVAL_TMP_nr, EVAL_TMP_AB);
@@ -84,9 +85,24 @@ public class TestPathResourceTrie {
verifyEvaluators("invalid: does-not-begin-with-sep", scope);
}
+ @Test
+ public void testPrefixScope() {
+ final ResourceElementMatchingScope scope = ResourceElementMatchingScope.SELF_OR_PREFIX;
+
+ verifyEvaluators("/", scope, EVAL_, EVAL_nr, EVAL_HOME, EVAL_HOME_, EVAL_TMPnr, EVAL_TMP_nr, EVAL_TMP_AB, EVAL_TMP_A_B, EVAL_TMP_AC_D_E_F, EVAL_TMPFILE, EVAL_TMPdTXT, EVAL_TMPA_B);
+ verifyEvaluators("/tmp", scope, EVAL_, EVAL_TMPnr, EVAL_TMP_nr, EVAL_TMP_AB, EVAL_TMP_A_B, EVAL_TMP_AC_D_E_F, EVAL_TMPFILE, EVAL_TMPdTXT, EVAL_TMPA_B);
+ verifyEvaluators("/tmp/", scope, EVAL_, EVAL_TMP_nr, EVAL_TMP_AB, EVAL_TMP_A_B, EVAL_TMP_AC_D_E_F);
+ verifyEvaluators("/tmp/a", scope, EVAL_, EVAL_TMP_AB, EVAL_TMP_A_B, EVAL_TMP_AC_D_E_F);
+ verifyEvaluators("/tmp/ac", scope, EVAL_, EVAL_TMP_AC_D_E_F);
+ verifyEvaluators("/tmp/ac/d", scope, EVAL_, EVAL_TMP_AC_D_E_F);
+ verifyEvaluators("/tmp/ac/d/e", scope, EVAL_, EVAL_TMP_AC_D_E_F);
+ verifyEvaluators("/unmatched", scope, EVAL_);
+ verifyEvaluators("invalid: does-not-begin-with-sep", scope);
+ }
+
@Test
public void testSelfScope() {
- final RangerAccessRequest.ResourceMatchingScope scope = RangerAccessRequest.ResourceMatchingScope.SELF;
+ final ResourceElementMatchingScope scope = ResourceElementMatchingScope.SELF;
verifyEvaluators("/", scope, EVAL_, EVAL_nr);
verifyEvaluators("/tmp", scope, EVAL_, EVAL_TMPnr);
@@ -99,7 +115,7 @@ public class TestPathResourceTrie {
verifyEvaluators("invalid: does-not-begin-with-sep", scope);
}
- private void verifyEvaluators(String resource, RangerAccessRequest.ResourceMatchingScope scope, RangerResourceEvaluator... evaluators) {
+ private void verifyEvaluators(String resource, ResourceElementMatchingScope scope, RangerResourceEvaluator... evaluators) {
Set<RangerResourceEvaluator> expected = evaluators.length == 0 ? null : new HashSet<>(Arrays.asList(evaluators));
Set<RangerResourceEvaluator> result = trie.getEvaluatorsForResource(resource, scope);
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 b2a5151e5..6a3875ad5 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
@@ -482,6 +482,20 @@ public class TestPolicyEngine {
runTestsFromResourceFiles(resourceFiles);
}
+ @Test
+ public void testAnyResourceAccess_Kafka() throws Exception {
+ String[] resourceFiles = {"/policyengine/test_policyengine_kafka.json"};
+
+ runTestsFromResourceFiles(resourceFiles);
+ }
+
+ @Test
+ public void testAnyResourceAccess_S3() throws Exception {
+ String[] resourceFiles = {"/policyengine/test_policyengine_aws_s3.json"};
+
+ runTestsFromResourceFiles(resourceFiles);
+ }
+
private void runTestsFromResourceFiles(String[] resourceNames) {
for(String resourceName : resourceNames) {
InputStream inStream = this.getClass().getResourceAsStream(resourceName);
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcherTest.java b/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcherTest.java
index e31437fc1..767795e81 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcherTest.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcherTest.java
@@ -19,6 +19,7 @@
package org.apache.ranger.plugin.resourcematcher;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceElementMatchingScope;
import org.junit.Test;
import java.util.Map;
@@ -42,7 +43,7 @@ public class RangerAbstractResourceMatcherTest {
static class AbstractMatcherWrapper extends RangerAbstractResourceMatcher {
@Override
- public boolean isMatch(Object resource, Map<String, Object> evalContext) {
+ public boolean isMatch(Object resource, ResourceElementMatchingScope matchingScope, Map<String, Object> evalContext) {
fail("This method is not expected to be used by test!");
return false;
}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcherTest.java b/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcherTest.java
index ad21b3239..e00bc834d 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcherTest.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcherTest.java
@@ -22,6 +22,7 @@ package org.apache.ranger.plugin.resourcematcher;
import com.google.common.collect.Lists;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceElementMatchingScope;
import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
import org.junit.Test;
@@ -59,7 +60,7 @@ public class RangerDefaultResourceMatcherTest {
RangerAccessRequestUtil.setCurrentUserInContext(evalContext, user);
MatcherWrapper matcher = new MatcherWrapper(policyValue, excludes);
- assertEquals(getMessage(row), result, matcher.isMatch(resource, evalContext));
+ assertEquals(getMessage(row), result, matcher.isMatch(resource, ResourceElementMatchingScope.SELF, evalContext));
}
}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcherTest.java b/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcherTest.java
index 8fe3be9cc..5e8efb720 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcherTest.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcherTest.java
@@ -22,7 +22,7 @@ package org.apache.ranger.plugin.resourcematcher;
import com.google.common.collect.Lists;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
-import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceElementMatchingScope;
import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
import org.junit.Test;
@@ -100,7 +100,7 @@ public class RangerPathResourceMatcherTest {
RangerAccessRequestUtil.setCurrentUserInContext(evalContext, user);
MatcherWrapper matcher = new MatcherWrapper(policyValue, optWildcard, isRecursive);
- assertEquals(getMessage(row), result, matcher.isMatch(resource, evalContext));
+ assertEquals(getMessage(row), result, matcher.isMatch(resource, ResourceElementMatchingScope.SELF, evalContext));
}
}
@@ -116,10 +116,9 @@ public class RangerPathResourceMatcherTest {
Map<String, Object> evalContext = new HashMap<>();
RangerAccessRequestUtil.setCurrentUserInContext(evalContext, user);
- evalContext.put(RangerAccessRequest.RANGER_ACCESS_REQUEST_SCOPE_STRING, RangerAccessRequest.ResourceMatchingScope.SELF_OR_CHILD);
MatcherWrapper matcher = new MatcherWrapper(policyValue, optWildcard, isRecursive);
- assertEquals(getMessage(row), result, matcher.isMatch(resource, evalContext));
+ assertEquals(getMessage(row), result, matcher.isMatch(resource, ResourceElementMatchingScope.SELF_OR_CHILD, evalContext));
}
}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/RangerURLResourceMatcherTest.java b/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/RangerURLResourceMatcherTest.java
index 2b7f27200..904cb61b2 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/RangerURLResourceMatcherTest.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/RangerURLResourceMatcherTest.java
@@ -22,6 +22,7 @@ package org.apache.ranger.plugin.resourcematcher;
import com.google.common.collect.Lists;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceElementMatchingScope;
import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
import org.junit.Test;
@@ -66,7 +67,7 @@ public class RangerURLResourceMatcherTest {
RangerAccessRequestUtil.setCurrentUserInContext(evalContext, user);
MatcherWrapper matcher = new MatcherWrapper(policyValue, optWildcard, isRecursive);
- assertEquals(getMessage(row), result, matcher.isMatch(resource, evalContext));
+ assertEquals(getMessage(row), result, matcher.isMatch(resource, ResourceElementMatchingScope.SELF, evalContext));
}
}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/TestResourceMatcher.java b/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/TestResourceMatcher.java
index ea7bc01f2..ef8ee6c32 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/TestResourceMatcher.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/TestResourceMatcher.java
@@ -28,6 +28,7 @@ import java.util.Map;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceElementMatchingScope;
import org.apache.ranger.plugin.resourcematcher.TestResourceMatcher.ResourceMatcherTestCases.TestCase;
import org.apache.ranger.plugin.resourcematcher.TestResourceMatcher.ResourceMatcherTestCases.TestCase.OneTest;
import org.junit.After;
@@ -112,7 +113,7 @@ public class TestResourceMatcher {
}
boolean expected = oneTest.result;
- boolean result = matcher.isMatch(oneTest.input, oneTest.evalContext);
+ boolean result = matcher.isMatch(oneTest.input, ResourceElementMatchingScope.SELF, oneTest.evalContext);
assertEquals("isMatch() failed! " + testCase.name + ":" + oneTest.name + ": input=" + oneTest.input, expected, result);
}
diff --git a/agents-common/src/test/resources/policyengine/aws_s3_tags.json b/agents-common/src/test/resources/policyengine/aws_s3_tags.json
new file mode 100644
index 000000000..be598893c
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/aws_s3_tags.json
@@ -0,0 +1,33 @@
+{
+ "op": "add_or_update",
+ "serviceName": "dev_aws-s3",
+ "tagDefinitions": {
+ "1": { "id": 1, "name": "PII" },
+ "2": { "id": 2, "name": "PII-VENDOR" }
+ },
+ "tags": {
+ "1": { "id": 1, "type": "PII" },
+ "2": { "id": 2, "type": "PII-VENDOR" }
+ },
+ "serviceResources": [
+ {
+ "id": 1, "serviceName": "dev_aws-s3",
+ "resourceElements": {
+ "bucketname": { "values": [ "mycompany" ] },
+ "objectpath": { "values": [ "/pii" ], "isRecursive": true }
+ }
+ },
+ {
+ "id": 2, "serviceName": "dev_aws-s3",
+ "resourceElements": {
+ "bucketname": { "values": [ "mycompany" ] },
+ "objectpath": { "values": [ "/vendor/pii" ], "isRecursive": true }
+ }
+ }
+ ],
+ "resourceToTagIds": {
+ "1": [ 1 ],
+ "2": [ 2 ]
+ }
+}
+
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_aws.json b/agents-common/src/test/resources/policyengine/test_policyengine_aws.json
index 118bef534..56e082ad8 100644
--- a/agents-common/src/test/resources/policyengine/test_policyengine_aws.json
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_aws.json
@@ -108,14 +108,14 @@
"tests":[
{"name":"ALLOW 'write /tmp/scott' for u=scott for scope SELF_OR_CHILD",
"request":{
- "resource":{"elements":{"path":"/tmp/scott"}}, "resourceMatchingScope": "SELF_OR_CHILD",
+ "resource":{"elements":{"path":"/tmp/scott"}}, "resourceElementMatchingScopes": { "path": "SELF_OR_CHILD" },
"accessType":"write","user":"scott","userGroups":[],"requestData":"write /tmp/scott"
},
"result":{"isAudited":true,"isAllowed":true,"policyId": 200}
},
{"name":"DENY 'ANY /tmp/scott' for u=joe for scope SELF_OR_CHILD",
"request":{
- "resource":{"elements":{"path":"/tmp/scott"}}, "resourceMatchingScope": "SELF_OR_CHILD",
+ "resource":{"elements":{"path":"/tmp/scott"}}, "resourceElementMatchingScopes": { "path": "SELF_OR_CHILD" },
"accessType":"","user":"joe","userGroups":[],"requestData":"ANY /tmp/scott"
},
"result":{"isAudited":false,"isAllowed":false,"policyId": -1}
@@ -136,7 +136,7 @@
},
{"name":"ALLOW 'write /user/dir' for u=scott for scope SELF_OR_CHILD",
"request":{
- "resource":{"elements":{"path":"/user/dir"}}, "resourceMatchingScope": "SELF_OR_CHILD",
+ "resource":{"elements":{"path":"/user/dir"}}, "resourceElementMatchingScopes": { "path": "SELF_OR_CHILD" },
"accessType":"write","user":"scott","userGroups":[],"requestData":"write /user/dir"
},
"result":{"isAudited":true,"isAllowed":true,"policyId": 400}
@@ -150,14 +150,14 @@
},
{"name":"DENY 'ANY /user/dir' for u=joe for scope SELF_OR_CHILD",
"request":{
- "resource":{"elements":{"path":"/user/dir"}}, "resourceMatchingScope": "SELF_OR_CHILD",
+ "resource":{"elements":{"path":"/user/dir"}}, "resourceElementMatchingScopes": { "path": "SELF_OR_CHILD" },
"accessType":"","user":"joe","userGroups":[],"requestData":"ANY /user/dir"
},
"result":{"isAudited":true,"isAllowed":false,"policyId": -1}
},
{"name":"ALLOW 'read /user/scott' for u=scott for scope SELF_OR_CHILD",
"request":{
- "resource":{"elements":{"path":"/user/scott"}}, "resourceMatchingScope": "SELF_OR_CHILD",
+ "resource":{"elements":{"path":"/user/scott"}}, "resourceElementMatchingScopes": { "path": "SELF_OR_CHILD" },
"accessType":"read","user":"scott","userGroups":[],"requestData":"read /tmp/scott"
},
"result":{"isAudited":true,"isAllowed":true,"policyId": 500}
@@ -171,7 +171,7 @@
},
{"name":"ALLOW 'ANY /' for u=user1",
"request":{
- "resource":{"elements":{"path":"/"}}, "resourceMatchingScope": "SELF_OR_CHILD",
+ "resource":{"elements":{"path":"/"}}, "resourceElementMatchingScopes": { "path": "SELF_OR_CHILD" },
"accessType":"","user":"user1","userGroups":[],"requestData":"ANY /"
},
"result":{"isAudited":true,"isAllowed":true,"policyId":20}
@@ -179,7 +179,7 @@
,
{"name":"ALLOW 'ANY /tmp' for u=user1",
"request":{
- "resource":{"elements":{"path":"/tmp"}}, "resourceMatchingScope": "SELF_OR_CHILD",
+ "resource":{"elements":{"path":"/tmp"}}, "resourceElementMatchingScopes": { "path": "SELF_OR_CHILD" },
"accessType":"","user":"user1","userGroups":[],"requestData":"ANY /tmp"
},
"result":{"isAudited":true,"isAllowed":true,"policyId":40}
@@ -187,7 +187,7 @@
,
{"name":"ALLOW 'ANY /tmp/' for u=user1",
"request":{
- "resource":{"elements":{"path":"/tmp/"}}, "resourceMatchingScope": "SELF_OR_CHILD",
+ "resource":{"elements":{"path":"/tmp/"}}, "resourceElementMatchingScopes": { "path": "SELF_OR_CHILD" },
"accessType":"","user":"user1","userGroups":[],"requestData":"ANY /tmp/"
},
"result":{"isAudited":true,"isAllowed":true,"policyId":40}
@@ -195,7 +195,7 @@
,
{"name":"ALLOW 'ANY /tmp/a' for u=user1",
"request":{
- "resource":{"elements":{"path":"/tmp/a"}}, "resourceMatchingScope": "SELF_OR_CHILD",
+ "resource":{"elements":{"path":"/tmp/a"}}, "resourceElementMatchingScopes": { "path": "SELF_OR_CHILD" },
"accessType":"","user":"user1","userGroups":[],"requestData":"ANY /tmp/a"
},
"result":{"isAudited":true,"isAllowed":true,"policyId":50}
@@ -203,7 +203,7 @@
,
{"name":"DENY 'ANY /tmp/ac' for u=user1",
"request":{
- "resource":{"elements":{"path":"/tmp/ac"}}, "resourceMatchingScope": "SELF_OR_CHILD",
+ "resource":{"elements":{"path":"/tmp/ac"}}, "resourceElementMatchingScopes": { "path": "SELF_OR_CHILD" },
"accessType":"","user":"user1","userGroups":[],"requestData":"ANY /tmp/ac"
},
"result":{"isAudited":false,"isAllowed":false,"policyId":-1}
@@ -211,7 +211,7 @@
,
{"name":"DENY 'ANY /tmp/ac/d' for u=user1",
"request":{
- "resource":{"elements":{"path":"/tmp/ac/d"}}, "resourceMatchingScope": "SELF_OR_CHILD",
+ "resource":{"elements":{"path":"/tmp/ac/d"}}, "resourceElementMatchingScopes": { "path": "SELF_OR_CHILD" },
"accessType":"","user":"user1","userGroups":[],"requestData":"ANY /tmp/ac/d"
},
"result":{"isAudited":false,"isAllowed":false,"policyId":-1}
@@ -219,7 +219,7 @@
,
{"name":"ALLOW 'ANY /tmp/ac/d/e' for u=user1",
"request":{
- "resource":{"elements":{"path":"/tmp/ac/d/e"}}, "resourceMatchingScope": "SELF_OR_CHILD",
+ "resource":{"elements":{"path":"/tmp/ac/d/e"}}, "resourceElementMatchingScopes": { "path": "SELF_OR_CHILD" },
"accessType":"","user":"user1","userGroups":[],"requestData":"ANY /tmp/ac/d/e"
},
"result":{"isAudited":true,"isAllowed":true,"policyId":10}
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_aws_s3.json b/agents-common/src/test/resources/policyengine/test_policyengine_aws_s3.json
new file mode 100644
index 000000000..e2373164c
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_aws_s3.json
@@ -0,0 +1,211 @@
+{
+ "serviceName": "dev_aws-s3",
+
+ "serviceDef": {
+ "name": "aws-s3", "id": 1,
+ "resources": [
+ { "name": "bucketname", "parent":"", "level": 1, "mandatory": true, "lookupSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": true, "ignoreCase": false }, "label": "Bucket Name", "description": "Bucket Name" },
+ { "name": "objectpath", "parent":"bucketname", "level": 2, "mandatory": true, "lookupSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher", "matcherOptions": { "wildCard": true, "ignoreCase": false }, "label": "Object Path", "description": "Object Path" }
+ ],
+ "accessTypes": [
+ { "name": "read", "label": "Read" },
+ { "name": "write", "label": "Write" },
+ { "name": "delete", "label": "Delete" }
+ ]
+ },
+
+ "policies": [
+ {
+ "id": 10, "name": "s3://mycompany/public", "isEnabled": true, "isAuditEnabled": true,
+ "resources": {
+ "bucketname": { "values": [ "mycompany" ] },
+ "objectpath": { "values": [ "/public" ], "isRecursive": true } },
+ "policyItems": [
+ { "accesses": [ { "type": "read", "isAllowed": true } ], "groups": [ "public" ] }
+ ]
+ },
+ {
+ "id": 20, "name": "s3://mycompany/home/{USER}", "isEnabled": true, "isAuditEnabled": true,
+ "resources": {
+ "bucketname": { "values": [ "mycompany" ] },
+ "objectpath": { "values": [ "/home/{USER}" ], "isRecursive": true } },
+ "policyItems": [
+ { "accesses": [ { "type": "read", "isAllowed": true }, { "type": "write", "isAllowed": true }, { "type": "delete", "isAllowed": true } ], "users": [ "{USER}" ] }
+ ]
+ },
+ {
+ "id": 30, "name": "s3://mycompany/dept/hr", "isEnabled": true, "isAuditEnabled": true,
+ "resources": {
+ "bucketname": { "values": [ "mycompany" ] },
+ "objectpath": { "values": [ "/dept/hr" ], "isRecursive": true } },
+ "policyItems": [
+ { "accesses": [ { "type": "read", "isAllowed": true }, { "type": "write", "isAllowed": true }, { "type": "delete", "isAllowed": true } ], "groups": [ "hr-admins" ] },
+ { "accesses": [ { "type": "read", "isAllowed": true } ], "groups": [ "hr-users" ] }
+ ]
+ }
+ ],
+ "tagPolicyInfo": {
+ "serviceName":"tagdev",
+ "serviceDef": {
+ "name": "tag", "id": 100,
+ "resources": [
+ { "name": "tag", "type": "string", "level": 1, "parent": "", "mandatory": true, "lookupSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": true, "ignoreCase": false }, "label": "TAG", "description": "TAG"
+ }
+ ],
+ "accessTypes": [
+ { "name": "aws-s3:read", "label": "aws-s3:read" },
+ { "name": "aws-s3:write", "label": "aws-s3:write" },
+ { "name": "aws-s3:delete", "label": "aws-s3:delete" }
+ ],
+ "contextEnrichers": [
+ {
+ "name" : "TagEnricher",
+ "enricher" : "org.apache.ranger.plugin.contextenricher.RangerTagEnricher",
+ "enricherOptions" : {
+ "tagRetrieverClassName": "org.apache.ranger.plugin.contextenricher.RangerFileBasedTagRetriever",
+ "tagRefresherPollingInterval": 60000,
+ "serviceTagsFileName": "/policyengine/aws_s3_tags.json"}
+ }
+ ]
+ },
+ "tagPolicies": [
+ {
+ "id": 1001, "name": "PII", "isEnabled": true, "isAuditEnabled": true,
+ "resources": { "tag": { "values": [ "PII" ] } },
+ "policyItems": [
+ { "accesses": [ { "type": "aws-s3:read", "isAllowed": true } ], "users": [ "user3" ] }
+ ]
+ },
+ {
+ "id": 1002, "name": "PII-VENDOR", "isEnabled": true, "isAuditEnabled": true,
+ "resources": { "tag": { "values": [ "PII-VENDOR" ] } },
+ "policyItems": [
+ { "accesses": [ { "type": "aws-s3:read", "isAllowed": true } ], "users": [ "user4" ] }
+ ]
+ }
+ ]
+ },
+ "tests": [
+ {
+ "name": "Verify user1 has read access to some object under s3://mycompany",
+ "request": {
+ "resource": { "elements": { "bucketname": "mycompany", "objectpath": "/" } }, "resourceElementMatchingScopes": { "objectpath": "SELF_OR_PREFIX" },
+ "accessType": "read", "user": "user1"
+ },
+ "result": { "isAudited": true, "isAllowed": true, "policyId": 10 }
+ },
+ {
+ "name": "Verify user1 has read access to some object under s3://mycompany/public",
+ "request": {
+ "resource": { "elements": { "bucketname": "mycompany", "objectpath": "/public/" } }, "resourceElementMatchingScopes": { "objectpath": "SELF_OR_PREFIX" },
+ "accessType": "read", "user": "user1"
+ },
+ "result": { "isAudited": true, "isAllowed": true, "policyId": 10 }
+ },
+ {
+ "name": "Verify user1 has no write access to any object under s3://mycompany/public",
+ "request": {
+ "resource": { "elements": { "bucketname": "mycompany", "objectpath": "/public/" } }, "resourceElementMatchingScopes": { "objectpath": "SELF_OR_PREFIX" },
+ "accessType": "write", "user": "user1"
+ },
+ "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+ },
+ {
+ "name": "Verify user1 has write access to some object under s3://mycompany/home",
+ "request": {
+ "resource": { "elements": { "bucketname": "mycompany", "objectpath": "/home" } }, "resourceElementMatchingScopes": { "objectpath": "SELF_OR_PREFIX" },
+ "accessType": "write", "user": "user1"
+ },
+ "result": { "isAudited": true, "isAllowed": true, "policyId": 20 }
+ },
+ {
+ "name": "Verify user1 has no write access to any object under s3://mycompany/dept",
+ "request": {
+ "resource": { "elements": { "bucketname": "mycompany", "objectpath": "/dept" } }, "resourceElementMatchingScopes": { "objectpath": "SELF_OR_PREFIX" },
+ "accessType": "write", "user": "user1"
+ },
+ "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+ },
+ {
+ "name": "Verify user3 has read access to some objects under s3://mycompany/",
+ "request": {
+ "resource": { "elements": { "bucketname": "mycompany", "objectpath": "/" } }, "resourceElementMatchingScopes": { "objectpath": "SELF_OR_PREFIX" },
+ "accessType": "read", "user": "user3"
+ },
+ "result": { "isAudited": true, "isAllowed": true, "policyId": 1001 }
+ },
+ {
+ "name": "Verify user3 has write access to some objects under s3://mycompany/",
+ "request": {
+ "resource": { "elements": { "bucketname": "mycompany", "objectpath": "/" } }, "resourceElementMatchingScopes": { "objectpath": "SELF_OR_PREFIX" },
+ "accessType": "write", "user": "user3"
+ },
+ "result": { "isAudited": true, "isAllowed": true, "policyId": 20 }
+ },
+ {
+ "name": "Verify user3 has read access to some objects under s3://mycompany/pii",
+ "request": {
+ "resource": { "elements": { "bucketname": "mycompany", "objectpath": "/pii" } }, "resourceElementMatchingScopes": { "objectpath": "SELF_OR_PREFIX" },
+ "accessType": "read", "user": "user3"
+ },
+ "result": { "isAudited": true, "isAllowed": true, "policyId": 1001 }
+ },
+ {
+ "name": "Verify user3 has no write access to any object under s3://mycompany/pii",
+ "request": {
+ "resource": { "elements": { "bucketname": "mycompany", "objectpath": "/pii" } }, "resourceElementMatchingScopes": { "objectpath": "SELF_OR_PREFIX" },
+ "accessType": "write", "user": "user3"
+ },
+ "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+ },
+ {
+ "name": "Verify user3 has no read access to any object under s3://mycompany/vendor/pii",
+ "request": {
+ "resource": { "elements": { "bucketname": "mycompany", "objectpath": "/vendor/pii" } }, "resourceElementMatchingScopes": { "objectpath": "SELF_OR_PREFIX" },
+ "accessType": "read", "user": "user3"
+ },
+ "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+ },
+ {
+ "name": "Verify user4 has read access to some objects under s3://mycompany/vendor",
+ "request": {
+ "resource": { "elements": { "bucketname": "mycompany", "objectpath": "/vendor" } }, "resourceElementMatchingScopes": { "objectpath": "SELF_OR_PREFIX" },
+ "accessType": "read", "user": "user4"
+ },
+ "result": { "isAudited": true, "isAllowed": true, "policyId": 1002 }
+ },
+ {
+ "name": "Verify user4 has read access to some objects under s3://mycompany/vendor/pii",
+ "request": {
+ "resource": { "elements": { "bucketname": "mycompany", "objectpath": "/vendor/pii" } }, "resourceElementMatchingScopes": { "objectpath": "SELF_OR_PREFIX" },
+ "accessType": "read", "user": "user4"
+ },
+ "result": { "isAudited": true, "isAllowed": true, "policyId": 1002 }
+ },
+ {
+ "name": "Verify user4 has read access to some objects under s3://mycompany/vendor/pii/test",
+ "request": {
+ "resource": { "elements": { "bucketname": "mycompany", "objectpath": "/vendor/pii/test" } }, "resourceElementMatchingScopes": { "objectpath": "SELF_OR_PREFIX" },
+ "accessType": "read", "user": "user4"
+ },
+ "result": { "isAudited": true, "isAllowed": true, "policyId": 1002 }
+ },
+ {
+ "name": "Verify user4 has no read access to any object under s3://mycompany/pii",
+ "request": {
+ "resource": { "elements": { "bucketname": "mycompany", "objectpath": "/pii" } }, "resourceElementMatchingScopes": { "objectpath": "SELF_OR_PREFIX" },
+ "accessType": "read", "user": "user4"
+ },
+ "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+ },
+ {
+ "name": "Verify user4 has no write access to any object under s3://mycompany/pii",
+ "request": {
+ "resource": { "elements": { "bucketname": "mycompany", "objectpath": "/pii" } }, "resourceElementMatchingScopes": { "objectpath": "SELF_OR_PREFIX" },
+ "accessType": "write", "user": "user4"
+ },
+ "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+ }
+ ]
+}
+
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_kafka.json b/agents-common/src/test/resources/policyengine/test_policyengine_kafka.json
new file mode 100644
index 000000000..89ab9c0b5
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_kafka.json
@@ -0,0 +1,157 @@
+{
+ "serviceName": "kafkadev",
+
+ "serviceDef": {
+ "name": "kafka", "id": 9,
+ "resources": [
+ { "name": "topic", "level": 1, "mandatory": true, "lookupSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": true, "ignoreCase": true }, "label": "Topic", "description": "Topic", "accessTypeRestrictions": [ "create", "delete", "configure", "alter", "alter_configs", "describe", "describe_configs", "consume", "publish" ] },
+ { "name": "transactionalid", "level": 1, "mandatory": true, "lookupSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": true, "ignoreCase": true }, "label": "Transactional Id", "description": "Transactional Id", "accessTypeRestrictions": [ "describe", "publish" ] },
+ { "name": "cluster", "level": 1, "mandatory": true, "lookupSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": true, "ignoreCase": true }, "label": "Cluster", "description": "Cluster", "accessTypeRestrictions": [ "create", "configure", "alter", "alter_configs", "describe", "describe_configs", "kafka_admin", "idempotent_write", "cluster_action" ] },
+ { "name": "delegationtoken", "level": 1, "mandatory": true, "lookupSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": true, "ignoreCase": true }, "label": "Delegation Token", "description": "Delegation Token", "accessTypeRestrictions": [ "describe" ] },
+ { "name": "consumergroup", "level": 1, "mandatory": true, "lookupSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": true, "ignoreCase": true }, "label": "Consumer Group", "description": "Consumer Group", "accessTypeRestrictions": [ "consume", "describe", "delete" ] }
+ ],
+ "accessTypes": [
+ { "name": "publish", "label": "Publish", "impliedGrants": [ "describe" ] },
+ { "name": "consume", "label": "Consume", "impliedGrants": [ "describe" ] },
+ { "name": "configure", "label": "Configure", "impliedGrants": [ "describe" ] },
+ { "name": "describe", "label": "Describe" },
+ { "name": "kafka_admin", "label": "Kafka Admin", "impliedGrants": [ "publish", "consume", "configure", "describe", "create", "delete", "describe_configs", "alter_configs", "alter", "idempotent_write", "cluster_action" ] },
+ { "name": "create", "label": "Create" },
+ { "name": "delete", "label": "Delete", "impliedGrants": [ "describe" ] },
+ { "name": "idempotent_write", "label": "Idempotent Write" },
+ { "name": "describe_configs", "label": "Describe Configs" },
+ { "name": "alter_configs", "label": "Alter Configs" },
+ { "name": "cluster_action", "label": "Cluster Action" },
+ { "name": "alter", "label": "alter" }
+ ]
+ },
+
+ "policies": [
+ {
+ "id": 10,"name": "10: test-topic publish/consume allowed","isEnabled": true,"isAuditEnabled": true,
+ "resources": { "topic": {"values": [ "test-topic-1" ], "isRecursive": true } },
+ "policyItems": [
+ {"accesses": [{"type": "publish", "isAllowed": true },{"type": "consume", "isAllowed": true }], "users": [ "user1" ], "groups": [] }
+ ]
+ },
+ {
+ "id": 101,"name": "101: test-topic publish/consume allowed","isEnabled": true,"isAuditEnabled": true,
+ "resources": { "topic": {"values": [ "test-topic-2" ], "isRecursive": true } },
+ "policyItems": [
+ {"accesses": [{"type": "publish", "isAllowed": true },{"type": "consume", "isAllowed": true }], "users": [ "user2" ], "groups": [] }
+ ]
+ },
+ {
+ "id": 102,"name": "102: test-topic publish/consume allowed","isEnabled": true,"isAuditEnabled": true,
+ "resources": {"topic": {"values": [ "test-topic-1","test-topic-4" ], "isRecursive": true } },
+ "policyItems": [
+ {"accesses": [{"type": "consume", "isAllowed": true }], "users": [ "user3" ], "groups": [] }
+ ]
+ },
+ {
+ "id": 103,"name": "103: test-topic publish/consume allowed","isEnabled": true,"isAuditEnabled": true,
+ "resources": { "topic": {"values": [ "test-topic-1","test-topic-5" ], "isRecursive": true } },
+ "policyItems": [
+ {"accesses": [{"type": "consume", "isAllowed": true }], "users": [ "user4", "user5" ], "groups": [] }
+ ]
+ },
+ {
+ "id": 104,"name": "104: test-topic publish/consume allowed","isEnabled": true,"isAuditEnabled": true,
+ "resources": { "topic": {"values": [ "test-topic-7" ], "isRecursive": true } },
+ "policyItems": [
+ {"accesses": [{"type": "publish", "isAllowed": true },{"type": "consume", "isAllowed": true }], "users": [ "user6" ], "groups": [] }
+ ]
+ },
+ {
+ "id": 20,"name": "02: transation id","isEnabled": true,"isAuditEnabled": true,"policyType": 1,
+ "resources": { "delegationtoken": {"values": [ "tid-1" ], "isRecursive": true } },
+ "policyItems": [
+ {"accesses": [{"type": "publish", "isAllowed": true }], "users": [ "user1" ], "groups": [] }
+ ]
+ },
+ {
+ "id": 30,"name": "create/alter access for user1 on cluster-1","isEnabled": true,"isAuditEnabled": true,
+ "resources": { "cluster": {"values": [ "cluseter-1" ], "isRecursive": true } },
+ "policyItems": [
+ {"accesses": [{"type": "create", "isAllowed": true },{"type": "alter", "isAllowed": true }], "users": [ "user1" ], "groups": [] }
+ ]
+ },
+ {
+ "id": 301,"name": "Alter access for user31 on cluster-2","isEnabled": true,"isAuditEnabled": true,
+ "resources": { "cluster": {"values": [ "cluster-2" ], "isRecursive": true } },
+ "policyItems": [
+ {"accesses": [{"type": "alter", "isAllowed": true }], "users": [ "user31" ], "groups": [] }
+ ]
+ },
+ {
+ "id": 302,"name": "Alter access for user32 on cluster-1","isEnabled": true,"isAuditEnabled": true,
+ "resources": { "cluster": {"values": [ "cluseter-1" ], "isRecursive": true } },
+ "policyItems": [
+ {"accesses": [{"type": "alter", "isAllowed": true }], "users": [ "user32" ], "groups": [] }
+ ]
+ },
+ {
+ "id": 40,"name": "delegationtoken","isEnabled": true,"isAuditEnabled": true,
+ "resources": { "delegationtoken": {"values": [ "dt-1" ], "isRecursive": true } },
+ "policyItems": [
+ {"accesses": [{"type": "describe", "isAllowed": true }], "users": [ "user1" ], "groups": [] }
+ ]
+ },
+ {
+ "id": 50,"name": "consumergroup-1 access","isEnabled": true,"isAuditEnabled": true,
+ "resources": { "consumergroup": {"values": [ "consumergroup-1" ], "isRecursive": true } },
+ "policyItems": [
+ {"accesses": [{"type": "consume", "isAllowed": true }], "users": [ "user1" ], "groups": [] }
+ ]
+ },
+ {
+ "id": 52,"name": "consumergroup-2 access for user4","isEnabled": true,"isAuditEnabled": true,
+ "resources": { "consumergroup": {"values": [ "consumergroup-2" ], "isRecursive": true } },
+ "policyItems": [
+ {"accesses": [{"type": "consume", "isAllowed": true }], "users": [ "user4" ], "groups": [] }
+ ]
+ },
+ {
+ "id": 110,"name": "110: test-topic-1/2 consume allowed for user2","isEnabled": true,"isAuditEnabled": true,
+ "resources": { "topic": {"values": [ "test-topic-1", "test-topic-2" ], "isRecursive": true } },
+ "policyItems": [
+ {"accesses": [{"type": "consume", "isAllowed": true }], "users": [ "user2" ], "groups": [] }
+ ]
+ },
+ {
+ "id": 111, "name": "110: new-topic-1/2 allowed for user2", "isEnabled": true, "isAuditEnabled": true,
+ "resources": { "topic": { "values": [ "new-topic-1", "new-topic-2" ], "isRecursive": true } },
+ "policyItems": [
+ { "accesses": [ { "type": "consume", "isAllowed": true } ], "users": [ "user2" ], "groups": [] }
+ ]
+ }
+ ],
+ "tests": [
+ {
+ "name": "Any topic Consume access for user3",
+ "request": {
+ "resource": { "elements": { "topic": "" } }, "resourceElementMatchingScopes": { "topic": "SELF_OR_PREFIX" },
+ "accessType": "consume", "user": "user3", "userGroups": []
+ },
+ "result": { "isAudited": true, "isAllowed": true, "policyId": 102 }
+ },
+ {
+ "name": "Any consumergroup consume access for user1",
+ "request": {
+ "resource": { "elements": { "consumergroup": "" } }, "resourceElementMatchingScopes": { "consumergroup": "SELF_OR_PREFIX" },
+ "accessType": "consume", "user": "user1", "userGroups": []
+ },
+ "result": { "isAudited": true, "isAllowed": true," policyId": 50 }
+ },
+
+ {
+ "name": "Any consumergroup consume access for user3",
+ "request": {
+ "resource": { "elements": { "consumergroup": "" } }, "resourceElementMatchingScopes": { "consumergroup": "SELF_OR_PREFIX" },
+ "accessType": "consume", "user": "user3", "userGroups": []
+ },
+ "result": { "isAudited": true, "isAllowed": false, "policyId": -1 }
+ }
+ ]
+}
+