KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fulcrum > security > impl > db > DBUserManager


1 package org.apache.fulcrum.security.impl.db;
2
3 /* ====================================================================
4  * The Apache Software License, Version 1.1
5  *
6  * Copyright (c) 2001 The Apache Software Foundation. All rights
7  * reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution,
22  * if any, must include the following acknowledgment:
23  * "This product includes software developed by the
24  * Apache Software Foundation (http://www.apache.org/)."
25  * Alternately, this acknowledgment may appear in the software itself,
26  * if and wherever such third-party acknowledgments normally appear.
27  *
28  * 4. The names "Apache" and "Apache Software Foundation" and
29  * "Apache Turbine" must not be used to endorse or promote products
30  * derived from this software without prior written permission. For
31  * written permission, please contact apache@apache.org.
32  *
33  * 5. Products derived from this software may not be called "Apache",
34  * "Apache Turbine", nor may "Apache" appear in their name, without
35  * prior written permission of the Apache Software Foundation.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals on behalf of the Apache Software Foundation. For more
53  * information on the Apache Software Foundation, please see
54  * <http://www.apache.org/>.
55  */

56
57 import java.util.ArrayList JavaDoc;
58 import java.util.Iterator JavaDoc;
59 import java.util.List JavaDoc;
60
61 import org.apache.fulcrum.security.TurbineSecurity;
62 import org.apache.fulcrum.security.UserManager;
63 import org.apache.fulcrum.security.entity.User;
64 import org.apache.fulcrum.security.impl.db.entity.TurbineUser;
65 import org.apache.fulcrum.security.impl.db.entity.TurbineUserPeer;
66 import org.apache.fulcrum.security.util.DataBackendException;
67 import org.apache.fulcrum.security.util.EntityExistsException;
68 import org.apache.fulcrum.security.util.PasswordMismatchException;
69 import org.apache.fulcrum.security.util.UnknownEntityException;
70 import org.apache.torque.util.Criteria;
71
72 /**
73  * An UserManager performs {@link org.apache.fulcrum.security.entity.User}
74  * objects related tasks on behalf of the
75  * {@link org.apache.fulcrum.security.BaseSecurityService}.
76  *
77  * This implementation uses a relational database for storing user data. It
78  * expects that the User interface implementation will be castable to
79  * {@link org.apache.torque.om.BaseObject}.
80  *
81  * @author <a HREF="mailto:jon@collab.net">Jon S. Stevens</a>
82  * @author <a HREF="mailto:jmcnally@collab.net">John D. McNally</a>
83  * @author <a HREF="mailto:frank.kim@clearink.com">Frank Y. Kim</a>
84  * @author <a HREF="mailto:cberry@gluecode.com">Craig D. Berry</a>
85  * @author <a HREF="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
86  * @version $Id: DBUserManager.java,v 1.1 2004/11/12 10:26:14 epugh Exp $
87  */

88 public class DBUserManager implements UserManager
89 {
90
91     /**
92      * System.out.println() debugging
93      */

94     private static final boolean DEBUG = false;
95
96     /**
97      * Check whether a specified user's account exists.
98      *
99      * The login name is used for looking up the account.
100      *
101      * @param user The user to be checked.
102      * @return true if the specified account exists
103      * @throws DataBackendException if there was an error accessing
104      * the data backend.
105      */

106     public boolean accountExists( User user )
107         throws DataBackendException
108     {
109         return accountExists(user.getUserName());
110     }
111
112     /**
113      * Check whether a specified user's account exists.
114      *
115      * The login name is used for looking up the account.
116      *
117      * @param usename The name of the user to be checked.
118      * @return true if the specified account exists
119      * @throws DataBackendException if there was an error accessing
120      * the data backend.
121      */

122     public boolean accountExists( String JavaDoc username )
123         throws DataBackendException
124     {
125         Criteria criteria = new Criteria();
126         criteria.add(TurbineUserPeer.USERNAME, username);
127         List JavaDoc users;
128         try
129         {
130             users = TurbineUserPeer.doSelect(criteria);
131         }
132         catch(Exception JavaDoc e)
133         {
134             throw new DataBackendException(
135                 "Failed to check account's presence", e);
136         }
137         if ( users.size() > 1 )
138         {
139             throw new DataBackendException(
140                 "Multiple Users with same username '" + username + "'");
141         }
142         return(users.size() == 1);
143     }
144
145     /**
146      * Retrieve a user from persistent storage using username as the
147      * key.
148      *
149      * @param username the name of the user.
150      * @return an User object.
151      * @exception UnknownEntityException if the user's account does not
152      * exist in the database.
153      * @exception DataBackendException if there is a problem accessing the
154      * storage.
155      */

156     public User retrieve( String JavaDoc username )
157         throws UnknownEntityException, DataBackendException
158     {
159         Criteria criteria = new Criteria();
160         criteria.add( TurbineUserPeer.USERNAME, username );
161         List JavaDoc users;
162         try
163         {
164             users = TurbineUserPeer.doSelect(criteria);
165         }
166         catch(Exception JavaDoc e)
167         {
168             throw new DataBackendException("Failed to retrieve user '" +
169                 username + "'", e);
170         }
171         if ( users.size() > 1 )
172         {
173             throw new DataBackendException(
174                 "Multiple Users with same username '" + username + "'");
175         }
176         if ( users.size() == 1 )
177         {
178             return (User)users.get(0);
179         }
180         throw new UnknownEntityException("Unknown user '" + username + "'");
181     }
182
183     /**
184      * Retrieve a set of users that meet the specified criteria.
185      *
186      * As the keys for the criteria, you should use the constants that
187      * are defined in {@link User} interface, plus the names
188      * of the custom attributes you added to your user representation
189      * in the data storage. Use verbatim names of the attributes -
190      * without table name prefix in case of DB implementation.
191      *
192      * @param criteria The criteria of selection.
193      * @return a List of users meeting the criteria.
194      * @throws DataBackendException if there is a problem accessing the
195      * storage.
196      */

197     public User[] retrieve( Criteria criteria )
198         throws DataBackendException
199     {
200         Iterator JavaDoc keys = criteria.keySet().iterator();
201         while(keys.hasNext())
202         {
203             String JavaDoc key = (String JavaDoc)keys.next();
204             // set the table name for all attached criterion
205
Criteria.Criterion[] criterion = criteria
206                 .getCriterion(key).getAttachedCriterion();
207             for (int i=0;i<criterion.length;i++)
208             {
209                 String JavaDoc table = criterion[i].getTable();
210                 if ( table == null || "".equals(table) )
211                 {
212                     criterion[i].setTable(TurbineUserPeer.getTableName());
213                 }
214             }
215         }
216         List JavaDoc users = new ArrayList JavaDoc(0);
217         try
218         {
219             users = TurbineUserPeer.doSelect(criteria);
220         }
221         catch(Exception JavaDoc e)
222         {
223             throw new DataBackendException("Failed to retrieve users", e);
224         }
225         return (User[])users.toArray(new User[0]);
226     }
227
228     /**
229      * Retrieve a user from persistent storage using username as the
230      * key, and authenticate the user. The implementation may chose
231      * to authenticate to the server as the user whose data is being
232      * retrieved.
233      *
234      * @param username the name of the user.
235      * @param password the user supplied password.
236      * @return an User object.
237      * @exception PasswordMismatchException if the supplied password was
238      * incorrect.
239      * @exception UnknownEntityException if the user's account does not
240      * exist in the database.
241      * @exception DataBackendException if there is a problem accessing the
242      * storage.
243      */

244     public User retrieve( String JavaDoc username, String JavaDoc password )
245          throws PasswordMismatchException, UnknownEntityException,
246                 DataBackendException
247     {
248         User user = retrieve(username);
249         authenticate(user, password);
250         return user;
251     }
252
253     /**
254      * Save an User object to persistent storage. User's account is
255      * required to exist in the storage.
256      *
257      * @param user an User object to store.
258      * @exception UnknownEntityException if the user's account does not
259      * exist in the database.
260      * @exception DataBackendException if there is a problem accessing the
261      * storage.
262      */

263     public void store(User user)
264         throws UnknownEntityException, DataBackendException
265     {
266         if (!accountExists(user))
267         {
268             throw new UnknownEntityException("The account '" +
269                 user.getUserName() + "' does not exist");
270         }
271
272         try
273         {
274             // this is to mimic the old behavior of the method, the user
275
// should be new that is passed to this method. It would be
276
// better if this was checked, but the original code did not
277
// care about the user's state, so we set it to be appropriate
278
((TurbineUser)user).setNew(false);
279             ((TurbineUser)user).setModified(true);
280             ((TurbineUser) user).save();
281         }
282         catch(Exception JavaDoc e)
283         {
284             throw new DataBackendException("Failed to save user object", e);
285         }
286     }
287
288     /**
289      * Authenticate an User with the specified password. If authentication
290      * is successful the method returns nothing. If there are any problems,
291      * exception was thrown.
292      *
293      * @param user an User object to authenticate.
294      * @param password the user supplied password.
295      * @exception PasswordMismatchException if the supplied password was
296      * incorrect.
297      * @exception UnknownEntityException if the user's account does not
298      * exist in the database.
299      * @exception DataBackendException if there is a problem accessing the
300      * storage.
301      */

302     public void authenticate( User user, String JavaDoc password )
303         throws PasswordMismatchException, UnknownEntityException,
304                DataBackendException
305     {
306         if (!accountExists(user))
307         {
308             throw new UnknownEntityException("The account '" +
309                 user.getUserName() + "' does not exist");
310         }
311         String JavaDoc encrypted = TurbineSecurity.encryptPassword(password);
312
313         if (DEBUG)
314         {
315             System.out.println ("Supplied Pass: " + password);
316             System.out.println ("User Pass: " + user.getPassword());
317             System.out.println ("Encrypted Pass: " + encrypted );
318         }
319         if (!user.getPassword().equals(encrypted))
320         {
321             throw new PasswordMismatchException("The passwords do not match");
322         }
323     }
324
325     /**
326      * Change the password for an User.
327      *
328      * @param user an User to change password for.
329      * @param password the new password.
330      * @exception PasswordMismatchException if the supplied password was
331      * incorrect.
332      * @exception UnknownEntityException if the user's account does not
333      * exist in the database.
334      * @exception DataBackendException if there is a problem accessing the
335      * storage.
336      */

337     public void changePassword( User user, String JavaDoc oldPassword,
338                                 String JavaDoc newPassword )
339         throws PasswordMismatchException, UnknownEntityException,
340                DataBackendException
341     {
342         String JavaDoc encrypted = TurbineSecurity.encryptPassword(oldPassword);
343         if (!accountExists(user))
344         {
345             throw new UnknownEntityException("The account '" +
346                 user.getUserName() + "' does not exist");
347         }
348         if (!user.getPassword().equals(encrypted))
349         {
350             throw new PasswordMismatchException(
351                 "The supplied old password for '" + user.getUserName() +
352                 "' was incorrect");
353         }
354         user.setPassword(TurbineSecurity.encryptPassword(newPassword));
355         // save the changes in the database imediately, to prevent the password
356
// being 'reverted' to the old value if the user data is lost somehow
357
// before it is saved at session's expiry.
358
store(user);
359     }
360
361     /**
362      * Forcibly sets new password for an User.
363      *
364      * This is supposed by the administrator to change the forgotten or
365      * compromised passwords. Certain implementatations of this feature
366      * would require administrative level access to the authenticating
367      * server / program.
368      *
369      * @param user an User to change password for.
370      * @param password the new password.
371      * @exception UnknownEntityException if the user's record does not
372      * exist in the database.
373      * @exception DataBackendException if there is a problem accessing the
374      * storage.
375      */

376     public void forcePassword( User user, String JavaDoc password )
377         throws UnknownEntityException, DataBackendException
378     {
379         if (!accountExists(user))
380         {
381             throw new UnknownEntityException("The account '" +
382                 user.getUserName() + "' does not exist");
383         }
384         user.setPassword(TurbineSecurity.encryptPassword(password));
385         // save the changes in the database immediately, to prevent the
386
// password being 'reverted' to the old value if the user data
387
// is lost somehow before it is saved at session's expiry.
388
store(user);
389     }
390
391     /**
392      * Creates new user account with specified attributes.
393      *
394      * @param user the object describing account to be created.
395      * @throws DataBackendException if there was an error accessing
396                the data backend.
397      * @throws EntityExistsException if the user account already exists.
398      */

399     public void createAccount( User user, String JavaDoc initialPassword )
400         throws EntityExistsException, DataBackendException
401     {
402         if (accountExists(user))
403         {
404             throw new EntityExistsException("The account '" +
405                 user.getUserName() + "' already exists");
406         }
407         String JavaDoc encrypted = TurbineSecurity.encryptPassword(initialPassword);
408         user.setPassword(encrypted);
409         try
410         {
411             // this is to mimic the old behavior of the method, the user
412
// should be new that is passed to this method. It would be
413
// better if this was checked, but the original code did not
414
// care about the user's state, so we set it to be appropriate
415
((TurbineUser)user).setNew(true);
416             ((TurbineUser)user).setModified(true);
417             // we can safely assume that TurbineUser derivate is used as User
418
// implementation with this UserManager
419
((TurbineUser) user).save();
420         }
421         catch(Exception JavaDoc e)
422         {
423             throw new DataBackendException("Failed to create account '" +
424                 user.getUserName() + "'", e);
425         }
426     }
427
428     /**
429      * Removes an user account from the system.
430      *
431      * @param user the object describing the account to be removed.
432      * @throws DataBackendException if there was an error accessing
433                the data backend.
434      * @throws UnknownEntityException if the user account is not present.
435      */

436     public void removeAccount( User user )
437         throws UnknownEntityException, DataBackendException
438     {
439         if (!accountExists(user))
440         {
441             throw new UnknownEntityException("The account '" +
442                 user.getUserName() + "' does not exist");
443         }
444         Criteria criteria = new Criteria();
445         criteria.add(TurbineUserPeer.USERNAME, user.getUserName());
446         try
447         {
448             TurbineUserPeer.doDelete(criteria);
449         }
450         catch(Exception JavaDoc e)
451         {
452             throw new DataBackendException("Failed to remove account '" +
453                 user.getUserName() + "'", e);
454         }
455     }
456 }
457
Popular Tags