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