Repository: incubator-ranger Updated Branches: refs/heads/master 80c46f22f -> 776533f94
RANGER-507: Resource-match logic moved out of policy-evaluator implementation to enable reuse Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/776533f9 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/776533f9 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/776533f9 Branch: refs/heads/master Commit: 776533f9463a2c9e7c6e4c83845e955bc70d4820 Parents: 80c46f2 Author: Madhan Neethiraj <[email protected]> Authored: Wed May 27 16:19:24 2015 -0700 Committer: Madhan Neethiraj <[email protected]> Committed: Wed May 27 17:30:30 2015 -0700 ---------------------------------------------------------------------- .../RangerDefaultPolicyEvaluator.java | 239 ++---------- .../RangerDefaultPolicyResourceMatcher.java | 364 +++++++++++++++++++ .../RangerPolicyResourceMatcher.java | 44 +++ 3 files changed, 430 insertions(+), 217 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/776533f9/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java index ede91f0..9233f8d 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java @@ -40,24 +40,22 @@ import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; import org.apache.ranger.plugin.model.RangerServiceDef; import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef; import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef; -import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef; import org.apache.ranger.plugin.policyengine.RangerAccessRequest; import org.apache.ranger.plugin.policyengine.RangerAccessResource; import org.apache.ranger.plugin.policyengine.RangerAccessResult; import org.apache.ranger.plugin.policyengine.RangerPolicyEngine; import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions; -import org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher; -import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher; +import org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher; +import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher; import com.google.common.base.Strings; -import com.google.common.collect.Sets; public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator { private static final Log LOG = LogFactory.getLog(RangerDefaultPolicyEvaluator.class); - private Map<String, RangerResourceMatcher> matchers; - private Map<String, RangerConditionEvaluator> conditionEvaluators; + private RangerPolicyResourceMatcher resourceMatcher = null; + private Map<String, RangerConditionEvaluator> conditionEvaluators = null; @Override public void init(RangerPolicy policy, RangerServiceDef serviceDef, RangerPolicyEngineOptions options) { @@ -69,24 +67,11 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator super.init(policy, serviceDef, options); - this.matchers = new HashMap<String, RangerResourceMatcher>(); + resourceMatcher = new RangerDefaultPolicyResourceMatcher(); - if(policy != null && policy.getResources() != null && serviceDef != null) { - for(RangerResourceDef resourceDef : serviceDef.getResources()) { - String resourceName = resourceDef.getName(); - RangerPolicyResource policyResource = policy.getResources().get(resourceName); - - if(policyResource != null) { - RangerResourceMatcher matcher = createResourceMatcher(resourceDef, policyResource); - - if(matcher != null) { - matchers.put(resourceName, matcher); - } else { - LOG.error("failed to find matcher for resource " + resourceName); - } - } - } - } + resourceMatcher.setServiceDef(serviceDef); + resourceMatcher.setPolicyResources(policy == null ? null : policy.getResources()); + resourceMatcher.init(); if(options.disableCustomConditions) { conditionEvaluators = Collections.<String, RangerConditionEvaluator>emptyMap(); @@ -347,36 +332,8 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator boolean ret = false; - RangerServiceDef serviceDef = getServiceDef(); - - if(serviceDef != null && serviceDef.getResources() != null) { - Collection<String> resourceKeys = resource == null ? null : resource.getKeys(); - Collection<String> policyKeys = matchers == null ? null : matchers.keySet(); - - boolean keysMatch = CollectionUtils.isEmpty(resourceKeys) || (policyKeys != null && policyKeys.containsAll(resourceKeys)); - - if(keysMatch) { - for(RangerResourceDef resourceDef : serviceDef.getResources()) { - String resourceName = resourceDef.getName(); - String resourceValue = resource == null ? null : resource.getValue(resourceName); - RangerResourceMatcher matcher = matchers == null ? null : matchers.get(resourceName); - - // when no value exists for a resourceName, consider it a match only if: policy doesn't have a matcher OR matcher allows no-value resource - if(StringUtils.isEmpty(resourceValue)) { - ret = matcher == null || matcher.isMatch(resourceValue); - } else { - ret = matcher != null && matcher.isMatch(resourceValue); - } - - if(! ret) { - break; - } - } - } else { - if(LOG.isDebugEnabled()) { - LOG.debug("isMatch(): keysMatch=false. isMatch=" + resourceKeys + "; policyKeys=" + policyKeys); - } - } + if(resourceMatcher != null) { + ret = resourceMatcher.isMatch(resource); } if(LOG.isDebugEnabled()) { @@ -394,39 +351,8 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator boolean ret = false; - RangerServiceDef serviceDef = getServiceDef(); - - if(serviceDef != null && serviceDef.getResources() != null) { - Collection<String> resourceKeys = resource == null ? null : resource.getKeys(); - Collection<String> policyKeys = matchers == null ? null : matchers.keySet(); - - boolean keysMatch = false; - - if (resourceKeys != null && policyKeys != null) { - keysMatch = CollectionUtils.isEqualCollection(resourceKeys, policyKeys); - } - - if(keysMatch) { - for(RangerResourceDef resourceDef : serviceDef.getResources()) { - String resourceName = resourceDef.getName(); - String resourceValue = resource == null ? null : resource.getValue(resourceName); - RangerResourceMatcher matcher = matchers == null ? null : matchers.get(resourceName); - - if(StringUtils.isEmpty(resourceValue)) { - ret = matcher == null || matcher.isSingleAndExactMatch(resourceValue); - } else { - ret = matcher != null && matcher.isSingleAndExactMatch(resourceValue); - } - - if(! ret) { - break; - } - } - } else { - if(LOG.isDebugEnabled()) { - LOG.debug("isSingleAndExactMatch(): keysMatch=false. resourceKeys=" + resourceKeys + "; policyKeys=" + policyKeys); - } - } + if(resourceMatcher != null) { + ret = resourceMatcher.isSingleAndExactMatch(resource); } if(LOG.isDebugEnabled()) { @@ -471,53 +397,11 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator if(LOG.isDebugEnabled()) { LOG.debug("==> RangerDefaultPolicyEvaluator.matchResourceHead(" + resource + ")"); } - boolean ret; - - if (resource == null || CollectionUtils.isEmpty(resource.getKeys())) { // sanity-check, firewalling - LOG.debug("matchResourceHead: resource was null/empty!"); - ret = true; // null resource matches anything - } else if (getServiceDef() == null) { // sanity-check, firewalling - LOG.debug("matchResourceHead: service-def was null!"); - ret = false; // null policy can never match a non-empty resource - } else if (getPolicy() == null || getPolicy().getResources() == null) { - LOG.debug("matchResourceHead: policy or its resources were null!"); - ret = false; // null policy can never match a non-empty resource - } else if (matchers == null || matchers.size() != getPolicy().getResources().size()) { // sanity-check, firewalling - LOG.debug("matchResourceHead: matchers could be found for some of the policy resources"); - ret = false; // empty policy can never match a non-empty resources and can't be evaluated meaningfully in matchers are absent - } else { - if (!Sets.difference(resource.getKeys(), matchers.keySet()).isEmpty()) { // e.g. avoid using udf policy for resource that has more than db specified and vice-versa - LOG.debug("matchResourceHead: resource/policy resource-keys mismatch. policy is incompatible with resource; can't match."); - ret = false; - } else { - Set<String> policyResourceNames = matchers.keySet(); - boolean skipped = false; - boolean matched = true; - Iterator<RangerResourceDef> iterator = getServiceDef().getResources().iterator(); - while (iterator.hasNext() && matched) { - RangerResourceDef resourceDef = iterator.next(); - String resourceName = resourceDef.getName(); - // we only work with resources that are relevant to this policy - if (policyResourceNames.contains(resourceName)) { - String resourceValue = resource.getValue(resourceName); - if (StringUtils.isEmpty(resourceValue)) { - if (LOG.isDebugEnabled()) { - LOG.debug("Skipping matching for " + resourceName + " since it is null/empty on resource"); - } - skipped = true; // once we skip a level all lower levels must be skippable, too - } else if (skipped == true) { - LOG.debug("matchResourceHead: found a lower level resource when a higer level resource was absent!"); - matched = false; - } else if (!matchers.get(resourceName).isMatch(resourceValue)) { - if (LOG.isDebugEnabled()) { - LOG.debug("matchResourceHead: matcher for " + resourceName + " failed"); - } - matched = false; - } - } - } - ret = matched; - } + + boolean ret = false; + + if(resourceMatcher != null) { + ret = resourceMatcher.isHeadMatch(resource); } if(LOG.isDebugEnabled()) { @@ -623,49 +507,6 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator return ret; } - protected static RangerResourceMatcher createResourceMatcher(RangerResourceDef resourceDef, RangerPolicyResource resource) { - if(LOG.isDebugEnabled()) { - LOG.debug("==> RangerDefaultPolicyEvaluator.createResourceMatcher(" + resourceDef + ", " + resource + ")"); - } - - RangerResourceMatcher ret = null; - - if (resourceDef != null) { - String resName = resourceDef.getName(); - String clsName = resourceDef.getMatcher(); - - if (!StringUtils.isEmpty(clsName)) { - try { - @SuppressWarnings("unchecked") - Class<RangerResourceMatcher> matcherClass = (Class<RangerResourceMatcher>) Class.forName(clsName); - - ret = matcherClass.newInstance(); - } catch (Exception excp) { - LOG.error("failed to instantiate resource matcher '" + clsName + "' for '" + resName + "'. Default resource matcher will be used", excp); - } - } - - - if (ret == null) { - ret = new RangerDefaultResourceMatcher(); - } - - if (ret != null) { - ret.setResourceDef(resourceDef); - ret.setPolicyResource(resource); - ret.init(); - } - } else { - LOG.error("RangerDefaultPolicyEvaluator: RangerResourceDef is null"); - } - - if(LOG.isDebugEnabled()) { - LOG.debug("<== RangerDefaultPolicyEvaluator.createResourceMatcher(" + resourceDef + ", " + resource + "): " + ret); - } - - return ret; - } - protected boolean isMatch(Map<String, RangerPolicyResource> resources) { if(LOG.isDebugEnabled()) { LOG.debug("==> RangerDefaultPolicyEvaluator.isMatch(" + resources + ")"); @@ -673,42 +514,8 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator boolean ret = false; - RangerServiceDef serviceDef = getServiceDef(); - - if(serviceDef != null && serviceDef.getResources() != null) { - Collection<String> resourceKeys = resources == null ? null : resources.keySet(); - Collection<String> policyKeys = matchers == null ? null : matchers.keySet(); - - boolean keysMatch = CollectionUtils.isEmpty(resourceKeys) || (policyKeys != null && policyKeys.containsAll(resourceKeys)); - - if(keysMatch) { - for(RangerResourceDef resourceDef : serviceDef.getResources()) { - String resourceName = resourceDef.getName(); - RangerPolicyResource resourceValues = resources == null ? null : resources.get(resourceName); - RangerResourceMatcher matcher = matchers == null ? null : matchers.get(resourceName); - - // when no value exists for a resourceName, consider it a match only if: policy doesn't have a matcher OR matcher allows no-value resource - if(resourceValues == null || CollectionUtils.isEmpty(resourceValues.getValues())) { - ret = matcher == null || matcher.isMatch(null); - } else if(matcher != null) { - for(String resourceValue : resourceValues.getValues()) { - ret = matcher.isMatch(resourceValue); - - if(! ret) { - break; - } - } - } - - if(! ret) { - break; - } - } - } else { - if(LOG.isDebugEnabled()) { - LOG.debug("isMatch(): keysMatch=false. resourceKeys=" + resourceKeys + "; policyKeys=" + policyKeys); - } - } + if(resourceMatcher != null) { + ret = resourceMatcher.isMatch(resources); } if(LOG.isDebugEnabled()) { @@ -785,11 +592,9 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator super.toString(sb); - sb.append("matchers={"); - if(matchers != null) { - for(RangerResourceMatcher matcher : matchers.values()) { - sb.append("{").append(matcher).append("} "); - } + sb.append("resourceMatcher={"); + if(resourceMatcher != null) { + resourceMatcher.toString(sb); } sb.append("} "); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/776533f9/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java new file mode 100644 index 0000000..a020b68 --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java @@ -0,0 +1,364 @@ +/* + * 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.policyresourcematcher; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.policyengine.RangerAccessResource; +import org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher; +import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher; + +import com.google.common.collect.Sets; + +public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceMatcher { + private static final Log LOG = LogFactory.getLog(RangerDefaultPolicyResourceMatcher.class); + + protected RangerServiceDef serviceDef = null; + protected Map<String, RangerPolicyResource> policyResources = null; + + private Map<String, RangerResourceMatcher> matchers = null; + + @Override + public void setServiceDef(RangerServiceDef serviceDef) { + this.serviceDef = serviceDef; + } + + @Override + public void setPolicyResources(Map<String, RangerPolicyResource> policyResources) { + this.policyResources = policyResources; + } + + @Override + public void init() { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyResourceMatcher.init()"); + } + + this.matchers = new HashMap<String, RangerResourceMatcher>(); + + if(policyResources != null && serviceDef != null) { + for(RangerResourceDef resourceDef : serviceDef.getResources()) { + String resourceName = resourceDef.getName(); + RangerPolicyResource policyResource = policyResources.get(resourceName); + + if(policyResource != null) { + RangerResourceMatcher matcher = createResourceMatcher(resourceDef, policyResource); + + if(matcher != null) { + matchers.put(resourceName, matcher); + } else { + LOG.error("failed to find matcher for resource " + resourceName); + } + } + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyResourceMatcher.init()"); + } + } + + @Override + public boolean isMatch(RangerAccessResource resource) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyResourceMatcher.isMatch(" + resource + ")"); + } + + boolean ret = false; + + if(serviceDef != null && serviceDef.getResources() != null) { + Collection<String> resourceKeys = resource == null ? null : resource.getKeys(); + Collection<String> policyKeys = matchers == null ? null : matchers.keySet(); + + boolean keysMatch = CollectionUtils.isEmpty(resourceKeys) || (policyKeys != null && policyKeys.containsAll(resourceKeys)); + + if(keysMatch) { + for(RangerResourceDef resourceDef : serviceDef.getResources()) { + String resourceName = resourceDef.getName(); + String resourceValue = resource == null ? null : resource.getValue(resourceName); + RangerResourceMatcher matcher = matchers == null ? null : matchers.get(resourceName); + + // when no value exists for a resourceName, consider it a match only if: policy doesn't have a matcher OR matcher allows no-value resource + if(StringUtils.isEmpty(resourceValue)) { + ret = matcher == null || matcher.isMatch(resourceValue); + } else { + ret = matcher != null && matcher.isMatch(resourceValue); + } + + if(! ret) { + break; + } + } + } else { + if(LOG.isDebugEnabled()) { + LOG.debug("isMatch(): keysMatch=false. isMatch=" + resourceKeys + "; policyKeys=" + policyKeys); + } + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyResourceMatcher.isMatch(" + resource + "): " + ret); + } + + return ret; + } + + + @Override + public boolean isMatch(Map<String, RangerPolicyResource> resources) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyResourceMatcher.isMatch(" + resources + ")"); + } + + boolean ret = false; + + if(serviceDef != null && serviceDef.getResources() != null) { + Collection<String> resourceKeys = resources == null ? null : resources.keySet(); + Collection<String> policyKeys = matchers == null ? null : matchers.keySet(); + + boolean keysMatch = CollectionUtils.isEmpty(resourceKeys) || (policyKeys != null && policyKeys.containsAll(resourceKeys)); + + if(keysMatch) { + for(RangerResourceDef resourceDef : serviceDef.getResources()) { + String resourceName = resourceDef.getName(); + RangerPolicyResource resourceValues = resources == null ? null : resources.get(resourceName); + RangerResourceMatcher matcher = matchers == null ? null : matchers.get(resourceName); + + // when no value exists for a resourceName, consider it a match only if: policy doesn't have a matcher OR matcher allows no-value resource + if(resourceValues == null || CollectionUtils.isEmpty(resourceValues.getValues())) { + ret = matcher == null || matcher.isMatch(null); + } else if(matcher != null) { + for(String resourceValue : resourceValues.getValues()) { + ret = matcher.isMatch(resourceValue); + + if(! ret) { + break; + } + } + } + + if(! ret) { + break; + } + } + } else { + if(LOG.isDebugEnabled()) { + LOG.debug("isMatch(): keysMatch=false. resourceKeys=" + resourceKeys + "; policyKeys=" + policyKeys); + } + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyResourceMatcher.isMatch(" + resources + "): " + ret); + } + + return ret; + } + + @Override + public boolean isSingleAndExactMatch(RangerAccessResource resource) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyResourceMatcher.isSingleAndExactMatch(" + resource + ")"); + } + + boolean ret = false; + + if(serviceDef != null && serviceDef.getResources() != null) { + Collection<String> resourceKeys = resource == null ? null : resource.getKeys(); + Collection<String> policyKeys = matchers == null ? null : matchers.keySet(); + + boolean keysMatch = false; + + if (resourceKeys != null && policyKeys != null) { + keysMatch = CollectionUtils.isEqualCollection(resourceKeys, policyKeys); + } + + if(keysMatch) { + for(RangerResourceDef resourceDef : serviceDef.getResources()) { + String resourceName = resourceDef.getName(); + String resourceValue = resource == null ? null : resource.getValue(resourceName); + RangerResourceMatcher matcher = matchers == null ? null : matchers.get(resourceName); + + if(StringUtils.isEmpty(resourceValue)) { + ret = matcher == null || matcher.isSingleAndExactMatch(resourceValue); + } else { + ret = matcher != null && matcher.isSingleAndExactMatch(resourceValue); + } + + if(! ret) { + break; + } + } + } else { + if(LOG.isDebugEnabled()) { + LOG.debug("isSingleAndExactMatch(): keysMatch=false. resourceKeys=" + resourceKeys + "; policyKeys=" + policyKeys); + } + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyResourceMatcher.isSingleAndExactMatch(" + resource + "): " + ret); + } + + return ret; + } + + @Override + public boolean isHeadMatch(RangerAccessResource resource) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyResourceMatcher.matchResourceHead(" + resource + ")"); + } + boolean ret; + + if (resource == null || CollectionUtils.isEmpty(resource.getKeys())) { // sanity-check, firewalling + LOG.debug("isHeadMatch: resource was null/empty!"); + ret = true; // null resource matches anything + } else if (serviceDef == null) { // sanity-check, firewalling + LOG.debug("isHeadMatch: service-def was null!"); + ret = false; // null policy can never match a non-empty resource + } else if (policyResources == null) { + LOG.debug("isHeadMatch: policyResources were null!"); + ret = false; // null policy can never match a non-empty resource + } else if (matchers == null || matchers.size() != policyResources.size()) { // sanity-check, firewalling + LOG.debug("isHeadMatch: matchers could be found for some of the policy resources"); + ret = false; // empty policy can never match a non-empty resources and can't be evaluated meaningfully in matchers are absent + } else { + if (!Sets.difference(resource.getKeys(), matchers.keySet()).isEmpty()) { // e.g. avoid using udf policy for resource that has more than db specified and vice-versa + LOG.debug("isHeadMatch: resource/policy resource-keys mismatch. policy is incompatible with resource; can't match."); + ret = false; + } else { + Set<String> policyResourceNames = matchers.keySet(); + boolean skipped = false; + boolean matched = true; + Iterator<RangerResourceDef> iterator = serviceDef.getResources().iterator(); + while (iterator.hasNext() && matched) { + RangerResourceDef resourceDef = iterator.next(); + String resourceName = resourceDef.getName(); + // we only work with resources that are relevant to this policy + if (policyResourceNames.contains(resourceName)) { + String resourceValue = resource.getValue(resourceName); + if (StringUtils.isEmpty(resourceValue)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Skipping matching for " + resourceName + " since it is null/empty on resource"); + } + skipped = true; // once we skip a level all lower levels must be skippable, too + } else if (skipped == true) { + LOG.debug("isHeadMatch: found a lower level resource when a higer level resource was absent!"); + matched = false; + } else if (!matchers.get(resourceName).isMatch(resourceValue)) { + if (LOG.isDebugEnabled()) { + LOG.debug("isHeadMatch: matcher for " + resourceName + " failed"); + } + matched = false; + } + } + } + ret = matched; + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyResourceMatcher.matchResourceHead(" + resource + "): " + ret); + } + + return ret; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + @Override + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerDefaultPolicyResourceMatcher={"); + + sb.append("matchers={"); + if(matchers != null) { + for(RangerResourceMatcher matcher : matchers.values()) { + sb.append("{").append(matcher).append("} "); + } + } + sb.append("} "); + + sb.append("}"); + + return sb; + } + + protected static RangerResourceMatcher createResourceMatcher(RangerResourceDef resourceDef, RangerPolicyResource resource) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyResourceMatcher.createResourceMatcher(" + resourceDef + ", " + resource + ")"); + } + + RangerResourceMatcher ret = null; + + if (resourceDef != null) { + String resName = resourceDef.getName(); + String clsName = resourceDef.getMatcher(); + + if (!StringUtils.isEmpty(clsName)) { + try { + @SuppressWarnings("unchecked") + Class<RangerResourceMatcher> matcherClass = (Class<RangerResourceMatcher>) Class.forName(clsName); + + ret = matcherClass.newInstance(); + } catch (Exception excp) { + LOG.error("failed to instantiate resource matcher '" + clsName + "' for '" + resName + "'. Default resource matcher will be used", excp); + } + } + + + if (ret == null) { + ret = new RangerDefaultResourceMatcher(); + } + + if (ret != null) { + ret.setResourceDef(resourceDef); + ret.setPolicyResource(resource); + ret.init(); + } + } else { + LOG.error("RangerDefaultPolicyResourceMatcher: RangerResourceDef is null"); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyResourceMatcher.createResourceMatcher(" + resourceDef + ", " + resource + "): " + ret); + } + + return ret; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/776533f9/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java new file mode 100644 index 0000000..4a613a2 --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java @@ -0,0 +1,44 @@ +/* + * 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.policyresourcematcher; + +import java.util.Map; + +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.policyengine.RangerAccessResource; + +public interface RangerPolicyResourceMatcher { + void setServiceDef(RangerServiceDef serviceDef); + + void setPolicyResources(Map<String, RangerPolicyResource> policyResources); + + void init(); + + boolean isMatch(RangerAccessResource resource); + + boolean isMatch(Map<String, RangerPolicyResource> resources); + + boolean isSingleAndExactMatch(RangerAccessResource resource); + + boolean isHeadMatch(RangerAccessResource resource); + + StringBuilder toString(StringBuilder sb); +}
