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