/* * Licensed 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 com.teradata.tempto.internal.fulfillment.ldap; import com.teradata.tempto.fulfillment.ldap.LdapObjectDefinition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Inject; import javax.inject.Named; import javax.naming.Context; import javax.naming.NameAlreadyBoundException; import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttribute; import javax.naming.directory.BasicAttributes; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import javax.naming.directory.ModificationItem; import java.util.Hashtable; import java.util.List; import static com.google.common.base.Preconditions.checkNotNull; import static java.lang.String.format; import static java.util.Objects.requireNonNull; import static java.util.stream.Collectors.toList; public class DefaultLdapObjectEntryManager implements LdapObjectEntryManager { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultLdapObjectEntryManager.class); private final String ldapUrl; private final String ldapAdminDistinguishedName; private final String ldapAdminPassword; @Inject public DefaultLdapObjectEntryManager( @Named("ldap.url") String ldapUrl, @Named("ldap.admin.dn") String ldapAdminDistinguishedName, @Named("ldap.admin.password") String ldapAdminPassword) { this.ldapUrl = requireNonNull(ldapUrl, "ldapUrl is null"); this.ldapAdminDistinguishedName = requireNonNull(ldapAdminDistinguishedName, "ldapAdminDistinguishedName is null"); this.ldapAdminPassword = requireNonNull(ldapAdminPassword, "ldapAdminPassword is null"); } private DirContext createContext(String ldapUrl, String ldapAdminDistinguishedName, String ldapAdminPassword) { Hashtable<String, String> environment = new Hashtable<>(); environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); environment.put(Context.PROVIDER_URL, ldapUrl); environment.put(Context.SECURITY_AUTHENTICATION, "simple"); environment.put(Context.SECURITY_PRINCIPAL, ldapAdminDistinguishedName); environment.put(Context.SECURITY_CREDENTIALS, ldapAdminPassword); try { return new InitialDirContext(environment); } catch (NamingException e) { throw new RuntimeException("Connection to LDAP server failed", e); } } private void closeQuietly(DirContext context) { try { if (context != null) { context.close(); } } catch (NamingException e) { // ignore } } private String addLdapDefinition(LdapObjectDefinition ldapObjectDefinition, DirContext context) { checkNotNull(ldapObjectDefinition, "LDAP Object Definition is null"); Attributes entries = new BasicAttributes(); Attribute objectClass = new BasicAttribute("objectClass"); ldapObjectDefinition.getAttributes() .forEach((k, v) -> entries.put(new BasicAttribute(k, v))); List<ModificationItem> modificationItems = ldapObjectDefinition.getModificationAttributes().entrySet().stream() .flatMap(entry -> entry.getValue().stream() .map(attribute -> new ModificationItem(DirContext.ADD_ATTRIBUTE, new BasicAttribute(entry.getKey(), attribute)))) .collect(toList()); ldapObjectDefinition.getObjectClasses() .forEach(objectClass::add); entries.put(objectClass); try { context.createSubcontext(ldapObjectDefinition.getDistinguishedName(), entries); context.modifyAttributes(ldapObjectDefinition.getDistinguishedName(), modificationItems.stream().toArray(ModificationItem[]::new)); LOGGER.info("Successfully added entry " + ldapObjectDefinition.getId()); } catch (NameAlreadyBoundException e) { LOGGER.info(format("LDAP Entry %s already exists. Ignoring...", ldapObjectDefinition.getId())); } catch (NamingException e) { throw new RuntimeException("LDAP Entry addition failed", e); } return ldapObjectDefinition.getId(); } @Override public void addLdapDefinitions(List<LdapObjectDefinition> ldapObjectDefinitions) { DirContext context = createContext(ldapUrl, ldapAdminDistinguishedName, ldapAdminPassword); try { for (LdapObjectDefinition ldapObjectDefinition : ldapObjectDefinitions) { addLdapDefinition(ldapObjectDefinition, context); } } finally { closeQuietly(context); } } }