RANGER-712 Create a sub-project to serve as not only a repository for samples 
for ranger extensions but also a template project for someone wanting to write 
extensions

(cherry picked from commit 433ab85239f3969c445903f992b982a66d455cf6)


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

Branch: refs/heads/tag-policy
Commit: 8aff4e1b355298f7a136ee0675f1ccd214c8250f
Parents: 1a0f7e2
Author: Alok Lal <[email protected]>
Authored: Fri Oct 30 16:26:47 2015 -0700
Committer: Madhan Neethiraj <[email protected]>
Committed: Thu Nov 5 13:58:53 2015 -0800

----------------------------------------------------------------------
 .../conditionevaluator/RangerSimpleMatcher.java | 133 ---------------
 .../contextenricher/RangerCountryProvider.java  |  79 ---------
 .../RangerFileBasedGeolocationProvider.java     |  35 ----
 .../contextenricher/RangerProjectProvider.java  |  79 ---------
 .../conditionevaluator/RangerSimpleMatcher.java | 133 +++++++++++++++
 .../RangerSimpleMatcherTest.java                | 146 ----------------
 .../RangerFileBasedGeolocationProvider.java     |  35 ++++
 pom.xml                                         |   1 +
 ranger-examples/pom.xml                         |  45 +++++
 .../RangerSampleSimpleMatcher.java              | 170 +++++++++++++++++++
 .../RangerSampleCountryProvider.java            | 105 ++++++++++++
 .../RangerSampleProjectProvider.java            | 103 +++++++++++
 .../RangerSampleSimpleMatcherTest.java          | 139 +++++++++++++++
 13 files changed, 731 insertions(+), 472 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8aff4e1b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerSimpleMatcher.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerSimpleMatcher.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerSimpleMatcher.java
deleted file mode 100644
index d9f6158..0000000
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerSimpleMatcher.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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 java.util.ArrayList;
-import java.util.List;
-
-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;
-
-public class RangerSimpleMatcher extends RangerAbstractConditionEvaluator {
-
-       private static final Log LOG = 
LogFactory.getLog(RangerSimpleMatcher.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("==> RangerSimpleMatcher.init(" + condition + 
")");
-               }
-
-               super.init();
-
-               if (condition == 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 : condition.getValues()) {
-                               _values.add(value);
-                       }
-               }
-
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== RangerSimpleMatcher.init(" + condition + 
"): countries[" + _values + "]");
-               }
-       }
-
-       @Override
-       public boolean isMatched(RangerAccessRequest request) {
-               
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> RangerSimpleMatcher.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("<== RangerSimpleMatcher.isMatched(" + 
request+ "): " + matched);
-               }
-
-               return matched;
-       }
-
-       String extractValue(final RangerAccessRequest request, String key) {
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> RangerSimpleMatcher.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("<== RangerSimpleMatcher.extractValue(" + 
request+ "): " + value);
-               }
-               return value;
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8aff4e1b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerCountryProvider.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerCountryProvider.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerCountryProvider.java
deleted file mode 100644
index 64f5023..0000000
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerCountryProvider.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.contextenricher;
-
-import java.util.Map;
-import java.util.Properties;
-
-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;
-
-
-public class RangerCountryProvider extends RangerAbstractContextEnricher {
-       private static final Log LOG = 
LogFactory.getLog(RangerCountryProvider.class);
-
-       private String     contextName    = "COUNTRY";
-       private Properties userCountryMap = null;
-       
-       @Override
-       public void init() {
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> RangerCountryProvider.init(" + 
enricherDef + ")");
-               }
-               
-               super.init();
-               
-               contextName = getOption("contextName", "COUNTRY");
-
-               String dataFile = getOption("dataFile", 
"/etc/ranger/data/userCountry.txt");
-
-               userCountryMap = readProperties(dataFile);
-
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== RangerCountryProvider.init(" + 
enricherDef + ")");
-               }
-       }
-
-       @Override
-       public void enrich(RangerAccessRequest request) {
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> RangerCountryProvider.enrich(" + request 
+ ")");
-               }
-               
-               if(request != null && userCountryMap != null) {
-                       Map<String, Object> context = request.getContext();
-                       String              country = 
userCountryMap.getProperty(request.getUser());
-       
-                       if(context != null && !StringUtils.isEmpty(country)) {
-                               request.getContext().put(contextName, country);
-                       } else {
-                               if(LOG.isDebugEnabled()) {
-                                       
LOG.debug("RangerCountryProvider.enrich(): skipping due to unavailable context 
or country. context=" + context + "; country=" + country);
-                               }
-                       }
-               }
-
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== RangerCountryProvider.enrich(" + request 
+ ")");
-               }
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8aff4e1b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerFileBasedGeolocationProvider.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerFileBasedGeolocationProvider.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerFileBasedGeolocationProvider.java
deleted file mode 100644
index ea599c7..0000000
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerFileBasedGeolocationProvider.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.contextenricher;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-public class RangerFileBasedGeolocationProvider extends 
RangerAbstractGeolocationProvider {
-
-       private static final Log LOG = 
LogFactory.getLog(RangerFileBasedGeolocationProvider.class);
-
-       public static final String GEOLOCATION_SOURCE_LOADER_FILELOADER = 
"org.apache.ranger.plugin.store.file.GeolocationFileStore";
-
-       @Override
-       public String getGeoSourceLoader() {
-               return GEOLOCATION_SOURCE_LOADER_FILELOADER;
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8aff4e1b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerProjectProvider.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerProjectProvider.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerProjectProvider.java
deleted file mode 100644
index 4df53cb..0000000
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerProjectProvider.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.contextenricher;
-
-import java.util.Map;
-import java.util.Properties;
-
-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;
-
-
-public class RangerProjectProvider extends RangerAbstractContextEnricher {
-       private static final Log LOG = 
LogFactory.getLog(RangerProjectProvider.class);
-
-       private String     contextName    = "PROJECT";
-       private Properties userProjectMap = null;
-       
-       @Override
-       public void init() {
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> RangerProjectProvider.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("<== RangerProjectProvider.init(" + 
enricherDef + ")");
-               }
-       }
-
-       @Override
-       public void enrich(RangerAccessRequest request) {
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> RangerProjectProvider.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("RangerProjectProvider.enrich(): skipping due to unavailable context 
or project. context=" + context + "; project=" + project);
-                               }
-                       }
-               }
-
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== RangerProjectProvider.enrich(" + request 
+ ")");
-               }
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8aff4e1b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerSimpleMatcher.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerSimpleMatcher.java
 
b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerSimpleMatcher.java
new file mode 100644
index 0000000..7ad7252
--- /dev/null
+++ 
b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerSimpleMatcher.java
@@ -0,0 +1,133 @@
+/*
+ * 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;
+
+public class RangerSimpleMatcher extends RangerAbstractConditionEvaluator {
+
+       private static final Log LOG = 
LogFactory.getLog(RangerSimpleMatcher.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("==> RangerSimpleMatcher.init(" + condition + 
")");
+               }
+
+               super.init();
+
+               if (condition == 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 : condition.getValues()) {
+                               _values.add(value);
+                       }
+               }
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("<== RangerSimpleMatcher.init(" + condition + 
"): countries[" + _values + "]");
+               }
+       }
+
+       @Override
+       public boolean isMatched(RangerAccessRequest request) {
+               
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> RangerSimpleMatcher.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("<== RangerSimpleMatcher.isMatched(" + 
request+ "): " + matched);
+               }
+
+               return matched;
+       }
+
+       String extractValue(final RangerAccessRequest request, String key) {
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> RangerSimpleMatcher.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("<== RangerSimpleMatcher.extractValue(" + 
request+ "): " + value);
+               }
+               return value;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8aff4e1b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerSimpleMatcherTest.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerSimpleMatcherTest.java
 
b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerSimpleMatcherTest.java
deleted file mode 100644
index 8d0bc75..0000000
--- 
a/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerSimpleMatcherTest.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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 static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-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.junit.Test;
-
-public class RangerSimpleMatcherTest {
-
-       final Map<String, String> _conditionOptions = new HashMap<String, 
String>();
-
-       {
-               _conditionOptions.put(RangerSimpleMatcher.CONTEXT_NAME, 
RangerSimpleMatcher.CONTEXT_NAME);
-       }
-
-       @Test
-       public void testIsMatched_happyPath() {
-               // this documents some unexpected behavior of the ip matcher
-               RangerSimpleMatcher ipMatcher = createMatcher(new 
String[]{"US", "C*"} );
-               assertTrue(ipMatcher.isMatched(createRequest("US")));
-               assertTrue(ipMatcher.isMatched(createRequest("CA")));
-               assertTrue(ipMatcher.isMatched(createRequest("C---")));
-               assertFalse(ipMatcher.isMatched(createRequest(" US ")));
-               assertFalse(ipMatcher.isMatched(createRequest("Us")));
-               assertFalse(ipMatcher.isMatched(createRequest("ca")));
-       }
-       
-       @Test
-       public void test_firewallings() {
-               
-               // create a request for some policyValue, say, country and use 
it to match against matcher initialized with all sorts of bad data
-               RangerAccessRequest request = createRequest("AB");
-
-               RangerSimpleMatcher matcher = new RangerSimpleMatcher();
-               // Matcher initialized with null policy should behave sensibly! 
 It matches everything!
-               matcher.setConditionDef(null);
-               matcher.setPolicyItemCondition(null);
-               matcher.init();
-               assertTrue(matcher.isMatched(request));
-               
-               RangerPolicyItemCondition policyItemCondition = 
mock(RangerPolicyItemCondition.class);
-               matcher.setConditionDef(null);
-               matcher.setPolicyItemCondition(policyItemCondition);
-               matcher.init();
-               assertTrue(matcher.isMatched(request));
-               
-               RangerPolicyConditionDef conditionDef = 
mock(RangerPolicyConditionDef.class);
-               matcher.setConditionDef(conditionDef);
-               matcher.setPolicyItemCondition(null);
-               matcher.init();
-               assertTrue(matcher.isMatched(request));
-               
-               // so should a policy item condition with initialized with null 
list of values 
-               when(policyItemCondition.getValues()).thenReturn(null);
-               matcher.setConditionDef(conditionDef);
-               matcher.setPolicyItemCondition(policyItemCondition);
-               matcher.init();
-               assertTrue(matcher.isMatched(request));
-
-               // not null item condition with empty condition list
-               List<String> values = new ArrayList<String>();
-               when(policyItemCondition.getValues()).thenReturn(values);
-               matcher.setConditionDef(conditionDef);
-               matcher.setPolicyItemCondition(policyItemCondition);
-               matcher.init();
-               assertTrue(matcher.isMatched(request));
-
-               // values as sensible items in it, however, the conditionDef 
has null evaluator option, so that too suppresses any check
-               values.add("AB");
-               when(policyItemCondition.getValues()).thenReturn(values);
-               when(conditionDef.getEvaluatorOptions()).thenReturn(null);
-               matcher.setConditionDef(conditionDef);
-               matcher.setPolicyItemCondition(policyItemCondition);
-               matcher.init();
-               assertTrue(matcher.isMatched(request));
-
-               // If evaluator option on the condition def is non-null then it 
starts to evaluate for real
-               
when(conditionDef.getEvaluatorOptions()).thenReturn(_conditionOptions);
-               matcher.setConditionDef(conditionDef);
-               matcher.setPolicyItemCondition(policyItemCondition);
-               matcher.init();
-               assertTrue(matcher.isMatched(request));
-       }
-       
-       RangerSimpleMatcher createMatcher(String[] ipArray) {
-               RangerSimpleMatcher matcher = new RangerSimpleMatcher();
-
-               if (ipArray == null) {
-                       matcher.setConditionDef(null);
-                       matcher.setPolicyItemCondition(null);
-                       matcher.init();
-               } else {
-                       RangerPolicyItemCondition condition = 
mock(RangerPolicyItemCondition.class);
-                       List<String> addresses = Arrays.asList(ipArray);
-                       when(condition.getValues()).thenReturn(addresses);
-                       
-                       RangerPolicyConditionDef conditionDef = 
mock(RangerPolicyConditionDef.class);
-
-                       
when(conditionDef.getEvaluatorOptions()).thenReturn(_conditionOptions);
-                       matcher.setConditionDef(conditionDef);
-                       matcher.setPolicyItemCondition(condition);
-                       matcher.init();
-               }
-               
-               return matcher;
-       }
-       
-       RangerAccessRequest createRequest(String value) {
-               Map<String, Object> context = new HashMap<String, Object>();
-               context.put(RangerSimpleMatcher.CONTEXT_NAME, value);
-               RangerAccessRequest request = mock(RangerAccessRequest.class);
-               when(request.getContext()).thenReturn(context);
-               return request;
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8aff4e1b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/RangerFileBasedGeolocationProvider.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/RangerFileBasedGeolocationProvider.java
 
b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/RangerFileBasedGeolocationProvider.java
new file mode 100644
index 0000000..ea599c7
--- /dev/null
+++ 
b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/RangerFileBasedGeolocationProvider.java
@@ -0,0 +1,35 @@
+/*
+ * 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.contextenricher;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class RangerFileBasedGeolocationProvider extends 
RangerAbstractGeolocationProvider {
+
+       private static final Log LOG = 
LogFactory.getLog(RangerFileBasedGeolocationProvider.class);
+
+       public static final String GEOLOCATION_SOURCE_LOADER_FILELOADER = 
"org.apache.ranger.plugin.store.file.GeolocationFileStore";
+
+       @Override
+       public String getGeoSourceLoader() {
+               return GEOLOCATION_SOURCE_LOADER_FILELOADER;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8aff4e1b/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index b7d0239..0648d67 100644
--- a/pom.xml
+++ b/pom.xml
@@ -104,6 +104,7 @@
   <module>ranger-knox-plugin-shim</module>
   <module>ranger-yarn-plugin-shim</module>
   <module>ranger-storm-plugin-shim</module>
+  <module>ranger-examples</module>
   </modules>
   <properties>
         <javac.source.version>1.7</javac.source.version>

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8aff4e1b/ranger-examples/pom.xml
----------------------------------------------------------------------
diff --git a/ranger-examples/pom.xml b/ranger-examples/pom.xml
new file mode 100644
index 0000000..8090170
--- /dev/null
+++ b/ranger-examples/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <parent>
+        <artifactId>ranger</artifactId>
+        <groupId>org.apache.ranger</groupId>
+        <version>0.5.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>ranger-examples</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>security_plugins.ranger-plugins-common</groupId>
+            <artifactId>ranger-plugins-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8aff4e1b/ranger-examples/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerSampleSimpleMatcher.java
----------------------------------------------------------------------
diff --git 
a/ranger-examples/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerSampleSimpleMatcher.java
 
b/ranger-examples/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerSampleSimpleMatcher.java
new file mode 100644
index 0000000..50ecb69
--- /dev/null
+++ 
b/ranger-examples/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerSampleSimpleMatcher.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 RangerSampleSimpleMatcher extends 
RangerAbstractConditionEvaluator {
+
+       private static final Log LOG = 
LogFactory.getLog(RangerSampleSimpleMatcher.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(" + 
condition + ")");
+               }
+
+               super.init();
+
+               if (condition == 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 : condition.getValues()) {
+                               _values.add(value);
+                       }
+               }
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("<== RangerSampleSimpleMatcher.init(" + 
condition + "): 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;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8aff4e1b/ranger-examples/src/main/java/org/apache/ranger/plugin/contextenricher/RangerSampleCountryProvider.java
----------------------------------------------------------------------
diff --git 
a/ranger-examples/src/main/java/org/apache/ranger/plugin/contextenricher/RangerSampleCountryProvider.java
 
b/ranger-examples/src/main/java/org/apache/ranger/plugin/contextenricher/RangerSampleCountryProvider.java
new file mode 100644
index 0000000..198dc5f
--- /dev/null
+++ 
b/ranger-examples/src/main/java/org/apache/ranger/plugin/contextenricher/RangerSampleCountryProvider.java
@@ -0,0 +1,105 @@
+/*
+ * 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.contextenricher;
+
+import java.util.Map;
+import java.util.Properties;
+
+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;
+
+/**
+ * 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": "country-provider",
+                       "enricher": 
"org.apache.ranger.plugin.contextenricher.RangerSampleCountryProvider",
+                       "enricherOptions": { "contextName" : "COUNTRY", 
"dataFile":"/etc/ranger/data/userCountry.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 COUNTRY.  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/userCountry.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>
+ *
+ * This Context Enricher is almost identical to another sample enricher 
<code>RangerSampleProjectProvider</code>.
+ */
+public class RangerSampleCountryProvider extends RangerAbstractContextEnricher 
{
+       private static final Log LOG = 
LogFactory.getLog(RangerSampleCountryProvider.class);
+
+       private String     contextName    = "COUNTRY";
+       private Properties userCountryMap = null;
+       
+       @Override
+       public void init() {
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> RangerSampleCountryProvider.init(" + 
enricherDef + ")");
+               }
+               
+               super.init();
+               
+               contextName = getOption("contextName", "COUNTRY");
+
+               String dataFile = getOption("dataFile", 
"/etc/ranger/data/userCountry.txt");
+
+               userCountryMap = readProperties(dataFile);
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("<== RangerSampleCountryProvider.init(" + 
enricherDef + ")");
+               }
+       }
+
+       @Override
+       public void enrich(RangerAccessRequest request) {
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> RangerSampleCountryProvider.enrich(" + 
request + ")");
+               }
+               
+               if(request != null && userCountryMap != null) {
+                       Map<String, Object> context = request.getContext();
+                       String              country = 
userCountryMap.getProperty(request.getUser());
+       
+                       if(context != null && !StringUtils.isEmpty(country)) {
+                               request.getContext().put(contextName, country);
+                       } else {
+                               if(LOG.isDebugEnabled()) {
+                                       
LOG.debug("RangerSampleCountryProvider.enrich(): skipping due to unavailable 
context or country. context=" + context + "; country=" + country);
+                               }
+                       }
+               }
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("<== RangerSampleCountryProvider.enrich(" + 
request + ")");
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8aff4e1b/ranger-examples/src/main/java/org/apache/ranger/plugin/contextenricher/RangerSampleProjectProvider.java
----------------------------------------------------------------------
diff --git 
a/ranger-examples/src/main/java/org/apache/ranger/plugin/contextenricher/RangerSampleProjectProvider.java
 
b/ranger-examples/src/main/java/org/apache/ranger/plugin/contextenricher/RangerSampleProjectProvider.java
new file mode 100644
index 0000000..d3de690
--- /dev/null
+++ 
b/ranger-examples/src/main/java/org/apache/ranger/plugin/contextenricher/RangerSampleProjectProvider.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.contextenricher;
+
+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.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.RangerSampleProjectProvider",
+                "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 RangerSampleProjectProvider extends RangerAbstractContextEnricher 
{
+       private static final Log LOG = 
LogFactory.getLog(RangerSampleProjectProvider.class);
+
+       private String     contextName    = "PROJECT";
+       private Properties userProjectMap = null;
+       
+       @Override
+       public void init() {
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> RangerSampleProjectProvider.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("<== RangerSampleProjectProvider.init(" + 
enricherDef + ")");
+               }
+       }
+
+       @Override
+       public void enrich(RangerAccessRequest request) {
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> RangerSampleProjectProvider.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("RangerSampleProjectProvider.enrich(): skipping due to unavailable 
context or project. context=" + context + "; project=" + project);
+                               }
+                       }
+               }
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("<== RangerSampleProjectProvider.enrich(" + 
request + ")");
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8aff4e1b/ranger-examples/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerSampleSimpleMatcherTest.java
----------------------------------------------------------------------
diff --git 
a/ranger-examples/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerSampleSimpleMatcherTest.java
 
b/ranger-examples/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerSampleSimpleMatcherTest.java
new file mode 100644
index 0000000..3e683ba
--- /dev/null
+++ 
b/ranger-examples/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerSampleSimpleMatcherTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition;
+import 
org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.util.*;
+
+public class RangerSampleSimpleMatcherTest {
+
+       final Map<String, String> _conditionOptions = new HashMap<String, 
String>();
+
+       {
+               _conditionOptions.put(RangerSampleSimpleMatcher.CONTEXT_NAME, 
RangerSampleSimpleMatcher.CONTEXT_NAME);
+       }
+
+       @Test
+       public void testIsMatched_happyPath() {
+               // this documents some unexpected behavior of the ip matcher
+               RangerSampleSimpleMatcher ipMatcher = createMatcher(new 
String[]{"US", "C*"} );
+               Assert.assertTrue(ipMatcher.isMatched(createRequest("US")));
+               Assert.assertTrue(ipMatcher.isMatched(createRequest("CA")));
+               Assert.assertTrue(ipMatcher.isMatched(createRequest("C---")));
+               Assert.assertFalse(ipMatcher.isMatched(createRequest(" US ")));
+               Assert.assertFalse(ipMatcher.isMatched(createRequest("Us")));
+               Assert.assertFalse(ipMatcher.isMatched(createRequest("ca")));
+       }
+       
+       @Test
+       public void test_firewallings() {
+               
+               // create a request for some policyValue, say, country and use 
it to match against matcher initialized with all sorts of bad data
+               RangerAccessRequest request = createRequest("AB");
+
+               RangerSampleSimpleMatcher matcher = new 
RangerSampleSimpleMatcher();
+               // Matcher initialized with null policy should behave sensibly! 
 It matches everything!
+               matcher.setConditionDef(null);
+               matcher.setPolicyItemCondition(null);
+               matcher.init();
+               Assert.assertTrue(matcher.isMatched(request));
+               
+               RangerPolicyItemCondition policyItemCondition = 
Mockito.mock(RangerPolicyItemCondition.class);
+               matcher.setConditionDef(null);
+               matcher.setPolicyItemCondition(policyItemCondition);
+               matcher.init();
+               Assert.assertTrue(matcher.isMatched(request));
+               
+               RangerPolicyConditionDef conditionDef = 
Mockito.mock(RangerPolicyConditionDef.class);
+               matcher.setConditionDef(conditionDef);
+               matcher.setPolicyItemCondition(null);
+               matcher.init();
+               Assert.assertTrue(matcher.isMatched(request));
+               
+               // so should a policy item condition with initialized with null 
list of values 
+               Mockito.when(policyItemCondition.getValues()).thenReturn(null);
+               matcher.setConditionDef(conditionDef);
+               matcher.setPolicyItemCondition(policyItemCondition);
+               matcher.init();
+               Assert.assertTrue(matcher.isMatched(request));
+
+               // not null item condition with empty condition list
+               List<String> values = new ArrayList<String>();
+               
Mockito.when(policyItemCondition.getValues()).thenReturn(values);
+               matcher.setConditionDef(conditionDef);
+               matcher.setPolicyItemCondition(policyItemCondition);
+               matcher.init();
+               Assert.assertTrue(matcher.isMatched(request));
+
+               // values as sensible items in it, however, the conditionDef 
has null evaluator option, so that too suppresses any check
+               values.add("AB");
+               
Mockito.when(policyItemCondition.getValues()).thenReturn(values);
+               
Mockito.when(conditionDef.getEvaluatorOptions()).thenReturn(null);
+               matcher.setConditionDef(conditionDef);
+               matcher.setPolicyItemCondition(policyItemCondition);
+               matcher.init();
+               Assert.assertTrue(matcher.isMatched(request));
+
+               // If evaluator option on the condition def is non-null then it 
starts to evaluate for real
+               
Mockito.when(conditionDef.getEvaluatorOptions()).thenReturn(_conditionOptions);
+               matcher.setConditionDef(conditionDef);
+               matcher.setPolicyItemCondition(policyItemCondition);
+               matcher.init();
+               Assert.assertTrue(matcher.isMatched(request));
+       }
+       
+       RangerSampleSimpleMatcher createMatcher(String[] ipArray) {
+               RangerSampleSimpleMatcher matcher = new 
RangerSampleSimpleMatcher();
+
+               if (ipArray == null) {
+                       matcher.setConditionDef(null);
+                       matcher.setPolicyItemCondition(null);
+                       matcher.init();
+               } else {
+                       RangerPolicyItemCondition condition = 
Mockito.mock(RangerPolicyItemCondition.class);
+                       List<String> addresses = Arrays.asList(ipArray);
+                       
Mockito.when(condition.getValues()).thenReturn(addresses);
+                       
+                       RangerPolicyConditionDef conditionDef = 
Mockito.mock(RangerPolicyConditionDef.class);
+
+                       
Mockito.when(conditionDef.getEvaluatorOptions()).thenReturn(_conditionOptions);
+                       matcher.setConditionDef(conditionDef);
+                       matcher.setPolicyItemCondition(condition);
+                       matcher.init();
+               }
+               
+               return matcher;
+       }
+       
+       RangerAccessRequest createRequest(String value) {
+               Map<String, Object> context = new HashMap<String, Object>();
+               context.put(RangerSampleSimpleMatcher.CONTEXT_NAME, value);
+               RangerAccessRequest request = 
Mockito.mock(RangerAccessRequest.class);
+               Mockito.when(request.getContext()).thenReturn(context);
+               return request;
+       }
+}

Reply via email to