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