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