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 1438644b7 RANGER-4234: simplify condition/row-filter expressions that
deal with delimited strings
1438644b7 is described below
commit 1438644b7f1f7f5fb9e62d0d855982d7e10e7fc6
Author: Eckman, Barbara <[email protected]>
AuthorDate: Fri Sep 22 11:38:07 2023 -0400
RANGER-4234: simplify condition/row-filter expressions that deal with
delimited strings
Signed-off-by: Madhan Neethiraj <[email protected]>
---
.../RangerDefaultRowFilterPolicyItemEvaluator.java | 9 ++-
.../apache/ranger/plugin/util/JavaScriptEdits.java | 77 ++++++++++++++++++++++
.../ranger/plugin/util/JavaScriptEditsTest.java | 45 +++++++++++++
3 files changed, 130 insertions(+), 1 deletion(-)
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java
index d2b3e746b..759c0ff59 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java
@@ -25,6 +25,7 @@ import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.policyengine.RangerAccessResult;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
import
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
+import org.apache.ranger.plugin.util.JavaScriptEdits;
import org.apache.ranger.plugin.util.RangerRequestExprResolver;
@@ -41,7 +42,13 @@ public class RangerDefaultRowFilterPolicyItemEvaluator
extends RangerDefaultPoli
RangerPolicyItemRowFilterInfo rowFilterInfo =
getRowFilterInfo();
if (rowFilterInfo != null && rowFilterInfo.getFilterExpr() !=
null) {
- rowFilterExpr = rowFilterInfo.getFilterExpr();
+ String rowFilterExpr = rowFilterInfo.getFilterExpr();
+
+ if (JavaScriptEdits.hasDoubleBrackets(rowFilterExpr)) {
+ rowFilterExpr =
JavaScriptEdits.replaceDoubleBrackets(rowFilterExpr);
+ }
+
+ this.rowFilterExpr = rowFilterExpr;
} else {
rowFilterExpr = null;
}
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/util/JavaScriptEdits.java
b/agents-common/src/main/java/org/apache/ranger/plugin/util/JavaScriptEdits.java
new file mode 100644
index 000000000..a2dd18e4f
--- /dev/null
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/util/JavaScriptEdits.java
@@ -0,0 +1,77 @@
+/*
+ * 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.util;
+
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class JavaScriptEdits {
+ private static final Logger LOG =
LoggerFactory.getLogger(JavaScriptEdits.class);
+
+ private static final String DOUBLE_BRACKET_START = "[[";
+ private static final String DOUBLE_BRACKET_END = "]]";
+ private static final String DOUBLE_BRACKET_REGEX =
"\\[\\[([}{\\$\"a-zA-Z0-9_.\\[\\]]+)(\\,['\\\"](.+?)['\\\"])*\\]\\]"; // regex:
/\[\[([a-zA-Z0-9_.\[\]]+)(\,['"](.+)['"])*\]\]/g;
+ private static final Pattern DOUBLE_BRACKET_PATTERN =
Pattern.compile(DOUBLE_BRACKET_REGEX);
+
+ public static boolean hasDoubleBrackets(String str) {
+ return StringUtils.contains(str, DOUBLE_BRACKET_START) &&
StringUtils.contains(str, DOUBLE_BRACKET_END);
+ }
+
+ /* some examples:
+ tag-based access policy:
+ original: [[TAG.value]].intersects([[USER[TAG._type]]])
+ replaced: TAG.value.split(",").intersects(USER[TAG._type].split(","))
+ Row-filter policy:
+ original: ${{[["$USER.eventType",'|']]}}.includes(eventType)
+ replaced:
${{"$USER.eventType".split("|")}}.includes(jsonAttr.eventType)
+ */
+ public static String replaceDoubleBrackets(String str) {
+ // Besides trivial inputs, re has been tested on ${{USER.x}} and
multiple [[]]'s
+ String ret = str;
+
+ for (Matcher m = DOUBLE_BRACKET_PATTERN.matcher(str); m.find(); ) {
+ String tokenToReplace = m.group(0);
+ String expr = m.group(1);
+ String delimiterSpec = m.group(2);
+ String delimiter = m.group(3);
+
+ if (delimiter == null) {
+ delimiter = ",";
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("replaceDoubleBrackets({}): tokenToReplace={}
expr={} delimiterSpec={} delimiter={}", str, tokenToReplace, expr,
delimiterSpec, delimiter);
+ }
+
+ ret = ret.replace(tokenToReplace, expr + ".split(\"" + delimiter +
"\")");
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== replaceDoubleBrackets({}): ret={}", str, ret);
+ }
+
+ return ret;
+ }
+}
+
diff --git
a/agents-common/src/test/java/org/apache/ranger/plugin/util/JavaScriptEditsTest.java
b/agents-common/src/test/java/org/apache/ranger/plugin/util/JavaScriptEditsTest.java
new file mode 100644
index 000000000..f531290d3
--- /dev/null
+++
b/agents-common/src/test/java/org/apache/ranger/plugin/util/JavaScriptEditsTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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.util;
+
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+
+public class JavaScriptEditsTest {
+
+ @Test
+ public void testExpressions() {
+ Map<String, String> tests = new HashMap<>();
+
+ tests.put("[[TAG.value]].intersects([[USER[TAG._type]]])",
"TAG.value.split(\",\").intersects(USER[TAG._type].split(\",\"))");
+
tests.put("${{[[\"$USER.eventType\",'|']]}}.includes(jsonAttr.eventType)",
"${{\"$USER.eventType\".split(\"|\")}}.includes(jsonAttr.eventType)");
+ tests.put("TAG.value == 'email'", "TAG.value == 'email'");
// output same as input
+ tests.put("UGNAMES[0] == 'analyst'", "UGNAMES[0] ==
'analyst'"); // output same as input
+
+ for (Map.Entry<String, String> test : tests.entrySet()) {
+ String input = test.getKey();
+ String output = test.getValue();
+
+ assertEquals("input: " + input, output,
JavaScriptEdits.replaceDoubleBrackets(input));
+ }
+ }
+}