001package co.codewizards.cloudstore.rest.server.ldap; 002 003import java.util.List; 004 005import org.slf4j.Logger; 006import org.slf4j.LoggerFactory; 007 008import co.codewizards.cloudstore.core.config.ConfigImpl; 009import co.codewizards.cloudstore.core.otp.LdapPasswordOneTimePadRegistry; 010import co.codewizards.cloudstore.core.otp.OneTimePadRegistry; 011import co.codewizards.cloudstore.core.util.StringUtil; 012 013/** 014 * Fail-safe initializer of choosen LdapClient implementation. 015 * <p> 016 * Since LDAP-based authentication is optional - this class won't throw any Exception 017 * during initialization, until you call getClient(). 018 * <p> 019 * Choice of proper LdapClient implementation is based on configuration in cloudstore.properties config file. 020 * 021 * @author Wojtek Wilk - wilk.wojtek at gmail.com 022 */ 023public class LdapClientProvider { 024 025 private static final Logger log = LoggerFactory.getLogger(LdapClientProvider.class); 026 027 public static final String LDAP_TEMPLATE_PATTERN = "ldap.bindDnTemplate[%d]"; 028 029 public static final String LDAP_URL = "ldap.url"; 030 private static final String LDAP_URL_DEFAULT = "ldap://localhost:389"; 031 032 public static final String LDAP_QUERY = "ldap.query"; 033 public static final String LDAP_ADMIN_DN = "ldap.adminDn"; 034 public static final String LDAP_QUERY_DN = "ldap.queryDn"; 035 036 private LdapClient ldapClient; 037 038 protected LdapClientProvider(){ 039 this(new LdapPasswordOneTimePadRegistry()); 040 } 041 042 protected LdapClientProvider(OneTimePadRegistry adminPasswordRegistry){ 043 try{ 044 final String url = ConfigImpl.getInstance().getProperty(LDAP_URL, LDAP_URL_DEFAULT); 045 final String query = ConfigImpl.getInstance().getProperty(LDAP_QUERY, ""); 046 if(StringUtil.isEmpty(query)){ 047 ldapClient = createSimpleLdapClient(url); 048 } else{ 049 ldapClient = createQueryLdapClient(adminPasswordRegistry, query, url); 050 } 051 } catch(Exception e){ 052 log.warn("LDAP client initialization failed. If you don't use LDAP you can ignore this warning, otherwise you can increase logging to DEBUG in order to see what is the cause of this failure."); 053 log.debug("LDAP client initialization failed", e); 054 } 055 } 056 057 public LdapClient getClient(){ 058 if(ldapClient == null){ 059 throw new IllegalStateException("LDAP is not properly configured. Maybe you forgot to put LDAP properties inside cloudstore.properties?"); 060 } 061 return ldapClient; 062 } 063 064 public static LdapClientProvider getInstance(){ 065 return Helper.INSTANCE; 066 } 067 068 private static class Helper{ 069 private static final LdapClientProvider INSTANCE = new LdapClientProvider(); 070 } 071 072 private SimpleLdapClient createSimpleLdapClient(final String url){ 073 final List<String> templates = new DnTemplateCollector().collect(); 074 return new SimpleLdapClient(templates, url); 075 } 076 077 private QueryLdapClient createQueryLdapClient(final OneTimePadRegistry adminPasswordRegistry, 078 final String query, final String url){ 079 final char[] password = adminPasswordRegistry.readFromFileAndDecrypt(); 080 final String queryDn = ConfigImpl.getInstance().getProperty(LDAP_QUERY_DN, null); 081 final String adminDn = ConfigImpl.getInstance().getProperty(LDAP_ADMIN_DN, null); 082 return new QueryLdapClient(query, queryDn, url, adminDn, password); 083 } 084}