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.resolver.provider.attributeDefinition;
19
20 import java.util.Map;
21
22 import javax.script.Compilable;
23 import javax.script.CompiledScript;
24 import javax.script.ScriptContext;
25 import javax.script.ScriptEngine;
26 import javax.script.ScriptEngineManager;
27 import javax.script.ScriptException;
28 import javax.script.SimpleScriptContext;
29
30 import org.opensaml.xml.util.DatatypeHelper;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 import edu.internet2.middleware.shibboleth.common.attribute.BaseAttribute;
35 import edu.internet2.middleware.shibboleth.common.attribute.resolver.AttributeResolutionException;
36 import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.ResolutionPlugIn;
37 import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.ShibbolethResolutionContext;
38 import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.dataConnector.DataConnector;
39
40
41
42
43
44 public class ScriptedAttributeDefinition extends BaseAttributeDefinition {
45
46
47 private final Logger log = LoggerFactory.getLogger(ScriptedAttributeDefinition.class);
48
49
50 private String scriptLanguage;
51
52
53 private String script;
54
55
56 private ScriptEngine scriptEngine;
57
58
59 private CompiledScript compiledScript;
60
61
62
63
64
65
66 public ScriptedAttributeDefinition(String language) {
67 scriptLanguage = language;
68 }
69
70
71
72
73
74
75 public String getScriptLanguage() {
76 return scriptLanguage;
77 }
78
79
80
81
82
83
84 public String getScript() {
85 return script;
86 }
87
88
89
90
91
92
93 public void setScript(String newScript) {
94 script = newScript;
95 compileScript();
96 }
97
98
99 public void initialize() {
100 ScriptEngineManager sem = new ScriptEngineManager();
101 scriptEngine = sem.getEngineByName(scriptLanguage);
102 compileScript();
103 }
104
105
106 public void validate() throws AttributeResolutionException {
107 if (scriptEngine == null) {
108 log.error("ScriptletAttributeDefinition " + getId()
109 + " unable to create scripting engine for the language: " + scriptLanguage);
110 throw new AttributeResolutionException("ScriptletAttributeDefinition " + getId()
111 + " unable to create scripting engine for the language: " + scriptLanguage);
112 }
113 }
114
115
116 protected BaseAttribute<?> doResolve(ShibbolethResolutionContext resolutionContext)
117 throws AttributeResolutionException {
118 ScriptContext context = getScriptContext(resolutionContext);
119
120 try {
121 if (compiledScript != null) {
122 compiledScript.eval(context);
123 } else {
124 scriptEngine.eval(script, context);
125 }
126
127 BaseAttribute attribute = (BaseAttribute) context.getAttribute(getId());
128 if (attribute == null) {
129 log.error("{} produced a null attribute", getId());
130 throw new AttributeResolutionException(getId() + " produced a null attributes");
131 }
132
133 return attribute;
134 } catch (ScriptException e) {
135 log.error("ScriptletAttributeDefinition " + getId() + " unable to execute script", e);
136 throw new AttributeResolutionException("ScriptletAttributeDefinition " + getId()
137 + " unable to execute script", e);
138 }
139 }
140
141
142 protected void compileScript() {
143 if (DatatypeHelper.isEmpty(script)) {
144 return;
145 }
146
147 try {
148 if (scriptEngine != null && scriptEngine instanceof Compilable) {
149 compiledScript = ((Compilable) scriptEngine).compile(script);
150 }
151 } catch (ScriptException e) {
152 compiledScript = null;
153 log.warn("{} unable to compile even though the scripting engine supports this functionality.", getId());
154 }
155 }
156
157
158
159
160
161
162
163
164
165
166
167 protected ScriptContext getScriptContext(ShibbolethResolutionContext resolutionContext)
168 throws AttributeResolutionException {
169 SimpleScriptContext scriptContext = new SimpleScriptContext();
170 scriptContext.setAttribute(getId(), null, ScriptContext.ENGINE_SCOPE);
171
172 scriptContext.setAttribute("requestContext", resolutionContext.getAttributeRequestContext(),
173 ScriptContext.ENGINE_SCOPE);
174
175 ResolutionPlugIn plugin;
176 Map<String, BaseAttribute> attributes;
177 BaseAttribute attribute;
178
179 if (!getDependencyIds().isEmpty()) {
180 for (String dependency : getDependencyIds()) {
181 plugin = resolutionContext.getResolvedPlugins().get(dependency);
182 if (plugin instanceof DataConnector) {
183 attributes = ((DataConnector) plugin).resolve(resolutionContext);
184 if (attributes != null) {
185 for (BaseAttribute attr : attributes.values()) {
186 scriptContext.setAttribute(attr.getId(), attr, ScriptContext.ENGINE_SCOPE);
187 }
188 }
189 } else if (plugin instanceof AttributeDefinition) {
190 attribute = ((AttributeDefinition) plugin).resolve(resolutionContext);
191 if (attribute != null) {
192 scriptContext.setAttribute(attribute.getId(), attribute, ScriptContext.ENGINE_SCOPE);
193 }
194 }
195 }
196 }
197
198 return scriptContext;
199 }
200 }