1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package edu.internet2.middleware.shibboleth.common.attribute.filtering.provider.match.basic;
19
20 import javax.script.Compilable;
21 import javax.script.CompiledScript;
22 import javax.script.ScriptContext;
23 import javax.script.ScriptEngine;
24 import javax.script.ScriptEngineManager;
25 import javax.script.ScriptException;
26 import javax.script.SimpleScriptContext;
27
28 import org.opensaml.xml.util.DatatypeHelper;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 import edu.internet2.middleware.shibboleth.common.attribute.filtering.provider.FilterProcessingException;
33 import edu.internet2.middleware.shibboleth.common.attribute.filtering.provider.ShibbolethFilteringContext;
34
35
36
37
38 public class ScriptMatchFunctor extends AbstractMatchFunctor {
39
40
41 private final Logger log = LoggerFactory.getLogger(ScriptMatchFunctor.class);
42
43
44 private String scriptLanguage;
45
46
47 private String script;
48
49
50 private ScriptEngine scriptEngine;
51
52
53 private CompiledScript compiledScript;
54
55
56
57
58
59
60
61 public ScriptMatchFunctor(String language, String newScript) {
62 scriptLanguage = language;
63 script = newScript;
64
65 ScriptEngineManager sem = new ScriptEngineManager();
66 scriptEngine = sem.getEngineByName(scriptLanguage);
67 compileScript();
68 }
69
70
71 protected boolean doEvaluateValue(ShibbolethFilteringContext filterContext, String attributeId,
72 Object attributeValue) throws FilterProcessingException {
73 ScriptContext context = getScriptContext(filterContext, attributeId, attributeValue);
74 return executeScript(context);
75 }
76
77
78 protected boolean doEvaluatePolicyRequirement(ShibbolethFilteringContext filterContext)
79 throws FilterProcessingException {
80 ScriptContext context = getScriptContext(filterContext, null, null);
81 return executeScript(context);
82 }
83
84
85 protected void compileScript() {
86 if (DatatypeHelper.isEmpty(script)) {
87 return;
88 }
89
90 try {
91 if (scriptEngine != null && scriptEngine instanceof Compilable) {
92 compiledScript = ((Compilable) scriptEngine).compile(script);
93 }
94 } catch (ScriptException e) {
95 compiledScript = null;
96 log.warn("Unable to pre-compile JSR-268 script: " + script, e);
97 }
98 }
99
100
101
102
103
104
105
106
107
108
109 protected ScriptContext getScriptContext(ShibbolethFilteringContext filterContext, String attributeId,
110 Object attributeValue) {
111 SimpleScriptContext scriptContext = new SimpleScriptContext();
112 scriptContext.setAttribute("filterContext", filterContext, ScriptContext.ENGINE_SCOPE);
113 scriptContext.setAttribute("attributeId", attributeId, ScriptContext.ENGINE_SCOPE);
114 scriptContext.setAttribute("attributeValue", attributeValue, ScriptContext.ENGINE_SCOPE);
115 return scriptContext;
116 }
117
118
119
120
121
122
123
124
125
126
127 protected Boolean executeScript(ScriptContext scriptContext) throws FilterProcessingException {
128 Boolean result;
129 try {
130 if (compiledScript != null) {
131 result = (Boolean) compiledScript.eval(scriptContext);
132 } else {
133 result = (Boolean) scriptEngine.eval(script, scriptContext);
134 }
135
136 if (result != null) {
137 return result.booleanValue();
138 } else {
139 return Boolean.FALSE;
140 }
141 } catch (ScriptException e) {
142 throw new FilterProcessingException("Unable to execute match functor script", e);
143 }
144 }
145 }