You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2023/03/05 07:55:30 UTC

[ranger] branch master updated: RANGER-4117: service-def option to include expression condition implicitly

This is an automated email from the ASF dual-hosted git repository.

madhan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/master by this push:
     new f46e7139a RANGER-4117: service-def option to include expression condition implicitly
f46e7139a is described below

commit f46e7139aa39804e8d6287a502c0b266d4c2b0f2
Author: Madhan Neethiraj <ma...@apache.org>
AuthorDate: Sat Mar 4 22:55:14 2023 -0800

    RANGER-4117: service-def option to include expression condition implicitly
---
 .../ranger/plugin/model/RangerServiceDef.java      |  1 +
 .../apache/ranger/plugin/util/ServiceDefUtil.java  |  2 +-
 .../org/apache/ranger/biz/PolicyRefUpdater.java    |  5 ++
 .../ranger/service/RangerServiceDefService.java    | 65 ++++++++++++++++++++++
 .../service/TestRangerServiceDefService.java       | 54 ++++++++++++++++++
 5 files changed, 126 insertions(+), 1 deletion(-)

diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
index 05dde4edf..e70a16592 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
@@ -47,6 +47,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 	private static final long serialVersionUID = 1L;
 
 	public static final String OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES = "enableDenyAndExceptionsInPolicies";
+	public static final String OPTION_ENABLE_IMPLICIT_CONDITION_EXPRESSION   = "enableImplicitConditionExpression";
 
 	private String                         name;
 	private String                         displayName;
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
index fe1cf9244..4808dfd83 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
@@ -442,7 +442,7 @@ public class ServiceDefUtil {
         return ret;
     }
 
-    private static boolean getBooleanValue(Map<String, String> map, String elementName, boolean defaultValue) {
+    public static boolean getBooleanValue(Map<String, String> map, String elementName, boolean defaultValue) {
         boolean ret = defaultValue;
 
         if(MapUtils.isNotEmpty(map) && map.containsKey(elementName)) {
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java b/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java
index 6cc3509d8..4581112fe 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java
@@ -54,6 +54,7 @@ import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo;
 import org.apache.ranger.plugin.model.RangerRole;
 import org.apache.ranger.service.RangerAuditFields;
+import org.apache.ranger.service.RangerServiceDefService;
 import org.apache.ranger.service.XGroupService;
 import org.apache.ranger.view.VXGroup;
 import org.apache.ranger.view.VXResponse;
@@ -248,6 +249,10 @@ public class PolicyRefUpdater {
 			XXPolicyConditionDef xPolCondDef = daoMgr.getXXPolicyConditionDef().findByServiceDefIdAndName(xServiceDef.getId(), condition);
 
 			if (xPolCondDef == null) {
+				if (StringUtils.equalsIgnoreCase(condition, RangerServiceDefService.IMPLICIT_CONDITION_EXPRESSION_NAME)) {
+					continue;
+				}
+
 				throw new Exception(condition + ": is not a valid condition-type. policy='"+  xPolicy.getName() + "' service='"+ xPolicy.getService() + "'");
 			}
 
diff --git a/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefService.java b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefService.java
index 954c10e74..328d8baa6 100644
--- a/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefService.java
+++ b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefService.java
@@ -18,14 +18,19 @@
 package org.apache.ranger.service;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.ranger.authorization.hadoop.config.RangerAdminConfig;
+import org.apache.ranger.common.PropertiesUtil;
 import org.apache.ranger.entity.XXServiceDef;
+import org.apache.ranger.plugin.conditionevaluator.RangerScriptConditionEvaluator;
 import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef;
 import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
+import org.apache.ranger.plugin.util.ServiceDefUtil;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Service;
 
@@ -33,6 +38,12 @@ import org.springframework.stereotype.Service;
 @Service
 @Scope("singleton")
 public class RangerServiceDefService extends RangerServiceDefServiceBase<XXServiceDef, RangerServiceDef> {
+	public static final String PROP_ENABLE_IMPLICIT_CONDITION_EXPRESSION = "ranger.servicedef.enableImplicitConditionExpression";
+	public static final String IMPLICIT_CONDITION_EXPRESSION_EVALUATOR   = RangerScriptConditionEvaluator.class.getCanonicalName();
+	public static final String IMPLICIT_CONDITION_EXPRESSION_NAME        = "_expression";
+	public static final String IMPLICIT_CONDITION_EXPRESSION_LABEL       = "Enter boolean expression";
+	public static final String IMPLICIT_CONDITION_EXPRESSION_DESC        = "Boolean expression";
+
 	private final RangerAdminConfig config;
 
 	public RangerServiceDefService() {
@@ -71,6 +82,9 @@ public class RangerServiceDefService extends RangerServiceDefServiceBase<XXServi
 			}
 			ret.setOptions(serviceDefOptions);
 		}
+
+		addImplicitConditionExpressionIfNeeded(ret);
+
 		return ret;
 	}
 
@@ -88,4 +102,55 @@ public class RangerServiceDefService extends RangerServiceDefServiceBase<XXServi
 	public RangerServiceDef getPopulatedViewObject(XXServiceDef xServiceDef) {
 		return this.populateViewBean(xServiceDef);
 	}
+
+
+	boolean addImplicitConditionExpressionIfNeeded(RangerServiceDef serviceDef) {
+		boolean ret                      = false;
+		boolean implicitConditionDefault = PropertiesUtil.getBooleanProperty(PROP_ENABLE_IMPLICIT_CONDITION_EXPRESSION, true);
+		boolean implicitConditionEnabled = ServiceDefUtil.getBooleanValue(serviceDef.getOptions(), RangerServiceDef.OPTION_ENABLE_IMPLICIT_CONDITION_EXPRESSION, implicitConditionDefault);
+
+		if (implicitConditionEnabled) {
+			boolean                        exists        = false;
+			Long                           maxItemId     = 0L;
+			List<RangerPolicyConditionDef> conditionDefs = serviceDef.getPolicyConditions();
+
+			if (conditionDefs == null) {
+				conditionDefs = new ArrayList<>();
+			}
+
+			for (RangerPolicyConditionDef conditionDef : conditionDefs) {
+				if (StringUtils.equalsIgnoreCase(conditionDef.getEvaluator(), IMPLICIT_CONDITION_EXPRESSION_EVALUATOR)) {
+					exists = true;
+
+					break;
+				}
+
+				if (conditionDef.getItemId() != null && maxItemId < conditionDef.getItemId()) {
+					maxItemId = conditionDef.getItemId();
+				}
+			}
+
+			if (!exists) {
+				RangerPolicyConditionDef conditionDef = new RangerPolicyConditionDef();
+				Map<String, String>      options      = new HashMap<>();
+
+				options.put("ui.isMultiline", "true");
+
+				conditionDef.setItemId(maxItemId + 1);
+				conditionDef.setName(IMPLICIT_CONDITION_EXPRESSION_NAME);
+				conditionDef.setLabel(IMPLICIT_CONDITION_EXPRESSION_LABEL);
+				conditionDef.setDescription(IMPLICIT_CONDITION_EXPRESSION_DESC);
+				conditionDef.setEvaluator(IMPLICIT_CONDITION_EXPRESSION_EVALUATOR);
+				conditionDef.setEvaluatorOptions(options);
+
+				conditionDefs.add(conditionDef);
+
+				serviceDef.setPolicyConditions(conditionDefs);
+
+				ret = true;
+			}
+		}
+
+		return ret;
+	}
 }
diff --git a/security-admin/src/test/java/org/apache/ranger/service/TestRangerServiceDefService.java b/security-admin/src/test/java/org/apache/ranger/service/TestRangerServiceDefService.java
index 032f2f870..31f698292 100644
--- a/security-admin/src/test/java/org/apache/ranger/service/TestRangerServiceDefService.java
+++ b/security-admin/src/test/java/org/apache/ranger/service/TestRangerServiceDefService.java
@@ -21,8 +21,10 @@ import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.ranger.common.ContextUtil;
 import org.apache.ranger.common.JSONUtil;
+import org.apache.ranger.common.PropertiesUtil;
 import org.apache.ranger.common.StringUtil;
 import org.apache.ranger.common.UserSessionBase;
 import org.apache.ranger.db.*;
@@ -50,6 +52,8 @@ import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.junit.MockitoJUnitRunner;
 
+import static org.apache.ranger.service.RangerServiceDefService.PROP_ENABLE_IMPLICIT_CONDITION_EXPRESSION;
+
 @RunWith(MockitoJUnitRunner.class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class TestRangerServiceDefService {
@@ -748,4 +752,54 @@ public class TestRangerServiceDefService {
 		Mockito.verify(daoManager).getXXEnumDef();
 	}
 
+	@Test
+	public void testImplicitConditionExpression() {
+		RangerServiceDef serviceDef = rangerServiceDef();
+		int              initCount  = serviceDef.getPolicyConditions().size();
+		boolean          isAdded    = serviceDefService.addImplicitConditionExpressionIfNeeded(serviceDef);
+
+		// serviceDef doesn't have RangerScriptConditionEvaluator condition, hence should be added
+		Assert.assertTrue(isAdded);
+
+		int postCount = serviceDef.getPolicyConditions().size();
+
+		Assert.assertEquals(initCount + 1, postCount);
+
+		boolean exists = false;
+
+		for (RangerPolicyConditionDef conditionDef : serviceDef.getPolicyConditions()) {
+			if (StringUtils.equals(conditionDef.getEvaluator(), RangerServiceDefService.IMPLICIT_CONDITION_EXPRESSION_EVALUATOR)) {
+				exists = true;
+
+				break;
+			}
+		}
+
+		Assert.assertTrue(exists);
+
+		isAdded = serviceDefService.addImplicitConditionExpressionIfNeeded(serviceDef);
+
+		// serviceDef already has RangerScriptConditionEvaluator, hence shouldn't be added again
+		Assert.assertFalse(isAdded);
+	}
+
+	@Test
+	public void testImplicitConditionExpressionDisabled() {
+		PropertiesUtil.getPropertiesMap().put(PROP_ENABLE_IMPLICIT_CONDITION_EXPRESSION, Boolean.FALSE.toString());
+
+		try {
+			RangerServiceDef serviceDef = rangerServiceDef();
+			int              initCount  = serviceDef.getPolicyConditions().size();
+			boolean          isAdded    = serviceDefService.addImplicitConditionExpressionIfNeeded(serviceDef);
+
+			// PROP_ENABLE_IMPLICIT_CONDITION_EXPR is false, hence shouldn't be added
+			Assert.assertFalse(isAdded);
+
+			int postCount = serviceDef.getPolicyConditions().size();
+
+			Assert.assertEquals(initCount, postCount);
+		} finally {
+			PropertiesUtil.getPropertiesMap().remove(PROP_ENABLE_IMPLICIT_CONDITION_EXPRESSION);
+		}
+	}
 }