]> git.argeo.org Git - lgpl/argeo-commons.git/blob - useradmin/LdapUserAdmin.java
Prepare next development cycle
[lgpl/argeo-commons.git] / useradmin / LdapUserAdmin.java
1 package org.argeo.osgi.useradmin;
2
3 import java.net.URI;
4 import java.util.ArrayList;
5 import java.util.Hashtable;
6 import java.util.List;
7
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;
19
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;
27
28 public class LdapUserAdmin extends AbstractLdapUserAdmin {
29 private final static Log log = LogFactory.getLog(LdapUserAdmin.class);
30
31 private String baseDn = "dc=example,dc=com";
32 private InitialLdapContext initialLdapContext = null;
33
34 public LdapUserAdmin(String uri) {
35 try {
36 setUri(new URI(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");
45
46 initialLdapContext = new InitialLdapContext(connEnv, null);
47 // StartTlsResponse tls = (StartTlsResponse) ctx
48 // .extendedOperation(new StartTlsRequest());
49 // tls.negotiate();
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,
55 "secret");
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);
62 }
63 }
64
65 public void destroy() {
66 try {
67 // tls.close();
68 initialLdapContext.close();
69 } catch (NamingException e) {
70 log.error("Cannot destroy LDAP user admin", e);
71 }
72 }
73
74 @Override
75 public Role createRole(String name, int type) {
76 // TODO Auto-generated method stub
77 return null;
78 }
79
80 @Override
81 public boolean removeRole(String name) {
82 // TODO Auto-generated method stub
83 return false;
84 }
85
86 @Override
87 public Role getRole(String name) {
88 try {
89 Attributes attrs = initialLdapContext.getAttributes(name);
90 LdifUser res;
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);
95 else
96 throw new ArgeoUserAdminException("Unsupported LDAP type for "
97 + name);
98 return res;
99 } catch (NamingException e) {
100 throw new ArgeoUserAdminException("Cannot get role for " + name, e);
101 }
102 }
103
104 @Override
105 public Role[] getRoles(String filter) throws InvalidSyntaxException {
106 try {
107 String searchFilter = filter;
108 SearchControls searchControls = new SearchControls();
109 searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
110
111 String searchBase = baseDn;
112 NamingEnumeration<SearchResult> results = initialLdapContext
113 .search(searchBase, searchFilter, searchControls);
114
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();
120 LdifUser role;
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);
125 else
126 throw new ArgeoUserAdminException(
127 "Unsupported LDAP type for " + name);
128 res.add(role);
129 }
130 return res.toArray(new Role[res.size()]);
131 } catch (Exception e) {
132 throw new ArgeoUserAdminException("Cannot get roles for filter "
133 + filter, e);
134 }
135 }
136
137 @Override
138 public User getUser(String key, String value) {
139 if (key == null) {
140 List<User> users = new ArrayList<User>();
141 for (String prop : getIndexedUserProperties()) {
142 User user = getUser(prop, value);
143 if (user != null)
144 users.add(user);
145 }
146 if (users.size() == 1)
147 return users.get(0);
148 else
149 return null;
150 }
151
152 try {
153 String searchFilter = "(&(objectClass=inetOrgPerson)(" + key + "="
154 + value + "))";
155
156 SearchControls searchControls = new SearchControls();
157 searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
158
159 String searchBase = baseDn;
160 NamingEnumeration<SearchResult> results = initialLdapContext
161 .search(searchBase, searchFilter, searchControls);
162
163 SearchResult searchResult = null;
164 if (results.hasMoreElements()) {
165 searchResult = (SearchResult) results.nextElement();
166 if (results.hasMoreElements())
167 searchResult = null;
168 }
169 if (searchResult == null)
170 return null;
171 return new LdifUser(toDn(searchBase, searchResult),
172 searchResult.getAttributes());
173 } catch (Exception e) {
174 throw new ArgeoUserAdminException("Cannot get user with " + key
175 + "=" + value, e);
176 }
177 }
178
179 @Override
180 public Authorization getAuthorization(User user) {
181 LdifUser u = (LdifUser) user;
182 populateDirectMemberOf(u);
183 return new LdifAuthorization(u);
184 }
185
186 private LdapName toDn(String baseDn, Binding binding)
187 throws InvalidNameException {
188 return new LdapName(binding.isRelative() ? binding.getName() + ","
189 + baseDn : binding.getName());
190 }
191
192 void populateDirectMemberOf(LdifUser user) {
193
194 try {
195 String searchFilter = "(&(objectClass=groupOfNames)(member="
196 + user.getName() + "))";
197
198 SearchControls searchControls = new SearchControls();
199 searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
200
201 String searchBase = "ou=node";
202 NamingEnumeration<SearchResult> results = initialLdapContext
203 .search(searchBase, searchFilter, searchControls);
204
205 // TODO synchro
206 user.directMemberOf.clear();
207 while (results.hasMoreElements()) {
208 SearchResult searchResult = (SearchResult) results
209 .nextElement();
210 LdifGroup group = new LdifGroup(toDn(searchBase, searchResult),
211 searchResult.getAttributes());
212 populateDirectMemberOf(group);
213 user.directMemberOf.add(group);
214 }
215 } catch (Exception e) {
216 throw new ArgeoException("Cannot populate direct members of "
217 + user, e);
218 }
219 }
220
221 }