Repository: incubator-ranger Updated Branches: refs/heads/tag-policy 327ecb3c5 -> 858156ee2
RANGER-274: Incorporated review comment. Tested with hive. Beefed up the test harness. Incorporated comments from review. Fixed tests for expiry date. Signed-off-by: Madhan Neethiraj <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/858156ee Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/858156ee Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/858156ee Branch: refs/heads/tag-policy Commit: 858156ee225152e42baa14e7a20d9e3c952b480b Parents: 327ecb3 Author: Abhay Kulkarni <[email protected]> Authored: Tue Jun 9 08:38:03 2015 -0700 Committer: Madhan Neethiraj <[email protected]> Committed: Tue Jun 16 19:07:44 2015 -0700 ---------------------------------------------------------------------- .../RangerScriptExecutionContext.java | 60 +++++ .../contextenricher/RangerTagProvider.java | 32 ++- .../ranger/plugin/model/RangerResource.java | 70 +++++ .../policyengine/RangerPolicyEngineImpl.java | 3 +- .../RangerDefaultPolicyEvaluator.java | 4 +- .../RangerDefaultPolicyResourceMatcher.java | 250 +++++++++++++---- .../RangerPolicyResourceMatcher.java | 2 + .../RangerDefaultResourceMatcher.java | 14 + .../plugin/policyengine/TestPolicyEngine.java | 65 ++++- .../policyengine/test_policyengine_hdfs.json | 123 --------- .../test_policyengine_tag_hdfs.json | 146 ++++++++++ .../test_policyengine_tag_hive.json | 269 +++++++++++++++++++ 12 files changed, 847 insertions(+), 191 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptExecutionContext.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptExecutionContext.java b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptExecutionContext.java index ff9387b..815b4cc 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptExecutionContext.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptExecutionContext.java @@ -226,6 +226,66 @@ public final class RangerScriptExecutionContext { } + public final boolean isAccessedAfter(String tagName, String attributeName) { + + boolean ret = false; + + Date accessDate = getAccessTime(); + + Date expiryDate = getTagAttributeAsDate(tagName, attributeName); + + if (expiryDate == null || accessDate.after(expiryDate) || accessDate.equals(expiryDate)) { + ret = true; + } + + return ret; + } + + public final boolean isAccessedAfter(String attributeName) { + + boolean ret = false; + + Date accessDate = getAccessTime(); + + Date expiryDate = getAsDate(getAttributeValue(attributeName)); + + if (expiryDate == null || accessDate.after(expiryDate) || accessDate.equals(expiryDate)) { + ret = true; + } + + return ret; + } + + public final boolean isAccessedBefore(String tagName, String attributeName) { + + boolean ret = true; + + Date accessDate = getAccessTime(); + + Date expiryDate = getTagAttributeAsDate(tagName, attributeName); + + if (expiryDate == null || accessDate.after(expiryDate)) { + ret = false; + } + + return ret; + } + + public final boolean isAccessedBefore(String attributeName) { + + boolean ret = true; + + Date accessDate = getAccessTime(); + + Date expiryDate = getAsDate(getAttributeValue(attributeName)); + + if (expiryDate == null || accessDate.after(expiryDate)) { + ret = false; + } + + return ret; + } + private List<RangerResource.RangerResourceTag> getAllTags() { @SuppressWarnings("unchecked") http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagProvider.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagProvider.java b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagProvider.java index 9d2b60b..61c8907 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagProvider.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagProvider.java @@ -22,6 +22,7 @@ package org.apache.ranger.plugin.contextenricher; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.ranger.plugin.model.RangerPolicy; import org.apache.ranger.plugin.model.RangerResource; import org.apache.ranger.plugin.policyengine.RangerAccessRequest; import org.apache.ranger.plugin.policyengine.RangerAccessResource; @@ -31,6 +32,7 @@ import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatche import java.util.ArrayList; import java.util.List; +import java.util.Map; public class RangerTagProvider extends RangerAbstractContextEnricher implements RangerTagReceiver { private static final Log LOG = LogFactory.getLog(RangerTagProvider.class); @@ -93,6 +95,13 @@ public class RangerTagProvider extends RangerAbstractContextEnricher implements if (CollectionUtils.isNotEmpty(matchedTags)) { request.getContext().put(RangerPolicyEngine.KEY_CONTEXT_TAGS, matchedTags); + if (LOG.isDebugEnabled()) { + LOG.debug("RangerTagProvider.enrich(" + request + ") - " + matchedTags.size() + " tags found by enricher."); + } + } else { + if (LOG.isDebugEnabled()) { + LOG.debug("RangerTagProvider.enrich(" + request + ") - no tags found by enricher."); + } } if (LOG.isDebugEnabled()) { @@ -109,10 +118,15 @@ public class RangerTagProvider extends RangerAbstractContextEnricher implements for (RangerResource taggedResource : resources) { RangerDefaultPolicyResourceMatcher matcher = new RangerDefaultPolicyResourceMatcher(); + matcher.setServiceDef(this.serviceDef); + matcher.setPolicyResources(taggedResource.getResourceSpec()); + if (LOG.isDebugEnabled()) { + LOG.debug("RangerTagProvider.setRangerResources() - Initializing matcher with (resource=" + taggedResource + + ", serviceDef=" + this.serviceDef.getName() + ")" ); - matcher.setPolicyResources(taggedResource.getResourceSpec()); + } matcher.init(); RangerTaggedResourceMatcher taggedResourceMatcher = new RangerTaggedResourceMatcher(taggedResource, matcher); @@ -121,9 +135,7 @@ public class RangerTagProvider extends RangerAbstractContextEnricher implements } } - if (CollectionUtils.isNotEmpty(resourceMatchers)) { - taggedResourceMatchers = resourceMatchers; - } + taggedResourceMatchers = resourceMatchers; if (tagRefresher != null && !tagRefresher.getIsStarted()) { tagRefresher.startRetriever(); @@ -144,9 +156,9 @@ public class RangerTagProvider extends RangerAbstractContextEnricher implements RangerResource taggedResource = resourceMatcher.getRangerResource(); RangerPolicyResourceMatcher matcher = resourceMatcher.getPolicyResourceMatcher(); - boolean isMatched = matcher.isMatch(resource); + boolean matchResult = matcher.isExactHeadMatch(resource); - if (isMatched) { + if (matchResult) { if (ret == null) { ret = new ArrayList<RangerResource.RangerResourceTag>(); } @@ -156,6 +168,14 @@ public class RangerTagProvider extends RangerAbstractContextEnricher implements } if (LOG.isDebugEnabled()) { + if (CollectionUtils.isEmpty(ret)) { + LOG.debug("RangerTagProvider.findMatchingTags(" + resource + ") - No tags Found "); + } else { + LOG.debug("RangerTagProvider.findMatchingTags(" + resource + ") - " + ret.size() + " tags Found "); + } + } + + if (LOG.isDebugEnabled()) { LOG.debug("<== RangerTagProvider.findMatchingTags(" + resource + ")"); } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerResource.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerResource.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerResource.java index 49d4739..39cca85 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerResource.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerResource.java @@ -96,6 +96,46 @@ public class RangerResource extends RangerBaseModelObject { this.tags = tags == null ? new ArrayList<RangerResourceTag>() : tags; } + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + + sb.append("{ "); + + sb.append("componentType={").append(componentType).append("} "); + sb.append("tagServiceName={").append(tagServiceName).append("} "); + + sb.append("RangerResource={"); + if(resourceSpec != null) { + for(Map.Entry<String, RangerPolicy.RangerPolicyResource> e : resourceSpec.entrySet()) { + sb.append(e.getKey()).append("={"); + e.getValue().toString(sb); + sb.append("} "); + } + } + sb.append("} "); + + sb.append("Tags={"); + if (tags != null) { + for (RangerResourceTag tag : tags) { + sb.append("{"); + tag.toString(sb); + sb.append("} "); + } + } + sb.append("} "); + + sb.append(" }"); + + return sb; + } /** * Represents a tag and its attribute-values for a resource. */ @@ -130,5 +170,35 @@ public class RangerResource extends RangerBaseModelObject { return attributeValues; } public void setAttributeValues(Map<String, String> attributeValues) { this.attributeValues = attributeValues; } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + + sb.append("{ "); + + sb.append("name={").append(name).append("} "); + + sb.append("attributeValues={"); + if(attributeValues != null) { + for(Map.Entry<String, String> e : attributeValues.entrySet()) { + sb.append(e.getKey()).append("={"); + sb.append(e.getValue()); + sb.append("} "); + } + } + sb.append("} "); + + sb.append(" }"); + + return sb; + } } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java index 16cad9b..389c264 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java @@ -398,8 +398,7 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine { evaluator.evaluate(tagEvalRequest, tagEvalResult); - if (evaluator.isFinal() || - (tagEvalResult.getIsAccessDetermined() && tagEvalResult.getIsAuditedDetermined())) { + if (tagEvalResult.getIsAccessDetermined() && tagEvalResult.getIsAuditedDetermined()) { if (LOG.isDebugEnabled()) { LOG.debug("RangerPolicyEngineImpl.isAccessAllowedForTagPolicies: concluding eval of tag (" + resourceTag.getName() + ") with authorization=" + tagEvalResult.getIsAllowed()); } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/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 56d15ee..dec8a37 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 @@ -153,7 +153,9 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator evaluatePolicyItemsForAccess(request, result); } } - if ((matchResult || headMatchResult) && !result.getIsAccessDetermined() && isFinalPolicy) { + if (isFinalPolicy + && !result.getIsAccessDetermined() + && (matchResult || headMatchResult)) { result.setIsAllowed(false); result.setPolicyId(getPolicy().getId()); } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/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 index a020b68..572a11b 100644 --- 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 @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; +import java.util.List; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; @@ -32,6 +33,7 @@ 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.model.validation.RangerServiceDefHelper; import org.apache.ranger.plugin.policyengine.RangerAccessResource; import org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher; import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher; @@ -45,6 +47,7 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM protected Map<String, RangerPolicyResource> policyResources = null; private Map<String, RangerResourceMatcher> matchers = null; + private List<RangerResourceDef> firstValidResourceDefHierarchy; @Override public void setServiceDef(RangerServiceDef serviceDef) { @@ -62,23 +65,103 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM LOG.debug("==> RangerDefaultPolicyResourceMatcher.init()"); } - this.matchers = new HashMap<String, RangerResourceMatcher>(); + String errorText = ""; - if(policyResources != null && serviceDef != null) { - for(RangerResourceDef resourceDef : serviceDef.getResources()) { - String resourceName = resourceDef.getName(); - RangerPolicyResource policyResource = policyResources.get(resourceName); + if(policyResources != null && policyResources.size() > 0 && serviceDef != null) { - if(policyResource != null) { - RangerResourceMatcher matcher = createResourceMatcher(resourceDef, policyResource); + Set<String> policyResourceKeySet = policyResources.keySet(); - if(matcher != null) { - matchers.put(resourceName, matcher); - } else { - LOG.error("failed to find matcher for resource " + resourceName); + RangerServiceDefHelper serviceDefHelper = new RangerServiceDefHelper(serviceDef, false); + Set<List<RangerResourceDef>> validResourceHierarchies = serviceDefHelper.getResourceHierarchies(); + + for (List<RangerResourceDef> validResourceHierarchy : validResourceHierarchies) { + + Set<String> resourceDefNameSet = serviceDefHelper.getAllResourceNames(validResourceHierarchy); + + if ((Sets.difference(policyResourceKeySet, resourceDefNameSet)).isEmpty()) { + + firstValidResourceDefHierarchy = validResourceHierarchy; + break; + + } + + } + + if (firstValidResourceDefHierarchy != null) { + List<String> resourceDefNameOrderedList = serviceDefHelper.getAllResourceNamesOrdered(firstValidResourceDefHierarchy); + + boolean foundGapsInResourceSpecs = false; + boolean skipped = false; + + for (String resourceDefName : resourceDefNameOrderedList) { + RangerPolicyResource policyResource = policyResources.get(resourceDefName); + if (policyResource == null) { + skipped = true; + } else if (skipped) { + foundGapsInResourceSpecs = true; + break; } } + + if (foundGapsInResourceSpecs) { + + errorText = "policyResources does not specify contiguous sequence in any valid resourcedef hiearchy."; + if (LOG.isDebugEnabled()) { + LOG.debug("RangerDefaultPolicyResourceMatcher.init() failed: Gaps found in policyResources, internal error, skipping.."); + } + firstValidResourceDefHierarchy = null; + + } else { + + matchers = new HashMap<String, RangerResourceMatcher>(); + + for (RangerResourceDef resourceDef : firstValidResourceDefHierarchy) { + + 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); + } + } else { + if (LOG.isDebugEnabled()) { + LOG.debug("RangerDefaultPolicyResourceMatcher.init() - no matcher created for " + resourceName + ". Continuing ..."); + } + } + } + } + } else { + errorText = "policyResources elements are not part of any valid resourcedef hierarchy."; } + } else { + errorText = " policyResources is null or empty, or serviceDef is null."; + } + + if(matchers == null) { + Set<String> policyResourceKeys = policyResources == null ? null : policyResources.keySet(); + String keysString = ""; + if (CollectionUtils.isNotEmpty(policyResourceKeys)) { + for (String policyResourceKeyName : policyResourceKeys) { + keysString += " " + policyResourceKeyName + " "; + } + } + String serviceDefName = serviceDef == null ? "" : serviceDef.getName(); + String validHierarchy = ""; + if (CollectionUtils.isNotEmpty(firstValidResourceDefHierarchy)) { + RangerServiceDefHelper serviceDefHelper = new RangerServiceDefHelper(serviceDef, false); + List<String> resourceDefNameOrderedList = serviceDefHelper.getAllResourceNamesOrdered(firstValidResourceDefHierarchy); + + for (String resourceDefName : resourceDefNameOrderedList) { + validHierarchy += " " + resourceDefName + " "; + } + } + LOG.warn("RangerDefaultPolicyResourceMatcher.init() failed: " + errorText + " (serviceDef=" + serviceDefName + ", policyResourceKeys=" + keysString + + ", validHierarchy=" + validHierarchy + ")"); } if(LOG.isDebugEnabled()) { @@ -233,56 +316,27 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM @Override public boolean isHeadMatch(RangerAccessResource resource) { + if(LOG.isDebugEnabled()) { - LOG.debug("==> RangerDefaultPolicyResourceMatcher.matchResourceHead(" + resource + ")"); + LOG.debug("==> RangerDefaultPolicyResourceMatcher.isHeadMatch(" + resource + ")"); } - boolean ret; + + boolean ret = false; - if (resource == null || CollectionUtils.isEmpty(resource.getKeys())) { // sanity-check, firewalling - LOG.debug("isHeadMatch: resource was null/empty!"); + if (matchers == null) { + + LOG.debug("RangerDefaultPolicyResourceMatcher.isHeadMatch(): PolicyResourceMatcher not initialized correctly!!!"); + ret = false; + + } else if (resource == null || CollectionUtils.isEmpty(resource.getKeys())) { // sanity-check, firewalling + + LOG.debug("RangerDefaultPolicyResourceMatcher.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; - } + + ret = newIsHeadMatch(resource); + } if(LOG.isDebugEnabled()) { @@ -293,6 +347,90 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM } @Override + public boolean isExactHeadMatch(RangerAccessResource resource) { + + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyResourceMatcher.isExactHeadMatch(" + resource + ")"); + } + + boolean ret = false; + + if (matchers == null) { + + LOG.debug("RangerDefaultPolicyResourceMatcher.isExactHeadMatch(): PolicyResourceMatcher not initialized correctly!!!"); + ret = false; + + } else if (resource == null || CollectionUtils.isEmpty(resource.getKeys())) { // sanity-check, firewalling + + LOG.debug("RangerDefaultPolicyResourceMatcher.isExactHeadMatch: resource was null/empty!"); + ret = false; + + } else if (matchers.size() > resource.getKeys().size()) { + + LOG.debug("RangerDefaultPolicyResourceMatcher.isExactHeadMatch: more levels specified in PolicyResourceMatcher than in resource being matched!!"); + ret = false; + + } else { + + ret = newIsHeadMatch(resource); + + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyResourceMatcher.isExactHeadMatch(" + resource + ")" + ret); + } + + return ret; + } + + private boolean newIsHeadMatch(RangerAccessResource resource) { + + if (LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyResourceMatcher.newIsHeadMatch(" + resource + ")"); + } + + boolean skipped = false; + boolean matched = true; + + for (RangerResourceDef resourceDef : firstValidResourceDefHierarchy) { + + String resourceName = resourceDef.getName(); + String resourceValue = resource.getValue(resourceName); + RangerResourceMatcher matcher = matchers.get(resourceName); + + if (matcher != null) { + + if (StringUtils.isNotBlank(resourceValue)) { + + if (!skipped) { + + matched = matcher.isMatch(resourceValue); + + } else { + + matched = false; + + } + } else { + + skipped = true; + + } + } + + if (!matched) { + break; + } + } + + if (LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyResourceMatcher.newIsHeadMatch(" + resource + "): " + matched); + } + + return matched; + } + + @Override public String toString() { StringBuilder sb = new StringBuilder(); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/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 index 4a613a2..d23178b 100644 --- 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 @@ -40,5 +40,7 @@ public interface RangerPolicyResourceMatcher { boolean isHeadMatch(RangerAccessResource resource); + boolean isExactHeadMatch(RangerAccessResource resource); + StringBuilder toString(StringBuilder sb); } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java index 79c3885..154da04 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java @@ -60,6 +60,20 @@ public class RangerDefaultResourceMatcher extends RangerAbstractResourceMatcher ret = !ret; } + if (ret == false) { + if(LOG.isDebugEnabled()) { + StringBuilder sb = new StringBuilder(); + sb.append("["); + for (String policyValue: policyValues) { + sb.append(policyValue); + sb.append(" "); + } + sb.append("]"); + + LOG.debug("RangerDefaultResourceMatcher.isMatch returns FALSE, (resource=" + resource + ", policyValues=" + sb.toString() + ")"); + } + } + if(LOG.isDebugEnabled()) { LOG.debug("<== RangerDefaultResourceMatcher.isMatch(" + resource + "): " + ret); } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java ---------------------------------------------------------------------- diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java index 21d8681..86357d7 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java @@ -20,7 +20,10 @@ package org.apache.ranger.plugin.policyengine; import com.google.gson.*; +import com.google.gson.reflect.TypeToken; +import org.apache.commons.lang.StringUtils; import org.apache.ranger.plugin.model.RangerPolicy; +import org.apache.ranger.plugin.model.RangerResource; import org.apache.ranger.plugin.model.RangerServiceDef; import org.apache.ranger.plugin.policyengine.TestPolicyEngine.PolicyEngineTestCase.TestData; import org.apache.ranger.plugin.util.ServicePolicies; @@ -32,6 +35,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Type; import java.util.List; +import java.util.Map; import static org.junit.Assert.*; @@ -62,6 +66,13 @@ public class TestPolicyEngine { } @Test + public void testPolicyEngine_hdfsForTag() { + String[] hdfsTestResourceFiles = { "/policyengine/test_policyengine_tag_hdfs.json" }; + + runTestsFromResourceFiles(hdfsTestResourceFiles); + } + + @Test public void testPolicyEngine_hive() { String[] hiveTestResourceFiles = { "/policyengine/test_policyengine_hive.json" }; @@ -69,6 +80,13 @@ public class TestPolicyEngine { } @Test + public void testPolicyEngine_hiveForTag() { + String[] hiveTestResourceFiles = { "/policyengine/test_policyengine_tag_hive.json" }; + + runTestsFromResourceFiles(hiveTestResourceFiles); + } + + @Test public void testPolicyEngine_hbase() { String[] hbaseTestResourceFiles = { "/policyengine/test_policyengine_hbase.json" }; @@ -115,15 +133,56 @@ public class TestPolicyEngine { RangerPolicyEngineOptions policyEngineOptions = new RangerPolicyEngineOptions(); // Uncomment next line for testing tag-policy evaluation - // policyEngineOptions.disableTagPolicyEvaluation = false; + policyEngineOptions.disableTagPolicyEvaluation = false; policyEngine = new RangerPolicyEngineImpl(servicePolicies, policyEngineOptions); + RangerAccessRequest request = null; + for(TestData test : testCase.tests) { - policyEngine.preProcess(test.request); + if (test.request.getContext().containsKey(RangerPolicyEngine.KEY_CONTEXT_TAGS)) { + // Create a new AccessRequest + RangerAccessRequestImpl newRequest = + new RangerAccessRequestImpl(test.request.getResource(), test.request.getAccessType(), + test.request.getUser(), test.request.getUserGroups()); + + newRequest.setClientType(test.request.getClientType()); + newRequest.setAccessTime(test.request.getAccessTime()); + newRequest.setAction(test.request.getAction()); + newRequest.setClientIPAddress(test.request.getClientIPAddress()); + newRequest.setRequestData(test.request.getRequestData()); + newRequest.setSessionId(test.request.getSessionId()); + + Map<String, Object> context = test.request.getContext(); + String tagsJsonString = (String) context.get(RangerPolicyEngine.KEY_CONTEXT_TAGS); + context.remove(RangerPolicyEngine.KEY_CONTEXT_TAGS); + + if(!StringUtils.isEmpty(tagsJsonString)) { + try { + Type listType = new TypeToken<List<RangerResource.RangerResourceTag>>() { + }.getType(); + List<RangerResource.RangerResourceTag> tagList = gsonBuilder.fromJson(tagsJsonString, listType); + + context.put(RangerPolicyEngine.KEY_CONTEXT_TAGS, tagList); + } catch (Exception e) { + System.err.println("TestPolicyEngine.runTests(): error parsing TAGS JSON string in file " + testName + ", tagsJsonString=" + + tagsJsonString + ", exception=" + e); + } + } + + + newRequest.setContext(context); + + request = newRequest; + + } + else { + request = test.request; + } + policyEngine.preProcess(request); RangerAccessResult expected = test.result; - RangerAccessResult result = policyEngine.isAccessAllowed(test.request, null); + RangerAccessResult result = policyEngine.isAccessAllowed(request, null); assertNotNull("result was null! - " + test.name, result); assertEquals("isAllowed mismatched! - " + test.name, expected.getIsAllowed(), result.getIsAllowed()); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/test/resources/policyengine/test_policyengine_hdfs.json ---------------------------------------------------------------------- diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_hdfs.json b/agents-common/src/test/resources/policyengine/test_policyengine_hdfs.json index 3c38919..eed71be 100644 --- a/agents-common/src/test/resources/policyengine/test_policyengine_hdfs.json +++ b/agents-common/src/test/resources/policyengine/test_policyengine_hdfs.json @@ -36,130 +36,7 @@ ] } ], - "tagPolicyInfo": { - "serviceName":"tagdev", - "serviceDef": { - "name": "_tag_", - "id": 101, - "resources": [ - { - "itemId": 1, - "name": "tag", - "type": "string", - "level": 1, - "parent": "", - "mandatory": true, - "lookupSupported": true, - "recursiveSupported": false, - "excludesSupported": false, - "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", - "matcherOptions": { - "wildCard": true, - "ignoreCase": false - }, - "validationRegEx": "", - "validationMessage": "", - "uiHint": "", - "label": "TAG", - "description": "TAG" - } - ], - "accessTypes": [ - { - "itemId": 1, - "name": "hdfs:read", - "label": "hdfs:Read" - }, - { - "itemId": 2, - "name": "hdfs:write", - "label": "hdfs:Write" - }, - { - "itemId": 3, - "name": "hdfs:execute", - "label": "hdfs:Execute" - } - , - { - "itemId": 4, - "name": "hive:grant", - "label": "hive:grant" - } - , - { - "itemId": 5, - "name": "kms:dek", - "label": "kms:dek" - } - , - { - "itemId": 6, - "name": "delete", - "label": "delete" - } - ], - "contextEnrichers": [ - { - "itemId": 1, - "name" : "TagEnricher", - "enricher" : "org.apache.ranger.plugin.contextenricher.RangerTagProvider", - "enricherOptions" : {"TagProviderType":"FILESTORE_BASED_TAG_PROVIDER", "pollingInterval":30000, "dataFile":"/etc/ranger/data/resourceTags.txt"} - } - ], - "policyConditions": [ - { - "itemId":1, - "name":"ScriptConditionEvaluator", - "evaluator": "org.apache.ranger.plugin.conditionevaluator.RangerScriptConditionEvaluator", - "evaluatorOptions" : {"engineName":"JavaScript"}, - "label":"Script", - "description": "Script to execute" - } - ] - }, - "tagPolicies":[ - {"id":5,"name":"allow somethingelse tag","isEnabled":true,"isAuditEnabled":true,"policyType":0, - "resources":{"tag":{"values":["pii"],"isRecursive":false}}, - "policyItems":[ - {"accesses":[{"type":"hdfs:read", "isAllowed":true}, {"type":"hive:grant", "isAllowed":true}, {"type":"delete", "isAllowed":true}, {"type":":write", "isAllowed":true}],"users":["user1"],"groups":["finance"],"delegateAdmin":false, - "conditions" : [{"type":"ScriptConditionEvaluator", "values": [ - "importPackage(java.util); var accessDate = ctx.getAsDate(ctx.accessTime); var expiryDate =ctx.getTagAttributeAsDate('pii','expiry'); expiryDate.getTime() < accessDate.getTime();" - , - "importPackage(java.util); var accessTime = ctx.accessTime; print('accessTime=' + accessTime); var accessDate = ctx.getAsDate(accessTime); println('accessDate=' + accessDate); var currentDate = new Date(); println('currentDate=' + currentDate); println('current=' +currentDate.getTime()); println('access='+ accessDate.getTime()); result = true;" - , - "importPackage(java.util); var accessTime = ctx.accessTime; var currentTime = Date(); print('accessTime=' + accessTime); println('currentTime=' + currentTime); accessTime.after(currentTime)" - , - "var ownerUser = request.resource.getOwnerUser(); println('ownerUser=' + ownerUser); result = true;" - , - "var ownerUser = request.resource.ownerUser; println('ownerUser=' + ownerUser); result = true;" - , - "var tagName = ctx.currentTagName; println('tagName=' + tagName); ctx.result = true;" - , - "var resource = ctx.get('RESOURCE').getAsMap(); println('resource path=' + resource.get('path')); result = true;" - - ] - }] - } - ] - } - , - {"id":4,"name":"allow partial-match tag","isEnabled":true,"isAuditEnabled":true, - "resources":{"tag":{"values":["restr*"],"isRecursive":false}}, - "policyItems":[ - {"accesses":[{"type":"hdfs:write","isAllowed":true}],"users":["user1"],"groups":["finance"],"delegateAdmin":false} - ] - } - , - {"id":3,"name":"restricted tags","isEnabled":true,"isAuditEnabled":true,"policyType":0, - "resources":{"tag":{"values":["res*"],"isRecursive":false}}, - "policyItems":[ - {"accesses":[{"type":"hdfs:write","isAllowed":true}],"users":["user1"],"groups":["finance"],"delegateAdmin":false} - ] - } - ] - }, "tests":[ {"name":"ALLOW 'read /finance/restricted/sales.db' for g=finance", "request":{ http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/test/resources/policyengine/test_policyengine_tag_hdfs.json ---------------------------------------------------------------------- diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hdfs.json b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hdfs.json new file mode 100644 index 0000000..55ae78c --- /dev/null +++ b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hdfs.json @@ -0,0 +1,146 @@ +{ + "serviceName":"hdfsdev", + + "serviceDef":{ + "name":"hdfs", + "id":1, + "resources":[ + {"name":"path","type":"path","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Resource Path","description":"HDFS file or directory path"} + ], + "accessTypes":[ + {"name":"read","label":"Read"}, + {"name":"write","label":"Write"}, + {"name":"execute","label":"Execute"} + ] + }, + + "policies":[ + {"id":1,"name":"audit-all-access under /finance/restricted/","isEnabled":true,"isAuditEnabled":true, + "resources":{"path":{"values":["/finance/restricted/"],"isRecursive":true}}, + "policyItems":[ + {"accesses":[],"users":[],"groups":["public"],"delegateAdmin":false} + ] + } + , + {"id":2,"name":"allow-read-to-all under /public/","isEnabled":true,"isAuditEnabled":false, + "resources":{"path":{"values":["/public/*"],"isRecursive":true}}, + "policyItems":[ + {"accesses":[{"type":"read","isAllowed":true},{"type":"execute","isAllowed":true}],"users":[],"groups":["public"],"delegateAdmin":false} + ] + } + , + {"id":3,"name":"allow-read-to-finance under /finance/restricted","isEnabled":true,"isAuditEnabled":true, + "resources":{"path":{"values":["/finance/restricted"],"isRecursive":true}}, + "policyItems":[ + {"accesses":[{"type":"read","isAllowed":true}],"users":[],"groups":["finance"],"delegateAdmin":false} + ] + } + ], + "tagPolicyInfo": { + + "serviceName":"tagdev", + "serviceDef": { + "name": "_tag_", + "id": 100, + "resources": [ + { + "itemId": 1, + "name": "tag", + "type": "string", + "level": 1, + "parent": "", + "mandatory": true, + "lookupSupported": true, + "recursiveSupported": false, + "excludesSupported": false, + "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", + "matcherOptions": { + "wildCard": true, + "ignoreCase": false + }, + "validationRegEx": "", + "validationMessage": "", + "uiHint": "", + "label": "TAG", + "description": "TAG" + } + ], + "accessTypes": [ + { + "itemId": 1, + "name": "hdfs:read", + "label": "hdfs:Read" + }, + { + "itemId": 2, + "name": "hdfs:write", + "label": "hdfs:Write" + }, + { + "itemId": 3, + "name": "hdfs:execute", + "label": "hdfs:Execute" + } + , + { + "itemId": 4, + "name": "hive:grant", + "label": "hive:grant" + } + , + { + "itemId": 5, + "name": "kms:dek", + "label": "kms:dek" + } + , + { + "itemId": 6, + "name": "delete", + "label": "delete" + } + ], + "contextEnrichers": [ + { + "itemId": 1, + "name" : "TagEnricher", + "enricher" : "org.apache.ranger.plugin.contextenricher.RangerTagProvider", + "enricherOptions" : {"TagProviderType":"FILESTORE_BASED_TAG_PROVIDER", "pollingInterval":-1, "dataFile":"/etc/ranger/data/resourceTags.txt"} + } + ], + "policyConditions": [ + { + "itemId":1, + "name":"ScriptConditionEvaluator", + "evaluator": "org.apache.ranger.plugin.conditionevaluator.RangerScriptConditionEvaluator", + "evaluatorOptions" : {"engineName":"JavaScript"}, + "label":"Script", + "description": "Script to execute" + } + ] + }, + "tagPolicies":[ + {"id":1,"name":"test_policy","isEnabled":true,"isAuditEnabled":true,"policyType":0, + "resources":{"tag":{"values":["PII"],"isRecursive":false}}, + "policyItems":[ + {"accesses":[{"type":"hdfs:read", "isAllowed":true}, {"type":"hive:grant", "isAllowed":true}, {"type":"delete", "isAllowed":true}, {"type":":write", "isAllowed":true}],"users":["user1"],"groups":["finance"],"delegateAdmin":false, + "conditions" : [{"type":"ScriptConditionEvaluator", "values": [ + "importPackage(java.util); var accessDate = ctx.getAsDate(ctx.accessTime); var expiryDate =ctx.getTagAttributeAsDate('pii','expiry'); expiryDate.getTime() < accessDate.getTime();" + ] + }] + } + ] + } + ] + }, + "tests":[ + {"name":"ALLOW 'read /finance/restricted/sales.db' for g=finance", + "request":{ + "resource":{"elements":{"path":"/finance/restricted/sales.db"}}, + "accessType":"read","user":"user1","userGroups":["finance"],"requestData":"read /finance/restricted/sales.db" + }, + "result":{"isAudited":true,"isAllowed":true,"policyId":3} + } + ] +} + http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/858156ee/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json ---------------------------------------------------------------------- diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json new file mode 100644 index 0000000..8821a1c --- /dev/null +++ b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json @@ -0,0 +1,269 @@ +{ + "serviceName":"hivedev", + + "serviceDef":{ + "name":"hive", + "id":3, + "resources":[ + {"name":"database","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive Database","description":"Hive Database"}, + {"name":"table","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive Table","description":"Hive Table"}, + {"name":"udf","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive UDF","description":"Hive UDF"}, + {"name":"column","level":3,"parent":"table","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive Column","description":"Hive Column"} + ], + "accessTypes":[ + {"name":"select","label":"Select"}, + {"name":"update","label":"Update"}, + {"name":"create","label":"Create"}, + {"name":"drop","label":"Drop"}, + {"name":"alter","label":"Alter"}, + {"name":"index","label":"Index"}, + {"name":"lock","label":"Lock"}, + {"name":"all","label":"All", + "impliedGrants": [ + "select", + "update", + "create", + "drop", + "alter", + "index", + "lock" + ] + } + ] + }, + + "policies":[ + {"id":101,"name":"db=*: audit-all-access","isEnabled":true,"isAuditEnabled":true, + "resources":{"database":{"values":["*"]},"table":{"values":["*"]},"column":{"values":["*"]}}, + "policyItems":[ + {"accesses":[{"type":"all","isAllowed":true}],"users":["hive", "user1", "user2"],"groups":["public"],"delegateAdmin":false} + ] + }, + {"id":102,"name":"db=*, udf=*: audit-all-access","isEnabled":true,"isAuditEnabled":true, + "resources":{"database":{"values":["*"]},"udf":{"values":["*"]}}, + "policyItems":[ + {"accesses":[{"type":"all","isAllowed":true}],"users":["hive", "user1", "user2"],"groups":["public"],"delegateAdmin":false} + ] + } + ], + "tagPolicyInfo": { + + "serviceName":"tagdev", + "serviceDef": { + "name": "_tag_", + "id": 100, + "resources": [ + { + "itemId": 1, + "name": "tag", + "type": "string", + "level": 1, + "parent": "", + "mandatory": true, + "lookupSupported": true, + "recursiveSupported": false, + "excludesSupported": false, + "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", + "matcherOptions": { + "wildCard": true, + "ignoreCase": false + }, + "validationRegEx": "", + "validationMessage": "", + "uiHint": "", + "label": "TAG", + "description": "TAG" + } + ], + "accessTypes": [ + { + "itemId": 1, + "name": "hive:select", + "label": "hive:select" + }, + { + "itemId": 2, + "name": "hive:update", + "label": "hive:update" + }, + { + "itemId": 3, + "name": "hive:create", + "label": "hive:create" + } + , + { + "itemId": 4, + "name": "hive:grant", + "label": "hive:grant" + } + , + { + "itemId": 5, + "name": "hive:drop", + "label": "hive:drop" + } + , + { + "itemId": 6, + "name": "hive:alter", + "label": "hive:alter" + }, + { + "itemId": 7, + "name": "hive:index", + "label": "hive:index" + }, + { + "itemId": 8, + "name": "hive:lock", + "label": "hive:lock" + }, + { + "itemId": 9, + "name": "hive:all", + "label": "hive:all" + } + ], + "contextEnrichers": [ + { + "itemId": 1, + "name" : "TagEnricher", + "enricher" : "org.apache.ranger.plugin.contextenricher.RangerTagProvider", + "enricherOptions" : {"TagProviderType":"FILESTORE_BASED_TAG_PROVIDER", "pollingInterval":-1, "dataFile":"/etc/ranger/data/resourceTags.txt"} + } + ], + "policyConditions": [ + { + "itemId":1, + "name":"ScriptConditionEvaluator", + "evaluator": "org.apache.ranger.plugin.conditionevaluator.RangerScriptConditionEvaluator", + "evaluatorOptions" : {"engineName":"JavaScript"}, + "label":"Script", + "description": "Script to execute" + } + ] + }, + "tagPolicies":[ + {"id":1,"name":"RESTRICTED_TAG_POLICY","isEnabled":true,"isAuditEnabled":true,"policyType":0, + "resources":{"tag":{"values":["RESTRICTED"],"isRecursive":false}}, + "policyItems":[ + { + "accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive", "user1"],"groups":[],"delegateAdmin":false, + "conditions":[{ + "type":"ScriptConditionEvaluator", + "values":["if ( ctx.isAccessedBefore('expiry') ) ctx.result = true;"] + }] + } + ] + }, + {"id":2,"name":"PII_TAG_POLICY","isEnabled":true,"isAuditEnabled":true,"policyType":0, + "resources":{"tag":{"values":["PII"],"isRecursive":false}}, + "policyItems":[ + {"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive"],"groups":[],"delegateAdmin":false} + ] + }, + {"id":3,"name":"PII_TAG_POLICY-FINAL","isEnabled":true,"isAuditEnabled":true,"policyType":1, + "resources":{"tag":{"values":["PII-FINAL"],"isRecursive":false}}, + "policyItems":[ + {"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive"],"groups":[],"delegateAdmin":false} + ] + }, + {"id":4,"name":"RESTRICTED_TAG_POLICY_FINAL","isEnabled":true,"isAuditEnabled":true,"policyType":1, + "resources":{"tag":{"values":["RESTRICTED-FINAL"],"isRecursive":false}}, + "policyItems":[ + { + "accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive", "user1"],"groups":[],"delegateAdmin":false, + "conditions":[{ + "type":"ScriptConditionEvaluator", + "values":["if ( ctx.isAccessedBefore('expiry') ) ctx.result = true;"] + }] + } + ] + } + ] + }, + + "tests":[ + {"name":"ALLOW 'select ssn from employee.personal;' for user1", + "request":{ + "resource":{"elements":{"database":"employee", "table":"personal", "column":"ssn"}}, + "accessType":"select","user":"user1","userGroups":[],"requestData":"select ssn from employee.personal;' for user1", + "context": {"TAGS":"[{\"name\":\"RESTRICTED\", \"attributeValues\":{\"expiry\":\"Mon Jun 15 13:00:00 PDT 2026\"}}]"} + }, + "result":{"isAudited":true,"isAllowed":true,"policyId":1} + }, + {"name":"DENY 'select ssn from employee.personal;' for user2", + "request":{ + "resource":{"elements":{"database":"employee", "table":"personal", "column":"ssn"}}, + "accessType":"select","user":"user2","userGroups":[],"requestData":"select ssn from employee.personal;' for user2", + "context": {"TAGS":"[{\"name\":\"RESTRICTED-FINAL\", \"attributeValues\":{\"expiry\":\"Mon Jun 15 13:00:00 PDT 2026\"}}]"} + }, + "result":{"isAudited":true,"isAllowed":false,"policyId":4} + }, + {"name":"ALLOW 'select name from employee.personal;' for user1 - no tag", + "request":{ + "resource":{"elements":{"database":"employee", "table":"personal", "column":"name"}}, + "accessType":"select","user":"user1","userGroups":[],"requestData":"select name from employee.personal;' for user1" + }, + "result":{"isAudited":true,"isAllowed":true,"policyId":101} + }, + {"name":"ALLOW 'select name from employee.personal;' for user2 - no tag", + "request":{ + "resource":{"elements":{"database":"employee", "table":"personal", "column":"name"}}, + "accessType":"select","user":"user2","userGroups":[],"requestData":"select name from employee.personal;' for user2" + }, + "result":{"isAudited":true,"isAllowed":true,"policyId":101} + }, + {"name":"ALLOW 'select name from default.table1;' for hive", + "request":{ + "resource":{"elements":{"database":"default", "table":"table1", "column":"name"}}, + "accessType":"select","user":"hive","userGroups":[],"requestData":"select name from default.table1;' for hive", + "context": {"TAGS":"[{\"name\":\"PII\", \"attributeValues\":{\"expiry\":\"Mon Jun 15 13:00:00 PDT 2026\"}}]"} + }, + "result":{"isAudited":true,"isAllowed":true,"policyId":2} + }, + {"name":"ALLOW 'desc default.table1;' for hive", + "request":{ + "resource":{"elements":{"database":"default", "table":"table1"}}, + "accessType":"","user":"hive","userGroups":[],"requestData":"desc default.table1;' for hive", + "context": {"TAGS":"[{\"name\":\"PII\", \"attributeValues\":{\"expiry\":\"Mon Jun 15 13:00:00 PDT 2026\"}}]"} + }, + "result":{"isAudited":true,"isAllowed":true,"policyId":2} + }, + {"name":"DENY 'desc default.table1;' for user1", + "request":{ + "resource":{"elements":{"database":"default", "table":"table1"}}, + "accessType":"","user":"user1","userGroups":[],"requestData":"desc default.table1;' for user1", + "context": {"TAGS":"[{\"name\":\"PII-FINAL\", \"attributeValues\":{\"expiry\":\"Mon Jun 15 13:00:00 PDT 2026\"}}]"} + }, + "result":{"isAudited":true,"isAllowed":false,"policyId":3} + }, + {"name":"ALLOW 'use default;' for hive", + "request":{ + "resource":{"elements":{"database":"default"}}, + "accessType":"","user":"hive","userGroups":[],"requestData":"use default", + "context": {"TAGS":"[{\"name\":\"PII-FINAL\", \"attributeValues\":{\"expiry\":\"Mon Jun 15 13:00:00 PDT 2026\"}}]"} + }, + "result":{"isAudited":true,"isAllowed":true,"policyId":3} + }, + {"name":"DENY 'use default;' for user1", + "request":{ + "resource":{"elements":{"database":"default"}}, + "accessType":"","user":"user1","userGroups":[],"requestData":"use default for user1", + "context": {"TAGS":"[{\"name\":\"PII-FINAL\", \"attributeValues\":{\"expiry\":\"Mon Jun 15 13:00:00 PDT 2026\"}}]"} + }, + "result":{"isAudited":true,"isAllowed":false,"policyId":3} + }, + {"name":"ALLOW 'select * from default.table1;' for hive", + "request":{ + "resource":{"elements":{"database":"default", "table":"table1", "column":"name"}}, + "accessType":"select","user":"hive","userGroups":[],"requestData":"select * from default.table1", + "context": {"TAGS":"[{\"name\":\"PII\", \"attributeValues\":{\"expiry\":\"Mon Jun 15 13:00:00 PDT 2026\"}}]"} + }, + "result":{"isAudited":true,"isAllowed":true,"policyId":2} + } + + ] +} +
