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 c96bc8b  RANGER-3586: updated script evaluator to support csv of 
group/tag attributes
c96bc8b is described below

commit c96bc8b4a7ac1412b43524cce193c5006c90516d
Author: Madhan Neethiraj <mad...@apache.org>
AuthorDate: Sat Jan 15 10:55:16 2022 -0800

    RANGER-3586: updated script evaluator to support csv of group/tag attributes
---
 .../policyengine/RangerRequestScriptEvaluator.java | 326 +++++++++++++++++----
 .../RangerRequestScriptEvaluatorTest.java          |  20 ++
 2 files changed, 291 insertions(+), 55 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 509244c..e3ce559 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
@@ -67,11 +67,21 @@ public final class RangerRequestScriptEvaluator {
                                                                                
  SCRIPT_VAR_TAGNAMES + "=" + SCRIPT_VAR__CTX + "." + SCRIPT_FIELD_TAG_NAMES + 
";";
 
        private static final Pattern JSON_VAR_NAMES_PATTERN = 
Pattern.compile(getJsonVarNamesPattern());
+       private static final Character CHAR_QUOTE = '\'';
+       private static final Character CHAR_COMMA = ',';
 
        private static String[] dateFormatStrings = null;
 
-       private final RangerAccessRequest accessRequest;
-       private       Boolean             result = false;
+       private final RangerAccessRequest              accessRequest;
+       private       boolean                          initDone   = false;
+       private       Map<String, String>              userAttrs  = 
Collections.emptyMap();
+       private       Map<String, Map<String, String>> groupAttrs = 
Collections.emptyMap();
+       private       Map<String, Map<String, Object>> tags       = 
Collections.emptyMap();
+       private       Map<String, Object>              tag        = 
Collections.emptyMap();
+       private       Collection<String>               userGroups = 
Collections.emptySet();
+       private       Collection<String>               userRoles  = 
Collections.emptySet();
+       private       Collection<String>               tagNames   = 
Collections.emptySet();
+       private       Boolean                          result     = false;
 
        static {
                init(null);
@@ -110,7 +120,6 @@ public final class RangerRequestScriptEvaluator {
                return ret;
        }
 
-
        public RangerRequestScriptEvaluator(final RangerAccessRequest 
accessRequest) {
                this.accessRequest = accessRequest.getReadOnlyCopy();
        }
@@ -187,11 +196,10 @@ public final class RangerRequestScriptEvaluator {
 
                Map<String, Object> ret        = new HashMap<>();
                Map<String, Object> request    = new HashMap<>();
-               RangerUserStore     userStore  = 
RangerAccessRequestUtil.getRequestUserStoreFromContext(accessRequest.getContext());
-               Collection<String>  userGroups = getSorted(getUserGroups());
-               Collection<String>  userRoles  = getSorted(getUserRoles());
                Date                accessTime = accessRequest.getAccessTime();
 
+               init();
+
                if (accessTime != null) {
                        request.put(SCRIPT_FIELD_ACCESS_TIME, 
accessTime.getTime());
                }
@@ -220,57 +228,16 @@ public final class RangerRequestScriptEvaluator {
                request.put(SCRIPT_FIELD_USER_GROUPS, userGroups);
                request.put(SCRIPT_FIELD_USER_ROLES, userRoles);
 
-               Map<String, Map<String, String>> userAttrMapping  = userStore 
!= null ? userStore.getUserAttrMapping() : Collections.emptyMap();
-               Map<String, Map<String, String>> groupAttrMapping = userStore 
!= null ? userStore.getGroupAttrMapping() : Collections.emptyMap();
-               Map<String, String>              userAttrs        = 
userAttrMapping.get(accessRequest.getUser());
-               Map<String, Map<String, String>> groupAttrs       = new 
HashMap<>();
-
-               userAttrs = userAttrs != null ? new HashMap<>(userAttrs) : new 
HashMap<>();
-
-               userAttrs.put(SCRIPT_FIELD__NAME, getUser());
-
                request.put(SCRIPT_FIELD_USER_ATTRIBUTES, userAttrs);
 
-               if (userGroups != null) {
-                       for (String groupName : userGroups) {
-                               Map<String, String> attrs = 
groupAttrMapping.get(groupName);
-
-                               attrs = attrs != null ? new HashMap<>(attrs) : 
new HashMap<>();
-
-                               attrs.put(SCRIPT_FIELD__NAME, groupName);
-
-                               groupAttrs.put(groupName, attrs);
-                       }
-               }
-
                request.put(SCRIPT_FIELD_USER_GROUP_ATTRIBUTES, groupAttrs);
                request.put(SCRIPT_FIELD_UGA, new 
UserGroupsAttributes(userGroups, groupAttrs).getAttributes());
 
                ret.put(SCRIPT_FIELD_REQUEST, request);
 
-               Set<RangerTagForEval> requestTags = 
RangerAccessRequestUtil.getRequestTagsFromContext(getRequestContext());
-
-               if (CollectionUtils.isNotEmpty(requestTags)) {
-                       Map<String, Map<String, Object>> tags     = new 
HashMap();
-                       Set<String>                      tagNames = new 
HashSet<>();
-
-                       for (RangerTagForEval tag : requestTags) {
-                               tags.put(tag.getType(), toMap(tag));
-                               tagNames.add(tag.getType());
-                       }
-
-                       ret.put(SCRIPT_FIELD_TAGS, tags);
-                       ret.put(SCRIPT_FIELD_TAG_NAMES, tagNames);
-
-                       RangerTagForEval currentTag = 
RangerAccessRequestUtil.getCurrentTagFromContext(getRequestContext());
-
-                       if (currentTag != null) {
-                               ret.put(SCRIPT_FIELD_TAG, toMap(currentTag));
-                       }
-               } else {
-                       ret.put(SCRIPT_FIELD_TAGS, Collections.emptyMap());
-                       ret.put(SCRIPT_FIELD_TAG_NAMES, Collections.emptySet());
-               }
+               ret.put(SCRIPT_FIELD_TAGS, tags);
+               ret.put(SCRIPT_FIELD_TAG_NAMES, tagNames);
+               ret.put(SCRIPT_FIELD_TAG, tag);
 
                String strRet = JsonUtils.objectToJson(ret);
 
@@ -589,6 +556,146 @@ public final class RangerRequestScriptEvaluator {
                return ret;
        }
 
+       public String ugNamesCsv() {
+               init();
+
+               return toCsv(userGroups);
+       }
+
+       public String ugNamesCsvQ() {
+               init();
+
+               return toCsvQ(userGroups);
+       }
+
+       public String urNamesCsv() {
+               init();
+
+               return toCsv(userRoles);
+       }
+
+       public String urNamesCsvQ() {
+               init();
+
+               return toCsvQ(userRoles);
+       }
+
+       public String tagNamesCsv() {
+               init();
+
+               return toCsv(tagNames);
+       }
+
+       public String tagNamesCsvQ() {
+               init();
+
+               return toCsvQ(tagNames);
+       }
+
+       public String userAttrNamesCsv() {
+               init();
+
+               return toCsv(getUserAttrNames());
+       }
+
+       public String userAttrNamesCsvQ() {
+               init();
+
+               return toCsvQ(getUserAttrNames());
+       }
+
+       public String ugAttrNamesCsv() {
+               init();
+
+               return toCsv(getUgAttrNames());
+       }
+
+       public String ugAttrNamesCsvQ() {
+               return toCsvQ(getUgAttrNames());
+       }
+
+       public String tagAttrNamesCsv() {
+               init();
+
+               return toCsv(getTagAttrNames());
+       }
+
+       public String tagAttrNamesCsvQ() {
+               init();
+
+               return toCsvQ(getTagAttrNames());
+       }
+
+       public String ugAttrCsv(String attrName) {
+               init();
+
+               return toCsv(getUgAttr(attrName));
+       }
+
+       public String ugAttrCsvQ(String attrName) {
+               init();
+
+               return toCsvQ(getUgAttr(attrName));
+       }
+
+       public String tagAttrCsv(String attrName) {
+               init();
+
+               return toCsv(getTagAttr(attrName));
+       }
+
+       public String tagAttrCsvQ(String attrName) {
+               init();
+
+               return toCsvQ(getTagAttr(attrName));
+       }
+
+       private void init() {
+               if (!initDone) {
+                       RangerUserStore                  userStore        = 
RangerAccessRequestUtil.getRequestUserStoreFromContext(accessRequest.getContext());
+                       Map<String, Map<String, String>> userAttrMapping  = 
userStore != null ? userStore.getUserAttrMapping() : Collections.emptyMap();
+                       Map<String, Map<String, String>> groupAttrMapping = 
userStore != null ? userStore.getGroupAttrMapping() : Collections.emptyMap();
+
+                       userGroups = getSorted(getUserGroups());
+                       userRoles  = getSorted(getUserRoles());
+                       userAttrs  = 
copyMap(userAttrMapping.get(accessRequest.getUser()));
+                       groupAttrs = new HashMap<>();
+
+                       userAttrs.put(SCRIPT_FIELD__NAME, getUser());
+
+                       for (String groupName : userGroups) {
+                               Map<String, String> attrs = 
groupAttrMapping.get(groupName);
+
+                               attrs = attrs != null ? new HashMap<>(attrs) : 
new HashMap<>();
+
+                               attrs.put(SCRIPT_FIELD__NAME, groupName);
+
+                               groupAttrs.put(groupName, attrs);
+                       }
+
+                       Set<RangerTagForEval> requestTags = 
RangerAccessRequestUtil.getRequestTagsFromContext(getRequestContext());
+
+                       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));
+                               }
+
+                               tagNames = getSorted(tags.keySet());
+                       } else {
+                               tags     = Collections.emptyMap();
+                               tagNames = Collections.emptySet();
+                               tag      = Collections.emptyMap();
+                       }
+
+                       initDone = true;
+               }
+       }
+
        private Map<String, Object> getRequestContext() {
                return accessRequest.getContext();
        }
@@ -619,16 +726,125 @@ public final class RangerRequestScriptEvaluator {
                return ret;
        }
 
-       private Collection<String> getSorted(Collection<String> coll) {
-               if (coll != null && coll.size() > 1) {
-                       List<String> lst = new ArrayList<>(coll);
+       private Collection<String> getSorted(Collection<String> values) {
+               final Collection<String> ret;
+
+               if (values == null) {
+                       ret = Collections.emptyList();
+               } else if (values.size() > 1) {
+                       List lst = new ArrayList<>(values);
 
                        Collections.sort(lst);
 
-                       coll = lst;
+                       ret = lst;
+               } else {
+                       ret = values;
+               }
+
+               return ret;
+       }
+
+       private Map<String, String> copyMap(Map<String, String> obj) { return 
obj == null ? new HashMap<>() : new HashMap<>(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;
+       }
+
+       private List<Object> getTagAttr(String attrName) {
+               List<Object> ret = new ArrayList<>();
+
+               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;
+       }
+
+       private Collection<String> getUserAttrNames() {
+               Collection<String> ret = getSorted(userAttrs.keySet());
+
+               if (ret.contains(SCRIPT_FIELD__NAME)) {
+                       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);
+       }
+
+       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);
+
+               return getSorted(ret);
+       }
+
+       private String toCsv(Collection<? extends Object> values) {
+               StringBuilder sb = new StringBuilder();
+
+               for (Object value : values) {
+                       if (value == null) {
+                               continue;
+                       }
+
+                       if (sb.length() > 0) {
+                               sb.append(CHAR_COMMA);
+                       }
+
+                       sb.append(value);
+               }
+
+               return sb.toString();
+       }
+
+       private String toCsvQ(Collection<? extends Object> values) {
+               StringBuilder sb = new StringBuilder();
+
+               for (Object value : values) {
+                       if (value == null) {
+                               continue;
+                       }
+
+                       if (sb.length() > 0) {
+                               sb.append(CHAR_COMMA);
+                       }
+
+                       sb.append(CHAR_QUOTE).append(value).append(CHAR_QUOTE);
                }
 
-               return coll;
+               return sb.toString();
        }
 
        private static String getJsonVarNamesPattern() {
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 ff638b2..2a0b027 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
@@ -55,6 +55,26 @@ public class RangerRequestScriptEvaluatorTest {
         RangerAccessRequest          request   = 
createRequest(Arrays.asList("PII", "PCI"));
         RangerRequestScriptEvaluator evaluator = new 
RangerRequestScriptEvaluator(request);
 
+        Assert.assertEquals("test: ctx.ugNamesCsv()", 
"test-group1,test-group2", evaluator.evaluateScript(scriptEngine, 
"ctx.ugNamesCsv()"));
+        Assert.assertEquals("test: ctx.urNamesCsv()", "test-role1,test-role2", 
evaluator.evaluateScript(scriptEngine, "ctx.urNamesCsv()"));
+        Assert.assertEquals("test: ctx.tagNamesCsv()", "PCI,PII", 
evaluator.evaluateScript(scriptEngine, "ctx.tagNamesCsv()"));
+        Assert.assertEquals("test: ctx.userAttrNamesCsv()", "state", 
evaluator.evaluateScript(scriptEngine, "ctx.userAttrNamesCsv()"));
+        Assert.assertEquals("test: ctx.ugAttrNamesCsv()", "dept,site", 
evaluator.evaluateScript(scriptEngine, "ctx.ugAttrNamesCsv()"));
+        Assert.assertEquals("test: ctx.tagAttrNamesCsv()", "attr1", 
evaluator.evaluateScript(scriptEngine, "ctx.tagAttrNamesCsv()"));
+        Assert.assertEquals("test: ctx.ugAttrCsv('dept')", "ENGG,PROD", 
evaluator.evaluateScript(scriptEngine, "ctx.ugAttrCsv('dept')"));
+        Assert.assertEquals("test: ctx.ugAttrCsv('site')", "10,20", 
evaluator.evaluateScript(scriptEngine, "ctx.ugAttrCsv('site')"));
+        Assert.assertEquals("test: ctx.tagAttrCsv('attr1')", 
"PCI_value,PII_value", evaluator.evaluateScript(scriptEngine, 
"ctx.tagAttrCsv('attr1')"));
+
+        Assert.assertEquals("test: ctx.ugNamesCsvQ()", 
"'test-group1','test-group2'", evaluator.evaluateScript(scriptEngine, 
"ctx.ugNamesCsvQ()"));
+        Assert.assertEquals("test: ctx.urNamesCsvQ()", 
"'test-role1','test-role2'", evaluator.evaluateScript(scriptEngine, 
"ctx.urNamesCsvQ()"));
+        Assert.assertEquals("test: ctx.tagNamesCsvQ()", "'PCI','PII'", 
evaluator.evaluateScript(scriptEngine, "ctx.tagNamesCsvQ()"));
+        Assert.assertEquals("test: ctx.userAttrNamesCsvQ()", "'state'", 
evaluator.evaluateScript(scriptEngine, "ctx.userAttrNamesCsvQ()"));
+        Assert.assertEquals("test: ctx.ugAttrNamesCsvQ()", "'dept','site'", 
evaluator.evaluateScript(scriptEngine, "ctx.ugAttrNamesCsvQ()"));
+        Assert.assertEquals("test: ctx.tagAttrNamesCsvQ()", "'attr1'", 
evaluator.evaluateScript(scriptEngine, "ctx.tagAttrNamesCsvQ()"));
+        Assert.assertEquals("test: ctx.ugAttrCsvQ('dept')", "'ENGG','PROD'", 
evaluator.evaluateScript(scriptEngine, "ctx.ugAttrCsvQ('dept')"));
+        Assert.assertEquals("test: ctx.ugAttrCsvQ('site')", "'10','20'", 
evaluator.evaluateScript(scriptEngine, "ctx.ugAttrCsvQ('site')"));
+        Assert.assertEquals("test: ctx.tagAttrCsvQ('attr1')", 
"'PCI_value','PII_value'", evaluator.evaluateScript(scriptEngine, 
"ctx.tagAttrCsvQ('attr1')"));
+
         Assert.assertTrue("test: USER._name is 'test-user'", (Boolean) 
evaluator.evaluateScript(scriptEngine, "USER._name == 'test-user'"));
         Assert.assertTrue("test: USER['state'] is 'CA'", (Boolean) 
evaluator.evaluateScript(scriptEngine, "USER['state'] == 'CA'"));
         Assert.assertTrue("test: USER.state is 'CA'", (Boolean) 
evaluator.evaluateScript(scriptEngine, "USER.state == 'CA'"));

Reply via email to