001package co.codewizards.cloudstore.rest.server.ldap;
002
003import static co.codewizards.cloudstore.core.util.AssertUtil.*;
004import static java.util.Objects.*;
005
006import java.util.HashMap;
007import java.util.List;
008import java.util.Map;
009
010import javax.naming.AuthenticationException;
011import javax.naming.NamingException;
012import javax.naming.directory.InitialDirContext;
013
014import co.codewizards.cloudstore.core.util.IOUtil;
015import co.codewizards.cloudstore.rest.server.auth.Auth;
016import co.codewizards.cloudstore.rest.server.auth.NotAuthorizedException;
017
018/**
019 * Simple implementation of LdapClient.
020 * <p>
021 * It is initialized with a list of DN templates, that are used to authenticate user.
022 * Example DN template:
023 * cn=${login}+sn=secret,ou=users,dc=example,dc=com
024 * Where login is user's name provided by user.
025 *
026 * @author Wojtek Wilk - wilk.wojtek at gmail.com
027 */
028public class SimpleLdapClient implements LdapClient{
029
030        private static final String TEMPLATE_VARIABLE = "login";
031
032        private final List<String> templates;
033        private final String url;
034
035        public SimpleLdapClient(final List<String> templates, final String url){
036                this.templates = assertNotEmpty(templates, "templates");
037                validateTemplates(templates);
038                this.url = requireNonNull(url, "url");
039        }
040
041        @Override
042        public String authenticate(final Auth auth){
043                for(String template : templates){
044                        String userNameTemplate = convertTemplate(template, auth.getUserName());
045                        LdapConfig config = new LdapConfig(url, userNameTemplate, auth.getPassword());
046                        if(tryAuthenticate(config)){
047                                return auth.getUserName();
048                        }
049                }
050                throw new NotAuthorizedException();
051        }
052
053        private boolean tryAuthenticate(LdapConfig env){
054                try {
055                        new InitialDirContext(env);
056                        return true;
057                } catch (AuthenticationException e) {
058                        return false;
059                } catch(NamingException e){
060                        throw new RuntimeException(e);
061                }
062        }
063
064        private String convertTemplate(final String template, final String username){
065                final Map<String, String> map = new HashMap<String, String>(1);
066                map.put(TEMPLATE_VARIABLE, username);
067                return IOUtil.replaceTemplateVariables(template, map);
068        }
069
070        private void validateTemplates(List<String> templates){
071                String variable = "${" + TEMPLATE_VARIABLE + "}";
072                for(String template : templates){
073                        if(!template.contains(variable))
074                                throw new IllegalArgumentException("every template has to contain " + variable);
075                }
076        }
077
078}