1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package edu.internet2.middleware.shibboleth.common.config.attribute.resolver.dataConnector;
18
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.StringTokenizer;
23
24 import javax.xml.namespace.QName;
25
26 import org.opensaml.xml.util.DatatypeHelper;
27 import org.opensaml.xml.util.XMLHelper;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30 import org.springframework.beans.factory.config.RuntimeBeanReference;
31 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
32 import org.springframework.beans.factory.xml.ParserContext;
33 import org.w3c.dom.Element;
34
35 import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.dataConnector.LdapDataConnector.AUTHENTICATION_TYPE;
36 import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.dataConnector.LdapDataConnector.SEARCH_SCOPE;
37 import edu.internet2.middleware.shibboleth.common.config.SpringConfigurationUtils;
38
39
40 public class LdapDataConnectorBeanDefinitionParser extends BaseDataConnectorBeanDefinitionParser {
41
42
43 public static final QName TYPE_NAME = new QName(DataConnectorNamespaceHandler.NAMESPACE, "LDAPDirectory");
44
45
46 private final Logger log = LoggerFactory.getLogger(LdapDataConnectorBeanDefinitionParser.class);
47
48
49 protected Class getBeanClass(Element element) {
50 return LdapDataConnectorFactoryBean.class;
51 }
52
53
54 protected void doParse(String pluginId, Element pluginConfig, Map<QName, List<Element>> pluginConfigChildren,
55 BeanDefinitionBuilder pluginBuilder, ParserContext parserContext) {
56 super.doParse(pluginId, pluginConfig, pluginConfigChildren, pluginBuilder, parserContext);
57
58 String ldapURL = pluginConfig.getAttributeNS(null, "ldapURL");
59 log.debug("Data connector {} LDAP URL: {}", pluginId, ldapURL);
60 pluginBuilder.addPropertyValue("ldapUrl", ldapURL);
61
62 String baseDN = pluginConfig.getAttributeNS(null, "baseDN");
63 log.debug("Data connector {} base DN: {}", pluginId, baseDN);
64 pluginBuilder.addPropertyValue("baseDN", baseDN);
65
66 AUTHENTICATION_TYPE authnType = AUTHENTICATION_TYPE.SIMPLE;
67 if (pluginConfig.hasAttributeNS(null, "authenticationType")) {
68 authnType = AUTHENTICATION_TYPE.valueOf(pluginConfig.getAttributeNS(null, "authenticationType"));
69 }
70 log.debug("Data connector {} authentication type: {}", pluginId, authnType);
71 pluginBuilder.addPropertyValue("authenticationType", authnType);
72
73 String principal = pluginConfig.getAttributeNS(null, "principal");
74 log.debug("Data connector {} principal: {}", pluginId, principal);
75 pluginBuilder.addPropertyValue("principal", principal);
76
77 String credential = pluginConfig.getAttributeNS(null, "principalCredential");
78 pluginBuilder.addPropertyValue("principalCredential", credential);
79
80 String filterTemplate = pluginConfigChildren.get(
81 new QName(DataConnectorNamespaceHandler.NAMESPACE, "FilterTemplate")).get(0).getTextContent();
82 filterTemplate = DatatypeHelper.safeTrimOrNullString(filterTemplate);
83 log.debug("Data connector {} LDAP filter template: {}", pluginId, filterTemplate);
84 pluginBuilder.addPropertyValue("filterTemplate", filterTemplate);
85
86 SEARCH_SCOPE searchScope = SEARCH_SCOPE.SUBTREE;
87 if (pluginConfig.hasAttributeNS(null, "searchScope")) {
88 searchScope = SEARCH_SCOPE.valueOf(pluginConfig.getAttributeNS(null, "searchScope"));
89 }
90 log.debug("Data connector {} search scope: {}", pluginId, searchScope);
91 pluginBuilder.addPropertyValue("searchScope", searchScope);
92
93 String[] returnAttributes = processReturnAttributes(pluginConfigChildren.get(new QName(
94 DataConnectorNamespaceHandler.NAMESPACE, "ReturnAttributes")));
95 log.debug("Data connector {} return attributes: {}", pluginId, returnAttributes);
96 pluginBuilder.addPropertyValue("returnAttributes", returnAttributes);
97
98 Map<String, String> ldapProperties = processLDAPProperties(pluginConfigChildren.get(new QName(
99 DataConnectorNamespaceHandler.NAMESPACE, "LDAPProperty")));
100 log.debug("Data connector {} LDAP properties: {}", pluginId, ldapProperties);
101 pluginBuilder.addPropertyValue("ldapProperties", ldapProperties);
102
103 RuntimeBeanReference trustCredential = processCredential(pluginConfigChildren.get(new QName(
104 DataConnectorNamespaceHandler.NAMESPACE, "StartTLSTrustCredential")), parserContext);
105 log.debug("Data connector {} using provided SSL/TLS trust material", pluginId);
106 pluginBuilder.addPropertyValue("trustCredential", trustCredential);
107
108 RuntimeBeanReference connectionCredential = processCredential(pluginConfigChildren.get(new QName(
109 DataConnectorNamespaceHandler.NAMESPACE, "StartTLSAuthenticationCredential")), parserContext);
110 log.debug("Data connector {} using provided SSL/TLS client authentication material", pluginId);
111 pluginBuilder.addPropertyValue("connectionCredential", connectionCredential);
112
113 boolean useStartTLS = false;
114 if (pluginConfig.hasAttributeNS(null, "useStartTLS")) {
115 useStartTLS = XMLHelper.getAttributeValueAsBoolean(pluginConfig.getAttributeNodeNS(null, "useStartTLS"));
116 }
117 log.debug("Data connector {} use startTLS: {}", pluginId, useStartTLS);
118 pluginBuilder.addPropertyValue("useStartTLS", useStartTLS);
119
120 int poolInitialSize = 0;
121 if (pluginConfig.hasAttributeNS(null, "poolInitialSize")) {
122 poolInitialSize = Integer.parseInt(pluginConfig.getAttributeNS(null, "poolInitialSize"));
123 }
124 log.debug("Data connector {} initial connection pool size: {}", pluginId, poolInitialSize);
125 pluginBuilder.addPropertyValue("poolInitialSize", poolInitialSize);
126
127 int poolMaxIdleSize = 3;
128 if (pluginConfig.hasAttributeNS(null, "poolMaxIdleSize")) {
129 poolMaxIdleSize = Integer.parseInt(pluginConfig.getAttributeNS(null, "poolMaxIdleSize"));
130 }
131 log.debug("Data connector {} maximum idle connection pool size: {}", pluginId, poolMaxIdleSize);
132 pluginBuilder.addPropertyValue("poolMaxIdleSize", poolMaxIdleSize);
133
134 int searchTimeLimit = 3000;
135 if (pluginConfig.hasAttributeNS(null, "searchTimeLimit")) {
136 searchTimeLimit = Integer.parseInt(pluginConfig.getAttributeNS(null, "searchTimeLimit"));
137 }
138 log.debug("Data connector {} search timeout: {}ms", pluginId, searchTimeLimit);
139 pluginBuilder.addPropertyValue("searchTimeLimit", searchTimeLimit);
140
141 int maxResultSize = 1;
142 if (pluginConfig.hasAttributeNS(null, "maxResultSize")) {
143 maxResultSize = Integer.parseInt(pluginConfig.getAttributeNS(null, "maxResultSize"));
144 }
145 log.debug("Data connector {} max search result size: {}", pluginId, maxResultSize);
146 pluginBuilder.addPropertyValue("maxResultSize", maxResultSize);
147
148 boolean cacheResults = false;
149 if (pluginConfig.hasAttributeNS(null, "cacheResults")) {
150 cacheResults = XMLHelper.getAttributeValueAsBoolean(pluginConfig.getAttributeNodeNS(null, "cacheResults"));
151 }
152 log.debug("Data connector {} cache results: {}", pluginId, cacheResults);
153 pluginBuilder.addPropertyValue("cacheResults", cacheResults);
154
155 boolean mergeResults = false;
156 if (pluginConfig.hasAttributeNS(null, "mergeResults")) {
157 mergeResults = XMLHelper.getAttributeValueAsBoolean(pluginConfig.getAttributeNodeNS(null, "mergeResults"));
158 }
159 log.debug("Data connector{} merge results: {}", pluginId, mergeResults);
160 pluginBuilder.addPropertyValue("mergeResults", mergeResults);
161
162 boolean noResultsIsError = false;
163 if (pluginConfig.hasAttributeNS(null, "noResultIsError")) {
164 noResultsIsError = XMLHelper.getAttributeValueAsBoolean(pluginConfig.getAttributeNodeNS(null,
165 "noResultIsError"));
166 }
167 log.debug("Data connector {} no results is error: {}", pluginId, noResultsIsError);
168 pluginBuilder.addPropertyValue("noResultsIsError", noResultsIsError);
169
170 String templateEngineRef = pluginConfig.getAttributeNS(null, "templateEngine");
171 pluginBuilder.addPropertyReference("templateEngine", templateEngineRef);
172 }
173
174
175
176
177
178
179
180
181 protected String[] processReturnAttributes(List<Element> returnAttributes) {
182 if (returnAttributes == null || returnAttributes.size() == 0) {
183 return null;
184 }
185
186 StringTokenizer attributeTokens = new StringTokenizer(returnAttributes.get(0).getTextContent(), " ");
187 String[] attributes = new String[attributeTokens.countTokens()];
188 for (int i = 0; attributeTokens.hasMoreTokens(); i++) {
189 attributes[i] = DatatypeHelper.safeTrimOrNullString(attributeTokens.nextToken());
190 }
191
192 return attributes;
193 }
194
195
196
197
198
199
200
201
202 protected Map<String, String> processLDAPProperties(List<Element> propertyElems) {
203 HashMap<String, String> properties = new HashMap<String, String>(5);
204
205 String propName;
206 String propValue;
207 if (propertyElems != null) {
208 for (Element propertyElem : propertyElems) {
209 propName = DatatypeHelper.safeTrimOrNullString(propertyElem.getAttributeNS(null, "name"));
210 propValue = DatatypeHelper.safeTrimOrNullString(propertyElem.getAttributeNS(null, "value"));
211 properties.put(propName, propValue);
212 }
213 }
214
215 return properties;
216 }
217
218
219
220
221
222
223
224
225
226 protected RuntimeBeanReference processCredential(List<Element> credentials, ParserContext parserContext) {
227 if (credentials == null) {
228 return null;
229 }
230
231 Element credentialElem = credentials.get(0);
232 return SpringConfigurationUtils.parseCustomElement(credentialElem, parserContext);
233 }
234 }