2 * Copyright (C) 2007-2012 Mathieu Baudier
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org
.argeo
.security
.ldap
;
18 import java
.util
.Collections
;
19 import java
.util
.List
;
21 import java
.util
.TreeSet
;
23 import javax
.naming
.Name
;
24 import javax
.naming
.NamingException
;
25 import javax
.naming
.directory
.DirContext
;
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
;
37 * Wraps low-level LDAP operation on user and roles, used by
38 * {@link ArgeoLdapUserDetailsManager}
40 public class ArgeoUserAdminDaoLdap
{
41 private String userBase
;
42 private String usernameAttribute
;
43 private String groupBase
;
44 private String
[] groupClasses
;
46 private String groupRoleAttribute
;
47 private String groupMemberAttribute
;
48 private String defaultRole
;
49 private String rolePrefix
;
51 private final LdapTemplate ldapTemplate
;
52 private LdapUsernameToDnMapper usernameMapper
;
55 * Standard constructor, using the LDAP context source shared with Spring
56 * Security components.
58 public ArgeoUserAdminDaoLdap(BaseLdapPathContextSource contextSource
) {
59 this.ldapTemplate
= new LdapTemplate(contextSource
);
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
);
73 .unmodifiableSortedSet(new TreeSet
<String
>(usernames
));
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
);
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
);
103 return Collections
.unmodifiableSortedSet(set
);
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
);
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);
128 public void deleteRole(String role
) {
129 String group
= convertRoleToGroup(role
);
130 Name dn
= buildGroupDn(group
);
131 ldapTemplate
.unbind(dn
);
134 /** Maps a role (ROLE_XXX) to the related LDAP group (xxx) */
135 protected String
convertRoleToGroup(String role
) {
137 if (group
.startsWith(rolePrefix
)) {
138 group
= group
.substring(rolePrefix
.length());
139 group
= group
.toLowerCase();
144 /** Maps anLDAP group (xxx) to the related role (ROLE_XXX) */
145 protected String
convertGroupToRole(String groupName
) {
146 groupName
= groupName
.toUpperCase();
148 return rolePrefix
+ groupName
;
151 protected Name
buildGroupDn(String name
) {
152 return new DistinguishedName(groupRoleAttribute
+ "=" + name
+ ","
156 public void setUserBase(String userBase
) {
157 this.userBase
= userBase
;
160 public void setUsernameAttribute(String usernameAttribute
) {
161 this.usernameAttribute
= usernameAttribute
;
164 public void setGroupBase(String groupBase
) {
165 this.groupBase
= groupBase
;
168 public void setGroupRoleAttribute(String groupRoleAttributeName
) {
169 this.groupRoleAttribute
= groupRoleAttributeName
;
172 public void setGroupMemberAttribute(String groupMemberAttributeName
) {
173 this.groupMemberAttribute
= groupMemberAttributeName
;
176 public void setDefaultRole(String defaultRole
) {
177 this.defaultRole
= defaultRole
;
180 public void setRolePrefix(String rolePrefix
) {
181 this.rolePrefix
= rolePrefix
;
184 public void setUsernameMapper(LdapUsernameToDnMapper usernameMapper
) {
185 this.usernameMapper
= usernameMapper
;
188 public String
getDefaultRole() {
192 public void setGroupClasses(String
[] groupClasses
) {
193 this.groupClasses
= groupClasses
;