/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.springldap;
import java.util.Map;
import java.util.function.BiFunction;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.ModificationItem;
import org.apache.camel.Exchange;
import org.apache.camel.impl.DefaultProducer;
import org.apache.commons.lang.StringUtils;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.core.LdapOperations;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.BaseLdapPathContextSource;
import org.springframework.ldap.query.LdapQueryBuilder;
public class SpringLdapProducer extends DefaultProducer {
public static final String DN = "dn";
public static final String FILTER = "filter";
public static final String ATTRIBUTES = "attributes";
public static final String PASSWORD = "password";
public static final String MODIFICATION_ITEMS = "modificationItems";
public static final String FUNCTION = "function";
public static final String REQUEST = "request";
SpringLdapEndpoint endpoint;
private AttributesMapper<Object> mapper = new AttributesMapper<Object>() {
@Override
public Object mapFromAttributes(Attributes attributes) throws NamingException {
return attributes;
}
};
/**
* Initializes the SpringLdapProducer with the given endpoint
*/
public SpringLdapProducer(SpringLdapEndpoint endpoint) {
super(endpoint);
this.endpoint = endpoint;
}
/**
* Performs the LDAP operation defined in SpringLdapEndpoint that created
* this producer. The in-message in the exchange must be a map, containing
* the following entries:
*
* <pre>
* key: "dn" - base DN for the LDAP operation
* key: "filter" - necessary for the search operation only; LDAP filter for the search operation,
* see <a http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol>http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol</a>
* key: "attributes" - necessary for the bind operation only; an instance of javax.naming.directory.Attributes,
* containing the information necessary to create an LDAP node.
* key: "password" - necessary for the authentication operation only;
* key: "modificationItems" - necessary for the modify_attributes operation only;
* key: "function" - necessary for the function_driven operation only; provides a flexible hook into the {@link LdapTemplate} to call any method
* key: "request" - necessary for the function_driven operation only; passed into the "function" to enable the client to bind parameters that need to be passed into the {@link LdapTemplate}
* </pre>
*
* The keys are defined as final fields above.
*/
@Override
public void process(Exchange exchange) throws Exception {
@SuppressWarnings("unchecked")
Map<String, Object> body = exchange.getIn().getBody(Map.class);
LdapOperation operation = endpoint.getOperation();
if (null == operation) {
throw new UnsupportedOperationException("LDAP operation must not be empty, but you provided an empty operation");
}
LdapTemplate ldapTemplate = endpoint.getLdapTemplate();
String dn = (String)body.get(DN);
if (StringUtils.isBlank(dn)) {
ContextSource contextSource = ldapTemplate.getContextSource();
if (contextSource instanceof BaseLdapPathContextSource) {
dn = ((BaseLdapPathContextSource) contextSource).getBaseLdapPathAsString();
}
}
if (operation != LdapOperation.FUNCTION_DRIVEN && (StringUtils.isBlank(dn))) {
throw new UnsupportedOperationException("DN must not be empty, but you provided an empty DN");
}
switch (operation) {
case SEARCH:
String filter = (String)body.get(FILTER);
exchange.getIn().setBody(ldapTemplate.search(dn, filter, endpoint.scopeValue(), mapper));
break;
case BIND:
Attributes attributes = (Attributes)body.get(ATTRIBUTES);
ldapTemplate.bind(dn, null, attributes);
break;
case UNBIND:
ldapTemplate.unbind(dn);
break;
case AUTHENTICATE:
ldapTemplate.authenticate(LdapQueryBuilder.query().base(dn).filter((String)body.get(FILTER)), (String)body.get(PASSWORD));
break;
case MODIFY_ATTRIBUTES:
ModificationItem[] modificationItems = (ModificationItem[])body.get(MODIFICATION_ITEMS);
ldapTemplate.modifyAttributes(dn, modificationItems);
break;
case FUNCTION_DRIVEN:
BiFunction<LdapOperations, Object, ?> ldapOperationFunction = (BiFunction<LdapOperations, Object, ?>)body.get(FUNCTION);
Object ldapOperationRequest = body.get(REQUEST);
exchange.getIn().setBody(ldapOperationFunction.apply(ldapTemplate, ldapOperationRequest));
break;
default:
throw new UnsupportedOperationException("Bug in the Spring-LDAP component. Despite of all assertions, you managed to call an unsupported operation '" + operation
+ "'");
}
}
}