View Javadoc

1   /***
2    * Redistribution and use of this software and associated documentation
3    * ("Software"), with or without modification, are permitted provided
4    * that the following conditions are met:
5    *
6    * 1. Redistributions of source code must retain copyright
7    *    statements and notices.  Redistributions must also contain a
8    *    copy of this document.
9    *
10   * 2. Redistributions in binary form must reproduce the
11   *    above copyright notice, this list of conditions and the
12   *    following disclaimer in the documentation and/or other
13   *    materials provided with the distribution.
14   *
15   * 3. The name "Exolab" must not be used to endorse or promote
16   *    products derived from this Software without prior written
17   *    permission of Exoffice Technologies.  For written permission,
18   *    please contact info@exolab.org.
19   *
20   * 4. Products derived from this Software may not be called "Exolab"
21   *    nor may "Exolab" appear in their names without prior written
22   *    permission of Exoffice Technologies. Exolab is a registered
23   *    trademark of Exoffice Technologies.
24   *
25   * 5. Due credit should be given to the Exolab Project
26   *    (http://www.exolab.org/).
27   *
28   * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
32   * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39   * OF THE POSSIBILITY OF SUCH DAMAGE.
40   *
41   * Copyright 2003 (C) Exoffice Technologies Inc. All Rights Reserved.
42   *
43   **/
44  package org.exolab.jms.authentication;
45  
46  import java.sql.Connection;
47  import java.util.Enumeration;
48  import java.util.HashMap;
49  import java.util.Iterator;
50  
51  import javax.transaction.TransactionManager;
52  
53  import org.apache.commons.logging.Log;
54  import org.apache.commons.logging.LogFactory;
55  
56  import org.exolab.core.service.ServiceException;
57  import org.exolab.jms.config.Configuration;
58  import org.exolab.jms.config.ConfigurationManager;
59  import org.exolab.jms.config.SecurityConfiguration;
60  import org.exolab.jms.persistence.DatabaseService;
61  import org.exolab.jms.persistence.PersistenceAdapter;
62  import org.exolab.jms.persistence.SQLHelper;
63  
64  
65  /***
66   * The user manager is responsible for creating and managing users.
67   *
68   * @version     $Revision: 1.3 $ $Date: 2003/08/07 13:32:49 $
69   * @author      <a href="mailto:knut@lerpold.no">Knut Lerpold</a>
70   */
71  public class UserManager {
72  
73      /***
74       * A list of all users are maintained
75       * in this data structure.
76       */
77      private HashMap _userCache = new HashMap();
78  
79      /***
80       * The logger
81       */
82      private static final Log _log = LogFactory.getLog(UserManager.class);
83  
84  
85      /***
86       * Construct a new <code>UserManager</code>
87       *
88       * @throws ServiceException if the service cannot be initialised
89       */
90      protected UserManager() throws ServiceException {
91          init();
92      }
93  
94      /***
95       * Create a new user
96       *
97       * @param user the userobject containing username and password
98       * @return <code>true</code> if the user is created
99       * otherwise <code>false</code>
100      */
101     public synchronized boolean createUser(User user) {
102         boolean success = false;
103         PersistenceAdapter adapter = DatabaseService.getAdapter();
104 
105         if (_userCache.get(user.getUsername()) == null) {
106             Connection connection = null;
107             try {
108                 connection = DatabaseService.getConnection();
109                 adapter.addUser(connection, user);
110                 addToUserCache(user);
111                 connection.commit();
112                 success = true;
113             } catch (Exception exception) {
114                 _log.error("Failed to create user", exception);
115                 SQLHelper.rollback(connection);
116             } finally {
117                 SQLHelper.close(connection);
118             }
119         }
120 
121         return success;
122     }
123 
124     /***
125      * Update user.
126      * Only possible update is password.
127      *
128      * @param user the userobject containing the username
129      * @return <code>true</code> if password is updated
130      * otherwise <code>false</code>
131      */
132     public synchronized boolean updateUser(User user) {
133         boolean success = false;
134         PersistenceAdapter adapter = DatabaseService.getAdapter();
135 
136         if (_userCache.get(user.getUsername()) != null) {
137             Connection connection = null;
138             try {
139                 connection = DatabaseService.getConnection();
140                 adapter.updateUser(connection, user);
141                 connection.commit();
142                 addToUserCache(user);
143                 success = true;
144             } catch (Exception exception) {
145                 _log.error("Failed to update user", exception);
146                 SQLHelper.rollback(connection);
147             } finally {
148                 SQLHelper.close(connection);
149             }
150         }
151 
152         return success;
153     }
154 
155     /***
156      * Delete a users
157      *
158      * @param user the userobject containing the username
159      * @return <code>true</code> if the is removed
160      * otherwise <code>false</code>
161      */
162     public synchronized boolean deleteUser(User user) {
163         boolean success = false;
164         PersistenceAdapter adapter = DatabaseService.getAdapter();
165 
166         if (_userCache.get(user.getUsername()) != null) {
167             Connection connection = null;
168             try {
169                 connection = DatabaseService.getConnection();
170                 adapter.removeUser(connection, user);
171                 removeFromUserCache(user);
172                 success = true;
173                 connection.commit();
174             } catch (Exception exception) {
175                 _log.error("Failed to remove user", exception);
176                 SQLHelper.rollback(connection);
177             } finally {
178                 SQLHelper.close(connection);
179             }
180         }
181         return success;
182     }
183 
184     /***
185      * Return a user
186      *
187      * @param user the userobject containing the username
188      * @return a User
189      */
190     public synchronized User getUser(User user) {
191         return (User) _userCache.get(user.getUsername());
192     }
193 
194     /***
195      * Return a list of user names currently supported by the user
196      * manager. This includes all types of users.
197      *
198      * @return an enumeration of the user names
199      */
200     public Iterator userNames() {
201         return _userCache.keySet().iterator();
202     }
203 
204     /***
205      * Destroy this manager. This is brutal and final
206      */
207     public synchronized void destroy() {
208         _userCache.clear();
209         _userCache = null;
210     }
211 
212     /***
213      * Determines if a user's name and password are valid
214      *
215      * @param username the user's name
216      * @param password the user's password
217      * @return <code>true</code> if the name and password are valid,
218      * otherwise <code>false</code>
219      */
220     public synchronized boolean validateUser(String username,
221                                              String password) {
222         boolean result = false;
223 
224         SecurityConfiguration config =
225             ConfigurationManager.getConfig().getSecurityConfiguration();
226         if (!config.getSecurityEnabled()) {
227             // security disabled
228             result = true;
229         }
230 
231         User user = (User) _userCache.get(username);
232         if (user != null && user.getPassword().equals(password)) {
233             result = true;
234         }
235 
236         return result;
237     }
238 
239     /***
240      * Initialise user manager.
241      *
242      * @throws ServiceException if the user manager cannot be initialised
243      */
244     protected void init() throws ServiceException {
245         Connection connection = null;
246         TransactionManager tm = null;
247         try {
248             connection = DatabaseService.getConnection();
249 
250             Enumeration iter =
251                 DatabaseService.getAdapter().getAllUsers(connection);
252             connection.commit();
253 
254             while (iter.hasMoreElements()) {
255                 // add each user to the cache
256                 User user = (User) iter.nextElement();
257                 addToUserCache(user);
258             }
259         } catch (Exception exception) {
260             SQLHelper.rollback(connection);
261             _log.error("Failed to initialise UserManager", exception);
262             throw new ServiceException(exception);
263         } finally {
264             SQLHelper.close(connection);
265         }
266 
267         registerConfiguredUsers();
268     }
269 
270     /***
271      * Add the specified entry to the user cache, if it doesn't
272      * already exist.
273      *
274      * @param user - user to add
275      */
276     protected void addToUserCache(User user) {
277         if (!_userCache.containsKey(user.getUsername())) {
278             _userCache.put(user.getUsername(), user);
279         }
280     }
281 
282     /***
283      * Remove the specified user from the cache
284      *
285      * @param user the user to remove
286      */
287     protected void removeFromUserCache(User user) {
288         _userCache.remove(user.getUsername());
289     }
290 
291     /***
292      * Registers users specified in the configuration
293      */
294     protected void registerConfiguredUsers() {
295         Configuration config = ConfigurationManager.getConfig();
296         if (config.getUsers() != null) {
297             org.exolab.jms.config.User[] users = config.getUsers().getUser();
298             for (int i = 0; i < users.length; ++i) {
299                 User user = new User(users[i].getName(),
300                     users[i].getPassword());
301                 createUser(user);
302             }
303         }
304     }
305 
306 }