Repository: incubator-ranger Updated Branches: refs/heads/tag-policy 990213ca4 -> b362c17e1
RANGER-605: creating default tag policy to enforce expiry 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/b362c17e Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/b362c17e Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/b362c17e Branch: refs/heads/tag-policy Commit: b362c17e115cac506f1b4af07d67640f82ed9b1e Parents: 990213c Author: Abhay Kulkarni <[email protected]> Authored: Thu Aug 13 21:48:59 2015 -0700 Committer: Madhan Neethiraj <[email protected]> Committed: Thu Aug 20 00:40:59 2015 -0700 ---------------------------------------------------------------------- .../RangerScriptConditionEvaluator.java | 69 +++++++----- .../RangerScriptTemplateConditionEvaluator.java | 112 +++++++++++++++++++ .../service-defs/ranger-servicedef-tag.json | 8 ++ .../test_policyengine_tag_hive.json | 59 ++++++++++ .../org/apache/ranger/biz/ServiceDBStore.java | 55 ++++----- 5 files changed, 241 insertions(+), 62 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b362c17e/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptConditionEvaluator.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptConditionEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptConditionEvaluator.java index 800c0b7..41fa3d3 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptConditionEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptConditionEvaluator.java @@ -78,59 +78,70 @@ public class RangerScriptConditionEvaluator extends RangerAbstractConditionEvalu @Override public boolean isMatched(RangerAccessRequest request) { if (LOG.isDebugEnabled()) { - LOG.debug("==>RangerScriptConditionEvaluator.isMatched()"); + LOG.debug("==> RangerScriptConditionEvaluator.isMatched()"); } boolean result = false; if (scriptEngine != null) { - List<String> values = condition.getValues(); + String script = getScript(); - if (CollectionUtils.isNotEmpty(values)) { + if (StringUtils.isNotBlank(script)) { - String value = values.get(0); - if (StringUtils.isNotBlank(value)) { + RangerAccessRequest readOnlyRequest = request.getReadOnlyCopy(); - RangerAccessRequest readOnlyRequest = request.getReadOnlyCopy(); + RangerScriptExecutionContext context = new RangerScriptExecutionContext(readOnlyRequest); - RangerScriptExecutionContext context = new RangerScriptExecutionContext(readOnlyRequest); + Bindings bindings = scriptEngine.createBindings(); - Bindings bindings = scriptEngine.createBindings(); + bindings.put("ctx", context); - bindings.put("ctx", context); + if (LOG.isDebugEnabled()) { + LOG.debug("RangerScriptConditionEvaluator.isMatched(): script={" + script + "}"); + } + try { - String script = value.trim(); + Object ret = scriptEngine.eval(script, bindings); - if (LOG.isDebugEnabled()) { - LOG.debug("RangerScriptConditionEvaluator.isMatched(): script={" + script + "}"); + if (ret == null) { + ret = context.getResult(); + } + if (ret instanceof Boolean) { + result = (Boolean) ret; } - try { - - Object ret = scriptEngine.eval(script, bindings); - - if (ret == null) { - ret = context.getResult(); - } - if (ret instanceof Boolean) { - result = (Boolean) ret; - } - } catch (NullPointerException nullp) { - LOG.error("RangerScriptConditionEvaluator.isMatched(): eval called with NULL argument(s)"); + } catch (NullPointerException nullp) { + LOG.error("RangerScriptConditionEvaluator.isMatched(): eval called with NULL argument(s)"); - } catch (ScriptException exception) { - LOG.error("RangerScriptConditionEvaluator.isMatched(): failed to evaluate script," + - " exception=" + exception); - } + } catch (ScriptException exception) { + LOG.error("RangerScriptConditionEvaluator.isMatched(): failed to evaluate script," + + " exception=" + exception); } } + } if (LOG.isDebugEnabled()) { - LOG.debug("<==RangerScriptConditionEvaluator.isMatched(), result=" + result); + LOG.debug("<== RangerScriptConditionEvaluator.isMatched(), result=" + result); } return result; } + + protected String getScript() { + String ret = null; + + List<String> values = condition.getValues(); + + if (CollectionUtils.isNotEmpty(values)) { + + String value = values.get(0); + if (StringUtils.isNotBlank(value)) { + ret = value.trim(); + } + } + + return ret; + } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b362c17e/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptTemplateConditionEvaluator.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptTemplateConditionEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptTemplateConditionEvaluator.java new file mode 100644 index 0000000..44157c3 --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptTemplateConditionEvaluator.java @@ -0,0 +1,112 @@ +/* + * 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.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.ranger.authorization.hadoop.config.RangerConfiguration; +import org.apache.ranger.plugin.policyengine.RangerAccessRequest; + +import java.util.List; +import java.util.Map; + +public class RangerScriptTemplateConditionEvaluator extends RangerScriptConditionEvaluator { + private static final Log LOG = LogFactory.getLog(RangerScriptTemplateConditionEvaluator.class); + + protected String scriptTemplate; + protected String script; + + @Override + public void init() { + + if (LOG.isDebugEnabled()) { + LOG.debug("==> RangerExpiryEnforcer.init(" + condition + ")"); + } + + super.init(); + + Map<String, String> evalOptions = conditionDef. getEvaluatorOptions(); + + if (MapUtils.isNotEmpty(evalOptions)) { + scriptTemplate = evalOptions.get("scriptTemplate"); + } + + if (StringUtils.isNotBlank(scriptTemplate)) { + scriptTemplate = scriptTemplate.trim(); + } + + script = formatScript(); + + if (LOG.isDebugEnabled()) { + LOG.debug("<== RangerExpiryEnforcer.init(" + condition + ")"); + } + } + + @Override + protected String getScript() { + return script; + } + + @Override + public boolean isMatched(RangerAccessRequest request) { + boolean ret = true; + + if (StringUtils.isNotBlank(script)) { + ret = super.isMatched(request); + } + + return ret; + } + + private String formatScript() { + + String ret = null; + + if (LOG.isDebugEnabled()) { + LOG.debug("==> RangerExpiryEnforcer.formatScript()"); + } + List<String> values = condition.getValues(); + + if (CollectionUtils.isNotEmpty(values)) { + + String value = values.get(0); + + if (StringUtils.isNotBlank(value)) { + + String s = value.trim().toLowerCase(); + + if (s.equals("no") || s.equals("false")) { + ret = null; + } else { + ret = scriptTemplate; + } + } + } + + if (LOG.isDebugEnabled()) { + LOG.debug("<== RangerExpiryEnforcer.formatScript(), ret=" + ret); + } + + return ret; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b362c17e/agents-common/src/main/resources/service-defs/ranger-servicedef-tag.json ---------------------------------------------------------------------- diff --git a/agents-common/src/main/resources/service-defs/ranger-servicedef-tag.json b/agents-common/src/main/resources/service-defs/ranger-servicedef-tag.json index 96cbb82..0b827e4 100644 --- a/agents-common/src/main/resources/service-defs/ranger-servicedef-tag.json +++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-tag.json @@ -106,6 +106,14 @@ "evaluatorOptions" : {"engineName":"JavaScript", "ui.isMultiline":"true" }, "label":"Script", "description": "Script to execute" + }, + { + "itemId":2, + "name":"enforce-expiry", + "evaluator": "org.apache.ranger.plugin.conditionevaluator.RangerScriptTemplateConditionEvaluator", + "evaluatorOptions" : { "scriptTemplate":"ctx.isAccessedBefore('expiry_date');" }, + "label":"Deny access after expiry_date?", + "description": "Deny access after expiry_date? (yes/no)" } ] } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b362c17e/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 index 2b4b056..7898223 100644 --- a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json +++ b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json @@ -141,6 +141,14 @@ "evaluatorOptions" : {"engineName":"JavaScript"}, "label":"Script", "description": "Script to execute" + }, + { + "itemId":2, + "name":"enforce-expiry", + "evaluator": "org.apache.ranger.plugin.conditionevaluator.RangerScriptTemplateConditionEvaluator", + "evaluatorOptions" : { "scriptTemplate":"ctx.isAccessedBefore('expiry_date');" }, + "label":"Deny access after expiry_date?", + "description": "Deny access after expiry_date? (yes/no)" } ] }, @@ -180,11 +188,62 @@ }] } ] + }, + {"id":5,"name":"EXPIRES_ON","isEnabled":true,"isAuditEnabled":true,"policyType":2, + "resources":{"tag":{"values":["EXPIRES_ON"],"isRecursive":false}}, + "policyItems":[ + { + "accesses":[{"type":"hive:select","isAllowed":true}],"users":[],"groups":["public"],"delegateAdmin":false, + "conditions":[{ + "type":"enforce-expiry", + "values":["yes"] + }] + }, + { + "accesses":[{"type":"hive:select","isAllowed":true}],"users":["dataloader"],"groups":[],"delegateAdmin":false, + "conditions":[{ + "type":"enforce-expiry", + "values":["no"] + }] + } + ] } ] }, "tests":[ + {"name":"ALLOW 'select ssn from employee.personal;' for user1 using EXPIRES_ON tag", + "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\":\"EXPIRES_ON\", \"attributeValues\":{\"expiry_date\":\"Mon Jun 15 13:00:00 PDT 2026\"}}]"} + }, + "result":{"isAudited":true,"isAllowed":true,"policyId":5} + }, + {"name":"DENY 'select ssn from employee.personal;' for user1 using EXPIRES_ON tag", + "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\":\"EXPIRES_ON\", \"attributeValues\":{\"expiry_date\":\"Mon Aug 10 13:00:00 PDT 2015\"}}]"} + }, + "result":{"isAudited":true,"isAllowed":false,"policyId":5} + }, + {"name":"DENY 'select ssn from employee.personal;' for user1 using EXPIRES_ON tag with multiple policyItems", + "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\":\"EXPIRES_ON\", \"attributeValues\":{\"expiry_date\":\"Mon Aug 10 13:00:00 PDT 2015\"}}]"} + }, + "result":{"isAudited":true,"isAllowed":false,"policyId":5} + }, + {"name":"ALLOW 'select ssn from employee.personal;' for dataloader using EXPIRES_ON tag with multiple policyItems", + "request":{ + "resource":{"elements":{"database":"employee", "table":"personal", "column":"ssn"}}, + "accessType":"select","user":"dataloader","userGroups":[],"requestData":"select ssn from employee.personal;' for dataloader", + "context": {"TAGS":"[{\"name\":\"EXPIRES_ON\", \"attributeValues\":{\"expiry_date\":\"Mon Aug 10 13:00:00 PDT 2015\"}}]"} + }, + "result":{"isAudited":true,"isAllowed":true,"policyId":5} + }, {"name":"ALLOW 'select ssn from employee.personal;' for user1", "request":{ "resource":{"elements":{"database":"employee", "table":"personal", "column":"ssn"}}, http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b362c17e/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java ---------------------------------------------------------------------- diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java index 7278fe9..1fec611 100644 --- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java +++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java @@ -132,12 +132,7 @@ import org.springframework.transaction.support.TransactionTemplate; @Component public class ServiceDBStore extends AbstractServiceStore { private static final Log LOG = LogFactory.getLog(ServiceDBStore.class); - - public static final String RANGER_DEFAULT_TAGPOLICY_TAG_PREFIX = "ranger.default.tagpolicy.tag."; - public static final String RANGER_DEFAULT_TAGPOLICY_TAG_NAME = RANGER_DEFAULT_TAGPOLICY_TAG_PREFIX + "name"; - public static final String RANGER_DEFAULT_TAGPOLICY_TAG_ATTRIBUTE_NAME = RANGER_DEFAULT_TAGPOLICY_TAG_PREFIX + "attribute.name"; - public static final String RANGER_DEFAULT_TAGPOLICY_TAG_SCRIPT_FORMAT = RANGER_DEFAULT_TAGPOLICY_TAG_PREFIX + "%1$s." + "script"; - + public static final String RANGER_TAG_EXPIRY_CONDITION_NAME = "enforce-expiry"; @Autowired RangerServiceDefService serviceDefService; @@ -1795,7 +1790,7 @@ public class ServiceDBStore extends AbstractServiceStore { } String tagResourceDefName = null; - String tagPolicyConditionName = null; + boolean isConditionDefFound = false; RangerServiceDef tagServiceDef = getServiceDef(createdService.getType()); List<RangerResourceDef> tagResourceDef = tagServiceDef.getResources(); @@ -1807,25 +1802,23 @@ public class ServiceDBStore extends AbstractServiceStore { LOG.error("ServiceDBStore.createService() - Cannot create default TAG policy: Cannot get tagResourceDef Name."); } - List<RangerPolicyConditionDef> policyConditions = tagServiceDef.getPolicyConditions(); - if (policyConditions != null && policyConditions.size() > 0) { - // Assumption : First (and perhaps the only) policyConditionDef is javascript evaluator - RangerPolicyConditionDef condition = policyConditions.get(0); - tagPolicyConditionName = condition.getName(); - } else { - LOG.error("ServiceDBStore.createService() - Cannot create default TAG policy: Cannot get tagPolicyConditionDef Name."); - } - - String tagName = RangerConfiguration.getInstance().get(RANGER_DEFAULT_TAGPOLICY_TAG_NAME, "EXPIRES_ON"); - String tagAttributeName = RangerConfiguration.getInstance().get(RANGER_DEFAULT_TAGPOLICY_TAG_ATTRIBUTE_NAME, "expiry_date"); + List<RangerPolicyConditionDef> policyConditionDefs = tagServiceDef.getPolicyConditions(); - if (LOG.isDebugEnabled()) { - LOG.debug("ServiceDBStore.createDefaultTagPolicy() - tagResourceDefName=" + tagResourceDefName + - ", tagPolicyConditionName=" + tagPolicyConditionName + ", tagName=" + tagName + - ", tagAttributeName=" + tagAttributeName); + if (CollectionUtils.isNotEmpty(policyConditionDefs)) { + for (RangerPolicyConditionDef conditionDef : policyConditionDefs) { + if (conditionDef.getName().equals(RANGER_TAG_EXPIRY_CONDITION_NAME)) { + isConditionDefFound = true; + break; + } + } } + if (!isConditionDefFound) { + LOG.error("ServiceDBStore.createService() - Cannot create default TAG policy: Cannot get tagPolicyConditionDef with name=" + RANGER_TAG_EXPIRY_CONDITION_NAME); + } + + if (tagResourceDefName != null && isConditionDefFound) { - if (tagResourceDefName != null && tagPolicyConditionName != null && tagName != null && tagAttributeName != null) { + String tagName = "EXPIRES_ON"; String policyName = createdService.getName() + "-" + tagName; @@ -1835,11 +1828,11 @@ public class ServiceDBStore extends AbstractServiceStore { policy.setVersion(1L); policy.setName(policyName); policy.setService(createdService.getName()); - policy.setDescription("Default Policy for TAG: " + tagName + " for TAG Service: " + createdService.getName()); + policy.setDescription(tagName + " Policy for TAG Service: " + createdService.getName()); policy.setIsAuditEnabled(true); policy.setPolicyType(RangerPolicy.POLICY_TYPE_EXCLUSIVE_ALLOW); - Map<String, RangerPolicyResource> resourceMap = new HashMap<>(); + Map<String, RangerPolicyResource> resourceMap = new HashMap<String, RangerPolicyResource>(); RangerPolicyResource polRes = new RangerPolicyResource(); polRes.setIsExcludes(false); @@ -1868,12 +1861,9 @@ public class ServiceDBStore extends AbstractServiceStore { policyItem.setAccesses(accesses); List<RangerPolicyItemCondition> policyItemConditions = new ArrayList<RangerPolicyItemCondition>(); - String propertyName = String.format(RANGER_DEFAULT_TAGPOLICY_TAG_SCRIPT_FORMAT, tagName); - String scriptFormat = RangerConfiguration.getInstance().get(propertyName, "if (ctx.isAccessedAfter('%1$s', '%2$s')) { ctx.result = false;} else { ctx.result = true;}"); - String formattedScript = String.format(scriptFormat, tagName, tagAttributeName); - List<String> javascriptScriptList = new ArrayList<String>(); - javascriptScriptList.add(formattedScript); - RangerPolicyItemCondition policyItemCondition = new RangerPolicyItemCondition(tagPolicyConditionName, javascriptScriptList); + List<String> values = new ArrayList<String>(); + values.add("yes"); + RangerPolicyItemCondition policyItemCondition = new RangerPolicyItemCondition(RANGER_TAG_EXPIRY_CONDITION_NAME, values); policyItemConditions.add(policyItemCondition); policyItem.setConditions(policyItemConditions); @@ -1886,8 +1876,7 @@ public class ServiceDBStore extends AbstractServiceStore { policy = createPolicy(policy); } else { LOG.error("ServiceDBStore.createService() - Cannot create default TAG policy, tagResourceDefName=" + tagResourceDefName + - ", tagPolicyConditionName=" + tagPolicyConditionName + ", defaultTagName=" + tagName + - ", defaultTagAttributeName=" + tagAttributeName); + ", tagPolicyConditionName=" + RANGER_TAG_EXPIRY_CONDITION_NAME); } if (LOG.isDebugEnabled()) {
