Repository: incubator-ranger
Updated Branches:
  refs/heads/ranger-0.6 76867e570 -> 9dfde6de9


RANGER-1261: fix path matching inconsistencies and wildcard treatment

Signed-off-by: Madhan Neethiraj <mad...@apache.org>
(cherry picked from commit 22029847559b3881cdc3176b15e545e847ef6d7c)


Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/9dfde6de
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/9dfde6de
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/9dfde6de

Branch: refs/heads/ranger-0.6
Commit: 9dfde6de92799d7d923cf8eb11bbdc8788d6664c
Parents: 76867e5
Author: Abhay Kulkarni <akulka...@hortonworks.com>
Authored: Mon Dec 5 20:49:52 2016 -0800
Committer: Madhan Neethiraj <mad...@apache.org>
Committed: Fri Jan 6 19:03:43 2017 -0800

----------------------------------------------------------------------
 .../RangerPathResourceMatcher.java              | 87 +++++++++++++++++++-
 .../test_resourcematcher_path.json              | 61 ++++++++++++++
 .../src/test/resources/hdfs-policies.json       | 10 +++
 3 files changed, 155 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/9dfde6de/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java
----------------------------------------------------------------------
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 a9ac84c..aeb9fb0 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
@@ -130,10 +130,12 @@ public class RangerPathResourceMatcher extends 
RangerDefaultResourceMatcher {
                        ret = optIgnoreCase ? new 
CaseInsensitiveRecursiveWildcardMatcher(policyValue, pathSeparatorChar)
                                                                : new 
CaseSensitiveRecursiveWildcardMatcher(policyValue, pathSeparatorChar);
                } else {
-                       ret = optIgnoreCase ? new 
CaseInsensitiveStartsWithMatcher(policyValue) : new 
CaseSensitiveStartsWithMatcher(policyValue);
+                       ret = optIgnoreCase ? new 
CaseInsensitiveRecursiveMatcher(policyValue, pathSeparatorChar) : new 
CaseSensitiveRecursiveMatcher(policyValue, pathSeparatorChar);
                }
 
-               ret.setDelimiters(startDelimiterChar, endDelimiterChar, 
escapeChar, tokenPrefix);
+               if (optReplaceTokens) {
+                       ret.setDelimiters(startDelimiterChar, endDelimiterChar, 
escapeChar, tokenPrefix);
+               }
 
                return ret;
        }
@@ -172,7 +174,6 @@ public class RangerPathResourceMatcher extends 
RangerDefaultResourceMatcher {
                return ret;
        }
 
-
        public StringBuilder toString(StringBuilder sb) {
                sb.append("RangerPathResourceMatcher={");
 
@@ -214,3 +215,83 @@ final class CaseInsensitiveRecursiveWildcardMatcher 
extends ResourceMatcher {
        int getPriority() { return 8 + (getNeedsDynamicEval() ? 
DYNAMIC_EVALUATION_PENALTY : 0);}
 
 }
+
+abstract class RecursiveMatcher extends ResourceMatcher {
+       final char levelSeparatorChar;
+       String valueWithoutSeparator = null;
+       String valueWithSeparator = null;
+
+       RecursiveMatcher(String value, char levelSeparatorChar) {
+               super(value);
+               this.levelSeparatorChar = levelSeparatorChar;
+       }
+
+       String getStringToCompare(String policyValue) {
+               return (policyValue.lastIndexOf(levelSeparatorChar) == 
policyValue.length()-1) ?
+                       policyValue.substring(0, policyValue.length()-1) : 
policyValue;
+       }
+}
+
+final class CaseSensitiveRecursiveMatcher extends RecursiveMatcher {
+       CaseSensitiveRecursiveMatcher(String value, char levelSeparatorChar) {
+               super(value, levelSeparatorChar);
+       }
+
+       @Override
+       boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+
+               final String noSeparator;
+               if (getNeedsDynamicEval()) {
+                       noSeparator = 
getStringToCompare(getExpandedValue(evalContext));
+               } else {
+                       if (valueWithoutSeparator == null) {
+                               valueWithoutSeparator = 
getStringToCompare(value);
+                               valueWithSeparator = valueWithoutSeparator + 
Character.toString(levelSeparatorChar);
+                       }
+                       noSeparator = valueWithoutSeparator;
+               }
+
+               boolean ret = StringUtils.equals(resourceValue, noSeparator);
+
+               if (!ret) {
+                       final String withSeparator = getNeedsDynamicEval() ? 
noSeparator + Character.toString(levelSeparatorChar) : valueWithSeparator;
+                       ret = StringUtils.startsWith(resourceValue, 
withSeparator);
+               }
+
+               return ret;
+       }
+       int getPriority() { return 7 + (getNeedsDynamicEval() ? 
DYNAMIC_EVALUATION_PENALTY : 0);}
+}
+
+final class CaseInsensitiveRecursiveMatcher extends RecursiveMatcher {
+       CaseInsensitiveRecursiveMatcher(String value, char levelSeparatorChar) {
+               super(value, levelSeparatorChar);
+       }
+
+       @Override
+       boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+
+               final String noSeparator;
+               if (getNeedsDynamicEval()) {
+                       noSeparator = 
getStringToCompare(getExpandedValue(evalContext));
+               } else {
+                       if (valueWithoutSeparator == null) {
+                               valueWithoutSeparator = 
getStringToCompare(value);
+                               valueWithSeparator = valueWithoutSeparator + 
Character.toString(levelSeparatorChar);
+                       }
+                       noSeparator = valueWithoutSeparator;
+               }
+
+               boolean ret = StringUtils.equalsIgnoreCase(resourceValue, 
noSeparator);
+
+               if (!ret) {
+                       final String withSeparator = getNeedsDynamicEval() ? 
noSeparator + Character.toString(levelSeparatorChar) : valueWithSeparator;
+                       ret = StringUtils.startsWithIgnoreCase(resourceValue, 
withSeparator);
+               }
+
+               return ret;
+       }
+
+       int getPriority() { return 8 + (getNeedsDynamicEval() ? 
DYNAMIC_EVALUATION_PENALTY : 0);}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/9dfde6de/agents-common/src/test/resources/resourcematcher/test_resourcematcher_path.json
----------------------------------------------------------------------
diff --git 
a/agents-common/src/test/resources/resourcematcher/test_resourcematcher_path.json
 
b/agents-common/src/test/resources/resourcematcher/test_resourcematcher_path.json
index c67ff45..86da28c 100644
--- 
a/agents-common/src/test/resources/resourcematcher/test_resourcematcher_path.json
+++ 
b/agents-common/src/test/resources/resourcematcher/test_resourcematcher_path.json
@@ -1,6 +1,45 @@
 {
   "testCases":[
          {
+                 "name":"value=/a/b*y.txt; isRecursive=true; wildCard=true; 
ignoreCase=true",
+                 "resourceDef":{
+                         
"matcher":"org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher",
+                         "matcherOptions":{"wildCard":true, "ignoreCase":true}
+                 },
+                 "policyResource":{
+                         "values": ["/a/b*y.txt"],
+                         "isRecursive":true
+                 },
+                 "tests":[
+                         { "name":"exact-path","input":"/a/b*y.txt", 
"result":true},
+                         { "name":"child-path","input":"/a/b/y.txt", 
"result":true},
+                         { "name":"grand-child-path","input":"/a/b1/b2/y.txt", 
"result":true},
+                         { 
"name":"descendant-child-path","input":"/a/b1/c1/d1/any.txt", "result":true},
+                         { "name":"mismatche-path","input":"/a/any.txt", 
"result":false},
+
+                 ]
+         }
+         ,
+         {
+                 "name":"value=/a/b*y.txt; isRecursive=false; wildCard=true; 
ignoreCase=true",
+                 "resourceDef":{
+                         
"matcher":"org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher",
+                         "matcherOptions":{"wildCard":true, "ignoreCase":true}
+                 },
+                 "policyResource":{
+                         "values": ["/a/b*y.txt"],
+                         "isRecursive":false
+                 },
+                 "tests":[
+                         { "name":"exact-path","input":"/a/b*y.txt", 
"result":true},
+                         { "name":"child-path","input":"/a/b/y.txt", 
"result":true},
+                         { "name":"grand-child-path","input":"/a/b1/b2/y.txt", 
"result":true},
+                         { 
"name":"descendant-child-path","input":"/a/b1/c1/d1/any.txt", "result":true},
+                         { "name":"mismatche-path","input":"/a/any.txt", 
"result":false},
+                 ]
+         }
+         ,
+         {
                  "name":"value=*; isRecursive=false; wildCard=true; 
ignoreCase=true",
                  "resourceDef":{
                          
"matcher":"org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher",
@@ -131,9 +170,31 @@
        { "name":"grand-child-path-camel-case","input":"/Path1/Path2/Path3", 
"result":true},
        { "name":"sibling-path","input":"/path2", "result":false},
        { "name":"invalid-path","input":"path1", "result":false},
+          { "name":"prefix-path","input":"/path12", "result":false},
+          { "name":"no-path","input":"", "result":false}
       ]
        }
        ,
+      {
+          "name": "value=/path1/path2; isRecursive=true; wildCard=true; 
ignoreCase=true",
+          "resourceDef": {
+              "matcher": 
"org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher",
+              "matcherOptions": {"wildCard": true, "ignoreCase": true
+              }
+          },
+          "policyResource": {"values": ["/path1/path2"], "isRecursive": true},
+          "tests": [
+              {"name": "exact-path", "input": "/path1/path2", "result": true},
+              {"name": "parent-path", "input": "/path1", "result": false},
+              {"name": "grand-parent-path", "input": "/", "result": false},
+              {"name": "child-path", "input": "/path1/path2/path3", "result": 
true},
+              {"name": "grandchild-path", "input": "/path1/path2/path3/path4", 
"result": true},
+              {"name": "sibling-path", "input": "/path1/path3", "result": 
false},
+              {"name": "prefix-path", "input": "/path1/path21", "result": 
false},
+              {"name": "invalid-path", "input": "path1/path2*", "result": 
false}
+          ]
+      }
+  ,
        {
       "name":"value=/path*; isRecursive=true; wildCard=true; ignoreCase=true",
       "resourceDef":{

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/9dfde6de/hdfs-agent/src/test/resources/hdfs-policies.json
----------------------------------------------------------------------
diff --git a/hdfs-agent/src/test/resources/hdfs-policies.json 
b/hdfs-agent/src/test/resources/hdfs-policies.json
index c99c811..eb61796 100644
--- a/hdfs-agent/src/test/resources/hdfs-policies.json
+++ b/hdfs-agent/src/test/resources/hdfs-policies.json
@@ -82,6 +82,11 @@
         {
           "accesses": [
             {
+              "type": "read",
+              "isAllowed": true
+            }
+            ,
+            {
               "type": "execute",
               "isAllowed": true
             }
@@ -96,6 +101,11 @@
         {
           "accesses": [
             {
+              "type": "read",
+              "isAllowed": true
+            }
+          ,
+            {
               "type": "execute",
               "isAllowed": true
             }

Reply via email to