]> git.argeo.org Git - lgpl/argeo-commons.git/blob - LdapUserAdmin.java
dabae718c2f1c9f71124d7f9ee4400086f2683e7
[lgpl/argeo-commons.git] / 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.Group;
26 import org.osgi.service.useradmin.Role;
27 import org.osgi.service.useradmin.User;
28
29 public class LdapUserAdmin extends AbstractLdapUserAdmin {
30 private final static Log log = LogFactory.getLog(LdapUserAdmin.class);
31
32 private String baseDn = "dc=example,dc=com";
33 private InitialLdapContext initialLdapContext = null;
34
35 public LdapUserAdmin(String uri) {
36 try {
37 setUri(new URI(uri));
38 Hashtable<String, Object> connEnv = new Hashtable<String, Object>();
39 connEnv.put(Context.INITIAL_CONTEXT_FACTORY,
40 "com.sun.jndi.ldap.LdapCtxFactory");
41 connEnv.put(Context.PROVIDER_URL, getUri().toString());
42 connEnv.put("java.naming.ldap.attributes.binary", "userPassword");
43 // connEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
44 // connEnv.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");
45 // connEnv.put(Context.SECURITY_CREDENTIALS, "secret");
46
47 initialLdapContext = new InitialLdapContext(connEnv, null);
48 // StartTlsResponse tls = (StartTlsResponse) ctx
49 // .extendedOperation(new StartTlsRequest());
50 // tls.negotiate();
51 initialLdapContext.addToEnvironment(
52 Context.SECURITY_AUTHENTICATION, "simple");
53 initialLdapContext.addToEnvironment(Context.SECURITY_PRINCIPAL,
54 "uid=admin,ou=system");
55 initialLdapContext.addToEnvironment(Context.SECURITY_CREDENTIALS,
56 "secret");
57 LdapContext ldapContext = (LdapContext) initialLdapContext
58 .lookup("uid=root,ou=users,dc=example,dc=com");
59 log.debug(initialLdapContext.getAttributes(
60 "uid=root,ou=users,dc=example,dc=com").get("cn"));
61 } catch (Exception e) {
62 throw new ArgeoUserAdminException("Cannot connect to LDAP", e);
63 }
64 }
65
66 public void destroy() {
67 try {
68 // tls.close();
69 initialLdapContext.close();
70 } catch (NamingException e) {
71 log.error("Cannot destroy LDAP user admin", e);
72 }
73 }
74
75 @Override
76 public Role createRole(String name, int type) {
77 // TODO Auto-generated method stub
78 return null;
79 }
80
81 @Override
82 public boolean removeRole(String name) {
83 // TODO Auto-generated method stub
84 return false;
85 }
86
87 @Override
88 public Role getRole(String name) {
89 try {
90 Attributes attrs = initialLdapContext.getAttributes(name);
91 LdifUser res;
92 if (attrs.get("objectClass").contains("groupOfNames"))
93 res = new LdifGroup(this, new LdapName(name), attrs);
94 else if (attrs.get("objectClass").contains("inetOrgPerson"))
95 res = new LdifUser(new LdapName(name), attrs);
96 else
97 throw new ArgeoUserAdminException("Unsupported LDAP type for "
98 + name);
99 return res;
100 } catch (NamingException e) {
101 throw new ArgeoUserAdminException("Cannot get role for " + name, e);
102 }
103 }
104
105 @Override
106 public Role[] getRoles(String filter) throws InvalidSyntaxException {
107 try {
108 String searchFilter = filter;
109 if (searchFilter == null)
110 searchFilter = "(|(objectClass=inetOrgPerson)(objectClass=groupOfNames))";
111 SearchControls searchControls = new SearchControls();
112 searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
113
114 String searchBase = baseDn;
115 NamingEnumeration<SearchResult> results = initialLdapContext
116 .search(searchBase, searchFilter, searchControls);
117
118 ArrayList<Role> res = new ArrayList<Role>();
119 while (results.hasMoreElements()) {
120 SearchResult searchResult = results.next();
121 Attributes attrs = searchResult.getAttributes();
122 LdifUser role;
123 if (attrs.get("objectClass").contains("groupOfNames"))
124 role = new LdifGroup(this, toDn(searchBase, searchResult),
125 attrs);
126 else if (attrs.get("objectClass").contains("inetOrgPerson"))
127 role = new LdifUser(toDn(searchBase, searchResult), attrs);
128 else
129 throw new ArgeoUserAdminException(
130 "Unsupported LDAP type for "
131 + searchResult.getName());
132 res.add(role);
133 }
134 return res.toArray(new Role[res.size()]);
135 } catch (Exception e) {
136 throw new ArgeoUserAdminException("Cannot get roles for filter "
137 + filter, e);
138 }
139 }
140
141 @Override
142 public User getUser(String key, String value) {
143 if (key == null) {
144 List<User> users = new ArrayList<User>();
145 for (String prop : getIndexedUserProperties()) {
146 User user = getUser(prop, value);
147 if (user != null)
148 users.add(user);
149 }
150 if (users.size() == 1)
151 return users.get(0);
152 else
153 return null;
154 }
155
156 try {
157 String searchFilter = "(&(objectClass=inetOrgPerson)(" + key + "="
158 + value + "))";
159
160 SearchControls searchControls = new SearchControls();
161 searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
162
163 String searchBase = baseDn;
164 NamingEnumeration<SearchResult> results = initialLdapContext
165 .search(searchBase, searchFilter, searchControls);
166
167 SearchResult searchResult = null;
168 if (results.hasMoreElements()) {
169 searchResult = (SearchResult) results.nextElement();
170 if (results.hasMoreElements())
171 searchResult = null;
172 }
173 if (searchResult == null)
174 return null;
175 return new LdifUser(toDn(searchBase, searchResult),
176 searchResult.getAttributes());
177 } catch (Exception e) {
178 throw new ArgeoUserAdminException("Cannot get user with " + key
179 + "=" + value, e);
180 }
181 }
182
183 @Override
184 public Authorization getAuthorization(User user) {
185 LdifUser u = (LdifUser) user;
186 // populateDirectMemberOf(u);
187 return new LdifAuthorization(u, getAllRoles(u));
188 }
189
190 private LdapName toDn(String baseDn, Binding binding)
191 throws InvalidNameException {
192 return new LdapName(binding.isRelative() ? binding.getName() + ","
193 + baseDn : binding.getName());
194 }
195
196 // void populateDirectMemberOf(LdifUser user) {
197 //
198 // try {
199 // String searchFilter = "(&(objectClass=groupOfNames)(member="
200 // + user.getName() + "))";
201 //
202 // SearchControls searchControls = new SearchControls();
203 // searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
204 //
205 // String searchBase = "ou=node";
206 // NamingEnumeration<SearchResult> results = initialLdapContext
207 // .search(searchBase, searchFilter, searchControls);
208 //
209 // // TODO synchro
210 // //user.directMemberOf.clear();
211 // while (results.hasMoreElements()) {
212 // SearchResult searchResult = (SearchResult) results
213 // .nextElement();
214 // LdifGroup group = new LdifGroup(toDn(searchBase, searchResult),
215 // searchResult.getAttributes());
216 // populateDirectMemberOf(group);
217 // //user.directMemberOf.add(group);
218 // }
219 // } catch (Exception e) {
220 // throw new ArgeoException("Cannot populate direct members of "
221 // + user, e);
222 // }
223 // }
224
225 @Override
226 protected List<? extends Group> getDirectGroups(User user) {
227 List<Group> directGroups = new ArrayList<Group>();
228 try {
229 String searchFilter = "(&(objectClass=groupOfNames)(member="
230 + user.getName() + "))";
231
232 SearchControls searchControls = new SearchControls();
233 searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
234
235 String searchBase = getGroupsSearchBase();
236 NamingEnumeration<SearchResult> results = initialLdapContext
237 .search(searchBase, searchFilter, searchControls);
238
239 while (results.hasMoreElements()) {
240 SearchResult searchResult = (SearchResult) results
241 .nextElement();
242 LdifGroup group = new LdifGroup(this, toDn(searchBase,
243 searchResult), searchResult.getAttributes());
244 directGroups.add(group);
245 }
246 return directGroups;
247 } catch (Exception e) {
248 throw new ArgeoException("Cannot populate direct members of "
249 + user, e);
250 }
251 }
252
253 protected String getGroupsSearchBase() {
254 // TODO configure group search base
255 return baseDn;
256 }
257 }