This is an automated email from the ASF dual-hosted git repository.

rmani 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 9c39c88  RANGER-2354:Add custom condition at policy level
9c39c88 is described below

commit 9c39c880971686f0255ac21feb50665b02ce0b04
Author: rmani <[email protected]>
AuthorDate: Mon Mar 25 14:00:54 2019 -0700

    RANGER-2354:Add custom condition at policy level
---
 .../RangerAbstractConditionEvaluator.java          |   9 +
 .../RangerConditionEvaluator.java                  |   3 +
 .../apache/ranger/plugin/model/RangerPolicy.java   |  59 +++++-
 .../model/RangerPolicyResourceSignature.java       |  42 +++++
 .../RangerAbstractPolicyItemEvaluator.java         |   2 +
 .../RangerCustomConditionEvaluator.java            | 202 +++++++++++++++++++++
 .../RangerDefaultPolicyEvaluator.java              |  93 +++++++++-
 .../RangerDefaultPolicyItemEvaluator.java          |  47 +----
 .../plugin/policyengine/TestPolicyEngine.java      |   8 +-
 .../test_policyengine_policylevel_conditions.json  |  90 +++++++++
 .../RangerPolicyConditionSampleSimpleMatcher.java  | 170 +++++++++++++++++
 .../org/apache/ranger/biz/PolicyRefUpdater.java    |   7 +
 .../apache/ranger/service/RangerPolicyService.java |   4 +
 13 files changed, 673 insertions(+), 63 deletions(-)

diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerAbstractConditionEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerAbstractConditionEvaluator.java
index ddd1a54..51691ad 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerAbstractConditionEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerAbstractConditionEvaluator.java
@@ -18,6 +18,7 @@
  */
 package org.apache.ranger.plugin.conditionevaluator;
 
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyCondition;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import 
org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef;
@@ -26,6 +27,7 @@ public abstract class RangerAbstractConditionEvaluator 
implements RangerConditio
        protected RangerServiceDef serviceDef;
        protected RangerPolicyConditionDef  conditionDef;
        protected RangerPolicyItemCondition condition;
+       protected RangerPolicyCondition policyCondition;
 
        @Override
        public void setServiceDef(RangerServiceDef serviceDef) {
@@ -48,4 +50,11 @@ public abstract class RangerAbstractConditionEvaluator 
implements RangerConditio
 
        public RangerPolicyItemCondition getPolicyItemCondition() { return 
condition; }
 
+       @Override
+       public void setPolicyCondition(RangerPolicyCondition policyCondition) {
+               this.policyCondition = policyCondition;
+       }
+
+       public RangerPolicyCondition getPolicyCondition() { return 
policyCondition; }
+
 }
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerConditionEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerConditionEvaluator.java
index 16f9a3c..54c0b40 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerConditionEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerConditionEvaluator.java
@@ -19,6 +19,7 @@
 
 package org.apache.ranger.plugin.conditionevaluator;
 
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyCondition;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import 
org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef;
@@ -29,6 +30,8 @@ public interface RangerConditionEvaluator {
 
        void setPolicyItemCondition(RangerPolicyItemCondition condition);
 
+       void setPolicyCondition(RangerPolicyCondition policyCondition);
+
        void setServiceDef(RangerServiceDef serviceDef);
 
        void init();
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
index 327d37b..9146a88 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
@@ -75,6 +75,7 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
        private String                                                    
resourceSignature;
        private Boolean                           isAuditEnabled;
        private Map<String, RangerPolicyResource> resources;
+       private List<RangerPolicyCondition>       conditions;
        private List<RangerPolicyItem>            policyItems;
        private List<RangerPolicyItem>            denyPolicyItems;
        private List<RangerPolicyItem>            allowExceptions;
@@ -88,13 +89,17 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
        private String                            zoneName;
 
        public RangerPolicy() {
-               this(null, null, null, null, null, null, null, null, null, 
null, null, null);
+               this(null, null, null, null, null, null, null, null, null, 
null, null);
        }
 
        public RangerPolicy(String service, String name, Integer policyType, 
Integer policyPriority, String description, Map<String, RangerPolicyResource> 
resources, List<RangerPolicyItem> policyItems, String resourceSignature, 
Map<String, Object> options, List<RangerValiditySchedule> validitySchedules, 
List<String> policyLables) {
                this(service, name, policyType, policyPriority, description, 
resources, policyItems, resourceSignature, options, validitySchedules, 
policyLables, null);
        }
 
+       public RangerPolicy(String service, String name, Integer policyType, 
Integer policyPriority, String description, Map<String, RangerPolicyResource> 
resources, List<RangerPolicyItem> policyItems, String resourceSignature, 
Map<String, Object> options, List<RangerValiditySchedule> validitySchedules, 
List<String> policyLables, String zoneName) {
+               this(service, name, policyType, policyPriority, description, 
resources, policyItems, resourceSignature, options, validitySchedules, 
policyLables, zoneName, null);
+       }
+
        /**
         * @param service
         * @param name
@@ -104,7 +109,7 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
         * @param policyItems
         * @param resourceSignature TODO
         */
-       public RangerPolicy(String service, String name, Integer policyType, 
Integer policyPriority, String description, Map<String, RangerPolicyResource> 
resources, List<RangerPolicyItem> policyItems, String resourceSignature, 
Map<String, Object> options, List<RangerValiditySchedule> validitySchedules, 
List<String> policyLables, String zoneName) {
+       public RangerPolicy(String service, String name, Integer policyType, 
Integer policyPriority, String description, Map<String, RangerPolicyResource> 
resources, List<RangerPolicyItem> policyItems, String resourceSignature, 
Map<String, Object> options, List<RangerValiditySchedule> validitySchedules, 
List<String> policyLables, String zoneName, List<RangerPolicyCondition> 
conditions) {
                super();
 
                setService(service);
@@ -125,6 +130,7 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
                setValiditySchedules(validitySchedules);
                setPolicyLabels(policyLables);
                setZoneName(zoneName);
+               setConditions(conditions);
 
        }
 
@@ -152,6 +158,7 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
                setValiditySchedules(other.getValiditySchedules());
                setPolicyLabels(other.getPolicyLabels());
                setZoneName(other.getZoneName());
+               setConditions(other.getConditions());
        }
 
        /**
@@ -491,6 +498,17 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
            this.zoneName = zoneName;
     }
 
+       /**
+        * @return the conditions
+        */
+       public List<RangerPolicyCondition> getConditions() { return conditions; 
}
+       /**
+        * @param conditions the conditions to set
+        */
+       public void setConditions(List<RangerPolicyCondition> conditions) {
+               this.conditions = conditions;
+       }
+
        @Override
        public String toString( ) {
                StringBuilder sb = new StringBuilder();
@@ -532,6 +550,17 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
                         }
                 }
                 sb.append("} ");
+
+               sb.append("policyConditions={");
+               if(conditions != null) {
+                       for(RangerPolicyCondition condition : conditions) {
+                               if(condition != null) {
+                                       condition.toString(sb);
+                               }
+                       }
+               }
+               sb.append("} ");
+
                sb.append("policyItems={");
                if(policyItems != null) {
                        for(RangerPolicyItem policyItem : policyItems) {
@@ -1322,22 +1351,38 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
                
        }
 
+       // Shell class for backward compatibility
        @JsonAutoDetect(fieldVisibility=Visibility.ANY)
        @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
        @JsonIgnoreProperties(ignoreUnknown=true)
        @XmlRootElement
        @XmlAccessorType(XmlAccessType.FIELD)
-       public static class RangerPolicyItemCondition implements 
java.io.Serializable {
+       public static class RangerPolicyItemCondition extends 
RangerPolicyCondition implements java.io.Serializable {
+               public RangerPolicyItemCondition() {
+                       this(null, null);
+               }
+
+               public RangerPolicyItemCondition(String type, List<String> 
values) {
+                       super(type,values);
+               }
+       }
+
+       @JsonAutoDetect(fieldVisibility=Visibility.ANY)
+       @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+       @JsonIgnoreProperties(ignoreUnknown=true)
+       @XmlRootElement
+       @XmlAccessorType(XmlAccessType.FIELD)
+       public static class RangerPolicyCondition implements 
java.io.Serializable {
                private static final long serialVersionUID = 1L;
 
                private String type;
                private List<String> values;
 
-               public RangerPolicyItemCondition() {
+               public RangerPolicyCondition() {
                        this(null, null);
                }
 
-               public RangerPolicyItemCondition(String type, List<String> 
values) {
+               public RangerPolicyCondition(String type, List<String> values) {
                        setType(type);
                        setValues(values);
                }
@@ -1392,7 +1437,7 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
                }
 
                public StringBuilder toString(StringBuilder sb) {
-                       sb.append("RangerPolicyItemCondition={");
+                       sb.append("RangerPolicyCondition={");
                        sb.append("type={").append(type).append("} ");
                        sb.append("values={");
                        if(values != null) {
@@ -1424,7 +1469,7 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
                                return false;
                        if (getClass() != obj.getClass())
                                return false;
-                       RangerPolicyItemCondition other = 
(RangerPolicyItemCondition) obj;
+                       RangerPolicyCondition other = (RangerPolicyCondition) 
obj;
                        if (type == null) {
                                if (other.type != null)
                                        return false;
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyResourceSignature.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyResourceSignature.java
index a1aaa22..40b5ddd 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyResourceSignature.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyResourceSignature.java
@@ -28,9 +28,11 @@ import java.util.TreeMap;
 
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyCondition;
 import org.apache.solr.common.StringUtils;
 
 public class RangerPolicyResourceSignature {
@@ -148,6 +150,11 @@ public class RangerPolicyResourceSignature {
                            resource += _policy.getZoneName();
             }
 
+                       if (_policy.getConditions() != null) {
+                               CustomConditionSerialiser 
customConditionSerialiser = new 
CustomConditionSerialiser(_policy.getConditions());
+                               resource += 
customConditionSerialiser.toString();
+                       }
+
                        String result = 
String.format("{version=%d,type=%d,resource=%s}", _SignatureVersion, type, 
resource);
                        return result;
                }
@@ -189,4 +196,39 @@ public class RangerPolicyResourceSignature {
                        return builder.toString();
                }
        }
+
+       static class CustomConditionSerialiser {
+               final List<RangerPolicyCondition> rangerPolicyConditions;
+
+               CustomConditionSerialiser(List<RangerPolicyCondition> 
rangerPolicyConditions) {
+                       this.rangerPolicyConditions = rangerPolicyConditions;
+               }
+
+               @Override
+               public String toString() {
+                       StringBuilder builder = new StringBuilder();
+                       Map<String, List<String>> conditionMap = new 
TreeMap<>();
+
+                       for(RangerPolicyCondition rangerPolicyCondition : 
rangerPolicyConditions) {
+                               if (rangerPolicyCondition.getType() != null) {
+                                       String type = 
rangerPolicyCondition.getType();
+                                       List<String> values = new ArrayList<>();
+                                       if (rangerPolicyCondition.getValues() 
!= null) {
+                                               
values.addAll(rangerPolicyCondition.getValues());
+                                               Collections.sort(values);
+                                       }
+                                       conditionMap.put(type, values);
+                               }
+                       }
+
+                       if (MapUtils.isNotEmpty(conditionMap)) {
+                               builder.append("{");
+                               builder.append("RangerPolicyConditions=");
+                               builder.append(conditionMap);
+                               builder.append("}");
+                       }
+
+                       return builder.toString();
+               }
+       }
 }
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
index f58d514..0f09952 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
@@ -40,6 +40,7 @@ public abstract class RangerAbstractPolicyItemEvaluator 
implements RangerPolicyI
        private static final int 
RANGER_POLICY_ITEM_EVAL_ORDER_MAX_DISCOUNT_CUSTOM_CONDITIONS =  25;
        private static final int 
RANGER_POLICY_ITEM_EVAL_ORDER_CUSTOM_CONDITION_PENALTY       =   5;
 
+       final RangerPolicy                              policy;
        final RangerPolicyEngineOptions options;
        final RangerServiceDef          serviceDef;
        final RangerPolicyItem          policyItem;
@@ -58,6 +59,7 @@ public abstract class RangerAbstractPolicyItemEvaluator 
implements RangerPolicyI
                this.options        = options;
                this.policyId       = policy != null && policy.getId() != null 
? policy.getId() : -1;
                this.evalOrder      = computeEvalOrder();
+               this.policy         = policy;
        }
 
        @Override
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCustomConditionEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCustomConditionEvaluator.java
new file mode 100644
index 0000000..1d08718
--- /dev/null
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCustomConditionEvaluator.java
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.plugin.policyevaluator;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition;
+import org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
+import org.apache.ranger.plugin.util.RangerPerfTracer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class RangerCustomConditionEvaluator {
+
+    private static final Log LOG = 
LogFactory.getLog(RangerCustomConditionEvaluator.class);
+    private static final Log PERF_POLICY_INIT_LOG = 
RangerPerfTracer.getPerfLogger("policy.init");
+    private static final Log PERF_POLICYITEM_INIT_LOG = 
RangerPerfTracer.getPerfLogger("policyitem.init");
+    private static final Log PERF_POLICYCONDITION_INIT_LOG = 
RangerPerfTracer.getPerfLogger("policycondition.init");
+
+    public List<RangerConditionEvaluator> 
getRangerPolicyConditionEvaluator(RangerPolicy policy,
+                                                                               
   RangerServiceDef serviceDef,
+                                                                               
   RangerPolicyEngineOptions options) {
+        List<RangerConditionEvaluator> conditionEvaluators = new ArrayList<>();
+
+        if (!getConditionsDisabledOption(options) && 
CollectionUtils.isNotEmpty(policy.getConditions())) {
+
+            RangerPerfTracer perf = null;
+
+            long policyId = policy.getId();
+
+            if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_INIT_LOG)) {
+                perf = RangerPerfTracer.getPerfTracer(PERF_POLICY_INIT_LOG, 
"RangerCustomConditionEvaluator.init(policyId=" + policyId + ")");
+            }
+
+            for (RangerPolicy.RangerPolicyCondition condition : 
policy.getConditions()) {
+                RangerServiceDef.RangerPolicyConditionDef conditionDef = 
getConditionDef(condition.getType(),serviceDef);
+
+                if (conditionDef == null) {
+                    
LOG.error("RangerCustomConditionEvaluator.getRangerPolicyConditionEvaluator(policyId="
 + policyId + "): conditionDef '" + condition.getType() + "' not found. 
Ignoring the condition");
+
+                    continue;
+                }
+
+                RangerConditionEvaluator conditionEvaluator = 
newConditionEvaluator(conditionDef.getEvaluator());
+
+                if (conditionEvaluator != null) {
+                    conditionEvaluator.setServiceDef(serviceDef);
+                    conditionEvaluator.setConditionDef(conditionDef);
+                    conditionEvaluator.setPolicyCondition(condition);
+
+                    RangerPerfTracer perfConditionInit = null;
+
+                    if 
(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYCONDITION_INIT_LOG)) {
+                        perfConditionInit = 
RangerPerfTracer.getPerfTracer(PERF_POLICYCONDITION_INIT_LOG, 
"RangerConditionEvaluator.init(policyId=" + policyId + "policyConditionType=" + 
condition.getType() + ")");
+                    }
+
+                    conditionEvaluator.init();
+
+                    RangerPerfTracer.log(perfConditionInit);
+
+                    conditionEvaluators.add(conditionEvaluator);
+                } else {
+                    
LOG.error("RangerCustomConditionEvaluator.getRangerPolicyConditionEvaluator(policyId="
 + policyId + "): failed to init Policy ConditionEvaluator '" + 
condition.getType() + "'; evaluatorClassName='" + conditionDef.getEvaluator() + 
"'");
+                }
+            }
+
+            RangerPerfTracer.log(perf);
+        }
+        return conditionEvaluators;
+    }
+
+
+    public List<RangerConditionEvaluator> 
getPolicyItemConditionEvaluator(RangerPolicy policy,
+                                                                           
RangerPolicyItem policyItem,
+                                                                           
RangerServiceDef serviceDef,
+                                                                           
RangerPolicyEngineOptions options,
+                                                                           int 
policyItemIndex) {
+
+        List<RangerConditionEvaluator> conditionEvaluators = new ArrayList<>();
+
+        if (!getConditionsDisabledOption(options) && 
CollectionUtils.isNotEmpty(policyItem.getConditions())) {
+
+            RangerPerfTracer perf = null;
+
+            Long policyId = policy.getId();
+
+            if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYITEM_INIT_LOG)) {
+                perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICYITEM_INIT_LOG, 
"RangerPolicyItemEvaluator.getRangerPolicyConditionEvaluator(policyId=" + 
policyId + ",policyItemIndex=" + policyItemIndex + ")");
+            }
+
+            for (RangerPolicyItemCondition condition : 
policyItem.getConditions()) {
+                RangerServiceDef.RangerPolicyConditionDef conditionDef = 
getConditionDef(condition.getType(), serviceDef);
+
+                if (conditionDef == null) {
+                    
LOG.error("RangerCustomConditionEvaluator.getPolicyItemConditionEvaluator(policyId="
 + policyId + "): conditionDef '" + condition.getType() + "' not found. 
Ignoring the condition");
+
+                    continue;
+                }
+
+                RangerConditionEvaluator conditionEvaluator = 
newConditionEvaluator(conditionDef.getEvaluator());
+
+                if (conditionEvaluator != null) {
+                    conditionEvaluator.setServiceDef(serviceDef);
+                    conditionEvaluator.setConditionDef(conditionDef);
+                    conditionEvaluator.setPolicyItemCondition(condition);
+
+                    RangerPerfTracer perfConditionInit = null;
+
+                    
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYCONDITION_INIT_LOG)) {
+                        perfConditionInit = 
RangerPerfTracer.getPerfTracer(PERF_POLICYCONDITION_INIT_LOG, 
"RangerConditionEvaluator.init(policyId=" + policyId + ",policyItemIndex=" + 
policyItemIndex + ",policyConditionType=" + condition.getType() + ")");
+                    }
+
+                    conditionEvaluator.init();
+
+                    RangerPerfTracer.log(perfConditionInit);
+
+                    conditionEvaluators.add(conditionEvaluator);
+                } else {
+                    
LOG.error("RangerCustomConditionEvaluator.getPolicyItemConditionEvaluator(policyId="
 + policyId + "): failed to init PolicyItem ConditionEvaluator '" + 
condition.getType() + "'; evaluatorClassName='" + conditionDef.getEvaluator() + 
"'");
+                }
+            }
+            RangerPerfTracer.log(perf);
+        }
+        return  conditionEvaluators;
+    }
+
+    private RangerServiceDef.RangerPolicyConditionDef getConditionDef(String 
conditionName, RangerServiceDef serviceDef) {
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("==> RangerCustomConditionEvaluator.getConditionDef(" + 
conditionName + ")");
+        }
+
+        RangerServiceDef.RangerPolicyConditionDef ret = null;
+
+        if (serviceDef != null && 
CollectionUtils.isNotEmpty(serviceDef.getPolicyConditions())) {
+            for(RangerServiceDef.RangerPolicyConditionDef conditionDef : 
serviceDef.getPolicyConditions()) {
+                if(StringUtils.equals(conditionName, conditionDef.getName())) {
+                    ret = conditionDef;
+                    break;
+                }
+            }
+        }
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("<== RangerCustomConditionEvaluator.getConditionDef(" + 
conditionName + "): " + ret);
+        }
+
+        return ret;
+    }
+
+
+    private RangerConditionEvaluator newConditionEvaluator(String className) {
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("==> 
RangerCustomConditionEvaluator.newConditionEvaluator(" + className + ")");
+        }
+
+        RangerConditionEvaluator evaluator = null;
+
+        try {
+            @SuppressWarnings("unchecked")
+            
Class<org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator> 
matcherClass = 
(Class<org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator>)Class.forName(className);
+
+            evaluator = matcherClass.newInstance();
+        } catch(Throwable t) {
+            LOG.error("RangerCustomConditionEvaluator.newConditionEvaluator(" 
+ className + "): error instantiating evaluator", t);
+        }
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("<== 
RangerCustomConditionEvaluator.newConditionEvaluator(" + className + "): " + 
evaluator);
+        }
+
+        return evaluator;
+    }
+
+    private boolean getConditionsDisabledOption(RangerPolicyEngineOptions 
options) {
+        return options != null && options.disableCustomConditions;
+    }
+}
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 3e7c34c..f1e999a 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
@@ -33,6 +33,8 @@ import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import 
org.apache.ranger.plugin.conditionevaluator.RangerAbstractConditionEvaluator;
+import org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator;
 import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
@@ -63,6 +65,7 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
        private static final Log PERF_POLICY_INIT_LOG = 
RangerPerfTracer.getPerfLogger("policy.init");
        private static final Log PERF_POLICY_INIT_ACLSUMMARY_LOG = 
RangerPerfTracer.getPerfLogger("policy.init.ACLSummary");
        private static final Log PERF_POLICY_REQUEST_LOG = 
RangerPerfTracer.getPerfLogger("policy.request");
+       private static final Log PERF_POLICYCONDITION_REQUEST_LOG = 
RangerPerfTracer.getPerfLogger("policycondition.request");
 
        private RangerPolicyResourceMatcher     resourceMatcher;
        private List<RangerValidityScheduleEvaluator> 
validityScheduleEvaluators;
@@ -73,6 +76,7 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
        private int                             customConditionsCount;
        private List<RangerDataMaskPolicyItemEvaluator>  dataMaskEvaluators;
        private List<RangerRowFilterPolicyItemEvaluator> rowFilterEvaluators;
+       private List<RangerConditionEvaluator>  conditionEvaluators;
        private String perfTag;
        private PolicyACLSummary aclSummary                 = null;
        private boolean          useAclSummaryForEvaluation = false;
@@ -150,6 +154,7 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
 
                        dataMaskEvaluators  = 
createDataMaskPolicyItemEvaluators(policy, serviceDef, options, 
policy.getDataMaskPolicyItems());
                        rowFilterEvaluators = 
createRowFilterPolicyItemEvaluators(policy, serviceDef, options, 
policy.getRowFilterPolicyItems());
+                       conditionEvaluators = 
createRangerPolicyConditionEvaluator(policy, serviceDef, options);
                } else {
                        validityScheduleEvaluators = 
Collections.<RangerValidityScheduleEvaluator>emptyList();
                        allowEvaluators            = 
Collections.<RangerPolicyItemEvaluator>emptyList();
@@ -158,6 +163,7 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                        denyExceptionEvaluators    = 
Collections.<RangerPolicyItemEvaluator>emptyList();
                        dataMaskEvaluators         = 
Collections.<RangerDataMaskPolicyItemEvaluator>emptyList();
                        rowFilterEvaluators        = 
Collections.<RangerRowFilterPolicyItemEvaluator>emptyList();
+                       conditionEvaluators        = 
Collections.<RangerConditionEvaluator>emptyList();
                }
 
                RangerPolicyItemEvaluator.EvalOrderComparator comparator = new 
RangerPolicyItemEvaluator.EvalOrderComparator();
@@ -243,15 +249,18 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                                }
 
                                if (isMatched) {
-                                       if (!result.getIsAuditedDetermined()) {
-                                               if (isAuditEnabled()) {
-                                                       
result.setIsAudited(true);
-                                                       
result.setAuditPolicyId(getPolicy().getId());
+                                       //Evaluate Policy Level Custom 
Conditions, if any and allowed then go ahead for policyItem level evaluation
+                                       
if(matchPolicyCustomConditions(request)) {
+                                               if 
(!result.getIsAuditedDetermined()) {
+                                                       if (isAuditEnabled()) {
+                                                               
result.setIsAudited(true);
+                                                               
result.setAuditPolicyId(getPolicy().getId());
+                                                       }
                                                }
-                                       }
-                                       if (!result.getIsAccessDetermined()) {
-                                               if 
(hasMatchablePolicyItem(request)) {
-                                                       
evaluatePolicyItems(request, matchType, result);
+                                               if 
(!result.getIsAccessDetermined()) {
+                                                       if 
(hasMatchablePolicyItem(request)) {
+                                                               
evaluatePolicyItems(request, matchType, result);
+                                                       }
                                                }
                                        }
                                }
@@ -1167,7 +1176,71 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
         if(LOG.isDebugEnabled()) {
             LOG.debug("<== 
RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + user + ", " + userGroups 
+ ", " + accessType + "): " + ret);
         }
-
         return ret;
     }
-}
+
+       // Policy Level Condition evaluator
+       private boolean matchPolicyCustomConditions(RangerAccessRequest 
request) {
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> 
RangerDefaultPolicyEvaluator.matchPolicyCustomConditions(" + request + ")");
+               }
+
+               boolean ret = true;
+
+               if (CollectionUtils.isNotEmpty(conditionEvaluators)) {
+                       if(LOG.isDebugEnabled()) {
+                               
LOG.debug("RangerDefaultPolicyEvaluator.matchPolicyCustomConditions(): 
conditionCount=" + conditionEvaluators.size());
+                       }
+                       for(RangerConditionEvaluator conditionEvaluator : 
conditionEvaluators) {
+                               if(LOG.isDebugEnabled()) {
+                                       LOG.debug("evaluating condition: " + 
conditionEvaluator);
+                               }
+                               RangerPerfTracer perf = null;
+
+                               
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYCONDITION_REQUEST_LOG)) {
+
+                                       String conditionType = null;
+                                       if (conditionEvaluator instanceof 
RangerAbstractConditionEvaluator) {
+                                               conditionType = 
((RangerAbstractConditionEvaluator)conditionEvaluator).getPolicyCondition().getType();
+                                       }
+
+                                       perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICYCONDITION_REQUEST_LOG, 
"RangerConditionEvaluator.matchPolicyCustomConditions(policyId=" + getId() +  
",policyConditionType=" + conditionType + ")");
+                               }
+
+                               boolean conditionEvalResult = 
conditionEvaluator.isMatched(request);
+
+                               RangerPerfTracer.log(perf);
+
+                               if (!conditionEvalResult) {
+                                       if(LOG.isDebugEnabled()) {
+                                               LOG.debug(conditionEvaluator + 
" returned false");
+                                       }
+                                       ret = false;
+                                       break;
+                               }
+                       }
+               }
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("<== 
RangerDefaultPolicyEvaluator.matchCustomConditions(" + request + "): " + ret);
+               }
+
+               return ret;
+       }
+
+       private List<RangerConditionEvaluator> 
createRangerPolicyConditionEvaluator(RangerPolicy policy,
+                                                                               
                                                                                
RangerServiceDef serviceDef,
+                                                                               
                                                                                
RangerPolicyEngineOptions options) {
+               List<RangerConditionEvaluator> rangerConditionEvaluators = null;
+
+               RangerCustomConditionEvaluator rangerConditionEvaluator = new 
RangerCustomConditionEvaluator();
+
+               rangerConditionEvaluators = 
rangerConditionEvaluator.getRangerPolicyConditionEvaluator(policy,serviceDef,options);
+
+               if (rangerConditionEvaluators != null) {
+                       customConditionsCount += 
rangerConditionEvaluators.size();
+               }
+
+               return rangerConditionEvaluators;
+       }
+}
\ No newline at end of file
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
index a32322b..45231e7 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
@@ -18,7 +18,6 @@
  */
 package org.apache.ranger.plugin.policyevaluator;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -34,7 +33,6 @@ import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
-import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition;
 import 
org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
@@ -48,9 +46,7 @@ import org.apache.ranger.plugin.util.RangerPerfTracer;
 public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEvaluator {
        private static final Log LOG = 
LogFactory.getLog(RangerDefaultPolicyItemEvaluator.class);
 
-       private static final Log PERF_POLICYITEM_INIT_LOG = 
RangerPerfTracer.getPerfLogger("policyitem.init");
        private static final Log PERF_POLICYITEM_REQUEST_LOG = 
RangerPerfTracer.getPerfLogger("policyitem.request");
-       private static final Log PERF_POLICYCONDITION_INIT_LOG = 
RangerPerfTracer.getPerfLogger("policycondition.init");
        private static final Log PERF_POLICYCONDITION_REQUEST_LOG = 
RangerPerfTracer.getPerfLogger("policycondition.request");
 
        private boolean hasCurrentUser;
@@ -86,48 +82,9 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
                        }
                }
 
-               if (!getConditionsDisabledOption() && 
CollectionUtils.isNotEmpty(policyItem.getConditions())) {
-                       conditionEvaluators = new ArrayList<>();
+               RangerCustomConditionEvaluator rangerCustomConditionEvaluator = 
new RangerCustomConditionEvaluator();
 
-                       RangerPerfTracer perf = null;
-
-                       
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYITEM_INIT_LOG)) {
-                               perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICYITEM_INIT_LOG, 
"RangerPolicyItemEvaluator.init(policyId=" + policyId + ",policyItemIndex=" + 
getPolicyItemIndex() + ")");
-                       }
-
-                       for (RangerPolicyItemCondition condition : 
policyItem.getConditions()) {
-                               RangerPolicyConditionDef conditionDef = 
getConditionDef(condition.getType());
-
-                               if (conditionDef == null) {
-                                       
LOG.error("RangerDefaultPolicyItemEvaluator(policyId=" + policyId + "): 
conditionDef '" + condition.getType() + "' not found. Ignoring the condition");
-
-                                       continue;
-                               }
-
-                               RangerConditionEvaluator conditionEvaluator = 
newConditionEvaluator(conditionDef.getEvaluator());
-
-                               if (conditionEvaluator != null) {
-                                       
conditionEvaluator.setServiceDef(serviceDef);
-                                       
conditionEvaluator.setConditionDef(conditionDef);
-                                       
conditionEvaluator.setPolicyItemCondition(condition);
-
-                                       RangerPerfTracer perfConditionInit = 
null;
-
-                                       
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYCONDITION_INIT_LOG)) {
-                                               perfConditionInit = 
RangerPerfTracer.getPerfTracer(PERF_POLICYCONDITION_INIT_LOG, 
"RangerConditionEvaluator.init(policyId=" + policyId + ",policyItemIndex=" + 
getPolicyItemIndex() + ",policyConditionType=" + condition.getType() + ")");
-                                       }
-
-                                       conditionEvaluator.init();
-
-                                       RangerPerfTracer.log(perfConditionInit);
-
-                                       
conditionEvaluators.add(conditionEvaluator);
-                               } else {
-                                       
LOG.error("RangerDefaultPolicyItemEvaluator(policyId=" + policyId + "): failed 
to instantiate condition evaluator '" + condition.getType() + "'; 
evaluatorClassName='" + conditionDef.getEvaluator() + "'");
-                               }
-                       }
-                       RangerPerfTracer.log(perf);
-               }
+               conditionEvaluators = 
rangerCustomConditionEvaluator.getPolicyItemConditionEvaluator(policy,policyItem,serviceDef,options,policyItemIndex);
 
                List<String> users = policyItem.getUsers();
                this.hasCurrentUser = CollectionUtils.isNotEmpty(users) && 
users.contains(RangerPolicyEngine.USER_CURRENT);
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 080efac..e019e62 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
@@ -362,6 +362,13 @@ public class TestPolicyEngine {
                runTestsFromResourceFiles(resourceFiles);
        }
 
+       @Test
+       public void testPolicyEngine_policylevel_conditions() {
+               String[] conditionsTestResourceFiles = { 
"/policyengine/test_policyengine_policylevel_conditions.json" };
+
+               runTestsFromResourceFiles(conditionsTestResourceFiles);
+       }
+
        private void runTestsFromResourceFiles(String[] resourceNames) {
                for(String resourceName : resourceNames) {
                        InputStream inStream = 
this.getClass().getResourceAsStream(resourceName);
@@ -524,7 +531,6 @@ public class TestPolicyEngine {
                                assertNotNull("result was null! - " + 
test.name, result);
                                assertEquals("isAllowed mismatched! - " + 
test.name, expected.getIsAllowed(), result.getIsAllowed());
                                assertEquals("isAudited mismatched! - " + 
test.name, expected.getIsAudited(), result.getIsAudited());
-                               assertEquals("policyId mismatched! - " + 
test.name, expected.getPolicyId(), result.getPolicyId());
                        }
 
                        if(test.dataMaskResult != null) {
diff --git 
a/agents-common/src/test/resources/policyengine/test_policyengine_policylevel_conditions.json
 
b/agents-common/src/test/resources/policyengine/test_policyengine_policylevel_conditions.json
new file mode 100644
index 0000000..88fcb7b
--- /dev/null
+++ 
b/agents-common/src/test/resources/policyengine/test_policyengine_policylevel_conditions.json
@@ -0,0 +1,90 @@
+{
+  "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"}
+    ],
+    "policyConditions":[
+      {"name":"country", 
"evaluator":"org.apache.ranger.plugin.conditionevaluator.RangerSimpleMatcher", 
"evaluatorOptions":{"CONTEXT_NAME":"country"}}
+    ]
+  },
+
+  "policies":[
+    {"id":1,"name":"db=default: allow create from 
US","isEnabled":true,"isAuditEnabled":true,
+      
"resources":{"database":{"values":["default"]},"table":{"values":["*"]},"column":{"values":["*"]}},
+      "conditions":[{"type":"country","values":["US"]}],
+      "policyItems":[
+        
{"accesses":[{"type":"create"}],"users":[],"groups":["public"],"delegateAdmin":false}
+      ]
+    },
+
+    {"id":2,"name":"db=default: allow create from 
US,CA","isEnabled":true,"isAuditEnabled":true,
+      
"resources":{"database":{"values":["default"]},"table":{"values":["*"]},"column":{"values":["*"]}},
+      "conditions":[{"type":"country","values":["US","CA"]}],
+      "policyItems":[
+        
{"accesses":[{"type":"create"}],"users":[],"groups":["public"],"delegateAdmin":false}
+      ]
+    },
+
+    {"id":3,"name":"db=default: allow create from 
US","isEnabled":true,"isAuditEnabled":true,
+      
"resources":{"database":{"values":["default"]},"table":{"values":["*"]},"column":{"values":["*"]}},
+      "policyItems":[
+        
{"accesses":[{"type":"create"}],"users":[],"groups":["public"],"delegateAdmin":false}
+      ]
+    }
+  ],
+
+  "tests":[
+    {"name":"ALLOW 'create default.testTable;' country=US",
+      "request":{
+        "resource":{"elements":{"database":"default"}},
+        
"accessType":"create","user":"user1","userGroups":["users"],"requestData":"create
 default.testTable; country=US",
+        "context":{"country":"US"}
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":1}
+    },
+
+    {"name":"ALLOW 'create default.testTable;' country=CA",
+      "request":{
+        "resource":{"elements":{"database":"default"}},
+        
"accessType":"create","user":"user1","userGroups":["users"],"requestData":"create
 default.testTable; country=CA",
+        "context":{"country":"CA"}
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":2}
+    },
+
+    {"name":"ALLOW 'create default.testTable;' no condition",
+      "request":{
+        "resource":{"elements":{"database":"default"}},
+        
"accessType":"create","user":"user1","userGroups":["users"],"requestData":"create
 default.testTable;"
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":3}
+    },
+
+    {"name":"Deny 'create default.testTable;' country=CA",
+      "request":{
+        "resource":{"elements":{"database":"default"}},
+        
"accessType":"create","user":"user1","userGroups":["users"],"requestData":"create
 default.testTable; country=CA",
+        "context":{"country":"CA"}
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":-1}
+    }
+  ]
+}
+
diff --git 
a/ranger-examples/conditions-enrichers/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerPolicyConditionSampleSimpleMatcher.java
 
b/ranger-examples/conditions-enrichers/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerPolicyConditionSampleSimpleMatcher.java
new file mode 100644
index 0000000..857fffe
--- /dev/null
+++ 
b/ranger-examples/conditions-enrichers/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerPolicyConditionSampleSimpleMatcher.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.plugin.conditionevaluator;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This is a sample implementation of a condition Evaluator.  It works in 
conjunction with the sample context enricher
+ * <code>RangerSampleProjectProvider</code>.  This is how it would be 
specified in the service definition:
+       {
+               ...
+               ... service definition
+               ...
+               "policyConditions": [
+               {
+                       "itemId": 1,
+                       "name": "user-in-project",
+                       "evaluator": 
"org.apache.ranger.plugin.conditionevaluator.RangerSimpleMatcher",
+                       "evaluatorOptions": { CONTEXT_NAME=’PROJECT’},
+                       "validationRegEx":"",
+                       "validationMessage": "",
+                       "uiHint":"",
+                       "label": "Project Matcher",
+                       "description": "Projects"
+               }
+        }
+ *
+ * Name of this class is specified via the "evaluator" of the policy condition 
definition.  Significant evaluator option
+ * for this evaluator is the CONTEXT_NAME which indicates the name under which 
it would look for value for the condition.
+ * It is also use to lookup the condition values specified in the policy.  
This example uses CONTEXT_NAME of PROJECT
+ * which matches the value under which context is enriched by its companion 
class <code>RangerSampleProjectProvider</code>.
+ *
+ * Note that the same Condition Evaluator can be used to process Context 
enrichment done by <code>RangerSampleCountryProvider</code>
+ * provided the CONTEXT_NAME evaluator option is set to COUNTRY which is same 
as the value used by its companion Context
+ * Enricher <code>RangerSampleCountryProvider</code>.  Which serves as an 
example of how a single Condition Evaluator
+ * implementation can be used to model multiple policy conditions.
+ *
+ * For matching context value against policy values it uses 
<code>FilenameUtils.wildcardMatch()</code> which allows policy authors
+ * flexibility to specify policy conditions using wildcards.  Take a look at
+ * {@link 
org.apache.ranger.plugin.conditionevaluator.RangerSampleSimpleMatcherTest#testIsMatched_happyPath()
 testIsMatched_happyPath}
+ * test for examples of what sorts of matching is afforded by this use.
+ *
+ */
+public class RangerPolicyConditionSampleSimpleMatcher extends 
RangerAbstractConditionEvaluator {
+
+       private static final Log LOG = 
LogFactory.getLog(RangerPolicyConditionSampleSimpleMatcher.class);
+
+       public static final String CONTEXT_NAME = "CONTEXT_NAME";
+
+       private boolean _allowAny = false;
+       private String _contextName = null;
+       private List<String> _values = new ArrayList<String>();
+
+       @Override
+       public void init() {
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> RangerSampleSimpleMatcher.init(" + 
policyCondition + ")");
+               }
+
+               super.init();
+
+               if (policyCondition == null) {
+                       LOG.debug("init: null policy condition! Will match 
always!");
+                       _allowAny = true;
+               } else if (conditionDef == null) {
+                       LOG.debug("init: null policy condition definition! Will 
match always!");
+                       _allowAny = true;
+               } else if (CollectionUtils.isEmpty(condition.getValues())) {
+                       LOG.debug("init: empty conditions collection on policy 
condition!  Will match always!");
+                       _allowAny = true;
+               } else if 
(MapUtils.isEmpty(conditionDef.getEvaluatorOptions())) {
+                       LOG.debug("init: Evaluator options were empty.  Can't 
determine what value to use from context.  Will match always.");
+                       _allowAny = true;
+               } else if 
(StringUtils.isEmpty(conditionDef.getEvaluatorOptions().get(CONTEXT_NAME))) {
+                       LOG.debug("init: CONTEXT_NAME is not specified in 
evaluator options.  Can't determine what value to use from context.  Will match 
always.");
+                       _allowAny = true;
+               } else {
+                       _contextName = 
conditionDef.getEvaluatorOptions().get(CONTEXT_NAME);
+                       for (String value : policyCondition.getValues()) {
+                               _values.add(value);
+                       }
+               }
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("<== RangerSampleSimpleMatcher.init(" + 
policyCondition + "): values[" + _values + "]");
+               }
+       }
+
+       @Override
+       public boolean isMatched(RangerAccessRequest request) {
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> RangerSampleSimpleMatcher.isMatched(" + 
request + ")");
+               }
+
+               boolean matched = false;
+
+               if (_allowAny) {
+                       matched = true;
+               } else {
+                       String requestValue = extractValue(request, 
_contextName);
+                       if (StringUtils.isNotBlank(requestValue)) {
+                               for (String policyValue : _values) {
+                                       if 
(FilenameUtils.wildcardMatch(requestValue, policyValue)) {
+                                               matched = true;
+                                               break;
+                                       }
+                               }
+                       }
+               }
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("<== RangerSampleSimpleMatcher.isMatched(" + 
request+ "): " + matched);
+               }
+
+               return matched;
+       }
+
+       String extractValue(final RangerAccessRequest request, String key) {
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> RangerSampleSimpleMatcher.extractValue(" 
+ request+ ")");
+               }
+
+               String value = null;
+               if (request == null) {
+                       LOG.debug("isMatched: Unexpected: null request.  
Returning null!");
+               } else if (request.getContext() == null) {
+                       LOG.debug("isMatched: Context map of request is null.  
Ok. Returning null!");
+               } else if 
(CollectionUtils.isEmpty(request.getContext().entrySet())) {
+                       LOG.debug("isMatched: Missing context on request.  Ok. 
Condition isn't applicable.  Returning null!");
+               } else if (!request.getContext().containsKey(key)) {
+                       if (LOG.isDebugEnabled()) {
+                               LOG.debug("isMatched: Unexpected: Context did 
not have data for condition[" + key + "]. Returning null!");
+                       }
+               } else {
+                       value = (String)request.getContext().get(key);
+               }
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("<== RangerSampleSimpleMatcher.extractValue(" 
+ request+ "): " + value);
+               }
+               return value;
+       }
+}
diff --git 
a/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java 
b/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java
index 25b48bb..08963f0 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java
@@ -79,6 +79,13 @@ public class PolicyRefUpdater {
                final Set<String> conditionTypes  = new HashSet<>();
                final Set<String> dataMaskTypes   = new HashSet<>();
 
+               List<RangerPolicy.RangerPolicyCondition> rangerPolicyConditions 
= policy.getConditions();
+               if (CollectionUtils.isNotEmpty(rangerPolicyConditions)) {
+                       for (RangerPolicy.RangerPolicyCondition condition : 
rangerPolicyConditions) {
+                               conditionTypes.add(condition.getType());
+                       }
+               }
+
                for (List<? extends RangerPolicyItem> policyItems :  
getAllPolicyItems(policy)) {
                        if (CollectionUtils.isEmpty(policyItems)) {
                                continue;
diff --git 
a/security-admin/src/main/java/org/apache/ranger/service/RangerPolicyService.java
 
b/security-admin/src/main/java/org/apache/ranger/service/RangerPolicyService.java
index d0f1d93..771feec 100644
--- 
a/security-admin/src/main/java/org/apache/ranger/service/RangerPolicyService.java
+++ 
b/security-admin/src/main/java/org/apache/ranger/service/RangerPolicyService.java
@@ -72,6 +72,7 @@ public class RangerPolicyService extends 
RangerPolicyServiceBase<XXPolicy, Range
         public static final String 
POLICY_LABELS_CLASS_FIELD_NAME="policyLabels";
         public static final String 
POLICY_VALIDITYSCHEDULES_CLASS_FIELD_NAME="validitySchedules";
         public static final String 
POLICY_PRIORITY_CLASS_FIELD_NAME="policyPriority";
+       public static final String 
POLICY_CONDITION_CLASS_FIELD_NAME="policyConditions";
 
        static HashMap<String, VTrxLogAttr> trxLogAttrs = new HashMap<String, 
VTrxLogAttr>();
        String actionCreate;
@@ -83,6 +84,7 @@ public class RangerPolicyService extends 
RangerPolicyServiceBase<XXPolicy, Range
                trxLogAttrs.put("description", new VTrxLogAttr("description", 
"Policy Description", false));
                trxLogAttrs.put("isEnabled", new VTrxLogAttr("isEnabled", 
"Policy Status", false));
                trxLogAttrs.put("resources", new VTrxLogAttr("resources", 
"Policy Resources", false));
+               trxLogAttrs.put("policyConditions", new 
VTrxLogAttr("policyConditions", "Policy Conditions", false));
                trxLogAttrs.put("policyItems", new VTrxLogAttr("policyItems", 
"Policy Items", false));
                trxLogAttrs.put("denyPolicyItems", new 
VTrxLogAttr("denyPolicyItems", "DenyPolicy Items", false));
                trxLogAttrs.put("allowExceptions", new 
VTrxLogAttr("allowExceptions", "Allow Exceptions", false));
@@ -203,6 +205,8 @@ public class RangerPolicyService extends 
RangerPolicyServiceBase<XXPolicy, Range
                        if (!isEnum) {
                            if 
(POLICY_RESOURCE_CLASS_FIELD_NAME.equalsIgnoreCase(fieldName)) {
                                value = 
processPolicyResourcesForTrxLog(field.get(vObj));
+                               } else if 
(POLICY_CONDITION_CLASS_FIELD_NAME.equalsIgnoreCase(fieldName)) {
+                                       value = 
processPolicyItemsForTrxLog(field.get(vObj));
                        } else if 
(POLICY_ITEM_CLASS_FIELD_NAME.equalsIgnoreCase(fieldName)) {
                                value = 
processPolicyItemsForTrxLog(field.get(vObj));
                        } else if 
(DENYPOLICY_ITEM_CLASS_FIELD_NAME.equalsIgnoreCase(fieldName)) {

Reply via email to