KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jivesoftware > messenger > ldap > LdapUserProvider


1 /**
2  * $RCSfile: LdapUserProvider.java,v $
3  * $Revision: 1.12 $
4  * $Date: 2005/04/27 07:06:18 $
5  *
6  * Copyright (C) 2004 Jive Software. All rights reserved.
7  *
8  * This software is published under the terms of the GNU Public License (GPL),
9  * a copy of which is included in this distribution.
10  */

11
12 package org.jivesoftware.messenger.ldap;
13
14 import org.jivesoftware.messenger.user.*;
15 import org.jivesoftware.util.JiveConstants;
16 import org.jivesoftware.util.JiveGlobals;
17 import org.jivesoftware.util.Log;
18 import org.xmpp.packet.JID;
19
20 import javax.naming.NamingEnumeration JavaDoc;
21 import javax.naming.directory.*;
22 import javax.naming.ldap.Control JavaDoc;
23 import javax.naming.ldap.LdapContext JavaDoc;
24 import javax.naming.ldap.SortControl JavaDoc;
25 import java.text.MessageFormat JavaDoc;
26 import java.util.*;
27
28 /**
29  * LDAP implementation of the UserProvider interface. All data in the directory is
30  * treated as read-only so any set operations will result in an exception.
31  *
32  * @author Matt Tucker
33  */

34 public class LdapUserProvider implements UserProvider {
35
36     private LdapManager manager;
37     private Map<String JavaDoc, String JavaDoc> searchFields;
38     private int userCount = -1;
39     private long expiresStamp = System.currentTimeMillis();
40
41     public LdapUserProvider() {
42         manager = LdapManager.getInstance();
43         searchFields = new LinkedHashMap<String JavaDoc,String JavaDoc>();
44         String JavaDoc fieldList = JiveGlobals.getXMLProperty("ldap.searchFields");
45         // If the value isn't present, default to to username, name, and email.
46
if (fieldList == null) {
47             searchFields.put("Username", manager.getUsernameField());
48             searchFields.put("Name", manager.getNameField());
49             searchFields.put("Email", manager.getEmailField());
50         }
51         else {
52             try {
53                 for (StringTokenizer i=new StringTokenizer(fieldList, ","); i.hasMoreTokens(); ) {
54                     String JavaDoc[] field = i.nextToken().split("/");
55                     searchFields.put(field[0], field[1]);
56                 }
57             }
58             catch (Exception JavaDoc e) {
59                 Log.error("Error parsing LDAP search fields: " + fieldList, e);
60             }
61         }
62     }
63
64     public User loadUser(String JavaDoc username) throws UserNotFoundException {
65         // Un-escape username.
66
username = JID.unescapeNode(username);
67         DirContext ctx = null;
68         try {
69             String JavaDoc userDN = manager.findUserDN(username);
70             // Load record.
71
String JavaDoc[] attributes = new String JavaDoc[]{
72                 manager.getUsernameField(), manager.getNameField(),
73                 manager.getEmailField()
74             };
75             ctx = manager.getContext();
76             Attributes attrs = ctx.getAttributes(userDN, attributes);
77             String JavaDoc name = null;
78             String JavaDoc email = null;
79             Attribute nameField = attrs.get(manager.getNameField());
80             if (nameField != null) {
81                 name = (String JavaDoc)nameField.get();
82             }
83             Attribute emailField = attrs.get(manager.getEmailField());
84             if (emailField != null) {
85                 email = (String JavaDoc)emailField.get();
86             }
87             return new User(username, name, email, new Date(), new Date());
88         }
89         catch (Exception JavaDoc e) {
90             throw new UserNotFoundException(e);
91         }
92         finally {
93             try { ctx.close(); }
94             catch (Exception JavaDoc ignored) { }
95         }
96     }
97
98     public User createUser(String JavaDoc username, String JavaDoc password, String JavaDoc name, String JavaDoc email)
99             throws UserAlreadyExistsException
100     {
101         throw new UnsupportedOperationException JavaDoc();
102     }
103
104     public void deleteUser(String JavaDoc username) {
105         throw new UnsupportedOperationException JavaDoc();
106     }
107
108     public int getUserCount() {
109         // Cache user count for 5 minutes.
110
if (userCount != -1 && System.currentTimeMillis() < expiresStamp) {
111             return userCount;
112         }
113         int count = 0;
114         DirContext ctx = null;
115         try {
116             ctx = manager.getContext();
117             // Search for the dn based on the username.
118
SearchControls constraints = new SearchControls();
119             constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
120             constraints.setReturningAttributes(new String JavaDoc[] { manager.getUsernameField() });
121             String JavaDoc filter = MessageFormat.format(manager.getSearchFilter(), "*");
122             NamingEnumeration JavaDoc answer = ctx.search("", filter, constraints);
123             while (answer.hasMoreElements()) {
124                 count++;
125                 answer.nextElement();
126             }
127         }
128         catch (Exception JavaDoc e) {
129             Log.error(e);
130         }
131         finally {
132             try { ctx.close(); }
133             catch (Exception JavaDoc ignored) { }
134         }
135         this.userCount = count;
136         this.expiresStamp = System.currentTimeMillis() + JiveConstants.MINUTE *5;
137         return count;
138     }
139
140     public Collection<User> getUsers() {
141         List<String JavaDoc> usernames = new ArrayList<String JavaDoc>();
142         LdapContext JavaDoc ctx = null;
143         try {
144             ctx = manager.getContext();
145             // Sort on username field.
146
Control JavaDoc[] searchControl = new Control JavaDoc[]{
147                 new SortControl JavaDoc(new String JavaDoc[]{manager.getUsernameField()}, Control.NONCRITICAL)
148             };
149             ctx.setRequestControls(searchControl);
150
151             // Search for the dn based on the username.
152
SearchControls constraints = new SearchControls();
153             constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
154             constraints.setReturningAttributes(new String JavaDoc[] { manager.getUsernameField() });
155             String JavaDoc filter = MessageFormat.format(manager.getSearchFilter(), "*");
156             NamingEnumeration JavaDoc answer = ctx.search("", filter, constraints);
157             while (answer.hasMoreElements()) {
158                 // Get the next userID.
159
String JavaDoc username = (String JavaDoc)((SearchResult)answer.next()).getAttributes().get(
160                         manager.getUsernameField()).get();
161                 // Escape username and add to results.
162
usernames.add(JID.escapeNode(username));
163             }
164         }
165         catch (Exception JavaDoc e) {
166             Log.error(e);
167         }
168         finally {
169             try {
170                 if (ctx != null) {
171                     ctx.setRequestControls(null);
172                     ctx.close();
173                 }
174             }
175             catch (Exception JavaDoc ignored) { }
176         }
177         // If client-side sorting is enabled, do it.
178
if (Boolean.valueOf(JiveGlobals.getXMLProperty("ldap.clientSideSorting")).booleanValue()) {
179             Collections.sort(usernames);
180         }
181         return new UserCollection((String JavaDoc[])usernames.toArray(new String JavaDoc[usernames.size()]));
182     }
183
184     public Collection<User> getUsers(int startIndex, int numResults) {
185         List<String JavaDoc> usernames = new ArrayList<String JavaDoc>();
186         LdapContext JavaDoc ctx = null;
187         try {
188             ctx = manager.getContext();
189             // Sort on username field.
190
Control JavaDoc[] searchControl = new Control JavaDoc[]{
191                 new SortControl JavaDoc(new String JavaDoc[]{manager.getUsernameField()}, Control.NONCRITICAL)
192             };
193             ctx.setRequestControls(searchControl);
194
195             // Search for the dn based on the username.
196
SearchControls constraints = new SearchControls();
197             constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
198             constraints.setReturningAttributes(new String JavaDoc[] { manager.getUsernameField() });
199             // Limit results to those we'll need to process unless client-side sorting
200
// is turned on.
201
if (!Boolean.valueOf(JiveGlobals.getXMLProperty(
202                     "ldap.clientSideSorting")).booleanValue())
203             {
204                 constraints.setCountLimit(startIndex+numResults);
205             }
206             String JavaDoc filter = MessageFormat.format(manager.getSearchFilter(), "*");
207             NamingEnumeration JavaDoc answer = ctx.search("", filter, constraints);
208             // If client-side sorting is enabled, read in all results, sort, then get a sublist.
209
if (Boolean.valueOf(JiveGlobals.getXMLProperty(
210                     "ldap.clientSideSorting")).booleanValue())
211             {
212                 while (answer.hasMoreElements()) {
213                     // Get the next userID.
214
String JavaDoc username = (String JavaDoc)((SearchResult)answer.next()).getAttributes().get(
215                             manager.getUsernameField()).get();
216                     // Escape username and add to results.
217
usernames.add(JID.escapeNode(username));
218                 }
219                 Collections.sort(usernames);
220                 usernames = usernames.subList(startIndex, startIndex+numResults);
221             }
222             // Otherwise, only read in certain results.
223
else {
224                 for (int i=0; i < startIndex; i++) {
225                     if (answer.hasMoreElements()) {
226                         answer.next();
227                     }
228                     else {
229                         return Collections.emptyList();
230                     }
231                 }
232                 // Now read in desired number of results (or stop if we run out of results).
233
for (int i = 0; i < numResults; i++) {
234                     if (answer.hasMoreElements()) {
235                         // Get the next userID.
236
String JavaDoc username = (String JavaDoc)((SearchResult)answer.next()).getAttributes().get(
237                                 manager.getUsernameField()).get();
238                         // Escape username and add to results.
239
usernames.add(JID.escapeNode(username));
240                     }
241                     else {
242                         break;
243                     }
244                 }
245             }
246         }
247         catch (Exception JavaDoc e) {
248             Log.error(e);
249         }
250         finally {
251             try {
252                 if (ctx != null) {
253                     ctx.setRequestControls(null);
254                     ctx.close();
255                 }
256             }
257             catch (Exception JavaDoc ignored) { }
258         }
259         return new UserCollection((String JavaDoc[])usernames.toArray(new String JavaDoc[usernames.size()]));
260     }
261
262     public String JavaDoc getPassword(String JavaDoc username) throws UserNotFoundException,
263             UnsupportedOperationException JavaDoc
264     {
265         throw new UnsupportedOperationException JavaDoc();
266     }
267
268     public void setPassword(String JavaDoc username, String JavaDoc password) throws UserNotFoundException {
269         throw new UnsupportedOperationException JavaDoc();
270     }
271
272     public void setName(String JavaDoc username, String JavaDoc name) throws UserNotFoundException {
273         throw new UnsupportedOperationException JavaDoc();
274     }
275
276     public void setEmail(String JavaDoc username, String JavaDoc email) throws UserNotFoundException {
277         throw new UnsupportedOperationException JavaDoc();
278     }
279
280     public void setCreationDate(String JavaDoc username, Date creationDate) throws UserNotFoundException {
281         throw new UnsupportedOperationException JavaDoc();
282     }
283
284     public void setModificationDate(String JavaDoc username, Date modificationDate) throws UserNotFoundException {
285         throw new UnsupportedOperationException JavaDoc();
286     }
287
288     public Set<String JavaDoc> getSearchFields() throws UnsupportedOperationException JavaDoc {
289         return Collections.unmodifiableSet(searchFields.keySet());
290     }
291
292     public Collection<User> findUsers(Set<String JavaDoc> fields, String JavaDoc query)
293             throws UnsupportedOperationException JavaDoc
294     {
295         if (fields.isEmpty()) {
296             return Collections.emptyList();
297         }
298         if (!searchFields.keySet().containsAll(fields)) {
299             throw new IllegalArgumentException JavaDoc("Search fields " + fields + " are not valid.");
300         }
301         List<String JavaDoc> usernames = new ArrayList<String JavaDoc>();
302         LdapContext JavaDoc ctx = null;
303         try {
304             ctx = manager.getContext();
305             // Sort on username field.
306
Control JavaDoc[] searchControl = new Control JavaDoc[]{
307                 new SortControl JavaDoc(new String JavaDoc[]{manager.getUsernameField()}, Control.NONCRITICAL)
308             };
309             ctx.setRequestControls(searchControl);
310
311             // Search for the dn based on the username.
312
SearchControls constraints = new SearchControls();
313             constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
314             constraints.setReturningAttributes(new String JavaDoc[] { manager.getUsernameField() });
315             StringBuilder JavaDoc filter = new StringBuilder JavaDoc();
316             if (fields.size() > 1) {
317                 filter.append("(|");
318             }
319             for (String JavaDoc field:fields) {
320                 String JavaDoc attribute = searchFields.get(field);
321                 filter.append("(").append(attribute).append("=").append(query).append(")");
322             }
323             if (fields.size() > 1) {
324                 filter.append(")");
325             }
326             NamingEnumeration JavaDoc answer = ctx.search("", filter.toString(), constraints);
327             while (answer.hasMoreElements()) {
328                 // Get the next userID.
329
String JavaDoc username = (String JavaDoc)((SearchResult)answer.next()).getAttributes().get(
330                         manager.getUsernameField()).get();
331                 // Escape username and add to results.
332
usernames.add(JID.escapeNode(username));
333             }
334             // If client-side sorting is enabled, sort.
335
if (Boolean.valueOf(JiveGlobals.getXMLProperty(
336                     "ldap.clientSideSorting")).booleanValue())
337             {
338                 Collections.sort(usernames);
339             }
340         }
341         catch (Exception JavaDoc e) {
342             Log.error(e);
343         }
344         finally {
345             try {
346                 if (ctx != null) {
347                     ctx.setRequestControls(null);
348                     ctx.close();
349                 }
350             }
351             catch (Exception JavaDoc ignored) { }
352         }
353         return new UserCollection((String JavaDoc[])usernames.toArray(new String JavaDoc[usernames.size()]));
354     }
355
356     public Collection<User> findUsers(Set<String JavaDoc> fields, String JavaDoc query, int startIndex,
357             int numResults) throws UnsupportedOperationException JavaDoc
358     {
359         if (fields.isEmpty()) {
360             return Collections.emptyList();
361         }
362         if (!searchFields.keySet().containsAll(fields)) {
363             throw new IllegalArgumentException JavaDoc("Search fields " + fields + " are not valid.");
364         }
365         List<String JavaDoc> usernames = new ArrayList<String JavaDoc>();
366         LdapContext JavaDoc ctx = null;
367         try {
368             ctx = manager.getContext();
369             // Sort on username field.
370
Control JavaDoc[] searchControl = new Control JavaDoc[]{
371                 new SortControl JavaDoc(new String JavaDoc[]{manager.getUsernameField()}, Control.NONCRITICAL)
372             };
373             ctx.setRequestControls(searchControl);
374
375             // Search for the dn based on the username.
376
SearchControls constraints = new SearchControls();
377             constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
378             constraints.setReturningAttributes(new String JavaDoc[] { manager.getUsernameField() });
379             StringBuilder JavaDoc filter = new StringBuilder JavaDoc();
380             if (fields.size() > 1) {
381                 filter.append("(|");
382             }
383             for (String JavaDoc field:fields) {
384                 String JavaDoc attribute = searchFields.get(field);
385                 filter.append("(").append(attribute).append("=").append(query).append(")");
386             }
387             if (fields.size() > 1) {
388                 filter.append(")");
389             }
390             // TODO: used paged results is supported by LDAP server.
391
NamingEnumeration JavaDoc answer = ctx.search("", filter.toString(), constraints);
392             for (int i=0; i < startIndex; i++) {
393                 if (answer.hasMoreElements()) {
394                     answer.next();
395                 }
396                 else {
397                     return Collections.emptyList();
398                 }
399             }
400             // Now read in desired number of results (or stop if we run out of results).
401
for (int i = 0; i < numResults; i++) {
402                 if (answer.hasMoreElements()) {
403                     // Get the next userID.
404
String JavaDoc username = (String JavaDoc)((SearchResult)answer.next()).getAttributes().get(
405                             manager.getUsernameField()).get();
406                     // Escape username and add to results.
407
usernames.add(JID.escapeNode(username));
408                 }
409                 else {
410                     break;
411                 }
412             }
413             
414             // If client-side sorting is enabled, sort.
415
if (Boolean.valueOf(JiveGlobals.getXMLProperty(
416                     "ldap.clientSideSorting")).booleanValue())
417             {
418                 Collections.sort(usernames);
419             }
420         }
421         catch (Exception JavaDoc e) {
422             Log.error(e);
423         }
424         finally {
425             try {
426                 if (ctx != null) {
427                     ctx.setRequestControls(null);
428                     ctx.close();
429                 }
430             }
431             catch (Exception JavaDoc ignored) { }
432         }
433         return new UserCollection((String JavaDoc[])usernames.toArray(new String JavaDoc[usernames.size()]));
434     }
435
436     public boolean isReadOnly() {
437         return true;
438     }
439 }
Popular Tags