]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - org.argeo.security.ldap/src/org/argeo/security/ldap/ArgeoUserAdminDaoLdap.java
New project conventions
[lgpl/argeo-commons.git] / org.argeo.security.ldap / src / org / argeo / security / ldap / ArgeoUserAdminDaoLdap.java
diff --git a/org.argeo.security.ldap/src/org/argeo/security/ldap/ArgeoUserAdminDaoLdap.java b/org.argeo.security.ldap/src/org/argeo/security/ldap/ArgeoUserAdminDaoLdap.java
new file mode 100644 (file)
index 0000000..37d2a06
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * 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 java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+
+import org.springframework.ldap.core.ContextExecutor;
+import org.springframework.ldap.core.ContextMapper;
+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.ldap.LdapUsernameToDnMapper;
+import org.springframework.security.ldap.LdapUtils;
+
+/**
+ * Wraps low-level LDAP operation on user and roles, used by
+ * {@link ArgeoLdapUserDetailsManager}
+ */
+public class ArgeoUserAdminDaoLdap {
+       private String userBase;
+       private String usernameAttribute;
+       private String groupBase;
+       private String[] groupClasses;
+
+       private String groupRoleAttribute;
+       private String groupMemberAttribute;
+       private String defaultRole;
+       private String rolePrefix;
+
+       private final LdapTemplate ldapTemplate;
+       private LdapUsernameToDnMapper usernameMapper;
+
+       /**
+        * Standard constructor, using the LDAP context source shared with Spring
+        * Security components.
+        */
+       public ArgeoUserAdminDaoLdap(BaseLdapPathContextSource contextSource) {
+               this.ldapTemplate = new LdapTemplate(contextSource);
+       }
+
+       @SuppressWarnings("unchecked")
+       public synchronized Set<String> listUsers() {
+               List<String> usernames = (List<String>) ldapTemplate.listBindings(
+                               new DistinguishedName(userBase), new ContextMapper() {
+                                       public Object mapFromContext(Object ctxArg) {
+                                               DirContextAdapter ctx = (DirContextAdapter) ctxArg;
+                                               return ctx.getStringAttribute(usernameAttribute);
+                                       }
+                               });
+
+               return Collections
+                               .unmodifiableSortedSet(new TreeSet<String>(usernames));
+       }
+
+       @SuppressWarnings("unchecked")
+       public Set<String> listEditableRoles() {
+               return Collections.unmodifiableSortedSet(new TreeSet<String>(
+                               ldapTemplate.listBindings(groupBase, new ContextMapper() {
+                                       public Object mapFromContext(Object ctxArg) {
+                                               String groupName = ((DirContextAdapter) ctxArg)
+                                                               .getStringAttribute(groupRoleAttribute);
+                                               String roleName = convertGroupToRole(groupName);
+                                               return roleName;
+                                       }
+                               })));
+       }
+
+       @SuppressWarnings("unchecked")
+       public Set<String> listUsersInRole(String role) {
+               return (Set<String>) ldapTemplate.lookup(
+                               buildGroupDn(convertRoleToGroup(role)), new ContextMapper() {
+                                       public Object mapFromContext(Object ctxArg) {
+                                               DirContextAdapter ctx = (DirContextAdapter) ctxArg;
+                                               String[] userDns = ctx
+                                                               .getStringAttributes(groupMemberAttribute);
+                                               TreeSet<String> set = new TreeSet<String>();
+                                               for (String userDn : userDns) {
+                                                       DistinguishedName dn = new DistinguishedName(userDn);
+                                                       String username = dn.getValue(usernameAttribute);
+                                                       set.add(username);
+                                               }
+                                               return Collections.unmodifiableSortedSet(set);
+                                       }
+                               });
+       }
+
+       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", groupClasses);
+               context.setAttributeValue("cn", group);
+               // Add superuser because cannot create empty group
+               context.setAttributeValue(groupMemberAttribute, superuserDn.toString());
+               ldapTemplate.bind(groupDn, context, null);
+       }
+
+       public void deleteRole(String role) {
+               String group = convertRoleToGroup(role);
+               Name dn = buildGroupDn(group);
+               ldapTemplate.unbind(dn);
+       }
+
+       /** Maps a role (ROLE_XXX) to the related LDAP group (xxx) */
+       protected String convertRoleToGroup(String role) {
+               String group = role;
+               if (group.startsWith(rolePrefix)) {
+                       group = group.substring(rolePrefix.length());
+                       group = group.toLowerCase();
+               }
+               return group;
+       }
+
+       /** Maps anLDAP group (xxx) to the related role (ROLE_XXX) */
+       protected String convertGroupToRole(String groupName) {
+               groupName = groupName.toUpperCase();
+
+               return rolePrefix + groupName;
+       }
+
+       protected Name buildGroupDn(String name) {
+               return new DistinguishedName(groupRoleAttribute + "=" + name + ","
+                               + groupBase);
+       }
+
+       public void setUserBase(String userBase) {
+               this.userBase = userBase;
+       }
+
+       public void setUsernameAttribute(String usernameAttribute) {
+               this.usernameAttribute = usernameAttribute;
+       }
+
+       public void setGroupBase(String groupBase) {
+               this.groupBase = groupBase;
+       }
+
+       public void setGroupRoleAttribute(String groupRoleAttributeName) {
+               this.groupRoleAttribute = groupRoleAttributeName;
+       }
+
+       public void setGroupMemberAttribute(String groupMemberAttributeName) {
+               this.groupMemberAttribute = 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 String getDefaultRole() {
+               return defaultRole;
+       }
+
+       public void setGroupClasses(String[] groupClasses) {
+               this.groupClasses = groupClasses;
+       }
+}