RANGER-881: sample application and its Ranger plugin to help understand Ranger authorization addition to an application
Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/f06795e2 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/f06795e2 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/f06795e2 Branch: refs/heads/master Commit: f06795e2e3ed70cc3c1970a25fa1c483a60362c2 Parents: 13e6b95 Author: Madhan Neethiraj <[email protected]> Authored: Wed Mar 9 01:31:40 2016 -0800 Committer: Madhan Neethiraj <[email protected]> Committed: Wed Mar 9 11:09:30 2016 -0800 ---------------------------------------------------------------------- ranger-examples/README.txt | 74 ++++++++ ranger-examples/conditions-enrichers/pom.xml | 43 +++++ .../RangerSampleSimpleMatcher.java | 170 +++++++++++++++++++ .../RangerSampleCountryProvider.java | 105 ++++++++++++ .../RangerSampleProjectProvider.java | 103 +++++++++++ .../RangerSampleSimpleMatcherTest.java | 139 +++++++++++++++ .../dev-support/findbugsIncludeFile.xml | 25 +++ .../dev-support/ranger-pmd-ruleset.xml | 70 ++++++++ .../conf/ranger-policymgr-ssl.xml | 63 +++++++ .../conf/ranger-sampleapp-audit.xml | 79 +++++++++ .../conf/ranger-sampleapp-security.xml | 83 +++++++++ ranger-examples/plugin-sampleapp/pom.xml | 85 ++++++++++ .../ranger/examples/sampleapp/IAuthorizer.java | 28 +++ .../examples/sampleapp/RangerAuthorizer.java | 61 +++++++ ranger-examples/pom.xml | 37 ++-- ranger-examples/sampleapp/conf/log4j.xml | 65 +++++++ ranger-examples/sampleapp/pom.xml | 41 +++++ .../sampleapp/scripts/run-sampleapp.sh | 39 +++++ .../examples/sampleapp/DefaultAuthorizer.java | 36 ++++ .../ranger/examples/sampleapp/IAuthorizer.java | 28 +++ .../ranger/examples/sampleapp/SampleApp.java | 159 +++++++++++++++++ .../src/main/assembly/plugin-sampleapp.xml | 75 ++++++++ ranger-examples/src/main/assembly/sampleapp.xml | 62 +++++++ .../RangerSampleSimpleMatcher.java | 170 ------------------- .../RangerSampleCountryProvider.java | 105 ------------ .../RangerSampleProjectProvider.java | 103 ----------- .../RangerSampleSimpleMatcherTest.java | 139 --------------- 27 files changed, 1655 insertions(+), 532 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/README.txt ---------------------------------------------------------------------- diff --git a/ranger-examples/README.txt b/ranger-examples/README.txt new file mode 100644 index 0000000..7b2387e --- /dev/null +++ b/ranger-examples/README.txt @@ -0,0 +1,74 @@ +# 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. + + +1. Introduction + +2. SampleApp + A simple application to demonstrate use of pluggable authorization. + - IAuthorizer: + the authorization interface. Authorizes read/write/execute access to a given file + - DefaultAuthorizer: + default authorizer implementation, authorizes all accesses + - SampleApp: + - main application that prompts the user to enter access to authorize in the following format: + read filePath user1 userGroup1 userGroup2 userGroup3 + write filePath user1 userGroup1 userGroup2 userGroup3 + execute filePath user1 userGroup1 userGroup2 userGroup3 + +3. SampleApp Plugin + - RangerAuthorizer implements IAuthorizer interface and performs authorization using Ranger policies. + - For simplicity, uses policies in a HDFS service instance (like cl1_hadoop): which uses 'path' as the resource and supports 'read', 'write' and 'execute' accessTypes + - conf/ranger-sampleapp-security.xml: has configurations for plugin, like Ranger Admin URL, name of the service containing policies + - conf/ranger-sampleapp-audit.xml: has configurations for plugin audit, like log4j logger name, HDFS folder, DB connection details + +4. Build + $ mvn clean compile package assembly:assembly + $ cd ranger-examples + $ mvn clean compile package assembly:assembly + # Following files created by the build will be required to setup SampleApp: + target/ranger-examples-0.6.0-sampleapp.tar.gz + target/ranger-examples-0.6.0-sampleapp-plugin.tar.gz + +5. Setup SampleApp + # Create a empty directory to setup the application + $ mkdir /tmp/sampleapp + $ cd /tmp/sampleapp + $ tar xvfz ranger-examples-0.6.0-sampleapp.tar.gz + # add Ranger authorizer bits + $ tar xvfz ranger-examples-0.6.0-sampleapp-plugin.tar.gz + # Review and update properties in conf/ranger-sampleapp-security.xml, especially the following: + - ranger.plugin.sampleapp.policy.rest.url + - ranger.plugin.sampleapp.service.name + # Review and update properties in conf/ranger-sampleapp-audit.xml + # Review and update properties in conf/log4j.xml + +6. Execute + - Use default authorizer i.e. not Ranger: + $ cd /tmp/sampleapp + $ ./run-sampleapp.sh + # At the prompt, enter commands to trigger access authorization, like: + command> read filePath user1 userGroup1 userGroup2 userGroup3 + command> write filePath user1 userGroup1 userGroup2 userGroup3 + command> execute filePath user1 userGroup1 userGroup2 userGroup3 + + - Use Ranger authorizer + $ cd /tmp/sampleapp + $ ./run-sampleapp.sh ranger-authz + # At the prompt, enter commands to trigger access authorization, like: + command> read filePath user1 userGroup1 userGroup2 userGroup3 + command> write filePath user1 userGroup1 userGroup2 userGroup3 + command> execute filePath user1 userGroup1 userGroup2 userGroup3 + # audit logs can be seen in /tmp/ranger_audit.log http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/conditions-enrichers/pom.xml ---------------------------------------------------------------------- diff --git a/ranger-examples/conditions-enrichers/pom.xml b/ranger-examples/conditions-enrichers/pom.xml new file mode 100644 index 0000000..6dc8f53 --- /dev/null +++ b/ranger-examples/conditions-enrichers/pom.xml @@ -0,0 +1,43 @@ +<?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"> + <modelVersion>4.0.0</modelVersion> + <artifactId>conditions-enrichers</artifactId> + <name>Ranger Examples - Conditions and ContextEnrichers</name> + <description>Ranger Examples - Conditions and ContextEnrichers</description> + <parent> + <artifactId>ranger-examples</artifactId> + <groupId>org.apache.ranger</groupId> + <version>0.6.0</version> + </parent> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + </dependency> + <dependency> + <groupId>org.apache.ranger</groupId> + <artifactId>ranger-plugins-common</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> +</project> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/conditions-enrichers/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerSampleSimpleMatcher.java ---------------------------------------------------------------------- diff --git a/ranger-examples/conditions-enrichers/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerSampleSimpleMatcher.java b/ranger-examples/conditions-enrichers/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerSampleSimpleMatcher.java new file mode 100644 index 0000000..50ecb69 --- /dev/null +++ b/ranger-examples/conditions-enrichers/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/f06795e2/ranger-examples/conditions-enrichers/src/main/java/org/apache/ranger/plugin/contextenricher/RangerSampleCountryProvider.java ---------------------------------------------------------------------- diff --git a/ranger-examples/conditions-enrichers/src/main/java/org/apache/ranger/plugin/contextenricher/RangerSampleCountryProvider.java b/ranger-examples/conditions-enrichers/src/main/java/org/apache/ranger/plugin/contextenricher/RangerSampleCountryProvider.java new file mode 100644 index 0000000..198dc5f --- /dev/null +++ b/ranger-examples/conditions-enrichers/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/f06795e2/ranger-examples/conditions-enrichers/src/main/java/org/apache/ranger/plugin/contextenricher/RangerSampleProjectProvider.java ---------------------------------------------------------------------- diff --git a/ranger-examples/conditions-enrichers/src/main/java/org/apache/ranger/plugin/contextenricher/RangerSampleProjectProvider.java b/ranger-examples/conditions-enrichers/src/main/java/org/apache/ranger/plugin/contextenricher/RangerSampleProjectProvider.java new file mode 100644 index 0000000..d3de690 --- /dev/null +++ b/ranger-examples/conditions-enrichers/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/f06795e2/ranger-examples/conditions-enrichers/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerSampleSimpleMatcherTest.java ---------------------------------------------------------------------- diff --git a/ranger-examples/conditions-enrichers/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerSampleSimpleMatcherTest.java b/ranger-examples/conditions-enrichers/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerSampleSimpleMatcherTest.java new file mode 100644 index 0000000..3e683ba --- /dev/null +++ b/ranger-examples/conditions-enrichers/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; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/dev-support/findbugsIncludeFile.xml ---------------------------------------------------------------------- diff --git a/ranger-examples/dev-support/findbugsIncludeFile.xml b/ranger-examples/dev-support/findbugsIncludeFile.xml new file mode 100644 index 0000000..8623906 --- /dev/null +++ b/ranger-examples/dev-support/findbugsIncludeFile.xml @@ -0,0 +1,25 @@ +<!-- + 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. +--> +<FindBugsFilter> + <!-- + For now, lets find only critical bugs from static code analyzer + --> + <Match> + <Bug Rank="1" /> + </Match> + +</FindBugsFilter> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/dev-support/ranger-pmd-ruleset.xml ---------------------------------------------------------------------- diff --git a/ranger-examples/dev-support/ranger-pmd-ruleset.xml b/ranger-examples/dev-support/ranger-pmd-ruleset.xml new file mode 100644 index 0000000..741601e --- /dev/null +++ b/ranger-examples/dev-support/ranger-pmd-ruleset.xml @@ -0,0 +1,70 @@ +<?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. +--> +<ruleset name="ranger-pmd" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd"> + <description> + Apache Ranger - PMD rule set + </description> + + <rule ref="rulesets/java/basic.xml"> + <exclude name="AvoidBranchingStatementAsLastInLoop" /> + <exclude name="AvoidThreadGroup" /> + <exclude name="AvoidUsingHardCodedIP" /> + <exclude name="BooleanInstantiation" /> + <exclude name="ClassCastExceptionWithToArray" /> + <exclude name="CollapsibleIfStatements" /> + <exclude name="DoubleCheckedLocking" /> + <exclude name="ExtendsObject" /> + <exclude name="OverrideBothEqualsAndHashcode" /> + </rule> + <rule ref="rulesets/java/unusedcode.xml"> + <exclude name="UnusedFormalParameter" /> + <exclude name="UnusedLocalVariable" /> + <exclude name="UnusedModifier" /> + <exclude name="UnusedPrivateField" /> + <exclude name="UnusedPrivateMethod" /> + </rule> + <rule ref="rulesets/java/imports.xml" > + <exclude name="ImportFromSamePackage" /> + <exclude name="UnnecessaryFullyQualifiedName" /> + </rule> + <rule ref="rulesets/java/braces.xml"> + <exclude name="ForLoopsMustUseBraces" /> + <exclude name="IfElseStmtsMustUseBraces" /> + <exclude name="IfStmtsMustUseBraces" /> + </rule> + <rule ref="rulesets/java/empty.xml"> + <exclude name="EmptyCatchBlock" /> + <exclude name="EmptyIfStmt" /> + <exclude name="EmptyStatementNotInLoop" /> + <exclude name="EmptyWhileStmt" /> + </rule> + <rule ref="rulesets/java/migrating.xml" /> + <rule ref="rulesets/java/unnecessary.xml"> + <exclude name="UnnecessaryConversionTemporary" /> + <exclude name="UnnecessaryReturn" /> + <exclude name="UnusedNullCheckInEquals" /> + <exclude name="UselessOverridingMethod" /> + <exclude name="UselessParentheses" /> + <exclude name="UnnecessaryFinalModifier" /> + </rule> + +</ruleset> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/plugin-sampleapp/conf/ranger-policymgr-ssl.xml ---------------------------------------------------------------------- diff --git a/ranger-examples/plugin-sampleapp/conf/ranger-policymgr-ssl.xml b/ranger-examples/plugin-sampleapp/conf/ranger-policymgr-ssl.xml new file mode 100644 index 0000000..964aac7 --- /dev/null +++ b/ranger-examples/plugin-sampleapp/conf/ranger-policymgr-ssl.xml @@ -0,0 +1,63 @@ +<?xml version="1.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. +--> +<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> +<configuration xmlns:xi="http://www.w3.org/2001/XInclude"> + <!-- The following properties are used for 2-way SSL client server validation --> + <property> + <name>xasecure.policymgr.clientssl.keystore</name> + <value>hadoopdev-clientcert.jks</value> + <description> + Java Keystore files + </description> + </property> + <property> + <name>xasecure.policymgr.clientssl.keystore.password</name> + <value>none</value> + <description> + password for keystore + </description> + </property> + <property> + <name>xasecure.policymgr.clientssl.truststore</name> + <value>cacerts-xasecure.jks</value> + <description> + java truststore file + </description> + </property> + <property> + <name>xasecure.policymgr.clientssl.truststore.password</name> + <value>none</value> + <description> + java truststore password + </description> + </property> + <property> + <name>xasecure.policymgr.clientssl.keystore.credential.file</name> + <value>jceks://file/tmp/keystore-hadoopdev-ssl.jceks</value> + <description> + java keystore credential file + </description> + </property> + <property> + <name>xasecure.policymgr.clientssl.truststore.credential.file</name> + <value>jceks://file/tmp/truststore-hadoopdev-ssl.jceks</value> + <description> + java truststore credential file + </description> + </property> +</configuration> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/plugin-sampleapp/conf/ranger-sampleapp-audit.xml ---------------------------------------------------------------------- diff --git a/ranger-examples/plugin-sampleapp/conf/ranger-sampleapp-audit.xml b/ranger-examples/plugin-sampleapp/conf/ranger-sampleapp-audit.xml new file mode 100644 index 0000000..5b19063 --- /dev/null +++ b/ranger-examples/plugin-sampleapp/conf/ranger-sampleapp-audit.xml @@ -0,0 +1,79 @@ +<?xml version="1.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. +--> +<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> +<configuration xmlns:xi="http://www.w3.org/2001/XInclude"> + <!-- DB audit provider configuration --> + <property> + <name>xasecure.audit.destination.db</name> + <value>false</value> + </property> + + <property> + <name>xasecure.audit.destination.db.jdbc.driver</name> + <value>com.mysql.jdbc.Driver</value> + </property> + + <property> + <name>xasecure.audit.destination.db.jdbc.url</name> + <value>jdbc:mysql://localhost/ranger_audit</value> + </property> + + <property> + <name>xasecure.audit.destination.db.password</name> + <value>rangerlogger</value> + </property> + + <property> + <name>xasecure.audit.destination.db.user</name> + <value>rangerlogger</value> + </property> + + <property> + <name>xasecure.audit.destination.db.batch.filespool.dir</name> + <value>/tmp/audit/db/spool</value> + </property> + + + <!-- HDFS audit provider configuration --> + <property> + <name>xasecure.audit.destination.hdfs</name> + <value>false</value> + </property> + + <property> + <name>xasecure.audit.destination.hdfs.dir</name> + <value>hdfs://localhost:8020/ranger/audit</value> + </property> + + <property> + <name>xasecure.audit.destination.hdfs.batch.filespool.dir</name> + <value>/tmp/audit/hdfs/spool</value> + </property> + + + <!-- Log4j audit provider configuration --> + <property> + <name>xasecure.audit.destination.log4j</name> + <value>true</value> + </property> + + <property> + <name>xasecure.audit.destination.log4j.logger</name> + <value>ranger_audit_logger</value> + </property> +</configuration> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/plugin-sampleapp/conf/ranger-sampleapp-security.xml ---------------------------------------------------------------------- diff --git a/ranger-examples/plugin-sampleapp/conf/ranger-sampleapp-security.xml b/ranger-examples/plugin-sampleapp/conf/ranger-sampleapp-security.xml new file mode 100644 index 0000000..befcea7 --- /dev/null +++ b/ranger-examples/plugin-sampleapp/conf/ranger-sampleapp-security.xml @@ -0,0 +1,83 @@ +<?xml version="1.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. +--> +<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> +<configuration xmlns:xi="http://www.w3.org/2001/XInclude"> + <property> + <name>ranger.plugin.sampleapp.policy.rest.url</name> + <value>http://localhost:6080</value> + <description> + URL to Ranger Admin + </description> + </property> + + <property> + <name>ranger.plugin.sampleapp.service.name</name> + <value>cl1_hadoop</value> + <description> + Name of the Ranger service containing policies for this SampleApp instance + </description> + </property> + + <property> + <name>ranger.plugin.sampleapp.policy.source.impl</name> + <value>org.apache.ranger.admin.client.RangerAdminRESTClient</value> + <description> + Class to retrieve policies from the source + </description> + </property> + + <property> + <name>ranger.plugin.sampleapp.policy.rest.ssl.config.file</name> + <value>ranger-policymgr-ssl.xml</value> + <description> + Path to the file containing SSL details to contact Ranger Admin + </description> + </property> + + <property> + <name>ranger.plugin.sampleapp.policy.pollIntervalMs</name> + <value>30000</value> + <description> + How often to poll for changes in policies? + </description> + </property> + + <property> + <name>ranger.plugin.sampleapp.policy.cache.dir</name> + <value>/tmp</value> + <description> + Directory where Ranger policies are cached after successful retrieval from the source + </description> + </property> + + <property> + <name>ranger.plugin.sampleapp.policy.rest.client.connection.timeoutMs</name> + <value>120000</value> + <description> + RangerRestClient Connection Timeout in Milli Seconds + </description> + </property> + + <property> + <name>ranger.plugin.sampleapp.policy.rest.client.read.timeoutMs</name> + <value>30000</value> + <description> + RangerRestClient read Timeout in Milli Seconds + </description> + </property> +</configuration> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/plugin-sampleapp/pom.xml ---------------------------------------------------------------------- diff --git a/ranger-examples/plugin-sampleapp/pom.xml b/ranger-examples/plugin-sampleapp/pom.xml new file mode 100644 index 0000000..5520120 --- /dev/null +++ b/ranger-examples/plugin-sampleapp/pom.xml @@ -0,0 +1,85 @@ +<?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"> + <modelVersion>4.0.0</modelVersion> + <artifactId>ranger-sampleapp-plugin</artifactId> + <name>Ranger Examples - Ranger Plugin for SampleApp</name> + <description>Ranger Examples - SampleApp</description> + <packaging>jar</packaging> + <parent> + <artifactId>ranger-examples</artifactId> + <groupId>org.apache.ranger</groupId> + <version>0.6.0</version> + </parent> + <dependencies> + <dependency> + <groupId>org.apache.ranger</groupId> + <artifactId>ranger-plugins-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.ranger</groupId> + <artifactId>ranger-plugins-audit</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.hadoop</groupId> + <artifactId>hadoop-common</artifactId> + <version>${hadoop-common.version}</version> + </dependency> + <dependency> + <groupId>commons-configuration</groupId> + <artifactId>commons-configuration</artifactId> + <version>${commons.configuration.version}</version> + </dependency> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <version>${commons.lang.version}</version> + </dependency> + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-bundle</artifactId> + <version>${jersey-bundle.version}</version> + </dependency> + <dependency> + <groupId>org.codehaus.jackson</groupId> + <artifactId>jackson-jaxrs</artifactId> + <version>${codehaus.jackson.storm.version}</version> + </dependency> + <dependency> + <groupId>org.codehaus.jackson</groupId> + <artifactId>jackson-core-asl</artifactId> + <version>${codehaus.jackson.storm.version}</version> + </dependency> + <dependency> + <groupId>org.codehaus.jackson</groupId> + <artifactId>jackson-xc</artifactId> + <version>${codehaus.jackson.storm.version}</version> + </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + <version>${google.guava.version}</version> + </dependency> + </dependencies> +</project> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/plugin-sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/IAuthorizer.java ---------------------------------------------------------------------- diff --git a/ranger-examples/plugin-sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/IAuthorizer.java b/ranger-examples/plugin-sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/IAuthorizer.java new file mode 100644 index 0000000..f5dd9cb --- /dev/null +++ b/ranger-examples/plugin-sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/IAuthorizer.java @@ -0,0 +1,28 @@ +/* + * 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.examples.sampleapp; + +import java.util.Set; + +interface IAuthorizer { + void init(); + + boolean authorize(String fileName, String accessType, String user, Set<String> userGroups); +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/plugin-sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/RangerAuthorizer.java ---------------------------------------------------------------------- diff --git a/ranger-examples/plugin-sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/RangerAuthorizer.java b/ranger-examples/plugin-sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/RangerAuthorizer.java new file mode 100644 index 0000000..e35dce1 --- /dev/null +++ b/ranger-examples/plugin-sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/RangerAuthorizer.java @@ -0,0 +1,61 @@ +package org.apache.ranger.examples.sampleapp; + +import java.util.Set; +/* + * 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. + */ + +import org.apache.ranger.plugin.audit.RangerDefaultAuditHandler; +import org.apache.ranger.plugin.service.RangerBasePlugin; +import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl; +import org.apache.ranger.plugin.policyengine.RangerAccessRequest; +import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl; +import org.apache.ranger.plugin.policyengine.RangerAccessResult; + +public class RangerAuthorizer implements IAuthorizer { + private static volatile RangerBasePlugin plugin = null; + + public RangerAuthorizer() { + + } + + public void init() { + if(plugin == null) { + synchronized (RangerAuthorizer.class) { + if(plugin == null) { + plugin = new RangerBasePlugin("sampleapp", "sampleapp"); + + plugin.setResultProcessor(new RangerDefaultAuditHandler()); + + plugin.init(); + } + } + } + } + + public boolean authorize(String fileName, String accessType, String user, Set<String> userGroups) { + RangerAccessResourceImpl resource = new RangerAccessResourceImpl(); + resource.setValue("path", fileName); // "path" must be a valud resource name in servicedef JSON + + RangerAccessRequest request = new RangerAccessRequestImpl(resource, accessType, user, userGroups); + + RangerAccessResult result = plugin.isAccessAllowed(request); + + return result != null && result.getIsAllowed(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/pom.xml ---------------------------------------------------------------------- diff --git a/ranger-examples/pom.xml b/ranger-examples/pom.xml index 37e9d68..8648b83 100644 --- a/ranger-examples/pom.xml +++ b/ranger-examples/pom.xml @@ -23,19 +23,26 @@ </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>org.apache.ranger</groupId> - <artifactId>ranger-plugins-common</artifactId> - <version>${project.version}</version> - </dependency> - </dependencies> + <packaging>pom</packaging> + <modules> + <module>conditions-enrichers</module> + <module>sampleapp</module> + <module>plugin-sampleapp</module> + </modules> + <build> + <pluginManagement> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.2-beta-5</version> + <configuration> + <descriptors> + <descriptor>src/main/assembly/sampleapp.xml</descriptor> + <descriptor>src/main/assembly/plugin-sampleapp.xml</descriptor> + </descriptors> + </configuration> + </plugin> + </plugins> + </pluginManagement> + </build> </project> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/sampleapp/conf/log4j.xml ---------------------------------------------------------------------- diff --git a/ranger-examples/sampleapp/conf/log4j.xml b/ranger-examples/sampleapp/conf/log4j.xml new file mode 100644 index 0000000..d475b91 --- /dev/null +++ b/ranger-examples/sampleapp/conf/log4j.xml @@ -0,0 +1,65 @@ +<?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. +--> +<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> + +<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false"> + <appender name="console_appender" class="org.apache.log4j.ConsoleAppender"> + <param name="target" value="System.out" /> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="[%p]: %m%n" /> + </layout> + </appender> + + <appender name="sampleapp_log_appender" class="org.apache.log4j.DailyRollingFileAppender"> + <param name="file" value="/tmp/sampleapp.log" /> + <param name="datePattern" value="'.'yyyy-MM-dd" /> + <param name="append" value="true" /> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%d [%t] %-5p %C{6} (%F:%L) - %m%n" /> + </layout> + </appender> + + <appender name="ranger_audit_appender" class="org.apache.log4j.DailyRollingFileAppender"> + <param name="file" value="/tmp/sampleapp-ranger_audit.log" /> + <param name="datePattern" value="'.'yyyy-MM-dd" /> + <param name="append" value="true" /> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%m%n" /> + </layout> + </appender> + + <category name="org.apache.ranger.examples.sampleapp" additivity="false"> + <priority value="info" /> + <appender-ref ref="console_appender" /> + </category> + + <category name="org.apache.ranger" additivity="false"> + <priority value="info" /> + <appender-ref ref="sampleapp_log_appender" /> + </category> + + <category name="ranger_audit_logger"> + <level value="info" /> + <appender-ref ref="ranger_audit_appender" /> + </category> + + <root> + <priority value="warn" /> + <appender-ref ref="sampleapp_log_appender" /> + </root> +</log4j:configuration> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/sampleapp/pom.xml ---------------------------------------------------------------------- diff --git a/ranger-examples/sampleapp/pom.xml b/ranger-examples/sampleapp/pom.xml new file mode 100644 index 0000000..28fa94e --- /dev/null +++ b/ranger-examples/sampleapp/pom.xml @@ -0,0 +1,41 @@ +<?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"> + <modelVersion>4.0.0</modelVersion> + <artifactId>sampleapp</artifactId> + <name>Ranger Examples - SampleApp</name> + <description>Ranger Examples - SampleApp</description> + <packaging>jar</packaging> + <parent> + <artifactId>ranger-examples</artifactId> + <groupId>org.apache.ranger</groupId> + <version>0.6.0</version> + </parent> + <dependencies> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>${commons.logging.version}</version> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <version>${log4j.version}</version> + </dependency> + </dependencies> +</project> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/sampleapp/scripts/run-sampleapp.sh ---------------------------------------------------------------------- diff --git a/ranger-examples/sampleapp/scripts/run-sampleapp.sh b/ranger-examples/sampleapp/scripts/run-sampleapp.sh new file mode 100755 index 0000000..028b531 --- /dev/null +++ b/ranger-examples/sampleapp/scripts/run-sampleapp.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# 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. + + +AUTHORIZER_TYPE=$1 + + +JARS= +for i in lib/*.jar conf +do + JARS="${JARS}:$i" +done + +if [ "${AUTHORIZER_TYPE}" == "ranger-authz" ] +then + AUTHORIZER_ARG="-Dsampleapp.authorizer=org.apache.ranger.examples.sampleapp.RangerAuthorizer" + for i in lib/ranger-sampleapp-plugin-impl/*.jar + do + JARS="${JARS}:$i" + done +fi + +CLASSPATH=$CLASSPATH:$JARS + +java -cp ${CLASSPATH} ${AUTHORIZER_ARG} org.apache.ranger.examples.sampleapp.SampleApp http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/DefaultAuthorizer.java ---------------------------------------------------------------------- diff --git a/ranger-examples/sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/DefaultAuthorizer.java b/ranger-examples/sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/DefaultAuthorizer.java new file mode 100644 index 0000000..a238da6 --- /dev/null +++ b/ranger-examples/sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/DefaultAuthorizer.java @@ -0,0 +1,36 @@ +/* + * 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.examples.sampleapp; + +import java.util.Set; + +public class DefaultAuthorizer implements IAuthorizer { + public DefaultAuthorizer() { + + } + + public void init() { + + } + + public boolean authorize(String fileName, String accessType, String user, Set<String> userGroups) { + return true; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/IAuthorizer.java ---------------------------------------------------------------------- diff --git a/ranger-examples/sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/IAuthorizer.java b/ranger-examples/sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/IAuthorizer.java new file mode 100644 index 0000000..f5dd9cb --- /dev/null +++ b/ranger-examples/sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/IAuthorizer.java @@ -0,0 +1,28 @@ +/* + * 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.examples.sampleapp; + +import java.util.Set; + +interface IAuthorizer { + void init(); + + boolean authorize(String fileName, String accessType, String user, Set<String> userGroups); +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/SampleApp.java ---------------------------------------------------------------------- diff --git a/ranger-examples/sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/SampleApp.java b/ranger-examples/sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/SampleApp.java new file mode 100644 index 0000000..93d74a9 --- /dev/null +++ b/ranger-examples/sampleapp/src/main/java/org/apache/ranger/examples/sampleapp/SampleApp.java @@ -0,0 +1,159 @@ +/* + * 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.examples.sampleapp; + +import java.util.HashSet; +import java.util.Scanner; +import java.util.Set; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class SampleApp { + private static final Log LOG = LogFactory.getLog(SampleApp.class); + + private static final Set<String> VALID_ACCESS_TYPES = new HashSet<String>(); + + private IAuthorizer authorizer = null; + + public static void main(String[] args) { + SampleApp app = new SampleApp(); + + app.init(); + + app.run(); + } + + public void init() { + VALID_ACCESS_TYPES.add("read"); + VALID_ACCESS_TYPES.add("write"); + VALID_ACCESS_TYPES.add("execute"); + + authorizer = createAuthorizer(); + } + + public void run() { + LOG.debug("==> SampleApp.run()"); + + do { + String input = getInput(); + + if(input == null) { + break; + } + + if(input.trim().isEmpty()) { + continue; + } + + String[] args = input.split("\\s+"); + String accessType = getStringArg(args, 0); + String fileName = getStringArg(args, 1); + String userName = getStringArg(args, 2); + Set<String> userGroups = new HashSet<String>(); + + for(int i = 3; i < args.length; i++) { + userGroups.add(args[i]); + } + + if(fileName == null || accessType == null || userName == null) { + LOG.info("Insufficient arguments. Usage: <accessType> <fileName> <userName> [userGroup1 userGroup2 userGroup3 ..]"); + + continue; + } + + if(! VALID_ACCESS_TYPES.contains(accessType)) { + LOG.info(accessType + ": invalid accessType"); + + continue; + } + + if(authorizer.authorize(fileName, accessType, userName, userGroups)) { + LOG.info("Authorized!"); + } else { + LOG.info("Not authorized!"); + } + } while(true); + + LOG.debug("<== SampleApp.run()"); + } + + private IAuthorizer createAuthorizer() { + IAuthorizer ret = null; + + String authzClassName = System.getProperty("sampleapp.authorizer"); + + if(authzClassName != null) { + try { + Class<IAuthorizer> clz = (Class<IAuthorizer>) Class.forName(authzClassName); + + ret = clz.newInstance(); + } catch(Exception excp) { + LOG.warn("Failed to create authorizer of type '" + authzClassName + "'", excp); + } + } + + if(ret == null) { + LOG.info("Using default authorizer"); + ret = new DefaultAuthorizer(); + } + + ret.init(); + + return ret; + } + + private String getStringArg(String[] args, int index) { + if(args == null || args.length <= index) { + return null; + } + + return args[index]; + } + + private Set<String> getStringSetArg(String[] args, int index) { + String argValue = getStringArg(args, index); + + if(argValue == null) { + return null; + } + + Set<String> ret = new HashSet<String>(); + + for(String value : argValue.split(",")) { + ret.add(value); + } + + return ret; + } + + private String getInput() { + Scanner inputReader = new Scanner(System.in); + + System.out.print("command> "); + System.out.flush(); + try { + return inputReader.nextLine(); + } catch(Exception excp) { + // ignore + } + + return null; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/src/main/assembly/plugin-sampleapp.xml ---------------------------------------------------------------------- diff --git a/ranger-examples/src/main/assembly/plugin-sampleapp.xml b/ranger-examples/src/main/assembly/plugin-sampleapp.xml new file mode 100644 index 0000000..de6b9a1 --- /dev/null +++ b/ranger-examples/src/main/assembly/plugin-sampleapp.xml @@ -0,0 +1,75 @@ +<?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. +--> +<assembly> + <id>sampleapp-plugin</id> + <formats> + <format>tar.gz</format> + </formats> + <baseDirectory>${project.name}-${project.version}-ranger-sampleapp-plugin</baseDirectory> + <includeBaseDirectory>false</includeBaseDirectory> + <moduleSets> + <moduleSet> + <binaries> + <includeDependencies>false</includeDependencies> + <dependencySets> + <dependencySet> + <outputDirectory>/lib/ranger-sampleapp-plugin-impl</outputDirectory> + <includes> + <include>org.apache.ranger:ranger-plugins-common</include> + <include>org.apache.ranger:ranger-plugins-audit</include> + <include>org.apache.httpcomponents:httpmime:jar:${httpcomponent.httpmime.version}</include> + <include>org.noggit:noggit:jar:${noggit.version}</include> + <include>org.apache.hadoop:hadoop-common:jar:${hadoop-common.version}</include> + <include>org.apache.hadoop:hadoop-auth:jar:${hadoop-common.version}</include> + <include>commons-collections:commons-collections</include> + <include>commons-configuration:commons-configuration:jar:${commons.configuration.version}</include> + <include>commons-logging:commons-logging:jar:${commons.logging.version}</include> + <include>commons-io:commons-io:jar:${commons.io.version}</include> + <include>commons-lang:commons-lang:jar:${commons.lang.version}</include> + <include>com.google.guava:guava:jar:${google.guava.version}</include> + <include>org.codehaus.jackson:jackson-jaxrs:jar:${codehaus.jackson.storm.version}</include> + <include>org.codehaus.jackson:jackson-core-asl:jar:${codehaus.jackson.storm.version}</include> + <include>org.codehaus.jackson:jackson-mapper-asl:jar:${codehaus.jackson.storm.version}</include> + <include>org.codehaus.jackson:jackson-xc:jar:${codehaus.jackson.storm.version}</include> + <include>com.google.guava:guava:jar:${google.guava.version}</include> + <include>org.slf4j:slf4j-api</include> + <include>log4j:log4j</include> + <include>com.sun.jersey:jersey-bundle</include> + <include>com.google.code.gson:gson</include> + </includes> + <unpack>false</unpack> + </dependencySet> + </dependencySets> + <outputDirectory>/lib/ranger-sampleapp-plugin-impl</outputDirectory> + <unpack>false</unpack> + <directoryMode>755</directoryMode> + <fileMode>644</fileMode> + </binaries> + <includes> + <include>org.apache.ranger:ranger-sampleapp-plugin</include> + </includes> + </moduleSet> + </moduleSets> + <fileSets> + <fileSet> + <outputDirectory>/conf</outputDirectory> + <directory>plugin-sampleapp/conf</directory> + <fileMode>644</fileMode> + </fileSet> + </fileSets> +</assembly> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/ranger-examples/src/main/assembly/sampleapp.xml ---------------------------------------------------------------------- diff --git a/ranger-examples/src/main/assembly/sampleapp.xml b/ranger-examples/src/main/assembly/sampleapp.xml new file mode 100644 index 0000000..56d43b5 --- /dev/null +++ b/ranger-examples/src/main/assembly/sampleapp.xml @@ -0,0 +1,62 @@ +<?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. +--> +<assembly> + <id>sampleapp</id> + <formats> + <format>tar.gz</format> + </formats> + <baseDirectory>${project.name}-${project.version}-sampleapp</baseDirectory> + <includeBaseDirectory>false</includeBaseDirectory> + <moduleSets> + <moduleSet> + <binaries> + <includeDependencies>false</includeDependencies> + <dependencySets> + <dependencySet> + <outputDirectory>/lib/</outputDirectory> + <includes> + </includes> + <unpack>false</unpack> + </dependencySet> + </dependencySets> + <unpack>false</unpack> + <directoryMode>755</directoryMode> + <fileMode>644</fileMode> + <outputDirectory>/lib/</outputDirectory> + </binaries> + <includes> + <include>org.apache.ranger:sampleapp</include> + </includes> + </moduleSet> + </moduleSets> + <fileSets> + <fileSet> + <outputDirectory>/</outputDirectory> + <directory>sampleapp/scripts</directory> + <includes> + <include>*.sh</include> + </includes> + <fileMode>755</fileMode> + </fileSet> + <fileSet> + <outputDirectory>/conf</outputDirectory> + <directory>sampleapp/conf</directory> + <fileMode>644</fileMode> + </fileSet> + </fileSets> +</assembly> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f06795e2/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 deleted file mode 100644 index 50ecb69..0000000 --- a/ranger-examples/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerSampleSimpleMatcher.java +++ /dev/null @@ -1,170 +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 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; - } -}
