You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ab...@apache.org on 2019/03/21 22:44:36 UTC

[ranger] branch master updated: RANGER-2375: RangerAuthContext is not correctly initialized

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

abhay 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 9f09d87  RANGER-2375: RangerAuthContext is not correctly initialized
9f09d87 is described below

commit 9f09d87e22ff2eb9324fd46959e21f1a54f69929
Author: Abhay Kulkarni <>
AuthorDate: Thu Mar 21 15:23:41 2019 -0700

    RANGER-2375: RangerAuthContext is not correctly initialized
---
 .../RangerAbstractContextEnricher.java             |  65 ++-
 .../ranger/plugin/service/RangerAuthContext.java   |  12 +-
 .../ranger/plugin/service/RangerBasePlugin.java    |  13 +-
 .../plugin/policyengine/TestProjectProvider.java   | 103 ++++
 .../plugin/policyengine/TestRangerAuthContext.java | 121 +++++
 .../policyengine/plugin/resourceTags.json          | 207 +++++++
 .../policyengine/plugin/test_auth_context.json     | 594 +++++++++++++++++++++
 .../resources/policyengine/plugin/userText.txt     |   1 +
 8 files changed, 1095 insertions(+), 21 deletions(-)

diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerAbstractContextEnricher.java b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerAbstractContextEnricher.java
index ddc6df2..0712bfc 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerAbstractContextEnricher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerAbstractContextEnricher.java
@@ -19,8 +19,12 @@
 
 package org.apache.ranger.plugin.contextenricher;
 
+import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.Map;
 import java.util.Properties;
 
@@ -198,26 +202,55 @@ public abstract class RangerAbstractContextEnricher implements RangerContextEnri
 	}
 
 	public Properties readProperties(String fileName) {
-		Properties ret = null;
-		
-		InputStream inStr = null;
+		Properties  ret     = null;
 
-		try {
-			inStr = new FileInputStream(fileName);
+		InputStream inStr   = null;
+		URL         fileURL = null;
+
+		File f = new File(fileName);
+
+		if (f.exists() && f.isFile() && f.canRead()) {
+			try {
+				inStr = new FileInputStream(f);
+				fileURL = f.toURI().toURL();
+			} catch (FileNotFoundException exception) {
+				LOG.error("Error processing input file:" + fileName + " or no privilege for reading file " + fileName, exception);
+			} catch (MalformedURLException malformedException) {
+				LOG.error("Error processing input file:" + fileName + " cannot be converted to URL " + fileName, malformedException);
+			}
+		} else {
+			fileURL = getClass().getResource(fileName);
+
+			if (fileURL == null && !fileName.startsWith("/")) {
+				fileURL = getClass().getResource("/" + fileName);
+			}
+
+			if (fileURL == null) {
+				fileURL = ClassLoader.getSystemClassLoader().getResource(fileName);
+				if (fileURL == null && !fileName.startsWith("/")) {
+					fileURL = ClassLoader.getSystemClassLoader().getResource("/" + fileName);
+				}
+			}
+		}
+
+		if (fileURL != null) {
+			try {
+				inStr = fileURL.openStream();
 
-			Properties prop = new Properties();
+				Properties prop = new Properties();
 
-			prop.load(inStr);
+				prop.load(inStr);
 
-			ret = prop;
-		} catch(Exception excp) {
-			LOG.error("failed to load properties from file '" + fileName + "'", excp);
-		} finally {
-			if(inStr != null) {
-				try {
-					inStr.close();
-				} catch(Exception excp) {
-					// ignore
+				ret = prop;
+			} catch (Exception excp) {
+				LOG.error("failed to load properties from file '" + fileName + "'", excp);
+			} finally {
+				if (inStr != null) {
+					try {
+						inStr.close();
+					} catch (Exception excp) {
+						// ignore
+					}
 				}
 			}
 		}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerAuthContext.java b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerAuthContext.java
index b2cccef..5a18226 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerAuthContext.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerAuthContext.java
@@ -79,8 +79,9 @@ public class RangerAuthContext implements RangerPolicyEngine {
         if (requestContextEnrichers == null) {
             requestContextEnrichers = new ConcurrentHashMap<>();
         }
-
-        requestContextEnrichers.put(enricher, database);
+        // concurrentHashMap does not allow null to be inserted into it, so insert a dummy which is checked
+        // when enrich() is called
+        requestContextEnrichers.put(enricher, database != null ? database : enricher);
     }
 
     public void cleanupRequestContextEnricher(RangerContextEnricher enricher) {
@@ -156,7 +157,12 @@ public class RangerAuthContext implements RangerPolicyEngine {
 	    RangerAccessRequestUtil.setCurrentUserInContext(request.getContext(), request.getUser());
 	    if (MapUtils.isNotEmpty(requestContextEnrichers)) {
             for (Map.Entry<RangerContextEnricher, Object> entry : requestContextEnrichers.entrySet()) {
-                entry.getKey().enrich(request);
+                if (entry.getValue() instanceof RangerContextEnricher && entry.getKey().equals(entry.getValue())) {
+                    // This entry was a result of addOrReplaceRequestContextEnricher() API called with null database value
+                    entry.getKey().enrich(request, null);
+                } else {
+                    entry.getKey().enrich(request, entry.getValue());
+                }
             }
         }
     }
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
index e52d4de..9081af2 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
@@ -274,6 +274,9 @@ public class RangerBasePlugin {
 	}
 
 	public void setPolicies(ServicePolicies policies) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> setPolicies(" + policies + ")");
+		}
 
 		// guard against catastrophic failure during policy engine Initialization or
 		try {
@@ -319,6 +322,7 @@ public class RangerBasePlugin {
 					if (LOG.isDebugEnabled()) {
 						LOG.debug("policies are not null. Creating engine from policies");
 					}
+					currentAuthContext = new RangerAuthContext();
 					newPolicyEngine = new RangerPolicyEngineImpl(appId, policies, policyEngineOptions);
 				} else {
 					if (LOG.isDebugEnabled()) {
@@ -338,6 +342,7 @@ public class RangerBasePlugin {
 								LOG.debug("Failed to apply policyDeltas=" + Arrays.toString(policies.getPolicyDeltas().toArray()) + "), Creating engine from policies");
 								LOG.debug("Creating new engine from servicePolicies:[" + servicePolicies + "]");
 							}
+							currentAuthContext = new RangerAuthContext();
 							newPolicyEngine = new RangerPolicyEngineImpl(appId, servicePolicies, policyEngineOptions);
 						}
 					} else {
@@ -348,7 +353,6 @@ public class RangerBasePlugin {
 				}
 
 				if (newPolicyEngine != null) {
-					currentAuthContext = new RangerAuthContext();
 
 					newPolicyEngine.setUseForwardedIPAddress(useForwardedIPAddress);
 					newPolicyEngine.setTrustedProxyAddresses(trustedProxyAddresses);
@@ -361,7 +365,9 @@ public class RangerBasePlugin {
 					if (oldPolicyEngine != null && !oldPolicyEngine.preCleanup()) {
 						LOG.error("preCleanup() failed on the previous policy engine instance !!");
 					}
-					this.refresher.saveToCache(usePolicyDeltas ? servicePolicies : policies);
+					if (this.refresher != null) {
+						this.refresher.saveToCache(usePolicyDeltas ? servicePolicies : policies);
+					}
 				}
 			} else {
 				LOG.error("Returning without saving policies to cache. Leaving current policy engine as-is");
@@ -370,6 +376,9 @@ public class RangerBasePlugin {
 		} catch (Exception e) {
 			LOG.error("setPolicies: policy engine initialization failed!  Leaving current policy engine as-is. Exception : ", e);
 		}
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== setPolicies(" + policies + ")");
+		}
 	}
 
 	public void contextChanged() {
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestProjectProvider.java b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestProjectProvider.java
new file mode 100644
index 0000000..ef99ecb
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestProjectProvider.java
@@ -0,0 +1,103 @@
+/*
+ * 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.policyengine;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.contextenricher.RangerAbstractContextEnricher;
+
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * This is a sample implementation of a Context Enricher.  It works in conjunction with a sample Condition Evaluator
+ * <code>RangerSampleSimpleMatcher</code>. It This is how it would be used in service definition:
+ {
+    ... service def
+    ...
+    "contextEnrichers": [
+		{
+		 "itemId": 1, "name": "project-provider",
+		 "enricher": "org.apache.ranger.plugin.contextenricher.TestProjectProvider",
+		 "enricherOptions": { "contextName" : "PROJECT", "dataFile":"/etc/ranger/data/userProject.txt"}
+		}
+ 	...
+ }
+
+ contextName: is used to specify the name under which the enricher would push value into context.
+           For purposes of this example the default value of this parameter, if unspecified is PROJECT.  This default
+           can be seen specified in <code>init()</code>.
+ dataFile: is the file which contains the lookup data that this particular enricher would use to
+           ascertain which value to insert into the context.  For purposes of this example the default value of
+           this parameter, if unspecified is /etc/ranger/data/userProject.txt.  This default can be seen specified
+           in <code>init()</code>.  Format of lookup data is in the form of standard java properties list.
+
+ @see <a href="http://docs.oracle.com/javase/6/docs/api/java/util/Properties.html#load(java.io.Reader)">Java Properties List</a>
+ */
+public class TestProjectProvider extends RangerAbstractContextEnricher {
+	private static final Log LOG = LogFactory.getLog(TestProjectProvider.class);
+
+	private String     contextName    = "PROJECT";
+	private Properties userProjectMap = null;
+	
+	@Override
+	public void init() {
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> TestProjectProvider.init(" + enricherDef + ")");
+		}
+		
+		super.init();
+		
+		contextName = getOption("contextName", "PROJECT");
+
+		String dataFile = getOption("dataFile", "/etc/ranger/data/userProject.txt");
+
+		userProjectMap = readProperties(dataFile);
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== TestProjectProvider.init(" + enricherDef + ")");
+		}
+	}
+
+	@Override
+	public void enrich(RangerAccessRequest request) {
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> TestProjectProvider.enrich(" + request + ")");
+		}
+		
+		if(request != null && userProjectMap != null) {
+			Map<String, Object> context = request.getContext();
+			String              project = userProjectMap.getProperty(request.getUser());
+	
+			if(context != null && !StringUtils.isEmpty(project)) {
+				request.getContext().put(contextName, project);
+			} else {
+				if(LOG.isDebugEnabled()) {
+					LOG.debug("TestProjectProvider.enrich(): skipping due to unavailable context or project. context=" + context + "; project=" + project);
+				}
+			}
+		}
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== TestProjectProvider.enrich(" + request + ")");
+		}
+	}
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestRangerAuthContext.java b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestRangerAuthContext.java
new file mode 100644
index 0000000..49dba88
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestRangerAuthContext.java
@@ -0,0 +1,121 @@
+/*
+ * 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.policyengine;
+
+import static org.junit.Assert.*;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections.MapUtils;
+import org.apache.ranger.plugin.contextenricher.RangerContextEnricher;
+import org.apache.ranger.plugin.service.RangerAuthContext;
+import org.apache.ranger.plugin.service.RangerBasePlugin;
+import org.apache.ranger.plugin.util.ServicePolicies;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+public class TestRangerAuthContext {
+	private static Gson gsonBuilder;
+	private static RangerBasePlugin plugin;
+
+	@BeforeClass
+	public static void setUpBeforeClass() throws Exception {
+		gsonBuilder = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSS-Z")
+				.setPrettyPrinting()
+				.create();
+
+		plugin = new RangerBasePlugin("hive", "TestRangerAuthContext");
+		RangerBasePlugin.getServicePluginMap().put("hivedev", plugin);
+	}
+
+	@AfterClass
+	public static void tearDownAfterClass() throws Exception {
+	}
+
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testRangerAuthContext() throws Exception {
+		String[] tests = {"/policyengine/plugin/test_auth_context.json"};
+
+		runTestsFromResourceFiles(tests);
+	}
+
+	private void runTestsFromResourceFiles(String[] resourceNames) throws Exception {
+		for(String resourceName : resourceNames) {
+			InputStream       inStream = this.getClass().getResourceAsStream(resourceName);
+			InputStreamReader reader   = new InputStreamReader(inStream);
+
+			runTests(reader, resourceName);
+		}
+	}
+
+	private void runTests(InputStreamReader reader, String fileName) throws Exception {
+		RangerAuthContextTests testCases = gsonBuilder.fromJson(reader, RangerAuthContextTests.class);
+
+		for(RangerAuthContextTests.TestCase testCase : testCases.testCases) {
+			String testName = testCase.name;
+			plugin.setPolicies(testCase.servicePolicies);
+			RangerAuthContext ctx = plugin.createRangerAuthContext();
+
+			Map<RangerContextEnricher, Object> contextEnrichers = ctx.getRequestContextEnrichers();
+			assertTrue(fileName + "-" + testName + " - Empty contextEnrichers", MapUtils.isNotEmpty(contextEnrichers) && contextEnrichers.size() == 2);
+
+			for (Map.Entry<RangerContextEnricher, Object> entry : contextEnrichers.entrySet()) {
+				String contextEnricherName = entry.getKey().getName();
+
+				if (contextEnricherName.equals("ProjectProvider")) {
+					assertTrue(fileName + "-" + testName + " - Invalid contextEnricher", entry.getValue() instanceof RangerContextEnricher);
+				} else if (contextEnricherName.equals("TagEnricher")) {
+					assertFalse("- Invalid contextEnricher", entry.getValue() instanceof RangerContextEnricher);
+				} else {
+					assertTrue(fileName + "-" + testName + " - Unexpected type of contextEnricher", false);
+				}
+			}
+
+		}
+	}
+
+	static class RangerAuthContextTests {
+		List<TestCase> testCases;
+
+		class TestCase {
+			String               name;
+			ServicePolicies      servicePolicies;
+		}
+	}
+
+}
+
diff --git a/agents-common/src/test/resources/policyengine/plugin/resourceTags.json b/agents-common/src/test/resources/policyengine/plugin/resourceTags.json
new file mode 100644
index 0000000..425e9a0
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/plugin/resourceTags.json
@@ -0,0 +1,207 @@
+{
+    "op":"add_or_update",
+    "tagModel":"resource_private",
+    "serviceName": "hivedev",
+    "tagDefinitions": {
+      "1": {
+        "name": "EXPIRES_ON",
+        "attributeDefs": [ { "name": "expiry_date", "type": "datetime" } ],
+        "id": 1,
+        "guid": "tagdefinition-expires-on-guid"
+      },
+      "2": {
+        "name": "PII",
+        "attributeDefs": [ { "name": "expiry", "type": "datetime" } ],
+        "id": 2,
+        "guid": "tagdefinition-pii-guid"
+      },
+      "3": {
+        "name": "PII-FINAL",
+        "attributeDefs": [ { "name": "expiry", "type": "datetime" } ],
+        "id": 3,
+        "guid": "tagdefinition-pii-final-guid"
+      },
+      "4": {
+        "name": "RESTRICTED",
+        "attributeDefs": [ { "name": "activation_date", "type": "datetime" } ],
+        "id": 4,
+        "guid": "tagdefinition-restricted-guid"
+      },
+      "5": {
+        "name": "RESTRICTED-FINAL",
+        "attributeDefs": [ { "name": "activation_date", "type": "datetime" } ],
+        "id": 5,
+        "guid": "tagdefinition-restricted-final-guid"
+      }
+    },
+    "tags": {
+      "1": {
+        "type": "EXPIRES_ON",
+        "attributes": { "expiry_date": "2026/06/15" },
+        "id": 1,
+        "guid": "tag-expires-on-1-guid"
+      },
+      "2": {
+        "type": "EXPIRES_ON",
+        "attributes": { "expiry_date": "2015/08/10" },
+        "id": 2,
+        "guid": "tag-expires-on-2-guid"
+      },
+      "3": {
+        "type": "RESTRICTED",
+        "attributes": { "activation_date": "2015/08/10", "score": "2" },
+        "id": 3,
+        "guid": "tag-restricted-3-guid"
+      },
+      "4": {
+        "type": "RESTRICTED-FINAL",
+        "attributes": { "activation_date": "2026/06/15" },
+        "id": 4,
+        "guid": "tag-restricted-final-4-guid"
+      },
+      "5": {
+        "type": "PII",
+        "attributes": { "expiry": "2026/06/15" },
+        "id": 5,
+        "guid": "tag-pii-5-guid"
+      },
+      "6": {
+        "type": "PII-FINAL",
+        "attributes": { "expiry": "2026/06/15" },
+        "id": 6,
+        "guid": "tag-pii-final-6-guid"
+      }
+    },
+    "serviceResources": [
+      {
+        "serviceName": "cl1_hive",
+        "resourceElements": {
+          "database": { "values": [ "employee" ] },
+          "table": { "values": [ "personal" ] },
+          "column": { "values": [ "ssn" ] }
+        },
+        "id": 1,
+        "guid": "employee.personal.ssn-guid"
+     },
+      {
+        "serviceName": "cl1_hive",
+        "resourceElements": {
+          "database": { "values": [ "employee" ] },
+          "table": { "values": [ "personal" ] },
+          "column": { "values": [ "id" ] }
+        },
+        "id": 2,
+        "guid": "employee.personal.id-guid"
+     },
+      {
+        "serviceName": "cl1_hive",
+        "resourceElements": {
+          "database": { "values": [ "employee" ] },
+          "table": { "values": [ "personal" ] },
+          "column": { "values": [ "city" ] }
+        },
+        "id": 3,
+        "guid": "employee.personal.city-guid"
+     },
+      {
+        "serviceName": "cl1_hive",
+        "resourceElements": {
+          "database": { "values": [ "employee" ] },
+          "table": { "values": [ "personal" ] },
+          "column": { "values": [ "address" ] }
+        },
+        "id": 4,
+        "guid": "employee.personal.address-guid"
+     },
+      {
+        "serviceName": "cl1_hive",
+        "resourceElements": {
+          "database": { "values": [ "employee" ] },
+          "table": { "values": [ "personal" ] },
+          "column": { "values": [ "salary" ] }
+        },
+        "id": 5,
+        "guid": "employee.personal.salary-guid"
+     },
+      {
+        "serviceName": "cl1_hive",
+        "resourceElements": {
+          "database": { "values": [ "employee" ] },
+          "table": { "values": [ "personal" ] },
+          "column": { "values": [ "emp-number" ] }
+        },
+        "id": 6,
+        "guid": "employee.personal.emp-number-guid"
+     },
+     {
+        "serviceName": "cl1_hive",
+        "resourceElements": {
+          "database": { "values": [ "employee" ] },
+          "table": { "values": [ "personal" ] },
+          "column": { "values": [ "name" ] }
+        },
+        "id": 7,
+        "guid": "employee.personal.name-guid"
+     },
+     {
+        "serviceName": "cl1_hive",
+        "resourceElements": {
+          "database": { "values": [ "nodb" ] }
+        },
+        "id": 8,
+        "guid": "nodb-guid"
+     },
+     {
+        "serviceName": "cl1_hive",
+        "resourceElements": {
+          "database": { "values": [ "nodb" ] },
+          "table": { "values": [ "table1" ] }
+        },
+        "id": 9,
+        "guid": "nodb.table1-guid"
+     },
+     {
+        "serviceName": "cl1_hive",
+        "resourceElements": {
+          "database": { "values": [ "nodb" ] },
+          "table": { "values": [ "table1" ] },
+          "column": { "values": [ "name" ] }
+        },
+        "id": 10,
+        "guid": "nodb.table1.name-guid"
+     },
+     {
+        "serviceName": "cl1_hive",
+        "resourceElements": {
+          "database": { "values": [ "finance" ] },
+          "table": { "values": [ "sales" ] }
+        },
+        "id": 11,
+        "guid": "finance.sales-guid"
+     },
+     {
+        "serviceName": "cl1_hive",
+        "resourceElements": {
+          "database": { "values": [ "finance" ] },
+          "table": { "values": [ "sales" ] },
+          "column": { "values": [ "invoice_id" ] }
+        },
+        "id": 12,
+        "guid": "finance.sales.invoice_id-guid"
+     }
+    ],
+    "resourceToTagIds": {
+      "1": [ 1 ],
+      "2": [ 2 ],
+      "3": [ 3 ],
+      "4": [ 4 ],
+      "5": [ 2 ],
+      "6": [ 2 ],
+      "8": [ 6 ],
+      "9": [ 5 ],
+      "10": [ 6 ],
+      "11": [ 6 ],
+      "12": [ 5 ]
+    }
+}
+
diff --git a/agents-common/src/test/resources/policyengine/plugin/test_auth_context.json b/agents-common/src/test/resources/policyengine/plugin/test_auth_context.json
new file mode 100644
index 0000000..9a42f83
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/plugin/test_auth_context.json
@@ -0,0 +1,594 @@
+{
+  "testCases": [
+    {
+      "name": "Test-Ranger-Auth-Context-1",
+
+      "servicePolicies": {
+        "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" }
+          ],
+          "contextEnrichers": [
+            { "itemId": 1, "name": "ProjectProvider",
+              "enricher": "org.apache.ranger.plugin.policyengine.TestProjectProvider",
+              "enricherOptions": {
+                "dataFile": "/policyengine/plugin/userProject.txt"
+              }
+            }
+          ],
+          "policyConditions":[
+            { "itemId": 1, "name": "ip-range",
+              "evaluator": "org.apache.ranger.plugin.conditionevaluator.RangerIpMatcher", "evaluatorOptions": { },
+              "label": "IP Address Range", "description": "IP Address Range"
+            }
+          ]
+        },
+        "policies": [
+          {
+            "id": 1, "name": "db=default: audit-all-access", "isEnabled": true, "isAuditEnabled": true,
+            "resources": {
+              "database": { "values": [ "default" ] },
+              "table": { "values": [ "*" ] },
+              "column": { "values": [ "*" ] }
+            },
+            "policyItems": [
+              { "accesses": [], "users": [], "groups": [ "public" ], "delegateAdmin": false }
+            ]
+          },
+          {
+            "id": 2, "name": "db=default; table=test1,test2; column=column1", "isEnabled": true, "isAuditEnabled": true,
+            "resources": {
+              "database": { "values": [ "default" ] },
+              "table": { "values": [ "test1", "test2" ] },
+              "column": { "values": [ "column1" ] }
+            },
+            "policyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true } ],
+                "users": [ "user1", "user2" ], "groups": [ "group1", "group2" ],
+                "delegateAdmin": false
+              },
+              { "accesses": [ { "type": "create", "isAllowed": true }, { "type": "drop", "isAllowed": true } ],
+                "users": [ "admin" ], "groups": [ "cluster-admin" ],
+                "delegateAdmin": true
+              }
+            ]
+          },
+          {
+            "id": 3, "name": "db=default; table=test1,test2; column=column2", "isEnabled": true, "isAuditEnabled": true,
+            "resources": {
+              "database": { "values": [ "default" ] },
+              "table": { "values": [ "test1", "test2" ] },
+              "column": { "values": [ "column2" ] }
+            },
+            "policyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true } ],
+                "users": [ "user1", "user2" ], "groups": [ "group1", "group2" ],
+                "delegateAdmin": false
+              },
+              {
+                "accesses": [
+                  { "type": "create", "isAllowed": true },
+                  { "type": "drop", "isAllowed": true }
+                ],
+                "users": [ "admin" ], "groups": [ "cluster-admin" ],
+                "delegateAdmin": true
+              }
+            ]
+          },
+          {
+            "id": 4, "name": "db=finance; table=fin_*; column=*", "isEnabled": true, "isAuditEnabled": true,
+            "resources": {
+              "database": { "values": [ "finance" ] },
+              "table": { "values": [ "fin_*" ] },
+              "column": { "values": [ "*" ] }
+            },
+            "policyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true } ],
+                "users": [ "user1", "user2" ], "groups": [ "finance-controller" ],
+                "delegateAdmin": true
+              }
+            ]
+          },
+          {
+            "id": 5, "name": "db=db1; table=tmp; column=tmp*", "isEnabled": true, "isAuditEnabled": true,
+            "resources": {
+              "database": { "values": [ "db1" ] },
+              "table": { "values": [ "tmp" ] },
+              "column": { "values": [ "tmp*" ], "isExcludes": false }
+            },
+            "policyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true }, { "type": "create", "isAllowed": true } ],
+                "users": [ "user1", "user2" ], "groups": [ "cluster-admin", "finance-controller" ],
+                "delegateAdmin": true
+              }
+            ]
+          },
+          {
+            "id": 6, "name": "db=hr;udf=udf", "isEnabled": true, "isAuditEnabled": true,
+            "resources": {
+              "database": { "values": [ "hr" ] },
+              "udf": { "values": [ "udf" ] }
+            },
+            "policyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true }, { "type": "create", "isAllowed": true } ],
+                "users": [ "user1", "user2" ], "groups": [ "cluster-admin" ],
+                "delegateAdmin": true
+              }
+            ]
+          },
+          {
+            "id": 7, "name": "db=hr;udf=udf*", "isEnabled": true, "isAuditEnabled": true,
+            "resources": {
+              "database": { "values": [ "hr" ] },
+              "udf": { "values": [ "udf*" ] }
+            },
+            "denyPolicyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true }, { "type": "create", "isAllowed": true } ],
+                "users": [ "user3" ], "groups": [ "public" ],
+                "delegateAdmin": true
+              }
+            ]
+          },
+          {
+            "id": 8, "name": "db=hr*;udf=udf", "isEnabled": true, "isAuditEnabled": true,
+            "resources": {
+              "database": { "values": [ "hr*" ] },
+              "udf": { "values": [ "udf" ] }
+            },
+            "validitySchedules": [
+              { "startTime": "2018/01/12 14:32:00", "endTime": "2020/02/13 12:16:00" }
+            ],
+            "policyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true }, { "type": "create", "isAllowed": true } ],
+                "users": [ "user4" ], "groups": [ "hr-admin" ],
+                "delegateAdmin": true
+              }
+            ]
+          },
+          {
+            "id": 9, "name": "db=default; table=test2; column=column2", "isEnabled": true, "isAuditEnabled": true,
+            "resources": {
+              "database": { "values": [ "default" ] },
+              "table": { "values": [ "test2" ] },
+              "column": { "values": [ "column2" ] }
+            },
+            "policyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true } ],
+                "users": [ "user2", "user3" ], "groups": [],
+                "delegateAdmin": false
+              }
+            ],
+            "denyPolicyItems": [
+              {
+                "accesses": [ { "type": "select", "isAllowed": true }, { "type": "create", "isAllowed": true } ],
+                "users": [ "user2", "user3", "user4" ], "groups": [ "group3" ],
+                "delegateAdmin": false
+              }
+            ],
+            "denyExceptions": [
+              { "accesses": [ { "type": "select", "isAllowed": true } ],
+                "users": [ "user3" ], "groups": [],
+                "delegateAdmin": false
+              }
+            ]
+          },
+          {
+            "id": 10, "name": "db=finance; table=fin_*; column=salary", "isEnabled": true, "isAuditEnabled": true,
+            "resources": {
+              "database": { "values": [ "finance" ] },
+              "table": { "values": [ "fin_*" ] },
+              "column": { "values": [ "salary" ] }
+            },
+            "policyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true } ],
+                "users": [ "user3" ], "groups": [ "cluster-admin" ],
+                "delegateAdmin": true,
+                "conditions":[{"type":"ip-range","values":["1.*.1.*"]}]
+              }
+            ]
+          },
+          {
+            "id": 11, "name": "db=default; table=table; column=column", "isEnabled": true, "isAuditEnabled": true,
+            "resources": {
+              "database": { "values": [ "default" ] },
+              "table": { "values": [ "table" ] },
+              "column": { "values": [ "column" ] }
+            },
+            "policyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true } ],
+                "users": [ "user1", "user2", "user3", "user4" ], "groups": [ "cluster-admin" ],
+                "delegateAdmin": true
+              }
+            ],
+            "allowExceptions": [
+              { "accesses": [ { "type": "select", "isAllowed": true } ],
+                "users": [ "user4" ], "groups": [ "finance-admin" ],
+                "delegateAdmin": true
+              }
+            ],
+            "denyPolicyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true } ],
+                "users": [ "user2", "user3" ], "groups": [ "public" ],
+                "delegateAdmin": true
+              }
+            ],
+            "denyExceptions": [
+              { "accesses": [ { "type": "select", "isAllowed": true } ],
+                "users": [ "user2", "user4" ], "groups": [],
+                "delegateAdmin": true
+              }
+            ]
+          },
+          {
+            "id": 12, "name": "db=finance; table=accounts; column=status", "isEnabled": true, "isAuditEnabled": true,
+            "resources": {
+              "database": { "values": [ "finance" ] },
+              "table": { "values": [ "accounts" ] },
+              "column": { "values": [ "status" ] }
+            },
+            "policyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true }, { "type": "update", "isAllowed": true } ],
+                "users": [ "john", "jane" ], "groups": [ "accounting", "admin" ],
+                "delegateAdmin": true
+              },
+              { "accesses": [ { "type": "select", "isAllowed": true } ],
+                "users": [], "groups": [ "public" ]
+              }
+            ],
+            "allowExceptions": [
+              { "accesses": [ { "type": "update", "isAllowed": true } ],
+                "users": [ "mary" ], "groups": [ "interns" ]
+              }
+            ],
+            "denyPolicyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true } ],
+                "users": [], "groups": [ "housekeeping" ]
+              }
+            ]
+          },
+          {
+            "id": 13, "name": "db=finance; table=accounts; column=amount", "isEnabled": true, "isAuditEnabled": true,
+            "resources": {
+              "database": { "values": [ "finance" ] },
+              "table": { "values": [ "accounts" ] },
+              "column": { "values": [ "amount" ] }
+            },
+            "policyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true }, { "type": "update", "isAllowed": true } ],
+                "users": [ "john", "jane" ], "groups": [ "accounting", "admin" ],
+                "delegateAdmin": true
+              },
+              { "accesses": [ { "type": "select", "isAllowed": true } ],
+                "users": [], "groups": [ "public" ]
+              }
+            ],
+            "allowExceptions": [
+              { "accesses": [ { "type": "update", "isAllowed": true } ],
+                "users": [ "mary" ], "groups": [ "interns" ]
+              }
+            ],
+            "denyPolicyItems": [
+              { "accesses": [ { "type": "drop", "isAllowed": true } ],
+                "users": [], "groups": [ "housekeeping" ]
+              }
+            ]
+          },
+          {
+            "id": 13, "name": "db=db1; table=tbl1; column=col1", "isEnabled": true, "isAuditEnabled": true,
+            "resources": {
+              "database": { "values": [ "db1" ] },
+              "table": { "values": [ "tbl1" ] },
+              "column": { "values": [ "col1" ] }
+            },
+            "policyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true }, { "type": "update", "isAllowed": true } ],
+                "users": [ "john", "jane" ]
+              }
+            ],
+            "allowExceptions": [
+              { "accesses": [ { "type": "update", "isAllowed": true } ],
+                "users": [ "john" ],
+                "conditions":[{"type":"ip-range","values":["1.*.1.*"]}]
+              }
+            ],
+            "denyPolicyItems": [
+              { "accesses": [ { "type": "drop", "isAllowed": true } ],
+                "users": ["adam", "eve"]
+              }
+            ],
+            "denyExceptions": [
+              { "accesses": [ { "type": "select", "isAllowed": true },  { "type": "drop", "isAllowed": true }],
+                "users": ["eve"],
+                "conditions":[{"type":"ip-range","values":["10.*.10.*"]}]
+              }
+            ]
+          },
+          {
+            "id": 14, "name": "db=db2; table=tbl2; column=col2", "isEnabled": true, "isAuditEnabled": true,
+            "resources": {
+              "database": { "values": [ "db2" ] },
+              "table": { "values": [ "tbl2" ] },
+              "column": { "values": [ "col2" ] }
+            },
+            "policyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true }, { "type": "update", "isAllowed": true } ],
+                "users": [ "john", "jane" ]
+              }
+            ],
+            "allowExceptions": [
+              { "accesses": [ { "type": "update", "isAllowed": true } ],
+                "users": [ "john" ]
+              }
+            ],
+            "denyPolicyItems": [
+              { "accesses": [ { "type": "drop", "isAllowed": true } ],
+                "users": ["adam", "eve"]
+              }
+            ],
+            "denyExceptions": [
+              { "accesses": [ { "type": "select", "isAllowed": true },  { "type": "drop", "isAllowed": true }],
+                "users": ["eve"],
+                "conditions":[{"type":"ip-range","values":["10.*.10.*"]}]
+              }
+            ]
+          }
+        ],
+        "tagPolicies": {
+          "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 },
+                "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:drop", "label": "hive:drop" },
+              { "itemId": 5, "name": "hive:alter", "label": "hive:alter" },
+              { "itemId": 6, "name": "hive:index", "label": "hive:index" },
+              { "itemId": 7, "name": "hive:lock", "label": "hive:lock" },
+              { "itemId": 8, "name": "hive:all", "label": "hive:all", 
+		"impliedGrants": [ "hive:select", "hive:update", "hive:create", "hive:drop", "hive:alter", "hive:index", "hive:lock" ] }
+            ],
+            "contextEnrichers": [
+              { "itemId": 1, "name": "TagEnricher",
+                "enricher": "org.apache.ranger.plugin.contextenricher.RangerTagEnricher",
+                "enricherOptions": {
+                  "tagRetrieverClassName": "org.apache.ranger.plugin.contextenricher.RangerFileBasedTagRetriever",
+                  "tagRefresherPollingInterval": 60000,
+                  "serviceTagsFileName": "/policyengine/plugin/resourceTags.json"
+                }
+              }
+            ],
+            "policyConditions": [
+              { "itemId": 1, "name": "expression",
+                "evaluator": "org.apache.ranger.plugin.conditionevaluator.RangerScriptConditionEvaluator",
+                "evaluatorOptions": { "engineName": "JavaScript", "ui.isMultiline": "true" },
+                "label": "Enter boolean expression", "description": "Boolean expression"
+              },
+              {
+                "itemId": 2, "name": "enforce-expiry",
+                "evaluator": "org.apache.ranger.plugin.conditionevaluator.RangerScriptTemplateConditionEvaluator",
+                "evaluatorOptions": { "scriptTemplate": "ctx.isAccessedAfter('expiry_date');" },
+                "label": "Deny access after expiry_date?", "description": "Deny access after expiry_date? (yes/no)"
+              },
+              {
+                "itemId": 3, "name": "ip-range",
+                "evaluator": "org.apache.ranger.plugin.conditionevaluator.RangerIpMatcher", "evaluatorOptions": { },
+                "label": "IP Address Range", "description": "IP Address Range"
+              }
+            ]
+          },
+          "policies": [
+            { "id": 101, "name": "RESTRICTED_TAG_POLICY", "isEnabled": true, "isAuditEnabled": true,
+              "resources": {
+                "tag": { "values": [ "RESTRICTED" ], "isRecursive": false }
+              },
+              "policyItems": [
+                { "accesses": [ { "type": "hive:select", "isAllowed": true } ],
+                  "users": [ "hive", "user1" ],
+                  "groups": [],
+                  "delegateAdmin": false,
+                  "conditions": [
+                    { "type": "expression", "values": [ "if ( tagAttr.get('score') < 2 ) ctx.result = true;" ] }
+                  ]
+                }
+              ]
+            },
+            {
+              "id": 102, "name": "PII_TAG_POLICY", "isEnabled": true, "isAuditEnabled": true,
+              "resources": {
+                "tag": { "values": [ "PII" ], "isRecursive": false }
+              },
+              "policyItems": [
+                { "accesses": [ { "type": "hive:select", "isAllowed": true }, { "type": "hive:create", "isAllowed": true } ],
+                  "users": [ "hive" ], "groups": [],
+                  "delegateAdmin": false
+                }
+              ],
+              "denyPolicyItems": [
+                { "accesses": [ { "type": "hive:select", "isAllowed": true } ],
+                  "users": [ "hive" ], "groups": [],
+                  "delegateAdmin": false
+                }
+              ]
+            },
+            {
+              "id": 103, "name": "PII_TAG_POLICY-FINAL", "isEnabled": true, "isAuditEnabled": true,
+              "resources": {
+                "tag": { "values": [ "PII-FINAL" ], "isRecursive": false }
+              },
+              "policyItems": [
+                { "accesses": [ { "type": "hive:index", "isAllowed": true } ],
+                  "users": [ ], "groups": [ "public" ],
+                  "delegateAdmin": false,
+                  "conditions":[{"type":"ip-range","values":["1.*.1.*"]}]
+                }
+              ],
+              "denyPolicyItems": [
+                { "accesses": [ { "type": "hive:select", "isAllowed": true } ],
+                  "users": [ "admin" ], "groups": [],
+                  "delegateAdmin": false
+                }
+              ],
+              "denyExceptions": [
+                {
+                  "accesses": [
+                    { "type": "hive:drop", "isAllowed": true }
+                  ],
+                  "users": [ "hive" ], "groups": [],
+                  "delegateAdmin": false
+                }
+              ]
+            },
+            {
+              "id": 104, "name": "RESTRICTED_TAG_POLICY_FINAL", "isEnabled": true, "isAuditEnabled": true,
+              "resources": {
+                "tag": { "values": [ "RESTRICTED-FINAL" ], "isRecursive": false }
+              },
+              "denyPolicyItems": [
+                { "accesses": [ { "type": "hive:select", "isAllowed": true } ],
+                  "users": [], "groups": [ "public" ],
+                  "delegateAdmin": false
+                }
+              ],
+              "denyExceptions": [
+                { "accesses": [ { "type": "hive:select", "isAllowed": true } ],
+                  "users": [ "hive", "user1" ], "groups": [],
+                  "delegateAdmin": false,
+                  "conditions": [
+                    { "type": "expression", "values": [ "if ( ctx.isAccessedBefore('activation_date') ) ctx.result = true;" ] }
+                  ]
+                }
+              ]
+            },
+            {
+              "id": 105, "name": "EXPIRES_ON", "isEnabled": true, "isAuditEnabled": true,
+              "resources": {
+                "tag": { "values": [ "EXPIRES_ON" ], "isRecursive": false }
+              },
+              "denyPolicyItems": [
+                { "accesses": [ { "type": "hive:select", "isAllowed": true } ],
+                  "users": [], "groups": [ "public" ],
+                  "delegateAdmin": false,
+                  "conditions": [
+                    { "type": "enforce-expiry", "values": [ "yes" ] }
+                  ]
+                }
+              ],
+              "denyExceptions": [
+                { "accesses": [ { "type": "hive:select", "isAllowed": true } ],
+                  "users": [ "dataloader" ], "groups": [],
+                  "delegateAdmin": false
+                }
+              ]
+            }
+          ]
+        }
+      },
+
+      "tests": [
+        {
+          "name": "all-deny-test",
+          "resource": {"elements":{"database":"hr", "udf":"udf" }},
+          "userPermissions": {},
+          "groupPermissions": {"public": {"SELECT":"NOT_ALLOWED","CREATE":"NOT_ALLOWED"}}
+        },
+        {
+          "name": "no-deny-test",
+          "resource": {"elements":{"database":"default", "table":"test1", "column":"column2"}},
+          "userPermissions": {"user1":{"SELECT":"ALLOWED"}, "user2":{"SELECT":"ALLOWED"}, "admin":{"CREATE":"ALLOWED","DROP":"ALLOWED"}},
+          "groupPermissions": {"group1": {"SELECT":"ALLOWED"}, "group2": {"SELECT":"ALLOWED"},"cluster-admin": {"CREATE":"ALLOWED","DROP":"ALLOWED"}}
+        },
+        {
+          "name": "partial-deny-test",
+          "resource": {"elements":{"database":"default", "table":"test2", "column":"column2"}},
+          "userPermissions": {"user1":{"SELECT":"ALLOWED"}, "user2":{"SELECT":"NOT_ALLOWED","CREATE":"NOT_ALLOWED"}, "user3":{"SELECT":"ALLOWED","CREATE":"NOT_ALLOWED"},"user4":{"SELECT":"NOT_ALLOWED","CREATE":"NOT_ALLOWED"},"admin":{"CREATE":"ALLOWED","DROP":"ALLOWED"}},
+          "groupPermissions": {"group1": {"SELECT":"ALLOWED"}, "group2": {"SELECT":"ALLOWED"},"group3": {"SELECT":"NOT_ALLOWED","CREATE":"NOT_ALLOWED"},"cluster-admin": {"CREATE":"ALLOWED","DROP":"ALLOWED"}}
+        },
+        {
+          "name": "conditional-deny-test",
+          "resource": {"elements":{"database":"finance", "table":"fin_1", "column":"salary"}},
+          "userPermissions": {"user1":{"SELECT":"ALLOWED"}, "user2":{"SELECT":"ALLOWED"}, "user3":{"SELECT":"CONDITIONAL_ALLOWED"} },
+          "groupPermissions": {"finance-controller": {"SELECT":"ALLOWED"}, "cluster-admin": {"SELECT":"CONDITIONAL_ALLOWED"}}
+        },
+        {
+          "name": "conditional-tag-only-test-descendant",
+          "resource": {"elements":{"database":"finance", "table":"sales"}},
+          "userPermissions": {"hive":{"SELECT":"NOT_ALLOWED","CREATE":"ALLOWED", "DROP":"NOT_ALLOWED"}, "admin":{"SELECT":"NOT_ALLOWED"} },
+          "groupPermissions": {"public": {"INDEX":"CONDITIONAL_ALLOWED"}}
+        },
+        {
+          "name": "all-types-of-policy-items",
+          "resource": {"elements":{"database":"default", "table":"table", "column":"column"}},
+          "userPermissions": {"user1":{"SELECT":"CONDITIONAL_ALLOWED"}, "user2":{"SELECT":"CONDITIONAL_ALLOWED"}, "user3":{"SELECT":"CONDITIONAL_ALLOWED"}, "user4":{"SELECT":"CONDITIONAL_ALLOWED"} },
+          "groupPermissions": {"public": {"SELECT":"CONDITIONAL_ALLOWED"}, "cluster-admin": {"SELECT":"CONDITIONAL_ALLOWED"}}
+        },
+        {
+          "name": "public-allow-test",
+          "resource": {"elements":{"database":"finance", "table":"accounts", "column": "status" }},
+          "userPermissions": {"john":{"SELECT":"CONDITIONAL_ALLOWED", "UPDATE":"CONDITIONAL_ALLOWED"}, "jane":{"SELECT":"CONDITIONAL_ALLOWED","UPDATE":"CONDITIONAL_ALLOWED"}, "mary":{"UPDATE":"NOT_ALLOWED"}},
+          "groupPermissions": {"public": {"SELECT":"CONDITIONAL_ALLOWED"}, "accounting": {"SELECT":"CONDITIONAL_ALLOWED","UPDATE":"CONDITIONAL_ALLOWED"}, "admin": {"SELECT":"CONDITIONAL_ALLOWED","UPDATE":"CONDITIONAL_ALLOWED"}, "interns":{"UPDATE":"NOT_ALLOWED"}, "housekeeping":{"SELECT":"NOT_ALLOWED"}}
+        },
+        {
+          "name": "public-allow-test-next",
+          "resource": {"elements":{"database":"finance", "table":"accounts", "column": "amount" }},
+          "userPermissions": {"john":{"SELECT":"CONDITIONAL_ALLOWED", "UPDATE":"CONDITIONAL_ALLOWED"}, "jane":{"SELECT":"CONDITIONAL_ALLOWED","UPDATE":"CONDITIONAL_ALLOWED"}, "mary":{"UPDATE":"NOT_ALLOWED"}},
+          "groupPermissions": {"public": {"SELECT":"CONDITIONAL_ALLOWED"}, "accounting": {"SELECT":"CONDITIONAL_ALLOWED","UPDATE":"CONDITIONAL_ALLOWED"}, "admin": {"SELECT":"CONDITIONAL_ALLOWED","UPDATE":"CONDITIONAL_ALLOWED"}, "interns":{"UPDATE":"NOT_ALLOWED"}, "housekeeping":{"DROP":"NOT_ALLOWED"}}
+        },
+        {
+          "name": "conditions-in-exceptions-test",
+          "resource": {"elements":{"database":"db1", "table":"tbl1", "column": "col1" }},
+          "userPermissions": {"john":{"SELECT":"CONDITIONAL_ALLOWED", "UPDATE":"CONDITIONAL_ALLOWED"}, "jane":{"SELECT":"CONDITIONAL_ALLOWED","UPDATE":"CONDITIONAL_ALLOWED"}, "adam":{"DROP":"CONDITIONAL_ALLOWED"}, "eve":{"DROP":"CONDITIONAL_ALLOWED"}},
+          "groupPermissions": {}
+        },
+        {
+          "name": "conditions-in-some-exceptions-test",
+          "resource": {"elements":{"database":"db2", "table":"tbl2", "column": "col2" }},
+          "userPermissions": {"john":{"SELECT":"ALLOWED", "UPDATE":"NOT_ALLOWED"}, "jane":{"SELECT":"ALLOWED","UPDATE":"ALLOWED"}, "adam":{"DROP":"CONDITIONAL_ALLOWED"}, "eve":{"DROP":"CONDITIONAL_ALLOWED"}},
+          "groupPermissions": {}
+        }
+      ]
+    }
+  ]
+}
diff --git a/agents-common/src/test/resources/policyengine/plugin/userText.txt b/agents-common/src/test/resources/policyengine/plugin/userText.txt
new file mode 100644
index 0000000..5af7ec4
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/plugin/userText.txt
@@ -0,0 +1 @@
+Truth = beauty