1 package org
.argeo
.osgi
.useradmin
;
4 import java
.util
.ArrayList
;
5 import java
.util
.Hashtable
;
8 import javax
.naming
.Binding
;
9 import javax
.naming
.Context
;
10 import javax
.naming
.InvalidNameException
;
11 import javax
.naming
.NamingEnumeration
;
12 import javax
.naming
.NamingException
;
13 import javax
.naming
.directory
.Attributes
;
14 import javax
.naming
.directory
.SearchControls
;
15 import javax
.naming
.directory
.SearchResult
;
16 import javax
.naming
.ldap
.InitialLdapContext
;
17 import javax
.naming
.ldap
.LdapContext
;
18 import javax
.naming
.ldap
.LdapName
;
20 import org
.apache
.commons
.logging
.Log
;
21 import org
.apache
.commons
.logging
.LogFactory
;
22 import org
.argeo
.ArgeoException
;
23 import org
.osgi
.framework
.InvalidSyntaxException
;
24 import org
.osgi
.service
.useradmin
.Authorization
;
25 import org
.osgi
.service
.useradmin
.Role
;
26 import org
.osgi
.service
.useradmin
.User
;
28 public class LdapUserAdmin
extends AbstractLdapUserAdmin
{
29 private final static Log log
= LogFactory
.getLog(LdapUserAdmin
.class);
31 private String baseDn
= "dc=example,dc=com";
32 private InitialLdapContext initialLdapContext
= null;
34 public LdapUserAdmin(String uri
) {
37 Hashtable
<String
, Object
> connEnv
= new Hashtable
<String
, Object
>();
38 connEnv
.put(Context
.INITIAL_CONTEXT_FACTORY
,
39 "com.sun.jndi.ldap.LdapCtxFactory");
40 connEnv
.put(Context
.PROVIDER_URL
, getUri().toString());
41 connEnv
.put("java.naming.ldap.attributes.binary", "userPassword");
42 // connEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
43 // connEnv.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");
44 // connEnv.put(Context.SECURITY_CREDENTIALS, "secret");
46 initialLdapContext
= new InitialLdapContext(connEnv
, null);
47 // StartTlsResponse tls = (StartTlsResponse) ctx
48 // .extendedOperation(new StartTlsRequest());
50 initialLdapContext
.addToEnvironment(
51 Context
.SECURITY_AUTHENTICATION
, "simple");
52 initialLdapContext
.addToEnvironment(Context
.SECURITY_PRINCIPAL
,
53 "uid=admin,ou=system");
54 initialLdapContext
.addToEnvironment(Context
.SECURITY_CREDENTIALS
,
56 LdapContext ldapContext
= (LdapContext
) initialLdapContext
57 .lookup("uid=root,ou=users,dc=example,dc=com");
58 log
.debug(initialLdapContext
.getAttributes(
59 "uid=root,ou=users,dc=example,dc=com").get("cn"));
60 } catch (Exception e
) {
61 throw new ArgeoUserAdminException("Cannot connect to LDAP", e
);
65 public void destroy() {
68 initialLdapContext
.close();
69 } catch (NamingException e
) {
70 log
.error("Cannot destroy LDAP user admin", e
);
75 public Role
createRole(String name
, int type
) {
76 // TODO Auto-generated method stub
81 public boolean removeRole(String name
) {
82 // TODO Auto-generated method stub
87 public Role
getRole(String name
) {
89 Attributes attrs
= initialLdapContext
.getAttributes(name
);
91 if (attrs
.get("objectClass").contains("groupOfNames"))
92 res
= new LdifGroup(new LdapName(name
), attrs
);
93 else if (attrs
.get("objectClass").contains("inetOrgPerson"))
94 res
= new LdifUser(new LdapName(name
), attrs
);
96 throw new ArgeoUserAdminException("Unsupported LDAP type for "
99 } catch (NamingException e
) {
100 throw new ArgeoUserAdminException("Cannot get role for " + name
, e
);
105 public Role
[] getRoles(String filter
) throws InvalidSyntaxException
{
107 String searchFilter
= filter
;
108 SearchControls searchControls
= new SearchControls();
109 searchControls
.setSearchScope(SearchControls
.SUBTREE_SCOPE
);
111 String searchBase
= baseDn
;
112 NamingEnumeration
<SearchResult
> results
= initialLdapContext
113 .search(searchBase
, searchFilter
, searchControls
);
115 ArrayList
<Role
> res
= new ArrayList
<Role
>();
116 while (results
.hasMoreElements()) {
117 SearchResult searchResult
= results
.next();
118 Attributes attrs
= searchResult
.getAttributes();
119 String name
= searchResult
.getName();
121 if (attrs
.get("objectClass").contains("groupOfNames"))
122 role
= new LdifGroup(new LdapName(name
), attrs
);
123 else if (attrs
.get("objectClass").contains("inetOrgPerson"))
124 role
= new LdifUser(new LdapName(name
), attrs
);
126 throw new ArgeoUserAdminException(
127 "Unsupported LDAP type for " + name
);
130 return res
.toArray(new Role
[res
.size()]);
131 } catch (Exception e
) {
132 throw new ArgeoUserAdminException("Cannot get roles for filter "
138 public User
getUser(String key
, String value
) {
140 List
<User
> users
= new ArrayList
<User
>();
141 for (String prop
: getIndexedUserProperties()) {
142 User user
= getUser(prop
, value
);
146 if (users
.size() == 1)
153 String searchFilter
= "(&(objectClass=inetOrgPerson)(" + key
+ "="
156 SearchControls searchControls
= new SearchControls();
157 searchControls
.setSearchScope(SearchControls
.SUBTREE_SCOPE
);
159 String searchBase
= baseDn
;
160 NamingEnumeration
<SearchResult
> results
= initialLdapContext
161 .search(searchBase
, searchFilter
, searchControls
);
163 SearchResult searchResult
= null;
164 if (results
.hasMoreElements()) {
165 searchResult
= (SearchResult
) results
.nextElement();
166 if (results
.hasMoreElements())
169 if (searchResult
== null)
171 return new LdifUser(toDn(searchBase
, searchResult
),
172 searchResult
.getAttributes());
173 } catch (Exception e
) {
174 throw new ArgeoUserAdminException("Cannot get user with " + key
180 public Authorization
getAuthorization(User user
) {
181 LdifUser u
= (LdifUser
) user
;
182 populateDirectMemberOf(u
);
183 return new LdifAuthorization(u
);
186 private LdapName
toDn(String baseDn
, Binding binding
)
187 throws InvalidNameException
{
188 return new LdapName(binding
.isRelative() ? binding
.getName() + ","
189 + baseDn
: binding
.getName());
192 void populateDirectMemberOf(LdifUser user
) {
195 String searchFilter
= "(&(objectClass=groupOfNames)(member="
196 + user
.getName() + "))";
198 SearchControls searchControls
= new SearchControls();
199 searchControls
.setSearchScope(SearchControls
.SUBTREE_SCOPE
);
201 String searchBase
= "ou=node";
202 NamingEnumeration
<SearchResult
> results
= initialLdapContext
203 .search(searchBase
, searchFilter
, searchControls
);
206 user
.directMemberOf
.clear();
207 while (results
.hasMoreElements()) {
208 SearchResult searchResult
= (SearchResult
) results
210 LdifGroup group
= new LdifGroup(toDn(searchBase
, searchResult
),
211 searchResult
.getAttributes());
212 populateDirectMemberOf(group
);
213 user
.directMemberOf
.add(group
);
215 } catch (Exception e
) {
216 throw new ArgeoException("Cannot populate direct members of "