]> git.argeo.org Git - lgpl/argeo-commons.git/blob - security/ldap/ArgeoUserAdminDaoLdap.java
Prepare next development cycle
[lgpl/argeo-commons.git] / security / ldap / ArgeoUserAdminDaoLdap.java
1 /*
2 * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.argeo.security.ldap;
18
19 import java.util.Collections;
20 import java.util.List;
21 import java.util.Set;
22 import java.util.TreeSet;
23
24 import javax.naming.Name;
25 import javax.naming.NamingException;
26 import javax.naming.directory.DirContext;
27
28 import org.springframework.ldap.core.ContextExecutor;
29 import org.springframework.ldap.core.ContextMapper;
30 import org.springframework.ldap.core.DirContextAdapter;
31 import org.springframework.ldap.core.DistinguishedName;
32 import org.springframework.ldap.core.LdapTemplate;
33 import org.springframework.ldap.core.support.BaseLdapPathContextSource;
34 import org.springframework.security.ldap.LdapUsernameToDnMapper;
35 import org.springframework.security.ldap.LdapUtils;
36
37 /**
38 * Wraps low-level LDAP operation on user and roles, used by
39 * {@link ArgeoLdapUserDetailsManager}
40 */
41 public class ArgeoUserAdminDaoLdap {
42 private String userBase;
43 private String usernameAttribute;
44 private String groupBase;
45 private String[] groupClasses;
46
47 private String groupRoleAttribute;
48 private String groupMemberAttribute;
49 private String defaultRole;
50 private String rolePrefix;
51
52 private final LdapTemplate ldapTemplate;
53 private LdapUsernameToDnMapper usernameMapper;
54
55 /**
56 * Standard constructor, using the LDAP context source shared with Spring
57 * Security components.
58 */
59 public ArgeoUserAdminDaoLdap(BaseLdapPathContextSource contextSource) {
60 this.ldapTemplate = new LdapTemplate(contextSource);
61 }
62
63 @SuppressWarnings("unchecked")
64 public synchronized Set<String> listUsers() {
65 List<String> usernames = (List<String>) ldapTemplate.listBindings(
66 new DistinguishedName(userBase), new ContextMapper() {
67 public Object mapFromContext(Object ctxArg) {
68 DirContextAdapter ctx = (DirContextAdapter) ctxArg;
69 return ctx.getStringAttribute(usernameAttribute);
70 }
71 });
72
73 return Collections
74 .unmodifiableSortedSet(new TreeSet<String>(usernames));
75 }
76
77 @SuppressWarnings("unchecked")
78 public Set<String> listEditableRoles() {
79 return Collections.unmodifiableSortedSet(new TreeSet<String>(
80 ldapTemplate.listBindings(groupBase, new ContextMapper() {
81 public Object mapFromContext(Object ctxArg) {
82 String groupName = ((DirContextAdapter) ctxArg)
83 .getStringAttribute(groupRoleAttribute);
84 String roleName = convertGroupToRole(groupName);
85 return roleName;
86 }
87 })));
88 }
89
90 @SuppressWarnings("unchecked")
91 public Set<String> listUsersInRole(String role) {
92 return (Set<String>) ldapTemplate.lookup(
93 buildGroupDn(convertRoleToGroup(role)), new ContextMapper() {
94 public Object mapFromContext(Object ctxArg) {
95 DirContextAdapter ctx = (DirContextAdapter) ctxArg;
96 String[] userDns = ctx
97 .getStringAttributes(groupMemberAttribute);
98 TreeSet<String> set = new TreeSet<String>();
99 for (String userDn : userDns) {
100 DistinguishedName dn = new DistinguishedName(userDn);
101 String username = dn.getValue(usernameAttribute);
102 set.add(username);
103 }
104 return Collections.unmodifiableSortedSet(set);
105 }
106 });
107 }
108
109 public void createRole(String role, final String superuserName) {
110 String group = convertRoleToGroup(role);
111 DistinguishedName superuserDn = (DistinguishedName) ldapTemplate
112 .executeReadWrite(new ContextExecutor() {
113 public Object executeWithContext(DirContext ctx)
114 throws NamingException {
115 return LdapUtils.getFullDn(
116 usernameMapper.buildDn(superuserName), ctx);
117 }
118 });
119
120 Name groupDn = buildGroupDn(group);
121 DirContextAdapter context = new DirContextAdapter();
122 context.setAttributeValues("objectClass", groupClasses);
123 context.setAttributeValue("cn", group);
124 // Add superuser because cannot create empty group
125 context.setAttributeValue(groupMemberAttribute, superuserDn.toString());
126 ldapTemplate.bind(groupDn, context, null);
127 }
128
129 public void deleteRole(String role) {
130 String group = convertRoleToGroup(role);
131 Name dn = buildGroupDn(group);
132 ldapTemplate.unbind(dn);
133 }
134
135 /** Maps a role (ROLE_XXX) to the related LDAP group (xxx) */
136 protected String convertRoleToGroup(String role) {
137 String group = role;
138 if (group.startsWith(rolePrefix)) {
139 group = group.substring(rolePrefix.length());
140 group = group.toLowerCase();
141 }
142 return group;
143 }
144
145 /** Maps anLDAP group (xxx) to the related role (ROLE_XXX) */
146 protected String convertGroupToRole(String groupName) {
147 groupName = groupName.toUpperCase();
148
149 return rolePrefix + groupName;
150 }
151
152 protected Name buildGroupDn(String name) {
153 return new DistinguishedName(groupRoleAttribute + "=" + name + ","
154 + groupBase);
155 }
156
157 public void setUserBase(String userBase) {
158 this.userBase = userBase;
159 }
160
161 public void setUsernameAttribute(String usernameAttribute) {
162 this.usernameAttribute = usernameAttribute;
163 }
164
165 public void setGroupBase(String groupBase) {
166 this.groupBase = groupBase;
167 }
168
169 public void setGroupRoleAttribute(String groupRoleAttributeName) {
170 this.groupRoleAttribute = groupRoleAttributeName;
171 }
172
173 public void setGroupMemberAttribute(String groupMemberAttributeName) {
174 this.groupMemberAttribute = groupMemberAttributeName;
175 }
176
177 public void setDefaultRole(String defaultRole) {
178 this.defaultRole = defaultRole;
179 }
180
181 public void setRolePrefix(String rolePrefix) {
182 this.rolePrefix = rolePrefix;
183 }
184
185 public void setUsernameMapper(LdapUsernameToDnMapper usernameMapper) {
186 this.usernameMapper = usernameMapper;
187 }
188
189 public String getDefaultRole() {
190 return defaultRole;
191 }
192
193 public void setGroupClasses(String[] groupClasses) {
194 this.groupClasses = groupClasses;
195 }
196 }