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; + } +}
