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