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 6047dbdad RANGER-5324: replace iterations with streams in 
RangerRequestScriptEvaluator (#671)
6047dbdad is described below

commit 6047dbdad8c0c75286798b99f3f831b6645abf65
Author: Madhan Neethiraj <[email protected]>
AuthorDate: Wed Sep 17 22:04:02 2025 -0700

    RANGER-5324: replace iterations with streams in 
RangerRequestScriptEvaluator (#671)
---
 .../policyengine/RangerRequestScriptEvaluator.java | 374 ++++++---------------
 .../RangerRequestScriptEvaluatorTest.java          |  49 +++
 2 files changed, 155 insertions(+), 268 deletions(-)

diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRequestScriptEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRequestScriptEvaluator.java
index 84e32e255..f94df27e6 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRequestScriptEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRequestScriptEvaluator.java
@@ -20,6 +20,7 @@
 package org.apache.ranger.plugin.policyengine;
 
 import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.ranger.authorization.utils.JsonUtils;
@@ -46,7 +47,6 @@
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -54,6 +54,7 @@
 import java.util.TimeZone;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_ACCESS_TIME;
 import static 
org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_ACCESS_TYPE;
@@ -159,7 +160,7 @@ public final class RangerRequestScriptEvaluator {
     private static final String  DEFAULT_RANGER_TAG_ATTRIBUTE_DATE_FORMAT     
= "yyyy/MM/dd";
     private static final String  DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT_NAME 
= "ATLAS_DATE_FORMAT";
     private static final String  DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT      
= "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
-    private static final String  SCRIPT_SAFE_PREEXEC                          
= "exit=null;quit=null;";
+    private static final String  SCRIPT_SAFE_PREEXEC                          
= 
"Object.defineProperty(this,'engine',{value:null,writable:false});exit=null;quit=null;";
     private static final String  SCRIPT_PREEXEC                               
= SCRIPT_VAR__CTX + "=JSON.parse(" + SCRIPT_VAR__CTX_JSON + "); 
J=JSON.stringify;" +
             SCRIPT_VAR_REQ + "=" + SCRIPT_VAR__CTX + "." + 
SCRIPT_FIELD_REQUEST + ";" +
             SCRIPT_VAR_RES + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_RESOURCE + ";" +
@@ -288,19 +289,7 @@ public static boolean 
hasUserGroupAttributeReference(String script) {
     }
 
     public static boolean hasUserGroupAttributeReference(Collection<String> 
scripts) {
-        boolean ret = false;
-
-        if (scripts != null) {
-            for (String script : scripts) {
-                if (hasUserGroupAttributeReference(script)) {
-                    ret = true;
-
-                    break;
-                }
-            }
-        }
-
-        return ret;
+        return scripts != null && 
scripts.stream().anyMatch(RangerRequestScriptEvaluator::hasUserGroupAttributeReference);
     }
 
     public static String expandMacros(String script) {
@@ -365,7 +354,7 @@ public String getResourceZone() {
     public Set<String> getResourceZones() {
         Set<String> ret = 
RangerAccessRequestUtil.getResourceZoneNamesFromContext(getRequestContext());
 
-        return ret != null ? Collections.emptySet() : ret;
+        return ret != null ? ret : Collections.emptySet();
     }
 
     public String getRequestContextAttribute(String attributeName) {
@@ -443,125 +432,65 @@ public String getCurrentTagType() {
     }
 
     public Set<String> getAllTagTypes() {
-        Set<String>           allTagTypes   = null;
-        Set<RangerTagForEval> tagObjectList = getAllTags();
-
-        if (CollectionUtils.isNotEmpty(tagObjectList)) {
-            for (RangerTagForEval tag : tagObjectList) {
-                String tagType = tag.getType();
-                if (allTagTypes == null) {
-                    allTagTypes = new HashSet<>();
-                }
-                allTagTypes.add(tagType);
-            }
-        }
-
-        return allTagTypes;
+        return Collections.unmodifiableSet(tags.keySet());
     }
 
     public Map<String, String> getTagAttributes(final String tagType) {
-        Map<String, String> ret = null;
-
-        if (StringUtils.isNotBlank(tagType)) {
-            Set<RangerTagForEval> tagObjectList = getAllTags();
-
-            // Assumption: There is exactly one tag with given tagType in the 
list of tags - may not be true ***TODO***
-            // This will get attributes of the first tagType that matches
-            if (CollectionUtils.isNotEmpty(tagObjectList)) {
-                for (RangerTagForEval tag : tagObjectList) {
-                    if (tag.getType().equals(tagType)) {
-                        ret = tag.getAttributes();
-                        break;
-                    }
-                }
-            }
-        }
+        Set<RangerTagForEval> tags = StringUtils.isBlank(tagType) ? null : 
getAllTags();
 
-        return ret;
+        // Assumption: There is exactly one tag with given tagType in the list 
of tags - may not be true ***TODO**
+        // This will get attributes of the first tagType that matches
+        return CollectionUtils.isEmpty(tags) ? null :
+                tags.stream()
+                        .filter(tag -> tagType.equals(tag.getType()))
+                        .map(RangerTagForEval::getAttributes)
+                        .filter(MapUtils::isNotEmpty)
+                        .findFirst()
+                        .orElse(null);
     }
 
     public List<Map<String, String>> getTagAttributesForAllMatchingTags(final 
String tagType) {
-        List<Map<String, String>> ret = null;
-
-        if (StringUtils.isNotBlank(tagType)) {
-            Set<RangerTagForEval> tagObjectList = getAllTags();
-
-            // Assumption: There is exactly one tag with given tagType in the 
list of tags - may not be true ***TODO***
-            // This will get attributes of the first tagType that matches
-            if (CollectionUtils.isNotEmpty(tagObjectList)) {
-                for (RangerTagForEval tag : tagObjectList) {
-                    if (tag.getType().equals(tagType)) {
-                        Map<String, String> tagAttributes = 
tag.getAttributes();
-                        if (tagAttributes != null) {
-                            if (ret == null) {
-                                ret = new ArrayList<>();
-                            }
-                            ret.add(tagAttributes);
-                        }
-                        break;
-                    }
-                }
-            }
-        }
+        Set<RangerTagForEval> tags = StringUtils.isBlank(tagType) ? null : 
getAllTags();
 
-        return ret;
+        return CollectionUtils.isEmpty(tags) ? null :
+                tags.stream()
+                        .filter(tag -> tagType.equals(tag.getType()))
+                        .map(RangerTagForEval::getAttributes)
+                        .filter(MapUtils::isNotEmpty)
+                        .collect(Collectors.toList());
     }
 
     public Set<String> getAttributeNames(final String tagType) {
-        Set<String>         ret        = null;
         Map<String, String> attributes = getTagAttributes(tagType);
 
-        if (attributes != null) {
-            ret = attributes.keySet();
-        }
-
-        return ret;
+        return attributes == null ? null : attributes.keySet();
     }
 
     public String getAttributeValue(final String tagType, final String 
attributeName) {
-        String ret = null;
-
-        if (StringUtils.isNotBlank(tagType) || 
StringUtils.isNotBlank(attributeName)) {
-            Map<String, String> attributes = getTagAttributes(tagType);
+        Map<String, String> attributes = (StringUtils.isBlank(tagType) || 
StringUtils.isBlank(attributeName)) ? null : getTagAttributes(tagType);
 
-            if (attributes != null) {
-                ret = attributes.get(attributeName);
-            }
-        }
-        return ret;
+        return attributes == null ? null : attributes.get(attributeName);
     }
 
     public List<String> getAttributeValueForAllMatchingTags(final String 
tagType, final String attributeName) {
-        List<String> ret = null;
-
-        if (StringUtils.isNotBlank(tagType) || 
StringUtils.isNotBlank(attributeName)) {
-            Map<String, String> attributes = getTagAttributes(tagType);
+        Set<RangerTagForEval> tags = StringUtils.isBlank(tagType) || 
StringUtils.isBlank(attributeName) ? null : getAllTags();
 
-            if (attributes != null && attributes.get(attributeName) != null) {
-                if (ret == null) {
-                    ret = new ArrayList<>();
-                }
-                ret.add(attributes.get(attributeName));
-            }
-        }
-        return ret;
+        return CollectionUtils.isEmpty(tags) ? null :
+                tags.stream()
+                        .filter(tag -> tagType.equals(tag.getType()))
+                        .map(RangerTagForEval::getAttributes)
+                        .filter(MapUtils::isNotEmpty)
+                        .map(tagAttrs -> tagAttrs.get(attributeName))
+                        .filter(Objects::nonNull)
+                        .sorted()
+                        .collect(Collectors.toList());
     }
 
     public String getAttributeValue(final String attributeName) {
-        String ret = null;
+        RangerTagForEval    tag        = StringUtils.isBlank(attributeName) ? 
null : getCurrentTag();
+        Map<String, String> attributes = tag == null ? null : 
tag.getAttributes();
 
-        if (StringUtils.isNotBlank(attributeName)) {
-            RangerTagForEval    tag        = getCurrentTag();
-            Map<String, String> attributes = null;
-            if (tag != null) {
-                attributes = tag.getAttributes();
-            }
-            if (attributes != null) {
-                ret = attributes.get(attributeName);
-            }
-        }
-
-        return ret;
+        return attributes == null ? null : attributes.get(attributeName);
     }
 
     public boolean getResult() {
@@ -573,19 +502,11 @@ public void setResult(final boolean result) {
     }
 
     public Date getAsDate(String value) {
-        Date ret = null;
-
-        if (StringUtils.isNotBlank(value)) {
-            for (SimpleDateFormat simpleDateFormat : 
THREADLOCAL_DATE_FORMATS.get()) {
-                ret = getAsDate(value, simpleDateFormat);
-                if (ret != null) {
-                    if (LOG.isDebugEnabled()) {
-                        logDebug("RangerRequestScriptEvaluator.getAsDate() 
-The best match found for Format-String:[" + simpleDateFormat.toPattern() + "], 
date:[" + ret + "]");
-                    }
-                    break;
-                }
-            }
-        }
+        Date ret = StringUtils.isBlank(value) ? null : 
THREADLOCAL_DATE_FORMATS.get().stream()
+                .map(dateFormat -> getAsDate(value, dateFormat))
+                .filter(Objects::nonNull)
+                .findFirst()
+                .orElse(null);
 
         if (ret == null) {
             logError("RangerRequestScriptEvaluator.getAsDate() - Could not 
convert [" + value + "] to Date using any of the Format-Strings: " + 
Arrays.toString(dateFormatStrings));
@@ -603,51 +524,31 @@ public Date getTagAttributeAsDate(String tagType, String 
attributeName) {
     }
 
     public boolean isAccessedAfter(String tagType, String attributeName) {
-        boolean ret        = false;
-        Date    accessDate = getAccessTime();
-        Date    expiryDate = getTagAttributeAsDate(tagType, attributeName);
-
-        if (expiryDate == null || accessDate.after(expiryDate) || 
accessDate.equals(expiryDate)) {
-            ret = true;
-        }
+        Date accessDate = getAccessTime();
+        Date expiryDate = getTagAttributeAsDate(tagType, attributeName);
 
-        return ret;
+        return expiryDate == null || accessDate.after(expiryDate) || 
accessDate.equals(expiryDate);
     }
 
     public 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;
-        }
+        Date accessDate = getAccessTime();
+        Date expiryDate = getAsDate(getAttributeValue(attributeName));
 
-        return ret;
+        return expiryDate == null || accessDate.after(expiryDate) || 
accessDate.equals(expiryDate);
     }
 
     public boolean isAccessedBefore(String tagType, String attributeName) {
-        boolean ret        = true;
-        Date    accessDate = getAccessTime();
-        Date    expiryDate = getTagAttributeAsDate(tagType, attributeName);
-
-        if (expiryDate == null || accessDate.after(expiryDate)) {
-            ret = false;
-        }
+        Date accessDate = getAccessTime();
+        Date expiryDate = getTagAttributeAsDate(tagType, attributeName);
 
-        return ret;
+        return !(expiryDate == null || accessDate.after(expiryDate));
     }
 
     public boolean isAccessedBefore(String attributeName) {
-        boolean ret        = true;
-        Date    accessDate = getAccessTime();
-        Date    expiryDate = getAsDate(getAttributeValue(attributeName));
-
-        if (expiryDate == null || accessDate.after(expiryDate)) {
-            ret = false;
-        }
+        Date accessDate = getAccessTime();
+        Date expiryDate = getAsDate(getAttributeValue(attributeName));
 
-        return ret;
+        return !(expiryDate == null || accessDate.after(expiryDate));
     }
 
     public String tagNames(Object... args) {
@@ -783,36 +684,15 @@ public boolean hasUserAttr(String attrName) {
     public boolean hasUgAttr(String attrName) {
         init();
 
-        boolean ret = false;
-
-        for (Map<String, String> attrs : groupAttrs.values()) {
-            if (attrs.containsKey(attrName)) {
-                ret = true;
-
-                break;
-            }
-        }
-
-        return ret;
+        return groupAttrs.values().stream().anyMatch(attrs -> 
attrs.containsKey(attrName));
     }
 
     public boolean hasTagAttr(String attrName) {
         init();
 
-        boolean               ret  = false;
         Set<RangerTagForEval> tags = 
RangerAccessRequestUtil.getRequestTagsFromContext(accessRequest.getContext());
 
-        if (tags != null) {
-            for (RangerTagForEval tag : tags) {
-                if (tag.getAttributes().containsKey(attrName)) {
-                    ret = true;
-
-                    break;
-                }
-            }
-        }
-
-        return ret;
+        return tags != null && tags.stream().anyMatch(tag -> 
tag.getAttributes().containsKey(attrName));
     }
 
     public boolean isInGroup(String groupName) {
@@ -1089,12 +969,8 @@ private void init() {
             if (CollectionUtils.isNotEmpty(requestTags)) {
                 RangerTagForEval currentTag = 
RangerAccessRequestUtil.getCurrentTagFromContext(getRequestContext());
 
-                tags = new HashMap();
                 tag  = (currentTag != null) ? toMap(currentTag) : 
Collections.emptyMap();
-
-                for (RangerTagForEval tag : requestTags) {
-                    tags.put(tag.getType(), toMap(tag));
-                }
+                tags = 
requestTags.stream().collect(Collectors.toMap(RangerTagForEval::getType, 
RangerRequestScriptEvaluator::toMap, (oldVal, newVal) -> newVal));
 
                 tagNames = getSorted(tags.keySet());
             } else {
@@ -1143,7 +1019,7 @@ private Collection<String> getSorted(Collection<String> 
values) {
         if (values == null) {
             ret = Collections.emptyList();
         } else if (values.size() > 1) {
-            List lst = new ArrayList<>(values);
+            List<String> lst = new ArrayList<>(values);
 
             Collections.sort(lst);
 
@@ -1160,124 +1036,86 @@ private Map<String, String> copyMap(Map<String, 
String> obj) {
     }
 
     private List<Object> getUgAttr(String attrName) {
-        List<Object> ret = new ArrayList<>();
-
-        for (String groupName : userGroups) {
-            Map<String, String> attrs = groupAttrs.get(groupName);
-            Object              val   = attrs != null ? attrs.get(attrName) : 
null;
-
-            if (val != null) {
-                ret.add(val);
-            }
-        }
-
-        return ret;
+        return userGroups.stream()
+                .map(groupAttrs::get)
+                .filter(Objects::nonNull)
+                .map(attrs -> attrs.get(attrName))
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
     }
 
     private List<Object> getTagAttr(String attrName) {
-        List<Object> ret = new ArrayList<>();
+        Set<RangerTagForEval> tags = StringUtils.isBlank(attrName) ? null : 
getAllTags();
 
-        for (String tagName : tagNames) {
-            Map<String, Object> attrs = tags.get(tagName);
-            Object              val   = attrs != null ? attrs.get(attrName) : 
null;
-
-            if (val != null) {
-                ret.add(val);
-            }
-        }
-
-        return ret;
+        return tags == null ? Collections.emptyList() : tags.stream()
+                .map(RangerTagForEval::getAttributes)
+                .filter(Objects::nonNull)
+                .map(attrs -> attrs.get(attrName))
+                .filter(Objects::nonNull)
+                .sorted()
+                .collect(Collectors.toList());
     }
 
     private Collection<String> getUserAttrNames() {
         Collection<String> ret = getSorted(userAttrs.keySet());
 
         if (ret.contains(SCRIPT_FIELD__NAME)) {
-            ret.remove(SCRIPT_FIELD__NAME);
+            if (ret.size() == 1) { // SCRIPT_FIELD__NAME is the only entry; 
return empty list
+                ret = Collections.emptyList();
+            } else { // ret is safe to mutate when size > 1 - see getSorted()
+                ret.remove(SCRIPT_FIELD__NAME);
+            }
         }
 
         return ret;
     }
 
     private Collection<String> getUgAttrNames() {
-        Set<String> ret = new HashSet<>();
-
-        for (Map<String, String> attrs : groupAttrs.values()) {
-            ret.addAll(attrs.keySet());
-        }
-
-        ret.remove(SCRIPT_FIELD__NAME);
-
-        return getSorted(ret);
+        return getSorted(
+                groupAttrs.values().stream()
+                        .flatMap(attrs -> attrs.keySet().stream())
+                        .filter(attr -> !SCRIPT_FIELD__NAME.equals(attr))
+                        .collect(Collectors.toSet()));
     }
 
     private Collection<String> getTagAttrNames() {
-        Set<String> ret = new HashSet<>();
-
-        for (Map<String, Object> attrs : tags.values()) {
-            ret.addAll(attrs.keySet());
-        }
-
-        ret.remove(SCRIPT_FIELD__TYPE);
-        ret.remove(SCRIPT_FIELD__MATCH_TYPE);
+        Set<RangerTagForEval> tags = getAllTags();
 
-        return getSorted(ret);
+        return tags == null ? Collections.emptySet() : getSorted(
+                tags.stream()
+                        .map(RangerTagForEval::getAttributes)
+                        .filter(Objects::nonNull)
+                        .flatMap(attrs -> attrs.keySet().stream())
+                        .filter(attr -> !SCRIPT_FIELD__TYPE.equals(attr) && 
!SCRIPT_FIELD__MATCH_TYPE.equals(attr))
+                        .collect(Collectors.toSet()));
     }
 
-    private String toCsv(Collection<? extends Object> values, Object[] args) {
-        StringBuilder sb        = new StringBuilder();
-        String        separator = getSeparator(args);
-
-        for (Object value : values) {
-            if (value == null) {
-                continue;
-            }
-
-            if (sb.length() > 0) {
-                sb.append(separator);
-            }
-
-            sb.append(value);
-        }
+    private String toCsv(Collection<?> values, Object[] args) {
+        String separator = getSeparator(args);
+        String ret       = 
values.stream().filter(Objects::nonNull).map(String::valueOf).collect(Collectors.joining(separator));
 
-        if (sb.length() == 0) {
-            String defValue = getDefaultValue(args);
-
-            if (defValue != null) {
-                sb.append(getDefaultValue(args));
-            }
+        if (StringUtils.isEmpty(ret)) {
+            ret = getDefaultValue(args);
         }
 
-        return sb.toString();
+        return ret == null ? StringUtils.EMPTY : ret;
     }
 
-    private String toCsvQ(Collection<? extends Object> values, Object[] args) {
-        StringBuilder sb         = new StringBuilder();
-        String        openQuote  = getOpenQuote(args);
-        String        closeQuote = getCloseQuote(args, openQuote);
-        String        separator  = getSeparator(args);
+    private String toCsvQ(Collection<?> values, Object[] args) {
+        String openQuote  = getOpenQuote(args);
+        String closeQuote = getCloseQuote(args, openQuote);
+        String separator  = getSeparator(args);
+        String ret        = values.stream().filter(Objects::nonNull).map(value 
-> openQuote + value + closeQuote).collect(Collectors.joining(separator));
 
-        for (Object value : values) {
-            if (value == null) {
-                continue;
-            }
-
-            if (sb.length() > 0) {
-                sb.append(separator);
-            }
-
-            sb.append(openQuote).append(value).append(closeQuote);
-        }
-
-        if (sb.length() == 0) {
+        if (StringUtils.isEmpty(ret)) {
             String defValue = getDefaultValue(args);
 
             if (defValue != null) {
-                
sb.append(openQuote).append(getDefaultValue(args)).append(closeQuote);
+                ret = (openQuote + defValue + closeQuote);
             }
         }
 
-        return sb.toString();
+        return ret;
     }
 
     private String getDefaultValue(Object[] args) {
diff --git 
a/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerRequestScriptEvaluatorTest.java
 
b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerRequestScriptEvaluatorTest.java
index 2fb481fc8..35e32496c 100644
--- 
a/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerRequestScriptEvaluatorTest.java
+++ 
b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerRequestScriptEvaluatorTest.java
@@ -35,6 +35,7 @@
 
 import javax.script.ScriptEngine;
 
+import java.io.File;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
@@ -432,6 +433,21 @@ public void testBlockJavaClassReferences() {
 
         Assert.assertNull("test: java.lang.System.out.println(\"test\");", 
evaluator.evaluateScript("java.lang.System.out.println(\"test\");"));
         Assert.assertNull("test: 
java.lang.Runtime.getRuntime().exec(\"bash\");", 
evaluator.evaluateScript("java.lang.Runtime.getRuntime().exec(\"bash\");"));
+
+        String fileName = "/tmp/ctest1-" + System.currentTimeMillis();
+        String script   = "var file = new java.io.File('" + fileName +  "'); 
file.createNewFile()";
+
+        Assert.assertNull("test file access using: " + script, 
evaluator.evaluateScript(script));
+
+        File testFile = new File(fileName);
+        Assert.assertFalse(fileName + ": file should not have been created", 
testFile.exists());
+
+        script = "engine.eval('malicious code')";
+
+        Assert.assertNull("test engine access using: " + script, 
evaluator.evaluateScript(script));
+
+        script = "var str = new java.lang.String('test'); str.length()";
+        Assert.assertNull("test Java String class access using: " + script, 
evaluator.evaluateScript(script));
     }
 
     @Test
@@ -464,6 +480,39 @@ public void testIsTimeMacros() {
         Assert.assertTrue("test: IS_ACCESS_TIME_BETWEEN('2010/01/01 15:00:42', 
'2100/01/01 15:00:42', 'GMT')", (Boolean) 
evaluator.evaluateScript("IS_ACCESS_TIME_BETWEEN('2010/01/01 15:00:42', 
'2100/01/01 15:00:42', 'GMT')"));
     }
 
+    @Test
+    public void testMultipleTagInstancesOfType() {
+        List<RangerTag> tags = Arrays.asList(new RangerTag("PII", 
Collections.singletonMap("type", "email")),
+                new RangerTag("PII", Collections.singletonMap("type", 
"phone")),
+                new RangerTag("PII", Collections.emptyMap()),
+                new RangerTag("PCI", Collections.singletonMap("kind", "pan")),
+                new RangerTag("PCI", Collections.singletonMap("kind", "sad")),
+                new RangerTag("PCI", null));
+        RangerAccessRequest          request   = createRequest("test-user", 
Collections.emptySet(), Collections.emptySet(), tags);
+        RangerRequestScriptEvaluator evaluator = new 
RangerRequestScriptEvaluator(request, scriptEngine);
+
+        Object[][] tests = new Object[][] {
+                {"TAG_NAMES_CSV", "PCI,PII"},
+                {"TAG_ATTR_NAMES_CSV", "kind,type"},
+                {"ctx.getAttributeValueForAllMatchingTags('PII', 'type')", 
Arrays.asList("email", "phone")},
+                {"ctx.getAttributeValueForAllMatchingTags('PCI', 'kind')", 
Arrays.asList("pan", "sad")},
+                {"ctx.getAttributeValueForAllMatchingTags('PII', 'kind')", 
Collections.emptyList()},
+                {"ctx.getAttributeValueForAllMatchingTags('PCI', 'type')", 
Collections.emptyList()},
+                {"ctx.getAttributeValueForAllMatchingTags('notag', 'noattr')", 
Collections.emptyList()},
+                {"ctx.getAttributeValueForAllMatchingTags('notag', null)", 
null},
+                {"ctx.getAttributeValueForAllMatchingTags(null, 'noattr')", 
null},
+                {"ctx.getAttributeValueForAllMatchingTags(null, noull)", null}
+        };
+
+        for (Object[] test : tests) {
+            String script   = (String) test[0];
+            Object expected = test[1];
+            Object actual   = evaluator.evaluateScript(script);
+
+            Assert.assertEquals("test: " + script, expected, actual);
+        }
+    }
+
     RangerAccessRequest createRequest(String userName, Set<String> userGroups, 
Set<String> userRoles, List<RangerTag> resourceTags) {
         RangerAccessResource resource = mock(RangerAccessResource.class);
 

Reply via email to