]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java
Add license headers
[lgpl/argeo-commons.git] / security / runtime / org.argeo.security.core / src / main / java / org / argeo / security / ldap / ArgeoSecurityDaoLdap.java
index ae1fceea319ea0a122ab8bd0ef425c8082a1c194..350050bbcb5e30786cdebc7f747b0067e00dbd8e 100644 (file)
@@ -1,6 +1,22 @@
+/*
+ * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ *
+ * 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 org.argeo.security.ldap;
 
-import static org.argeo.security.core.ArgeoUserDetails.createBasicArgeoUser;
+import static org.argeo.security.core.ArgeoUserDetails.createSimpleArgeoUser;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -11,41 +27,95 @@ import javax.naming.directory.DirContext;
 
 import org.argeo.security.ArgeoSecurityDao;
 import org.argeo.security.ArgeoUser;
+import org.argeo.security.SimpleArgeoUser;
 import org.argeo.security.core.ArgeoUserDetails;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.ldap.core.ContextExecutor;
 import org.springframework.ldap.core.ContextMapper;
-import org.springframework.ldap.core.ContextSource;
 import org.springframework.ldap.core.DirContextAdapter;
 import org.springframework.ldap.core.DistinguishedName;
 import org.springframework.ldap.core.LdapTemplate;
+import org.springframework.ldap.core.support.BaseLdapPathContextSource;
+import org.springframework.security.Authentication;
+import org.springframework.security.context.SecurityContextHolder;
 import org.springframework.security.ldap.DefaultLdapUsernameToDnMapper;
+import org.springframework.security.ldap.LdapAuthoritiesPopulator;
 import org.springframework.security.ldap.LdapUsernameToDnMapper;
 import org.springframework.security.ldap.LdapUtils;
+import org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator;
+import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
 import org.springframework.security.userdetails.UserDetails;
 import org.springframework.security.userdetails.UserDetailsManager;
+import org.springframework.security.userdetails.UserDetailsService;
+import org.springframework.security.userdetails.ldap.LdapUserDetailsManager;
+import org.springframework.security.userdetails.ldap.LdapUserDetailsService;
+import org.springframework.security.userdetails.ldap.UserDetailsContextMapper;
 
 public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, InitializingBean {
        // private final static Log log = LogFactory.getLog(UserDaoLdap.class);
 
        private UserDetailsManager userDetailsManager;
-       private ArgeoLdapAuthoritiesPopulator authoritiesPopulator;
-       private String userBase = "ou=users";
-       private String usernameAttribute = "uid";
+       private LdapAuthoritiesPopulator authoritiesPopulator;
+       private String userBase = "ou=People";
+       private String usernameAttributeName = "uid";
+       private String groupBase = "ou=Roles";
+       private String[] groupClasses = { "top", "groupOfNames" };
+       private String groupRoleAttributeName = "cn";
+       private String groupMemberAttributeName = "member";
+       private String defaultRole = "ROLE_USER";
+       private String rolePrefix = "ROLE_";
 
+       private final BaseLdapPathContextSource contextSource;
        private final LdapTemplate ldapTemplate;
 
-       /* TODO: factorize with user details manager */
        private LdapUsernameToDnMapper usernameMapper = null;
 
+       private UserDetailsContextMapper userDetailsMapper;
+       private LdapUserDetailsService ldapUserDetailsService;
+       private List<UserNatureMapper> userNatureMappers;
+
        public void afterPropertiesSet() throws Exception {
                if (usernameMapper == null)
                        usernameMapper = new DefaultLdapUsernameToDnMapper(userBase,
-                                       usernameAttribute);
+                                       usernameAttributeName);
+
+               if (authoritiesPopulator == null) {
+                       DefaultLdapAuthoritiesPopulator ap = new DefaultLdapAuthoritiesPopulator(
+                                       ldapTemplate.getContextSource(), groupBase);
+                       ap.setDefaultRole(defaultRole);
+                       ap.setGroupSearchFilter(groupMemberAttributeName + "={0}");
+                       authoritiesPopulator = ap;
+               }
+
+               if (userDetailsMapper == null) {
+                       ArgeoUserDetailsContextMapper audm = new ArgeoUserDetailsContextMapper();
+                       audm.setUserNatureMappers(userNatureMappers);
+                       userDetailsMapper = audm;
+               }
+
+               if (userDetailsManager == null) {
+                       LdapUserDetailsManager ludm = new LdapUserDetailsManager(
+                                       ldapTemplate.getContextSource());
+                       ludm.setGroupSearchBase(groupBase);
+                       ludm.setUserDetailsMapper(userDetailsMapper);
+                       ludm.setUsernameMapper(usernameMapper);
+                       ludm.setGroupMemberAttributeName(groupMemberAttributeName);
+                       userDetailsManager = ludm;
+               }
+
+               if (ldapUserDetailsService == null) {
+                       FilterBasedLdapUserSearch ldapUserSearch = new FilterBasedLdapUserSearch(
+                                       userBase, "(" + usernameAttributeName + "={0})",
+                                       contextSource);
+                       ldapUserDetailsService = new LdapUserDetailsService(ldapUserSearch,
+                                       authoritiesPopulator);
+                       ldapUserDetailsService.setUserDetailsMapper(userDetailsMapper);
+               }
        }
 
-       public ArgeoSecurityDaoLdap(ContextSource contextSource) {
-               ldapTemplate = new LdapTemplate(contextSource);
+       public ArgeoSecurityDaoLdap(BaseLdapPathContextSource contextSource) {
+               this.contextSource = contextSource;
+               ldapTemplate = new LdapTemplate(this.contextSource);
        }
 
        public void create(ArgeoUser user) {
@@ -53,7 +123,24 @@ public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, InitializingBean
        }
 
        public ArgeoUser getUser(String uname) {
-               return createBasicArgeoUser(getDetails(uname));
+               SimpleArgeoUser user = createSimpleArgeoUser(getDetails(uname));
+               user.setPassword(null);
+               return user;
+       }
+
+       public ArgeoUser getUserWithPassword(String uname) {
+               return createSimpleArgeoUser(getDetails(uname));
+       }
+
+       public ArgeoUser getCurrentUser() {
+               Authentication authentication = SecurityContextHolder.getContext()
+                               .getAuthentication();
+               ArgeoUser argeoUser = ArgeoUserDetails.asArgeoUser(authentication);
+               if (argeoUser == null)
+                       return null;
+               if (argeoUser.getRoles().contains(defaultRole))
+                       argeoUser.getRoles().remove(defaultRole);
+               return argeoUser;
        }
 
        @SuppressWarnings("unchecked")
@@ -62,30 +149,28 @@ public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, InitializingBean
                                new DistinguishedName(userBase), new ContextMapper() {
                                        public Object mapFromContext(Object ctxArg) {
                                                DirContextAdapter ctx = (DirContextAdapter) ctxArg;
-                                               return ctx.getStringAttribute(usernameAttribute);
+                                               return ctx.getStringAttribute(usernameAttributeName);
                                        }
                                });
 
                List<ArgeoUser> lst = new ArrayList<ArgeoUser>();
                for (String username : usernames) {
-                       lst.add(createBasicArgeoUser(getDetails(username)));
+                       lst.add(createSimpleArgeoUser(getDetails(username)));
                }
                return lst;
        }
 
        @SuppressWarnings("unchecked")
        public List<String> listEditableRoles() {
-               return (List<String>) ldapTemplate.listBindings(authoritiesPopulator
-                               .getGroupSearchBase(), new ContextMapper() {
-                       public Object mapFromContext(Object ctxArg) {
-                               String groupName = ((DirContextAdapter) ctxArg)
-                                               .getStringAttribute(authoritiesPopulator
-                                                               .getGroupRoleAttribute());
-                               String roleName = authoritiesPopulator
-                                               .convertGroupToRole(groupName);
-                               return roleName;
-                       }
-               });
+               return (List<String>) ldapTemplate.listBindings(groupBase,
+                               new ContextMapper() {
+                                       public Object mapFromContext(Object ctxArg) {
+                                               String groupName = ((DirContextAdapter) ctxArg)
+                                                               .getStringAttribute(groupRoleAttributeName);
+                                               String roleName = convertGroupToRole(groupName);
+                                               return roleName;
+                                       }
+                               });
        }
 
        public void update(ArgeoUser user) {
@@ -96,10 +181,6 @@ public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, InitializingBean
                userDetailsManager.deleteUser(username);
        }
 
-       public void updatePassword(String oldPassword, String newPassword) {
-               userDetailsManager.changePassword(oldPassword, newPassword);
-       }
-
        public Boolean userExists(String username) {
                return userDetailsManager.userExists(username);
        }
@@ -117,12 +198,12 @@ public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, InitializingBean
 
                Name groupDn = buildGroupDn(group);
                DirContextAdapter context = new DirContextAdapter();
-               context.setAttributeValues("objectClass", new String[] { "top",
-                               "groupOfUniqueNames" });
+               context.setAttributeValues("objectClass", groupClasses);
                context.setAttributeValue("cn", group);
 
                // Add superuser because cannot create empty group
-               context.setAttributeValue("uniqueMember", superuserDn.toString());
+               context.setAttributeValue(groupMemberAttributeName, superuserDn
+                               .toString());
 
                ldapTemplate.bind(groupDn, context, null);
        }
@@ -134,18 +215,23 @@ public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, InitializingBean
        }
 
        protected String convertRoleToGroup(String role) {
-               // FIXME: factorize with spring security
                String group = role;
-               if (group.startsWith("ROLE_")) {
-                       group = group.substring("ROLE_".length());
+               if (group.startsWith(rolePrefix)) {
+                       group = group.substring(rolePrefix.length());
                        group = group.toLowerCase();
                }
                return group;
        }
 
+       public String convertGroupToRole(String groupName) {
+               groupName = groupName.toUpperCase();
+
+               return rolePrefix + groupName;
+       }
+
        protected Name buildGroupDn(String name) {
-               return new DistinguishedName("cn=" + name + ","
-                               + authoritiesPopulator.getGroupSearchBase());
+               return new DistinguishedName(groupRoleAttributeName + "=" + name + ","
+                               + groupBase);
        }
 
        public void setUserDetailsManager(UserDetailsManager userDetailsManager) {
@@ -156,16 +242,69 @@ public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, InitializingBean
                this.userBase = userBase;
        }
 
-       public void setUsernameAttribute(String usernameAttribute) {
-               this.usernameAttribute = usernameAttribute;
+       public void setUsernameAttributeName(String usernameAttribute) {
+               this.usernameAttributeName = usernameAttribute;
        }
 
        public void setAuthoritiesPopulator(
-                       ArgeoLdapAuthoritiesPopulator authoritiesPopulator) {
+                       LdapAuthoritiesPopulator authoritiesPopulator) {
                this.authoritiesPopulator = authoritiesPopulator;
        }
 
        protected UserDetails getDetails(String username) {
                return userDetailsManager.loadUserByUsername(username);
        }
+
+       public void setGroupBase(String groupBase) {
+               this.groupBase = groupBase;
+       }
+
+       public void setGroupRoleAttributeName(String groupRoleAttributeName) {
+               this.groupRoleAttributeName = groupRoleAttributeName;
+       }
+
+       public void setGroupMemberAttributeName(String groupMemberAttributeName) {
+               this.groupMemberAttributeName = groupMemberAttributeName;
+       }
+
+       public void setDefaultRole(String defaultRole) {
+               this.defaultRole = defaultRole;
+       }
+
+       public void setRolePrefix(String rolePrefix) {
+               this.rolePrefix = rolePrefix;
+       }
+
+       public void setUsernameMapper(LdapUsernameToDnMapper usernameMapper) {
+               this.usernameMapper = usernameMapper;
+       }
+
+       public void setUserDetailsMapper(UserDetailsContextMapper userDetailsMapper) {
+               this.userDetailsMapper = userDetailsMapper;
+       }
+
+       public LdapAuthoritiesPopulator getAuthoritiesPopulator() {
+               return authoritiesPopulator;
+       }
+
+       public UserDetailsContextMapper getUserDetailsMapper() {
+               return userDetailsMapper;
+       }
+
+       public void setUserNatureMappers(List<UserNatureMapper> userNatureMappers) {
+               this.userNatureMappers = userNatureMappers;
+       }
+
+       public String getDefaultRole() {
+               return defaultRole;
+       }
+
+       public void setGroupClasses(String[] groupClasses) {
+               this.groupClasses = groupClasses;
+       }
+
+       public UserDetailsService getUserDetailsService() {
+               return ldapUserDetailsService;
+       }
+
 }