mneethiraj commented on code in PR #442: URL: https://github.com/apache/ranger/pull/442#discussion_r1881251725
########## agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRequestScriptEvaluator.java: ########## @@ -25,1375 +25,1481 @@ import org.apache.ranger.authorization.utils.JsonUtils; import org.apache.ranger.authorization.utils.StringUtil; import org.apache.ranger.plugin.contextenricher.RangerTagForEval; +import org.apache.ranger.plugin.util.JavaScriptEdits; import org.apache.ranger.plugin.util.MacroProcessor; import org.apache.ranger.plugin.util.RangerAccessRequestUtil; import org.apache.ranger.plugin.util.RangerPerfTracer; import org.apache.ranger.plugin.util.RangerTimeRangeChecker; import org.apache.ranger.plugin.util.RangerUserStore; -import org.apache.ranger.plugin.util.JavaScriptEdits; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.script.Bindings; import javax.script.ScriptEngine; import javax.script.ScriptException; + import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +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; +import java.util.Set; +import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static org.apache.ranger.plugin.util.RangerCommonConstants.*; - +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_ACCESS_TIME; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_ACCESS_TYPE; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_ACTION; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_CLIENT_IP_ADDRESS; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_CLIENT_TYPE; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_CLUSTER_NAME; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_CLUSTER_TYPE; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_FORWARDED_ADDRESSES; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_REMOTE_IP_ADDRESS; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_REQUEST; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_REQUEST_DATA; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_RESOURCE; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_RESOURCE_MATCHING_SCOPE; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_TAG; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_TAGS; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_TAG_NAMES; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_UGA; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_USER; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_USER_ATTRIBUTES; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_USER_GROUPS; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_USER_GROUP_ATTRIBUTES; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD_USER_ROLES; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD__MATCH_TYPE; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD__NAME; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD__OWNER_USER; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_FIELD__TYPE; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_ATTR; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_ATTR_CSV; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_ATTR_NAMES; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_ATTR_NAMES_Q; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_ATTR_Q; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_ATTR_Q_CSV; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_NAMES; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_TAG_NAMES_Q; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_ATTR; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_ATTR_CSV; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_ATTR_NAMES; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_ATTR_NAMES_Q; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_ATTR_Q; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_ATTR_Q_CSV; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_NAMES; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UG_NAMES_Q; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UR_NAMES; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_UR_NAMES_Q; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_USER_ATTR; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_USER_ATTR_NAMES; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_USER_ATTR_NAMES_Q; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_GET_USER_ATTR_Q; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_HAS_ANY_TAG; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_HAS_NO_TAG; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_HAS_TAG; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_HAS_TAG_ATTR; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_HAS_UG_ATTR; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_HAS_USER_ATTR; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_ACCESS_TIME_AFTER; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_ACCESS_TIME_BEFORE; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_ACCESS_TIME_BETWEEN; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_IN_ANY_GROUP; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_IN_ANY_ROLE; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_IN_GROUP; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_IN_ROLE; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_NOT_IN_ANY_GROUP; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_IS_NOT_IN_ANY_ROLE; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_TAG_ATTR_NAMES_CSV; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_TAG_ATTR_NAMES_Q_CSV; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_TAG_NAMES_CSV; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_TAG_NAMES_Q_CSV; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_UG_ATTR_NAMES_CSV; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_UG_ATTR_NAMES_Q_CSV; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_UG_NAMES_CSV; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_UG_NAMES_Q_CSV; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_UR_NAMES_CSV; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_UR_NAMES_Q_CSV; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_USER_ATTR_NAMES_CSV; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_MACRO_USER_ATTR_NAMES_Q_CSV; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_POLYFILL_INCLUDES; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_POLYFILL_INTERSECTS; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_REQ; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_RES; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_TAG; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_TAGNAMES; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_TAGS; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_UG; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_UGA; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_UGNAMES; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_URNAMES; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_USER; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR__CTX; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR__CTX_JSON; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_ctx; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_tag; +import static org.apache.ranger.plugin.util.RangerCommonConstants.SCRIPT_VAR_tagAttr; public final class RangerRequestScriptEvaluator { - private static final Logger LOG = LoggerFactory.getLogger(RangerRequestScriptEvaluator.class); - - private static final Logger PERF_POLICY_CONDITION_SCRIPT_TOJSON = RangerPerfTracer.getPerfLogger("policy.condition.script.tojson"); - private static final Logger PERF_POLICY_CONDITION_SCRIPT_EVAL = RangerPerfTracer.getPerfLogger("policy.condition.script.eval"); - private static final String TAG_ATTR_DATE_FORMAT_PROP = "ranger.plugin.tag.attr.additional.date.formats"; - private static final String TAG_ATTR_DATE_FORMAT_SEPARATOR = "||"; - private static final String TAG_ATTR_DATE_FORMAT_SEPARATOR_REGEX = "\\|\\|"; - 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_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 + ";" + - SCRIPT_VAR_USER + "=" + SCRIPT_VAR_REQ + "." + SCRIPT_FIELD_USER_ATTRIBUTES + ";" + - SCRIPT_VAR_UGNAMES + "=" + SCRIPT_VAR_REQ + "." + SCRIPT_FIELD_USER_GROUPS + ";" + - SCRIPT_VAR_UG + "=" + SCRIPT_VAR_REQ + "." + SCRIPT_FIELD_USER_GROUP_ATTRIBUTES + ";" + - SCRIPT_VAR_UGA + "=" + SCRIPT_VAR_REQ + "." + SCRIPT_FIELD_UGA + ";" + - SCRIPT_VAR_URNAMES + "=" + SCRIPT_VAR_REQ + "." + SCRIPT_FIELD_USER_ROLES + ";" + - SCRIPT_VAR_TAG + "=" + SCRIPT_VAR__CTX + "." + SCRIPT_FIELD_TAG + ";" + - SCRIPT_VAR_TAGS + "=" + SCRIPT_VAR__CTX + "." + SCRIPT_FIELD_TAGS + ";" + - SCRIPT_VAR_TAGNAMES + "=" + SCRIPT_VAR__CTX + "." + SCRIPT_FIELD_TAG_NAMES + ";"; - private static final Pattern JSON_VAR_NAMES_PATTERN = Pattern.compile(getJsonVarNamesPattern()); - private static final Pattern USER_ATTRIBUTES_PATTERN = Pattern.compile(getUserAttributesPattern()); - private static final Pattern GROUP_ATTRIBUTES_PATTERN = Pattern.compile(getGroupAttributesPattern()); - private static final String STR_QUOTE = "'"; - private static final String STR_COMMA = ","; - - private static final MacroProcessor MACRO_PROCESSOR = new MacroProcessor(getMacrosMap()); - - private static String[] dateFormatStrings = null; - - private final RangerAccessRequest accessRequest; - private final ScriptEngine scriptEngine; - private final Bindings bindings; - 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); - } - - private static final ThreadLocal<List<SimpleDateFormat>> THREADLOCAL_DATE_FORMATS = - new ThreadLocal<List<SimpleDateFormat>>() { - @Override protected List<SimpleDateFormat> initialValue() { - List<SimpleDateFormat> ret = new ArrayList<>(); - - for (String dateFormatString : dateFormatStrings) { - try { - if (StringUtils.isNotBlank(dateFormatString)) { - if (StringUtils.equalsIgnoreCase(dateFormatString, DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT_NAME)) { - dateFormatString = DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT; - } - SimpleDateFormat df = new SimpleDateFormat(dateFormatString); - df.setLenient(false); - ret.add(df); - } - } catch (Exception exception) { - // Ignore - } - } - - return ret; - } - }; - - - public static boolean needsJsonCtxEnabled(String script) { - boolean ret = false; - - if (script != null) { - Matcher matcher = JSON_VAR_NAMES_PATTERN.matcher(script); - - ret = matcher.find(); - } - - return ret; - } - - public static boolean hasUserAttributeReference(String script) { - boolean ret = false; - - if (script != null) { - Matcher matcher = USER_ATTRIBUTES_PATTERN.matcher(script); - - ret = matcher.find(); - } - - return ret; - } - - public static boolean hasGroupAttributeReference(String script) { - boolean ret = false; - - if (script != null) { - Matcher matcher = GROUP_ATTRIBUTES_PATTERN.matcher(script); - - ret = matcher.find(); - } - - return ret; - } - - public static boolean hasUserGroupAttributeReference(String script) { - return hasUserAttributeReference(script) || hasGroupAttributeReference(script); - } - - public static boolean hasUserGroupAttributeReference(Collection<String> scripts) { - boolean ret = false; - - if (scripts != null) { - for (String script : scripts) { - if (hasUserGroupAttributeReference(script)) { - ret = true; - - break; - } - } - } + private static final Logger LOG = LoggerFactory.getLogger(RangerRequestScriptEvaluator.class); + + private static final Logger PERF_POLICY_CONDITION_SCRIPT_TOJSON = RangerPerfTracer.getPerfLogger("policy.condition.script.tojson"); + private static final Logger PERF_POLICY_CONDITION_SCRIPT_EVAL = RangerPerfTracer.getPerfLogger("policy.condition.script.eval"); + private static final String TAG_ATTR_DATE_FORMAT_PROP = "ranger.plugin.tag.attr.additional.date.formats"; + private static final String TAG_ATTR_DATE_FORMAT_SEPARATOR = "||"; + private static final String TAG_ATTR_DATE_FORMAT_SEPARATOR_REGEX = "\\|\\|"; + 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_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 + ";" + + SCRIPT_VAR_USER + "=" + SCRIPT_VAR_REQ + "." + SCRIPT_FIELD_USER_ATTRIBUTES + ";" + + SCRIPT_VAR_UGNAMES + "=" + SCRIPT_VAR_REQ + "." + SCRIPT_FIELD_USER_GROUPS + ";" + + SCRIPT_VAR_UG + "=" + SCRIPT_VAR_REQ + "." + SCRIPT_FIELD_USER_GROUP_ATTRIBUTES + ";" + + SCRIPT_VAR_UGA + "=" + SCRIPT_VAR_REQ + "." + SCRIPT_FIELD_UGA + ";" + + SCRIPT_VAR_URNAMES + "=" + SCRIPT_VAR_REQ + "." + SCRIPT_FIELD_USER_ROLES + ";" + + SCRIPT_VAR_TAG + "=" + SCRIPT_VAR__CTX + "." + SCRIPT_FIELD_TAG + ";" + + SCRIPT_VAR_TAGS + "=" + SCRIPT_VAR__CTX + "." + SCRIPT_FIELD_TAGS + ";" + + SCRIPT_VAR_TAGNAMES + "=" + SCRIPT_VAR__CTX + "." + SCRIPT_FIELD_TAG_NAMES + ";"; + private static final Pattern JSON_VAR_NAMES_PATTERN = Pattern.compile(getJsonVarNamesPattern()); + private static final Pattern USER_ATTRIBUTES_PATTERN = Pattern.compile(getUserAttributesPattern()); + private static final Pattern GROUP_ATTRIBUTES_PATTERN = Pattern.compile(getGroupAttributesPattern()); + private static final String STR_QUOTE = "'"; + private static final String STR_COMMA = ","; + + private static final MacroProcessor MACRO_PROCESSOR = new MacroProcessor(getMacrosMap()); + + private static String[] dateFormatStrings = {}; + private static final ThreadLocal<List<SimpleDateFormat>> THREADLOCAL_DATE_FORMATS = ThreadLocal.withInitial(() -> { + List<SimpleDateFormat> ret = new ArrayList<>(); + + for (String dateFormatString : dateFormatStrings) { + try { + if (StringUtils.isNotBlank(dateFormatString)) { + if (StringUtils.equalsIgnoreCase(dateFormatString, DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT_NAME)) { + dateFormatString = DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT; + } + SimpleDateFormat df = new SimpleDateFormat(dateFormatString); + df.setLenient(false); + ret.add(df); + } + } catch (Exception exception) { + // Ignore + } + } + + return ret; + }); + + private final RangerAccessRequest accessRequest; + private final ScriptEngine scriptEngine; + private final Bindings bindings; + private boolean initDone; + 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; + + public RangerRequestScriptEvaluator(RangerAccessRequest accessRequest, ScriptEngine scriptEngine) { + this(accessRequest, scriptEngine, true); + } + + public RangerRequestScriptEvaluator(RangerAccessRequest accessRequest, ScriptEngine scriptEngine, boolean enableJsonCtx) { + this.accessRequest = accessRequest.getReadOnlyCopy(); + this.scriptEngine = scriptEngine; + this.bindings = scriptEngine.createBindings(); + + RangerTagForEval currentTag = this.getCurrentTag(); + Map<String, String> tagAttribs = currentTag != null ? currentTag.getAttributes() : Collections.emptyMap(); + + bindings.put(SCRIPT_VAR_ctx, this); + bindings.put(SCRIPT_VAR_tag, currentTag); + bindings.put(SCRIPT_VAR_tagAttr, tagAttribs); + + String preExecScript = ""; + + if (enableJsonCtx) { + bindings.put(SCRIPT_VAR__CTX_JSON, this.toJson()); + + preExecScript += SCRIPT_PREEXEC; + } + + if (StringUtils.isNotBlank(preExecScript)) { + try { + scriptEngine.eval(preExecScript, bindings); + } catch (ScriptException excp) { + LOG.error("RangerRequestScriptEvaluator(): initialization failed", excp); + } + } + } + + public static boolean needsJsonCtxEnabled(String script) { + boolean ret = false; + + if (script != null) { + Matcher matcher = JSON_VAR_NAMES_PATTERN.matcher(script); + + ret = matcher.find(); + } + + return ret; + } + + public static boolean hasUserAttributeReference(String script) { + boolean ret = false; - return ret; - } - - public static String expandMacros(String script) { - return MACRO_PROCESSOR.expandMacros(script); - } - - public RangerRequestScriptEvaluator(RangerAccessRequest accessRequest, ScriptEngine scriptEngine) { - this(accessRequest, scriptEngine, true); - } + if (script != null) { + Matcher matcher = USER_ATTRIBUTES_PATTERN.matcher(script); - public RangerRequestScriptEvaluator(RangerAccessRequest accessRequest, ScriptEngine scriptEngine, boolean enableJsonCtx) { - this.accessRequest = accessRequest.getReadOnlyCopy(); - this.scriptEngine = scriptEngine; - this.bindings = scriptEngine.createBindings(); + ret = matcher.find(); + } - RangerTagForEval currentTag = this.getCurrentTag(); - Map<String, String> tagAttribs = currentTag != null ? currentTag.getAttributes() : Collections.emptyMap(); + return ret; + } - bindings.put(SCRIPT_VAR_ctx, this); - bindings.put(SCRIPT_VAR_tag, currentTag); - bindings.put(SCRIPT_VAR_tagAttr, tagAttribs); - - String preExecScript = ""; + public static boolean hasGroupAttributeReference(String script) { + boolean ret = false; - if (enableJsonCtx) { - bindings.put(SCRIPT_VAR__CTX_JSON, this.toJson()); + if (script != null) { + Matcher matcher = GROUP_ATTRIBUTES_PATTERN.matcher(script); - preExecScript += SCRIPT_PREEXEC; - } + ret = matcher.find(); + } - if (StringUtils.isNotBlank(preExecScript)) { - try { - scriptEngine.eval(preExecScript, bindings); - } catch (ScriptException excp) { - LOG.error("RangerRequestScriptEvaluator(): initialization failed", excp); - } - } - } + return ret; + } - public Object evaluateScript(String script) { - script = expandMacros(script); + public static boolean hasUserGroupAttributeReference(String script) { + return hasUserAttributeReference(script) || hasGroupAttributeReference(script); + } - return evaluateScriptImpl(script); - } + public static boolean hasUserGroupAttributeReference(Collection<String> scripts) { + boolean ret = false; - public Object evaluateConditionScript(String script) { - Object ret = evaluateScript(script); + if (scripts != null) { + for (String script : scripts) { + if (hasUserGroupAttributeReference(script)) { + ret = true; - if (ret == null) { - ret = getResult(); - } + break; + } + } + } - if (ret instanceof Boolean) { - result = (Boolean) ret; - } + return ret; + } - return ret; - } + public static String expandMacros(String script) { + return MACRO_PROCESSOR.expandMacros(script); + } - private Object evaluateScriptImpl(String script) { - Object ret = null; - RangerPerfTracer perf = null; + public static void init(Configuration config) { + StringBuilder sb = new StringBuilder(DEFAULT_RANGER_TAG_ATTRIBUTE_DATE_FORMAT); - try { - if (RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_CONDITION_SCRIPT_EVAL)) { - perf = RangerPerfTracer.getPerfTracer(PERF_POLICY_CONDITION_SCRIPT_EVAL, "RangerRequestScriptEvaluator.evaluateScript(requestHash=" + accessRequest.hashCode() + ")"); - } + sb.append(TAG_ATTR_DATE_FORMAT_SEPARATOR).append(DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT_NAME); - String preExec = SCRIPT_SAFE_PREEXEC; + String additionalDateFormatsValue = config != null ? config.get(TAG_ATTR_DATE_FORMAT_PROP) : null; - if (script.contains(".includes(")) { - preExec += SCRIPT_POLYFILL_INCLUDES; - } + if (StringUtils.isNotBlank(additionalDateFormatsValue)) { + sb.append(TAG_ATTR_DATE_FORMAT_SEPARATOR).append(additionalDateFormatsValue); + } - if (script.contains(".intersects(")) { - preExec += SCRIPT_POLYFILL_INTERSECTS; - } + String[] formatStrings = sb.toString().split(TAG_ATTR_DATE_FORMAT_SEPARATOR_REGEX); - if (JavaScriptEdits.hasDoubleBrackets(script)) { - script = JavaScriptEdits.replaceDoubleBrackets(script); - } + Arrays.sort(formatStrings, (first, second) -> Integer.compare(second.length(), first.length())); - ret = scriptEngine.eval(preExec + script, bindings); - } catch (NullPointerException nullp) { - LOG.error("RangerRequestScriptEvaluator.evaluateScript(): eval called with NULL argument(s)", nullp); - } catch (ScriptException excp) { - LOG.error("RangerRequestScriptEvaluator.evaluateScript(): failed to evaluate script", excp); - } catch (Throwable t) { - LOG.error("RangerRequestScriptEvaluator.evaluateScript(): failed to evaluate script", t); - } finally { - RangerPerfTracer.log(perf); - } + RangerRequestScriptEvaluator.dateFormatStrings = formatStrings; + } - return ret; - } + public Object evaluateScript(String script) { + script = expandMacros(script); - private String toJson() { - RangerPerfTracer perf = null; + return evaluateScriptImpl(script); + } - if (RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_CONDITION_SCRIPT_TOJSON)) { - perf = RangerPerfTracer.getPerfTracer(PERF_POLICY_CONDITION_SCRIPT_TOJSON, "RangerRequestScriptEvaluator.toJson(requestHash=" + accessRequest.hashCode() + ")"); - } + public Object evaluateConditionScript(String script) { + Object ret = evaluateScript(script); - Map<String, Object> ret = new HashMap<>(); - Map<String, Object> request = new HashMap<>(); - Date accessTime = accessRequest.getAccessTime(); + if (ret == null) { + ret = getResult(); + } - init(); + if (ret instanceof Boolean) { + result = (Boolean) ret; + } - if (accessTime != null) { - request.put(SCRIPT_FIELD_ACCESS_TIME, accessTime.getTime()); - } + return ret; + } - request.put(SCRIPT_FIELD_ACCESS_TYPE, accessRequest.getAccessType()); - request.put(SCRIPT_FIELD_ACTION, accessRequest.getAction()); - request.put(SCRIPT_FIELD_CLIENT_IP_ADDRESS, accessRequest.getClientIPAddress()); - request.put(SCRIPT_FIELD_CLIENT_TYPE, accessRequest.getClientType()); - request.put(SCRIPT_FIELD_CLUSTER_NAME, accessRequest.getClusterName()); - request.put(SCRIPT_FIELD_CLUSTER_TYPE, accessRequest.getClusterType()); - request.put(SCRIPT_FIELD_FORWARDED_ADDRESSES, accessRequest.getForwardedAddresses()); - request.put(SCRIPT_FIELD_REMOTE_IP_ADDRESS, accessRequest.getRemoteIPAddress()); - request.put(SCRIPT_FIELD_REQUEST_DATA, accessRequest.getRequestData()); + public String getResource() { + String ret = null; + RangerAccessResource val = RangerAccessRequestUtil.getCurrentResourceFromContext(getRequestContext()); - if (accessRequest.getResource() != null) { - Map<String, Object> resource = new HashMap<>(accessRequest.getResource().getAsMap()); + if (val != null) { + ret = val.getAsString(); + } - resource.put(SCRIPT_FIELD__OWNER_USER, accessRequest.getResource().getOwnerUser()); + return ret; + } - request.put(SCRIPT_FIELD_RESOURCE, resource); - } + public String getResourceZone() { + String ret = RangerAccessRequestUtil.getResourceZoneNameFromContext(getRequestContext()); - request.put(SCRIPT_FIELD_RESOURCE_MATCHING_SCOPE, accessRequest.getResourceMatchingScope()); + return ret != null ? ret : StringUtils.EMPTY; + } - request.put(SCRIPT_FIELD_USER, getUser()); - request.put(SCRIPT_FIELD_USER_GROUPS, userGroups); - request.put(SCRIPT_FIELD_USER_ROLES, userRoles); + public Set<String> getResourceZones() { + Set<String> ret = RangerAccessRequestUtil.getResourceZoneNamesFromContext(getRequestContext()); - request.put(SCRIPT_FIELD_USER_ATTRIBUTES, userAttrs); + return ret != null ? Collections.emptySet() : ret; + } - request.put(SCRIPT_FIELD_USER_GROUP_ATTRIBUTES, groupAttrs); - request.put(SCRIPT_FIELD_UGA, new UserGroupsAttributes(userGroups, groupAttrs).getAttributes()); + public String getRequestContextAttribute(String attributeName) { + String ret = null; - ret.put(SCRIPT_FIELD_REQUEST, request); + if (StringUtils.isNotBlank(attributeName)) { + Object val = getRequestContext().get(attributeName); - ret.put(SCRIPT_FIELD_TAGS, tags); - ret.put(SCRIPT_FIELD_TAG_NAMES, tagNames); - ret.put(SCRIPT_FIELD_TAG, tag); + if (val != null) { + ret = val.toString(); + } + } - String strRet = JsonUtils.objectToJson(ret); + return ret; + } - RangerPerfTracer.log(perf); + public boolean isAccessTypeAny() { + return accessRequest.isAccessTypeAny(); + } - return strRet; - } + public boolean isAccessTypeDelegatedAdmin() { + return accessRequest.isAccessTypeDelegatedAdmin(); + } - public static void init(Configuration config) { - StringBuilder sb = new StringBuilder(DEFAULT_RANGER_TAG_ATTRIBUTE_DATE_FORMAT); + public String getUser() { + return accessRequest.getUser(); + } - sb.append(TAG_ATTR_DATE_FORMAT_SEPARATOR).append(DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT_NAME); + public Set<String> getUserGroups() { + return accessRequest.getUserGroups(); + } - String additionalDateFormatsValue = config != null ? config.get(TAG_ATTR_DATE_FORMAT_PROP) : null; + public Set<String> getUserRoles() { + return RangerAccessRequestUtil.getUserRoles(accessRequest); + } + + public Date getAccessTime() { + return accessRequest.getAccessTime() != null ? accessRequest.getAccessTime() : new Date(); + } + + public String getClientIPAddress() { + return accessRequest.getClientIPAddress(); + } + + public String getClientType() { + return accessRequest.getClientType(); + } + + public String getAction() { + return accessRequest.getAction(); + } + + public String getRequestData() { + return accessRequest.getRequestData(); + } + + public String getSessionId() { + return accessRequest.getSessionId(); + } + + public RangerTagForEval getCurrentTag() { + RangerTagForEval ret = RangerAccessRequestUtil.getCurrentTagFromContext(getRequestContext()); + + if (ret == null) { + if (LOG.isDebugEnabled()) { Review Comment: isDebugEnabled() in this class helps avoid overhead of potential string concats and calls to Objects.toString() in logDebug(). -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: dev-unsubscr...@ranger.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org