Repository: incubator-ranger
Updated Branches:
  refs/heads/tag-policy 327ecb3c5 -> 858156ee2


RANGER-274: Incorporated review comment. Tested with hive. Beefed up the test 
harness. Incorporated comments from review. Fixed tests for expiry date.

Signed-off-by: Madhan Neethiraj <[email protected]>


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

Branch: refs/heads/tag-policy
Commit: 858156ee225152e42baa14e7a20d9e3c952b480b
Parents: 327ecb3
Author: Abhay Kulkarni <[email protected]>
Authored: Tue Jun 9 08:38:03 2015 -0700
Committer: Madhan Neethiraj <[email protected]>
Committed: Tue Jun 16 19:07:44 2015 -0700

----------------------------------------------------------------------
 .../RangerScriptExecutionContext.java           |  60 +++++
 .../contextenricher/RangerTagProvider.java      |  32 ++-
 .../ranger/plugin/model/RangerResource.java     |  70 +++++
 .../policyengine/RangerPolicyEngineImpl.java    |   3 +-
 .../RangerDefaultPolicyEvaluator.java           |   4 +-
 .../RangerDefaultPolicyResourceMatcher.java     | 250 +++++++++++++----
 .../RangerPolicyResourceMatcher.java            |   2 +
 .../RangerDefaultResourceMatcher.java           |  14 +
 .../plugin/policyengine/TestPolicyEngine.java   |  65 ++++-
 .../policyengine/test_policyengine_hdfs.json    | 123 ---------
 .../test_policyengine_tag_hdfs.json             | 146 ++++++++++
 .../test_policyengine_tag_hive.json             | 269 +++++++++++++++++++
 12 files changed, 847 insertions(+), 191 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptExecutionContext.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptExecutionContext.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptExecutionContext.java
index ff9387b..815b4cc 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptExecutionContext.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptExecutionContext.java
@@ -226,6 +226,66 @@ public final class RangerScriptExecutionContext {
 
        }
 
+       public final boolean isAccessedAfter(String tagName, String 
attributeName) {
+
+               boolean ret = false;
+
+               Date accessDate = getAccessTime();
+
+               Date expiryDate = getTagAttributeAsDate(tagName, attributeName);
+
+               if (expiryDate == null || accessDate.after(expiryDate) || 
accessDate.equals(expiryDate)) {
+                       ret = true;
+               }
+
+               return ret;
+       }
+
+       public final boolean isAccessedAfter(String attributeName) {
+
+               boolean ret = false;
+
+               Date accessDate = getAccessTime();
+
+               Date expiryDate = getAsDate(getAttributeValue(attributeName));
+
+               if (expiryDate == null || accessDate.after(expiryDate) || 
accessDate.equals(expiryDate)) {
+                       ret = true;
+               }
+
+               return ret;
+       }
+
+       public final boolean isAccessedBefore(String tagName, String 
attributeName) {
+
+               boolean ret = true;
+
+               Date accessDate = getAccessTime();
+
+               Date expiryDate = getTagAttributeAsDate(tagName, attributeName);
+
+               if (expiryDate == null || accessDate.after(expiryDate)) {
+                       ret = false;
+               }
+
+               return ret;
+       }
+
+       public final boolean isAccessedBefore(String attributeName) {
+
+               boolean ret = true;
+
+               Date accessDate = getAccessTime();
+
+               Date expiryDate = getAsDate(getAttributeValue(attributeName));
+
+               if (expiryDate == null || accessDate.after(expiryDate)) {
+                       ret = false;
+               }
+
+               return ret;
+       }
+
        private List<RangerResource.RangerResourceTag> getAllTags() {
 
                @SuppressWarnings("unchecked")

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagProvider.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagProvider.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagProvider.java
index 9d2b60b..61c8907 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagProvider.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagProvider.java
@@ -22,6 +22,7 @@ package org.apache.ranger.plugin.contextenricher;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerResource;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
@@ -31,6 +32,7 @@ import 
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatche
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 public class RangerTagProvider extends RangerAbstractContextEnricher 
implements RangerTagReceiver {
        private static final Log LOG = 
LogFactory.getLog(RangerTagProvider.class);
@@ -93,6 +95,13 @@ public class RangerTagProvider extends 
RangerAbstractContextEnricher implements
 
                if (CollectionUtils.isNotEmpty(matchedTags)) {
                        
request.getContext().put(RangerPolicyEngine.KEY_CONTEXT_TAGS, matchedTags);
+                       if (LOG.isDebugEnabled()) {
+                               LOG.debug("RangerTagProvider.enrich(" + request 
+ ") - " + matchedTags.size() + " tags found by enricher.");
+                       }
+               } else {
+                       if (LOG.isDebugEnabled()) {
+                               LOG.debug("RangerTagProvider.enrich(" + request 
+ ") - no tags found by enricher.");
+                       }
                }
 
                if (LOG.isDebugEnabled()) {
@@ -109,10 +118,15 @@ public class RangerTagProvider extends 
RangerAbstractContextEnricher implements
 
                        for (RangerResource taggedResource : resources) {
                                RangerDefaultPolicyResourceMatcher matcher = 
new RangerDefaultPolicyResourceMatcher();
+
                                matcher.setServiceDef(this.serviceDef);
+                               
matcher.setPolicyResources(taggedResource.getResourceSpec());
 
+                               if (LOG.isDebugEnabled()) {
+                                       
LOG.debug("RangerTagProvider.setRangerResources() - Initializing matcher with 
(resource=" + taggedResource
+                                                       + ", serviceDef=" + 
this.serviceDef.getName() + ")" );
 
-                               
matcher.setPolicyResources(taggedResource.getResourceSpec());
+                               }
                                matcher.init();
 
                                RangerTaggedResourceMatcher 
taggedResourceMatcher = new RangerTaggedResourceMatcher(taggedResource, 
matcher);
@@ -121,9 +135,7 @@ public class RangerTagProvider extends 
RangerAbstractContextEnricher implements
                        }
                }
 
-               if (CollectionUtils.isNotEmpty(resourceMatchers)) {
-                       taggedResourceMatchers = resourceMatchers;
-               }
+               taggedResourceMatchers = resourceMatchers;
 
                if (tagRefresher != null && !tagRefresher.getIsStarted()) {
                        tagRefresher.startRetriever();
@@ -144,9 +156,9 @@ public class RangerTagProvider extends 
RangerAbstractContextEnricher implements
                                RangerResource taggedResource = 
resourceMatcher.getRangerResource();
                                RangerPolicyResourceMatcher matcher = 
resourceMatcher.getPolicyResourceMatcher();
 
-                               boolean isMatched = matcher.isMatch(resource);
+                               boolean matchResult = 
matcher.isExactHeadMatch(resource);
 
-                               if (isMatched) {
+                               if (matchResult) {
                                        if (ret == null) {
                                                ret = new 
ArrayList<RangerResource.RangerResourceTag>();
                                        }
@@ -156,6 +168,14 @@ public class RangerTagProvider extends 
RangerAbstractContextEnricher implements
                }
 
                if (LOG.isDebugEnabled()) {
+                       if (CollectionUtils.isEmpty(ret)) {
+                               LOG.debug("RangerTagProvider.findMatchingTags(" 
+ resource + ") - No tags Found ");
+                       } else {
+                               LOG.debug("RangerTagProvider.findMatchingTags(" 
+ resource + ") - " + ret.size() + " tags Found ");
+                       }
+               }
+
+               if (LOG.isDebugEnabled()) {
                        LOG.debug("<== RangerTagProvider.findMatchingTags(" + 
resource + ")");
                }
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerResource.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerResource.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerResource.java
index 49d4739..39cca85 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerResource.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerResource.java
@@ -96,6 +96,46 @@ public class RangerResource extends RangerBaseModelObject {
         this.tags = tags == null ? new ArrayList<RangerResourceTag>() : tags;
     }
 
+    @Override
+    public String toString( ) {
+        StringBuilder sb = new StringBuilder();
+
+        toString(sb);
+
+        return sb.toString();
+    }
+
+    public StringBuilder toString(StringBuilder sb) {
+
+        sb.append("{ ");
+
+        sb.append("componentType={").append(componentType).append("} ");
+        sb.append("tagServiceName={").append(tagServiceName).append("} ");
+
+        sb.append("RangerResource={");
+        if(resourceSpec != null) {
+            for(Map.Entry<String, RangerPolicy.RangerPolicyResource> e : 
resourceSpec.entrySet()) {
+                sb.append(e.getKey()).append("={");
+                e.getValue().toString(sb);
+                sb.append("} ");
+            }
+        }
+        sb.append("} ");
+
+        sb.append("Tags={");
+        if (tags != null) {
+            for (RangerResourceTag tag : tags) {
+                sb.append("{");
+                tag.toString(sb);
+                sb.append("} ");
+            }
+        }
+        sb.append("} ");
+
+        sb.append(" }");
+
+        return sb;
+    }
     /**
      * Represents a tag and its attribute-values for a resource.
      */
@@ -130,5 +170,35 @@ public class RangerResource extends RangerBaseModelObject {
             return attributeValues;
         }
         public void setAttributeValues(Map<String, String> attributeValues) { 
this.attributeValues = attributeValues; }
+
+        @Override
+        public String toString( ) {
+            StringBuilder sb = new StringBuilder();
+
+            toString(sb);
+
+            return sb.toString();
+        }
+
+        public StringBuilder toString(StringBuilder sb) {
+
+            sb.append("{ ");
+
+            sb.append("name={").append(name).append("} ");
+
+            sb.append("attributeValues={");
+            if(attributeValues != null) {
+                for(Map.Entry<String, String> e : attributeValues.entrySet()) {
+                    sb.append(e.getKey()).append("={");
+                    sb.append(e.getValue());
+                    sb.append("} ");
+                }
+            }
+            sb.append("} ");
+
+            sb.append(" }");
+
+            return sb;
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
----------------------------------------------------------------------
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 16cad9b..389c264 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
@@ -398,8 +398,7 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
 
                                                
evaluator.evaluate(tagEvalRequest, tagEvalResult);
 
-                                               if (evaluator.isFinal() ||
-                                                               
(tagEvalResult.getIsAccessDetermined() && 
tagEvalResult.getIsAuditedDetermined())) {
+                                               if 
(tagEvalResult.getIsAccessDetermined() && 
tagEvalResult.getIsAuditedDetermined()) {
                                                        if 
(LOG.isDebugEnabled()) {
                                                                
LOG.debug("RangerPolicyEngineImpl.isAccessAllowedForTagPolicies: concluding 
eval of tag (" + resourceTag.getName() + ") with authorization=" + 
tagEvalResult.getIsAllowed());
                                                        }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
----------------------------------------------------------------------
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 56d15ee..dec8a37 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
@@ -153,7 +153,9 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                     evaluatePolicyItemsForAccess(request, result);
                 }
             }
-                       if ((matchResult || headMatchResult) && 
!result.getIsAccessDetermined() && isFinalPolicy) {
+                       if (isFinalPolicy
+                                       && !result.getIsAccessDetermined()
+                                       && (matchResult || headMatchResult)) {
                                result.setIsAllowed(false);
                                result.setPolicyId(getPolicy().getId());
                        }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
----------------------------------------------------------------------
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 a020b68..572a11b 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
@@ -24,6 +24,7 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
+import java.util.List;
 
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
@@ -32,6 +33,7 @@ import org.apache.commons.logging.LogFactory;
 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.RangerAccessResource;
 import org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher;
 import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher;
@@ -45,6 +47,7 @@ public class RangerDefaultPolicyResourceMatcher implements 
RangerPolicyResourceM
        protected Map<String, RangerPolicyResource> policyResources = null;
 
        private Map<String, RangerResourceMatcher> matchers = null;
+       private List<RangerResourceDef> firstValidResourceDefHierarchy;
 
        @Override
        public void setServiceDef(RangerServiceDef serviceDef) {
@@ -62,23 +65,103 @@ public class RangerDefaultPolicyResourceMatcher implements 
RangerPolicyResourceM
                        LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.init()");
                }
 
-               this.matchers = new HashMap<String, RangerResourceMatcher>();
+               String errorText = "";
 
-               if(policyResources != null && serviceDef != null) {
-                       for(RangerResourceDef resourceDef : 
serviceDef.getResources()) {
-                               String               resourceName   = 
resourceDef.getName();
-                               RangerPolicyResource policyResource = 
policyResources.get(resourceName);
+               if(policyResources != null && policyResources.size() > 0 && 
serviceDef != null) {
 
-                               if(policyResource != null) {
-                                       RangerResourceMatcher matcher = 
createResourceMatcher(resourceDef, policyResource);
+                       Set<String> policyResourceKeySet = 
policyResources.keySet();
 
-                                       if(matcher != null) {
-                                               matchers.put(resourceName, 
matcher);
-                                       } else {
-                                               LOG.error("failed to find 
matcher for resource " + resourceName);
+                       RangerServiceDefHelper serviceDefHelper = new 
RangerServiceDefHelper(serviceDef, false);
+                       Set<List<RangerResourceDef>> validResourceHierarchies = 
serviceDefHelper.getResourceHierarchies();
+
+                       for (List<RangerResourceDef> validResourceHierarchy : 
validResourceHierarchies) {
+
+                               Set<String> resourceDefNameSet = 
serviceDefHelper.getAllResourceNames(validResourceHierarchy);
+
+                               if ((Sets.difference(policyResourceKeySet, 
resourceDefNameSet)).isEmpty()) {
+
+                                       firstValidResourceDefHierarchy = 
validResourceHierarchy;
+                                       break;
+
+                               }
+
+                       }
+
+                       if (firstValidResourceDefHierarchy != null) {
+                               List<String> resourceDefNameOrderedList = 
serviceDefHelper.getAllResourceNamesOrdered(firstValidResourceDefHierarchy);
+
+                               boolean foundGapsInResourceSpecs = false;
+                               boolean skipped = false;
+
+                               for (String resourceDefName : 
resourceDefNameOrderedList) {
+                                       RangerPolicyResource policyResource = 
policyResources.get(resourceDefName);
+                                       if (policyResource == null) {
+                                               skipped = true;
+                                       } else if (skipped) {
+                                               foundGapsInResourceSpecs = true;
+                                               break;
                                        }
                                }
+
+                               if (foundGapsInResourceSpecs) {
+
+                                       errorText = "policyResources does not 
specify contiguous sequence in any valid resourcedef hiearchy.";
+                                       if (LOG.isDebugEnabled()) {
+                                               
LOG.debug("RangerDefaultPolicyResourceMatcher.init() failed: Gaps found in 
policyResources, internal error, skipping..");
+                                       }
+                                       firstValidResourceDefHierarchy = null;
+
+                               } else {
+
+                                       matchers = new HashMap<String, 
RangerResourceMatcher>();
+
+                                       for (RangerResourceDef resourceDef : 
firstValidResourceDefHierarchy) {
+
+                                               String resourceName = 
resourceDef.getName();
+                                               RangerPolicyResource 
policyResource = policyResources.get(resourceName);
+
+                                               if (policyResource != null) {
+                                                       RangerResourceMatcher 
matcher = createResourceMatcher(resourceDef, policyResource);
+
+                                                       if (matcher != null) {
+                                                               
matchers.put(resourceName, matcher);
+                                                       } else {
+                                                               
LOG.error("failed to find matcher for resource " + resourceName);
+                                                       }
+                                               } else {
+                                                       if 
(LOG.isDebugEnabled()) {
+                                                               
LOG.debug("RangerDefaultPolicyResourceMatcher.init() - no matcher created for " 
+ resourceName + ". Continuing ...");
+                                                       }
+                                               }
+                                       }
+                               }
+                       } else {
+                               errorText = "policyResources elements are not 
part of any valid resourcedef hierarchy.";
                        }
+               } else {
+                       errorText = " policyResources is null or empty, or 
serviceDef is null.";
+               }
+
+               if(matchers == null) {
+                       Set<String> policyResourceKeys = policyResources == 
null ? null : policyResources.keySet();
+                       String keysString = "";
+                       if (CollectionUtils.isNotEmpty(policyResourceKeys)) {
+                               for (String policyResourceKeyName : 
policyResourceKeys) {
+                                       keysString += " " + 
policyResourceKeyName + " ";
+                               }
+                       }
+                       String serviceDefName = serviceDef == null ? "" : 
serviceDef.getName();
+                       String validHierarchy = "";
+                       if 
(CollectionUtils.isNotEmpty(firstValidResourceDefHierarchy)) {
+                               RangerServiceDefHelper serviceDefHelper = new 
RangerServiceDefHelper(serviceDef, false);
+                               List<String> resourceDefNameOrderedList = 
serviceDefHelper.getAllResourceNamesOrdered(firstValidResourceDefHierarchy);
+
+                               for (String resourceDefName : 
resourceDefNameOrderedList) {
+                                       validHierarchy += " " + resourceDefName 
+ " ";
+                               }
+                       }
+                       LOG.warn("RangerDefaultPolicyResourceMatcher.init() 
failed: " + errorText + " (serviceDef=" + serviceDefName + ", 
policyResourceKeys=" + keysString
+                       + ", validHierarchy=" + validHierarchy + ")");
                }
 
                if(LOG.isDebugEnabled()) {
@@ -233,56 +316,27 @@ public class RangerDefaultPolicyResourceMatcher 
implements RangerPolicyResourceM
 
        @Override
        public boolean isHeadMatch(RangerAccessResource resource) {
+
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.matchResourceHead(" + resource + ")");
+                       LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.isHeadMatch(" + resource + ")");
                }
-               boolean ret; 
+
+               boolean ret = false;
                
-               if (resource == null || 
CollectionUtils.isEmpty(resource.getKeys())) { // sanity-check, firewalling
-                       LOG.debug("isHeadMatch: resource was null/empty!");
+               if (matchers == null) {
+
+                       
LOG.debug("RangerDefaultPolicyResourceMatcher.isHeadMatch(): 
PolicyResourceMatcher not initialized correctly!!!");
+                       ret = false;
+
+               } else if (resource == null || 
CollectionUtils.isEmpty(resource.getKeys())) { // sanity-check, firewalling
+
+                       
LOG.debug("RangerDefaultPolicyResourceMatcher.isHeadMatch: resource was 
null/empty!");
                        ret = true; // null resource matches anything
-               } else if (serviceDef == null) { // sanity-check, firewalling
-                       LOG.debug("isHeadMatch: service-def was null!");
-                       ret = false; // null policy can never match a non-empty 
resource 
-               } else if (policyResources == null) {
-                       LOG.debug("isHeadMatch: policyResources were null!");
-                       ret = false; // null policy can never match a non-empty 
resource 
-               } else if (matchers == null || matchers.size() != 
policyResources.size()) { // sanity-check, firewalling
-                       LOG.debug("isHeadMatch: matchers could be found for 
some of the policy resources");
-                       ret = false; // empty policy can never match a 
non-empty resources and can't be evaluated meaningfully in matchers are absent
+
                } else {
-                       if (!Sets.difference(resource.getKeys(), 
matchers.keySet()).isEmpty()) { // e.g. avoid using udf policy for resource 
that has more than db specified and vice-versa
-                               LOG.debug("isHeadMatch: resource/policy 
resource-keys mismatch. policy is incompatible with resource; can't match.");
-                               ret = false;
-                       } else {
-                               Set<String> policyResourceNames = 
matchers.keySet();
-                               boolean skipped = false;
-                               boolean matched = true;
-                               Iterator<RangerResourceDef> iterator = 
serviceDef.getResources().iterator();
-                               while (iterator.hasNext() && matched) {
-                                       RangerResourceDef resourceDef = 
iterator.next();
-                                       String resourceName = 
resourceDef.getName();
-                                       // we only work with resources that are 
relevant to this policy
-                                       if 
(policyResourceNames.contains(resourceName)) {
-                                               String resourceValue = 
resource.getValue(resourceName);
-                                               if 
(StringUtils.isEmpty(resourceValue)) {
-                                                       if 
(LOG.isDebugEnabled()) {
-                                                               
LOG.debug("Skipping matching for " + resourceName + " since it is null/empty on 
resource");
-                                                       }
-                                                       skipped = true; // once 
we skip a level all lower levels must be skippable, too
-                                               } else if (skipped == true) {
-                                                       LOG.debug("isHeadMatch: 
found a lower level resource when a higer level resource was absent!");
-                                                       matched = false;
-                                               } else if 
(!matchers.get(resourceName).isMatch(resourceValue)) {
-                                                       if 
(LOG.isDebugEnabled()) {
-                                                               
LOG.debug("isHeadMatch: matcher for " + resourceName + " failed");
-                                                       }
-                                                       matched = false;
-                                               }
-                                       }
-                               }
-                               ret = matched;
-                       }
+
+                       ret = newIsHeadMatch(resource);
+
                }
 
                if(LOG.isDebugEnabled()) {
@@ -293,6 +347,90 @@ public class RangerDefaultPolicyResourceMatcher implements 
RangerPolicyResourceM
        }
 
        @Override
+       public boolean isExactHeadMatch(RangerAccessResource resource) {
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.isExactHeadMatch(" + resource + ")");
+               }
+
+               boolean ret = false;
+
+               if (matchers == null) {
+
+                       
LOG.debug("RangerDefaultPolicyResourceMatcher.isExactHeadMatch(): 
PolicyResourceMatcher not initialized correctly!!!");
+                       ret = false;
+
+               } else if (resource == null || 
CollectionUtils.isEmpty(resource.getKeys())) { // sanity-check, firewalling
+
+                       
LOG.debug("RangerDefaultPolicyResourceMatcher.isExactHeadMatch: resource was 
null/empty!");
+                       ret = false;
+
+               } else if (matchers.size() > resource.getKeys().size()) {
+
+                       
LOG.debug("RangerDefaultPolicyResourceMatcher.isExactHeadMatch: more levels 
specified in PolicyResourceMatcher than in resource being matched!!");
+                       ret = false;
+
+               } else {
+
+                       ret = newIsHeadMatch(resource);
+
+               }
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("<== 
RangerDefaultPolicyResourceMatcher.isExactHeadMatch(" + resource + ")" + ret);
+               }
+
+               return ret;
+       }
+
+       private boolean newIsHeadMatch(RangerAccessResource resource) {
+
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.newIsHeadMatch(" + resource + ")");
+               }
+
+               boolean skipped = false;
+               boolean matched = true;
+
+               for (RangerResourceDef resourceDef : 
firstValidResourceDefHierarchy) {
+
+                       String resourceName = resourceDef.getName();
+                       String resourceValue = resource.getValue(resourceName);
+                       RangerResourceMatcher matcher = 
matchers.get(resourceName);
+
+                       if (matcher != null) {
+
+                               if (StringUtils.isNotBlank(resourceValue)) {
+
+                                       if (!skipped) {
+
+                                               matched = 
matcher.isMatch(resourceValue);
+
+                                       } else {
+
+                                               matched = false;
+
+                                       }
+                               } else {
+
+                                       skipped = true;
+
+                               }
+                       }
+
+                       if (!matched) {
+                               break;
+                       }
+               }
+
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("<== 
RangerDefaultPolicyResourceMatcher.newIsHeadMatch(" + resource + "): " + 
matched);
+               }
+
+               return matched;
+       }
+
+       @Override
        public String toString() {
                StringBuilder sb = new StringBuilder();
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
----------------------------------------------------------------------
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 4a613a2..d23178b 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
@@ -40,5 +40,7 @@ public interface RangerPolicyResourceMatcher {
 
        boolean isHeadMatch(RangerAccessResource resource);
 
+       boolean isExactHeadMatch(RangerAccessResource resource);
+
        StringBuilder toString(StringBuilder sb);
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java
----------------------------------------------------------------------
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 79c3885..154da04 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
@@ -60,6 +60,20 @@ public class RangerDefaultResourceMatcher extends 
RangerAbstractResourceMatcher
                        ret = !ret;
                }
 
+               if (ret == false) {
+                       if(LOG.isDebugEnabled()) {
+                               StringBuilder sb = new StringBuilder();
+                               sb.append("[");
+                               for (String policyValue: policyValues) {
+                                       sb.append(policyValue);
+                                       sb.append(" ");
+                               }
+                               sb.append("]");
+
+                               LOG.debug("RangerDefaultResourceMatcher.isMatch 
returns FALSE, (resource=" + resource + ", policyValues=" + sb.toString() + 
")");
+                       }
+               }
+
                if(LOG.isDebugEnabled()) {
                        LOG.debug("<== RangerDefaultResourceMatcher.isMatch(" + 
resource + "): " + ret);
                }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
----------------------------------------------------------------------
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 21d8681..86357d7 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
@@ -20,7 +20,10 @@
 package org.apache.ranger.plugin.policyengine;
 
 import com.google.gson.*;
+import com.google.gson.reflect.TypeToken;
+import org.apache.commons.lang.StringUtils;
 import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerResource;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import 
org.apache.ranger.plugin.policyengine.TestPolicyEngine.PolicyEngineTestCase.TestData;
 import org.apache.ranger.plugin.util.ServicePolicies;
@@ -32,6 +35,7 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.lang.reflect.Type;
 import java.util.List;
+import java.util.Map;
 
 import static org.junit.Assert.*;
 
@@ -62,6 +66,13 @@ public class TestPolicyEngine {
        }
 
        @Test
+       public void testPolicyEngine_hdfsForTag() {
+               String[] hdfsTestResourceFiles = { 
"/policyengine/test_policyengine_tag_hdfs.json" };
+
+               runTestsFromResourceFiles(hdfsTestResourceFiles);
+       }
+
+       @Test
        public void testPolicyEngine_hive() {
                String[] hiveTestResourceFiles = { 
"/policyengine/test_policyengine_hive.json" };
 
@@ -69,6 +80,13 @@ public class TestPolicyEngine {
        }
 
        @Test
+       public void testPolicyEngine_hiveForTag() {
+               String[] hiveTestResourceFiles = { 
"/policyengine/test_policyengine_tag_hive.json" };
+
+               runTestsFromResourceFiles(hiveTestResourceFiles);
+       }
+
+       @Test
        public void testPolicyEngine_hbase() {
                String[] hbaseTestResourceFiles = { 
"/policyengine/test_policyengine_hbase.json" };
 
@@ -115,15 +133,56 @@ public class TestPolicyEngine {
                RangerPolicyEngineOptions policyEngineOptions = new 
RangerPolicyEngineOptions();
 
                // Uncomment next line for testing tag-policy evaluation
-               // policyEngineOptions.disableTagPolicyEvaluation = false;
+               policyEngineOptions.disableTagPolicyEvaluation = false;
 
                policyEngine = new RangerPolicyEngineImpl(servicePolicies, 
policyEngineOptions);
 
+               RangerAccessRequest request = null;
+
                for(TestData test : testCase.tests) {
-                       policyEngine.preProcess(test.request);
+                       if 
(test.request.getContext().containsKey(RangerPolicyEngine.KEY_CONTEXT_TAGS)) {
+                               // Create a new AccessRequest
+                               RangerAccessRequestImpl newRequest =
+                                               new 
RangerAccessRequestImpl(test.request.getResource(), 
test.request.getAccessType(),
+                                                               
test.request.getUser(), test.request.getUserGroups());
+
+                               
newRequest.setClientType(test.request.getClientType());
+                               
newRequest.setAccessTime(test.request.getAccessTime());
+                               newRequest.setAction(test.request.getAction());
+                               
newRequest.setClientIPAddress(test.request.getClientIPAddress());
+                               
newRequest.setRequestData(test.request.getRequestData());
+                               
newRequest.setSessionId(test.request.getSessionId());
+
+                               Map<String, Object> context = 
test.request.getContext();
+                               String tagsJsonString = (String) 
context.get(RangerPolicyEngine.KEY_CONTEXT_TAGS);
+                               
context.remove(RangerPolicyEngine.KEY_CONTEXT_TAGS);
+
+                               if(!StringUtils.isEmpty(tagsJsonString)) {
+                                       try {
+                                               Type listType = new 
TypeToken<List<RangerResource.RangerResourceTag>>() {
+                                               }.getType();
+                                               
List<RangerResource.RangerResourceTag> tagList = 
gsonBuilder.fromJson(tagsJsonString, listType);
+
+                                               
context.put(RangerPolicyEngine.KEY_CONTEXT_TAGS, tagList);
+                                       } catch (Exception e) {
+                                               
System.err.println("TestPolicyEngine.runTests(): error parsing TAGS JSON string 
in file " + testName + ", tagsJsonString=" +
+                                                               tagsJsonString 
+ ", exception=" + e);
+                                       }
+                               }
+
+
+                               newRequest.setContext(context);
+
+                               request = newRequest;
+
+                       }
+                       else {
+                               request = test.request;
+                       }
+                       policyEngine.preProcess(request);
 
                        RangerAccessResult expected = test.result;
-                       RangerAccessResult result   = 
policyEngine.isAccessAllowed(test.request, null);
+                       RangerAccessResult result   = 
policyEngine.isAccessAllowed(request, null);
 
                        assertNotNull("result was null! - " + test.name, 
result);
                        assertEquals("isAllowed mismatched! - " + test.name, 
expected.getIsAllowed(), result.getIsAllowed());

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/test/resources/policyengine/test_policyengine_hdfs.json
----------------------------------------------------------------------
diff --git 
a/agents-common/src/test/resources/policyengine/test_policyengine_hdfs.json 
b/agents-common/src/test/resources/policyengine/test_policyengine_hdfs.json
index 3c38919..eed71be 100644
--- a/agents-common/src/test/resources/policyengine/test_policyengine_hdfs.json
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_hdfs.json
@@ -36,130 +36,7 @@
      ]
     }
   ],
-  "tagPolicyInfo": {
 
-    "serviceName":"tagdev",
-    "serviceDef": {
-      "name": "_tag_",
-      "id": 101,
-      "resources": [
-        {
-          "itemId": 1,
-          "name": "tag",
-          "type": "string",
-          "level": 1,
-          "parent": "",
-          "mandatory": true,
-          "lookupSupported": true,
-          "recursiveSupported": false,
-          "excludesSupported": false,
-          "matcher": 
"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
-          "matcherOptions": {
-            "wildCard": true,
-            "ignoreCase": false
-          },
-          "validationRegEx": "",
-          "validationMessage": "",
-          "uiHint": "",
-          "label": "TAG",
-          "description": "TAG"
-        }
-      ],
-      "accessTypes": [
-        {
-          "itemId": 1,
-          "name": "hdfs:read",
-          "label": "hdfs:Read"
-        },
-        {
-          "itemId": 2,
-          "name": "hdfs:write",
-          "label": "hdfs:Write"
-        },
-        {
-          "itemId": 3,
-          "name": "hdfs:execute",
-          "label": "hdfs:Execute"
-        }
-        ,
-        {
-          "itemId": 4,
-          "name": "hive:grant",
-          "label": "hive:grant"
-        }
-        ,
-        {
-          "itemId": 5,
-          "name": "kms:dek",
-          "label": "kms:dek"
-        }
-        ,
-        {
-          "itemId": 6,
-          "name": "delete",
-          "label": "delete"
-        }
-      ],
-      "contextEnrichers": [
-        {
-          "itemId": 1,
-          "name" : "TagEnricher",
-          "enricher" : 
"org.apache.ranger.plugin.contextenricher.RangerTagProvider",
-          "enricherOptions" : 
{"TagProviderType":"FILESTORE_BASED_TAG_PROVIDER", "pollingInterval":30000, 
"dataFile":"/etc/ranger/data/resourceTags.txt"}
-        }
-      ],
-      "policyConditions": [
-        {
-          "itemId":1,
-          "name":"ScriptConditionEvaluator",
-          "evaluator": 
"org.apache.ranger.plugin.conditionevaluator.RangerScriptConditionEvaluator",
-          "evaluatorOptions" : {"engineName":"JavaScript"},
-          "label":"Script",
-          "description": "Script to execute"
-        }
-      ]
-    },
-    "tagPolicies":[
-      {"id":5,"name":"allow somethingelse 
tag","isEnabled":true,"isAuditEnabled":true,"policyType":0,
-        "resources":{"tag":{"values":["pii"],"isRecursive":false}},
-        "policyItems":[
-          {"accesses":[{"type":"hdfs:read", "isAllowed":true}, 
{"type":"hive:grant", "isAllowed":true}, {"type":"delete", "isAllowed":true}, 
{"type":":write", 
"isAllowed":true}],"users":["user1"],"groups":["finance"],"delegateAdmin":false,
-          "conditions" : [{"type":"ScriptConditionEvaluator", "values": [
-            "importPackage(java.util); var accessDate = 
ctx.getAsDate(ctx.accessTime); var expiryDate 
=ctx.getTagAttributeAsDate('pii','expiry'); expiryDate.getTime() < 
accessDate.getTime();"
-            ,
-            "importPackage(java.util); var accessTime = ctx.accessTime; 
print('accessTime=' + accessTime); var accessDate = ctx.getAsDate(accessTime); 
println('accessDate=' + accessDate); var currentDate = new Date(); 
println('currentDate=' + currentDate); println('current=' 
+currentDate.getTime()); println('access='+ accessDate.getTime()); result = 
true;"
-            ,
-            "importPackage(java.util); var accessTime = ctx.accessTime; var 
currentTime = Date(); print('accessTime=' + accessTime); println('currentTime=' 
+ currentTime); accessTime.after(currentTime)"
-            ,
-            "var ownerUser = request.resource.getOwnerUser(); 
println('ownerUser=' + ownerUser); result = true;"
-            ,
-            "var ownerUser = request.resource.ownerUser; println('ownerUser=' 
+ ownerUser); result = true;"
-            ,
-            "var tagName = ctx.currentTagName; println('tagName=' + tagName); 
ctx.result = true;"
-            ,
-            "var resource = ctx.get('RESOURCE').getAsMap(); println('resource 
path=' + resource.get('path')); result = true;"
-
-          ]
-                          }]
-          }
-        ]
-      }
-      ,
-      {"id":4,"name":"allow partial-match 
tag","isEnabled":true,"isAuditEnabled":true,
-        "resources":{"tag":{"values":["restr*"],"isRecursive":false}},
-        "policyItems":[
-          
{"accesses":[{"type":"hdfs:write","isAllowed":true}],"users":["user1"],"groups":["finance"],"delegateAdmin":false}
-        ]
-      }
-      ,
-      {"id":3,"name":"restricted 
tags","isEnabled":true,"isAuditEnabled":true,"policyType":0,
-        "resources":{"tag":{"values":["res*"],"isRecursive":false}},
-        "policyItems":[
-          
{"accesses":[{"type":"hdfs:write","isAllowed":true}],"users":["user1"],"groups":["finance"],"delegateAdmin":false}
-        ]
-      }
-    ]
-  },
   "tests":[
     {"name":"ALLOW 'read /finance/restricted/sales.db' for g=finance",
      "request":{

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/test/resources/policyengine/test_policyengine_tag_hdfs.json
----------------------------------------------------------------------
diff --git 
a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hdfs.json 
b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hdfs.json
new file mode 100644
index 0000000..55ae78c
--- /dev/null
+++ 
b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hdfs.json
@@ -0,0 +1,146 @@
+{
+  "serviceName":"hdfsdev",
+
+  "serviceDef":{
+    "name":"hdfs",
+    "id":1,
+    "resources":[
+    
{"name":"path","type":"path","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher","matcherOptions":{"wildCard":true,
 "ignoreCase":true},"label":"Resource Path","description":"HDFS file or 
directory path"}
+    ],
+    "accessTypes":[
+      {"name":"read","label":"Read"},
+      {"name":"write","label":"Write"},
+      {"name":"execute","label":"Execute"}
+    ]
+  },
+
+  "policies":[
+    {"id":1,"name":"audit-all-access under 
/finance/restricted/","isEnabled":true,"isAuditEnabled":true,
+     
"resources":{"path":{"values":["/finance/restricted/"],"isRecursive":true}},
+     "policyItems":[
+       {"accesses":[],"users":[],"groups":["public"],"delegateAdmin":false}
+     ]
+    }
+    ,
+    {"id":2,"name":"allow-read-to-all under 
/public/","isEnabled":true,"isAuditEnabled":false,
+     "resources":{"path":{"values":["/public/*"],"isRecursive":true}},
+     "policyItems":[
+       
{"accesses":[{"type":"read","isAllowed":true},{"type":"execute","isAllowed":true}],"users":[],"groups":["public"],"delegateAdmin":false}
+     ]
+    }
+    ,
+    {"id":3,"name":"allow-read-to-finance under 
/finance/restricted","isEnabled":true,"isAuditEnabled":true,
+     
"resources":{"path":{"values":["/finance/restricted"],"isRecursive":true}},
+     "policyItems":[
+       
{"accesses":[{"type":"read","isAllowed":true}],"users":[],"groups":["finance"],"delegateAdmin":false}
+     ]
+    }
+  ],
+  "tagPolicyInfo": {
+
+    "serviceName":"tagdev",
+    "serviceDef": {
+      "name": "_tag_",
+      "id": 100,
+      "resources": [
+        {
+          "itemId": 1,
+          "name": "tag",
+          "type": "string",
+          "level": 1,
+          "parent": "",
+          "mandatory": true,
+          "lookupSupported": true,
+          "recursiveSupported": false,
+          "excludesSupported": false,
+          "matcher": 
"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+          "matcherOptions": {
+            "wildCard": true,
+            "ignoreCase": false
+          },
+          "validationRegEx": "",
+          "validationMessage": "",
+          "uiHint": "",
+          "label": "TAG",
+          "description": "TAG"
+        }
+      ],
+      "accessTypes": [
+        {
+          "itemId": 1,
+          "name": "hdfs:read",
+          "label": "hdfs:Read"
+        },
+        {
+          "itemId": 2,
+          "name": "hdfs:write",
+          "label": "hdfs:Write"
+        },
+        {
+          "itemId": 3,
+          "name": "hdfs:execute",
+          "label": "hdfs:Execute"
+        }
+        ,
+        {
+          "itemId": 4,
+          "name": "hive:grant",
+          "label": "hive:grant"
+        }
+        ,
+        {
+          "itemId": 5,
+          "name": "kms:dek",
+          "label": "kms:dek"
+        }
+        ,
+        {
+          "itemId": 6,
+          "name": "delete",
+          "label": "delete"
+        }
+      ],
+      "contextEnrichers": [
+        {
+          "itemId": 1,
+          "name" : "TagEnricher",
+          "enricher" : 
"org.apache.ranger.plugin.contextenricher.RangerTagProvider",
+          "enricherOptions" : 
{"TagProviderType":"FILESTORE_BASED_TAG_PROVIDER", "pollingInterval":-1, 
"dataFile":"/etc/ranger/data/resourceTags.txt"}
+        }
+      ],
+      "policyConditions": [
+        {
+          "itemId":1,
+          "name":"ScriptConditionEvaluator",
+          "evaluator": 
"org.apache.ranger.plugin.conditionevaluator.RangerScriptConditionEvaluator",
+          "evaluatorOptions" : {"engineName":"JavaScript"},
+          "label":"Script",
+          "description": "Script to execute"
+        }
+      ]
+    },
+    "tagPolicies":[
+      
{"id":1,"name":"test_policy","isEnabled":true,"isAuditEnabled":true,"policyType":0,
+        "resources":{"tag":{"values":["PII"],"isRecursive":false}},
+        "policyItems":[
+          {"accesses":[{"type":"hdfs:read", "isAllowed":true}, 
{"type":"hive:grant", "isAllowed":true}, {"type":"delete", "isAllowed":true}, 
{"type":":write", 
"isAllowed":true}],"users":["user1"],"groups":["finance"],"delegateAdmin":false,
+          "conditions" : [{"type":"ScriptConditionEvaluator", "values": [
+            "importPackage(java.util); var accessDate = 
ctx.getAsDate(ctx.accessTime); var expiryDate 
=ctx.getTagAttributeAsDate('pii','expiry'); expiryDate.getTime() < 
accessDate.getTime();"
+          ]
+                          }]
+          }
+        ]
+      }
+    ]
+  },
+  "tests":[
+    {"name":"ALLOW 'read /finance/restricted/sales.db' for g=finance",
+     "request":{
+      "resource":{"elements":{"path":"/finance/restricted/sales.db"}},
+      
"accessType":"read","user":"user1","userGroups":["finance"],"requestData":"read 
/finance/restricted/sales.db"
+     },
+     "result":{"isAudited":true,"isAllowed":true,"policyId":3}
+    }
+  ]
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json
----------------------------------------------------------------------
diff --git 
a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json 
b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json
new file mode 100644
index 0000000..8821a1c
--- /dev/null
+++ 
b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json
@@ -0,0 +1,269 @@
+{
+  "serviceName":"hivedev",
+
+  "serviceDef":{
+    "name":"hive",
+    "id":3,
+    "resources":[
+      
{"name":"database","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true,
 "ignoreCase":true},"label":"Hive Database","description":"Hive Database"},
+      
{"name":"table","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true,
 "ignoreCase":true},"label":"Hive Table","description":"Hive Table"},
+      
{"name":"udf","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true,
 "ignoreCase":true},"label":"Hive UDF","description":"Hive UDF"},
+      
{"name":"column","level":3,"parent":"table","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true,
 "ignoreCase":true},"label":"Hive Column","description":"Hive Column"}
+    ],
+    "accessTypes":[
+      {"name":"select","label":"Select"},
+      {"name":"update","label":"Update"},
+      {"name":"create","label":"Create"},
+      {"name":"drop","label":"Drop"},
+      {"name":"alter","label":"Alter"},
+      {"name":"index","label":"Index"},
+      {"name":"lock","label":"Lock"},
+      {"name":"all","label":"All",
+        "impliedGrants": [
+          "select",
+          "update",
+          "create",
+          "drop",
+          "alter",
+          "index",
+          "lock"
+        ]
+      }
+    ]
+  },
+
+  "policies":[
+    {"id":101,"name":"db=*: 
audit-all-access","isEnabled":true,"isAuditEnabled":true,
+     
"resources":{"database":{"values":["*"]},"table":{"values":["*"]},"column":{"values":["*"]}},
+     "policyItems":[
+       {"accesses":[{"type":"all","isAllowed":true}],"users":["hive", "user1", 
"user2"],"groups":["public"],"delegateAdmin":false}
+     ]
+    },
+    {"id":102,"name":"db=*, udf=*: 
audit-all-access","isEnabled":true,"isAuditEnabled":true,
+      "resources":{"database":{"values":["*"]},"udf":{"values":["*"]}},
+      "policyItems":[
+        {"accesses":[{"type":"all","isAllowed":true}],"users":["hive", 
"user1", "user2"],"groups":["public"],"delegateAdmin":false}
+      ]
+    }
+  ],
+  "tagPolicyInfo": {
+
+    "serviceName":"tagdev",
+    "serviceDef": {
+      "name": "_tag_",
+      "id": 100,
+      "resources": [
+        {
+          "itemId": 1,
+          "name": "tag",
+          "type": "string",
+          "level": 1,
+          "parent": "",
+          "mandatory": true,
+          "lookupSupported": true,
+          "recursiveSupported": false,
+          "excludesSupported": false,
+          "matcher": 
"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+          "matcherOptions": {
+            "wildCard": true,
+            "ignoreCase": false
+          },
+          "validationRegEx": "",
+          "validationMessage": "",
+          "uiHint": "",
+          "label": "TAG",
+          "description": "TAG"
+        }
+      ],
+      "accessTypes": [
+        {
+          "itemId": 1,
+          "name": "hive:select",
+          "label": "hive:select"
+        },
+        {
+          "itemId": 2,
+          "name": "hive:update",
+          "label": "hive:update"
+        },
+        {
+          "itemId": 3,
+          "name": "hive:create",
+          "label": "hive:create"
+        }
+      ,
+        {
+          "itemId": 4,
+          "name": "hive:grant",
+          "label": "hive:grant"
+        }
+      ,
+        {
+          "itemId": 5,
+          "name": "hive:drop",
+          "label": "hive:drop"
+        }
+      ,
+        {
+          "itemId": 6,
+          "name": "hive:alter",
+          "label": "hive:alter"
+        },
+        {
+          "itemId": 7,
+          "name": "hive:index",
+          "label": "hive:index"
+        },
+        {
+          "itemId": 8,
+          "name": "hive:lock",
+          "label": "hive:lock"
+        },
+        {
+          "itemId": 9,
+          "name": "hive:all",
+          "label": "hive:all"
+        }
+      ],
+      "contextEnrichers": [
+        {
+          "itemId": 1,
+          "name" : "TagEnricher",
+          "enricher" : 
"org.apache.ranger.plugin.contextenricher.RangerTagProvider",
+          "enricherOptions" : 
{"TagProviderType":"FILESTORE_BASED_TAG_PROVIDER", "pollingInterval":-1, 
"dataFile":"/etc/ranger/data/resourceTags.txt"}
+        }
+      ],
+      "policyConditions": [
+        {
+          "itemId":1,
+          "name":"ScriptConditionEvaluator",
+          "evaluator": 
"org.apache.ranger.plugin.conditionevaluator.RangerScriptConditionEvaluator",
+          "evaluatorOptions" : {"engineName":"JavaScript"},
+          "label":"Script",
+          "description": "Script to execute"
+        }
+      ]
+    },
+    "tagPolicies":[
+      
{"id":1,"name":"RESTRICTED_TAG_POLICY","isEnabled":true,"isAuditEnabled":true,"policyType":0,
+        "resources":{"tag":{"values":["RESTRICTED"],"isRecursive":false}},
+        "policyItems":[
+          {
+            
"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive", 
"user1"],"groups":[],"delegateAdmin":false,
+            "conditions":[{
+              "type":"ScriptConditionEvaluator",
+              "values":["if ( ctx.isAccessedBefore('expiry') ) ctx.result = 
true;"]
+            }]
+          }
+        ]
+      },
+      
{"id":2,"name":"PII_TAG_POLICY","isEnabled":true,"isAuditEnabled":true,"policyType":0,
+        "resources":{"tag":{"values":["PII"],"isRecursive":false}},
+        "policyItems":[
+          
{"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive"],"groups":[],"delegateAdmin":false}
+        ]
+      },
+      
{"id":3,"name":"PII_TAG_POLICY-FINAL","isEnabled":true,"isAuditEnabled":true,"policyType":1,
+        "resources":{"tag":{"values":["PII-FINAL"],"isRecursive":false}},
+        "policyItems":[
+          
{"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive"],"groups":[],"delegateAdmin":false}
+        ]
+      },
+      
{"id":4,"name":"RESTRICTED_TAG_POLICY_FINAL","isEnabled":true,"isAuditEnabled":true,"policyType":1,
+        
"resources":{"tag":{"values":["RESTRICTED-FINAL"],"isRecursive":false}},
+        "policyItems":[
+          {
+            
"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive", 
"user1"],"groups":[],"delegateAdmin":false,
+            "conditions":[{
+              "type":"ScriptConditionEvaluator",
+              "values":["if ( ctx.isAccessedBefore('expiry') ) ctx.result = 
true;"]
+            }]
+          }
+        ]
+      }
+    ]
+  },
+
+  "tests":[
+    {"name":"ALLOW 'select ssn from employee.personal;' for user1",
+      "request":{
+        "resource":{"elements":{"database":"employee", "table":"personal", 
"column":"ssn"}},
+        
"accessType":"select","user":"user1","userGroups":[],"requestData":"select ssn 
from employee.personal;' for user1",
+        "context": {"TAGS":"[{\"name\":\"RESTRICTED\", 
\"attributeValues\":{\"expiry\":\"Mon Jun 15 13:00:00 PDT 2026\"}}]"}
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":1}
+    },
+    {"name":"DENY 'select ssn from employee.personal;' for user2",
+      "request":{
+        "resource":{"elements":{"database":"employee", "table":"personal", 
"column":"ssn"}},
+        
"accessType":"select","user":"user2","userGroups":[],"requestData":"select ssn 
from employee.personal;' for user2",
+        "context": {"TAGS":"[{\"name\":\"RESTRICTED-FINAL\", 
\"attributeValues\":{\"expiry\":\"Mon Jun 15 13:00:00 PDT 2026\"}}]"}
+      },
+      "result":{"isAudited":true,"isAllowed":false,"policyId":4}
+    },
+    {"name":"ALLOW 'select name from employee.personal;' for user1 - no tag",
+      "request":{
+        "resource":{"elements":{"database":"employee", "table":"personal", 
"column":"name"}},
+        
"accessType":"select","user":"user1","userGroups":[],"requestData":"select name 
from employee.personal;' for user1"
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":101}
+    },
+    {"name":"ALLOW 'select name from employee.personal;' for user2 - no tag",
+      "request":{
+        "resource":{"elements":{"database":"employee", "table":"personal", 
"column":"name"}},
+        
"accessType":"select","user":"user2","userGroups":[],"requestData":"select name 
from employee.personal;' for user2"
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":101}
+    },
+    {"name":"ALLOW 'select name from default.table1;' for hive",
+      "request":{
+        "resource":{"elements":{"database":"default", "table":"table1", 
"column":"name"}},
+        
"accessType":"select","user":"hive","userGroups":[],"requestData":"select name 
from default.table1;' for hive",
+        "context": {"TAGS":"[{\"name\":\"PII\", 
\"attributeValues\":{\"expiry\":\"Mon Jun 15 13:00:00 PDT 2026\"}}]"}
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":2}
+    },
+    {"name":"ALLOW 'desc default.table1;' for hive",
+      "request":{
+        "resource":{"elements":{"database":"default", "table":"table1"}},
+        "accessType":"","user":"hive","userGroups":[],"requestData":"desc 
default.table1;' for hive",
+        "context": {"TAGS":"[{\"name\":\"PII\", 
\"attributeValues\":{\"expiry\":\"Mon Jun 15 13:00:00 PDT 2026\"}}]"}
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":2}
+    },
+    {"name":"DENY 'desc default.table1;' for user1",
+      "request":{
+        "resource":{"elements":{"database":"default", "table":"table1"}},
+        "accessType":"","user":"user1","userGroups":[],"requestData":"desc 
default.table1;' for user1",
+        "context": {"TAGS":"[{\"name\":\"PII-FINAL\", 
\"attributeValues\":{\"expiry\":\"Mon Jun 15 13:00:00 PDT 2026\"}}]"}
+      },
+      "result":{"isAudited":true,"isAllowed":false,"policyId":3}
+    },
+    {"name":"ALLOW 'use default;' for hive",
+      "request":{
+        "resource":{"elements":{"database":"default"}},
+        "accessType":"","user":"hive","userGroups":[],"requestData":"use 
default",
+        "context": {"TAGS":"[{\"name\":\"PII-FINAL\", 
\"attributeValues\":{\"expiry\":\"Mon Jun 15 13:00:00 PDT 2026\"}}]"}
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":3}
+    },
+    {"name":"DENY 'use default;' for user1",
+      "request":{
+        "resource":{"elements":{"database":"default"}},
+        "accessType":"","user":"user1","userGroups":[],"requestData":"use 
default for user1",
+        "context": {"TAGS":"[{\"name\":\"PII-FINAL\", 
\"attributeValues\":{\"expiry\":\"Mon Jun 15 13:00:00 PDT 2026\"}}]"}
+      },
+      "result":{"isAudited":true,"isAllowed":false,"policyId":3}
+    },
+    {"name":"ALLOW 'select * from default.table1;' for hive",
+      "request":{
+        "resource":{"elements":{"database":"default", "table":"table1", 
"column":"name"}},
+        
"accessType":"select","user":"hive","userGroups":[],"requestData":"select * 
from default.table1",
+        "context": {"TAGS":"[{\"name\":\"PII\", 
\"attributeValues\":{\"expiry\":\"Mon Jun 15 13:00:00 PDT 2026\"}}]"}
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":2}
+    }
+
+  ]
+}
+

Reply via email to