X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=security%2Fruntime%2Forg.argeo.security.core%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fsecurity%2Fldap%2FArgeoSecurityDaoLdap.java;fp=security%2Fruntime%2Forg.argeo.security.core%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fsecurity%2Fldap%2FArgeoSecurityDaoLdap.java;h=ae1fceea319ea0a122ab8bd0ef425c8082a1c194;hb=ec59a58bc368dc922a454d52eb70bb91dfd68793;hp=0000000000000000000000000000000000000000;hpb=b00a7e9898ea2819100290cab22bf614e23a3abf;p=lgpl%2Fargeo-commons.git diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java new file mode 100644 index 000000000..ae1fceea3 --- /dev/null +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java @@ -0,0 +1,171 @@ +package org.argeo.security.ldap; + +import static org.argeo.security.core.ArgeoUserDetails.createBasicArgeoUser; + +import java.util.ArrayList; +import java.util.List; + +import javax.naming.Name; +import javax.naming.NamingException; +import javax.naming.directory.DirContext; + +import org.argeo.security.ArgeoSecurityDao; +import org.argeo.security.ArgeoUser; +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.security.ldap.DefaultLdapUsernameToDnMapper; +import org.springframework.security.ldap.LdapUsernameToDnMapper; +import org.springframework.security.ldap.LdapUtils; +import org.springframework.security.userdetails.UserDetails; +import org.springframework.security.userdetails.UserDetailsManager; + +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 final LdapTemplate ldapTemplate; + + /* TODO: factorize with user details manager */ + private LdapUsernameToDnMapper usernameMapper = null; + + public void afterPropertiesSet() throws Exception { + if (usernameMapper == null) + usernameMapper = new DefaultLdapUsernameToDnMapper(userBase, + usernameAttribute); + } + + public ArgeoSecurityDaoLdap(ContextSource contextSource) { + ldapTemplate = new LdapTemplate(contextSource); + } + + public void create(ArgeoUser user) { + userDetailsManager.createUser(new ArgeoUserDetails(user)); + } + + public ArgeoUser getUser(String uname) { + return createBasicArgeoUser(getDetails(uname)); + } + + @SuppressWarnings("unchecked") + public List listUsers() { + List usernames = (List) ldapTemplate.listBindings( + new DistinguishedName(userBase), new ContextMapper() { + public Object mapFromContext(Object ctxArg) { + DirContextAdapter ctx = (DirContextAdapter) ctxArg; + return ctx.getStringAttribute(usernameAttribute); + } + }); + + List lst = new ArrayList(); + for (String username : usernames) { + lst.add(createBasicArgeoUser(getDetails(username))); + } + return lst; + } + + @SuppressWarnings("unchecked") + public List listEditableRoles() { + return (List) 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; + } + }); + } + + public void update(ArgeoUser user) { + userDetailsManager.updateUser(new ArgeoUserDetails(user)); + } + + public void delete(String username) { + userDetailsManager.deleteUser(username); + } + + public void updatePassword(String oldPassword, String newPassword) { + userDetailsManager.changePassword(oldPassword, newPassword); + } + + public Boolean userExists(String username) { + return userDetailsManager.userExists(username); + } + + public void createRole(String role, final String superuserName) { + String group = convertRoleToGroup(role); + DistinguishedName superuserDn = (DistinguishedName) ldapTemplate + .executeReadWrite(new ContextExecutor() { + public Object executeWithContext(DirContext ctx) + throws NamingException { + return LdapUtils.getFullDn(usernameMapper + .buildDn(superuserName), ctx); + } + }); + + Name groupDn = buildGroupDn(group); + DirContextAdapter context = new DirContextAdapter(); + context.setAttributeValues("objectClass", new String[] { "top", + "groupOfUniqueNames" }); + context.setAttributeValue("cn", group); + + // Add superuser because cannot create empty group + context.setAttributeValue("uniqueMember", superuserDn.toString()); + + ldapTemplate.bind(groupDn, context, null); + } + + public void deleteRole(String role) { + String group = convertRoleToGroup(role); + Name dn = buildGroupDn(group); + ldapTemplate.unbind(dn); + } + + protected String convertRoleToGroup(String role) { + // FIXME: factorize with spring security + String group = role; + if (group.startsWith("ROLE_")) { + group = group.substring("ROLE_".length()); + group = group.toLowerCase(); + } + return group; + } + + protected Name buildGroupDn(String name) { + return new DistinguishedName("cn=" + name + "," + + authoritiesPopulator.getGroupSearchBase()); + } + + public void setUserDetailsManager(UserDetailsManager userDetailsManager) { + this.userDetailsManager = userDetailsManager; + } + + public void setUserBase(String userBase) { + this.userBase = userBase; + } + + public void setUsernameAttribute(String usernameAttribute) { + this.usernameAttribute = usernameAttribute; + } + + public void setAuthoritiesPopulator( + ArgeoLdapAuthoritiesPopulator authoritiesPopulator) { + this.authoritiesPopulator = authoritiesPopulator; + } + + protected UserDetails getDetails(String username) { + return userDetailsManager.loadUserByUsername(username); + } +}