View Javadoc
1 package org.apache.turbine.services.security.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; 58 import java.util.Iterator; 59 import java.util.List; 60 import org.apache.torque.om.BaseObject; 61 import org.apache.torque.util.Criteria; 62 import org.apache.turbine.om.security.User; 63 import org.apache.turbine.om.security.peer.TurbineUserPeer; 64 import org.apache.turbine.services.security.TurbineSecurity; 65 import org.apache.turbine.services.security.UserManager; 66 import org.apache.turbine.util.security.DataBackendException; 67 import org.apache.turbine.util.security.EntityExistsException; 68 import org.apache.turbine.util.security.PasswordMismatchException; 69 import org.apache.turbine.util.security.UnknownEntityException; 70 71 /*** 72 * An UserManager performs {@link org.apache.turbine.om.security.User} objects 73 * related tasks on behalf of the 74 * {@link org.apache.turbine.services.security.BaseSecurityService}. 75 * 76 * This implementation uses a relational database for storing user data. It 77 * expects that the User interface implementation will be castable to 78 * {@link org.apache.turbine.om.BaseObject}. 79 * 80 * @author <a href="mailto:jon@collab.net">Jon S. Stevens</a> 81 * @author <a href="mailto:john.mcnally@clearink.com">John D. McNally</a> 82 * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a> 83 * @author <a href="mailto:cberry@gluecode.com">Craig D. Berry</a> 84 * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> 85 * @version $Id: DBUserManager.java,v 1.3 2002/07/11 07:34:31 mpoeschl Exp $ 86 */ 87 public class DBUserManager implements UserManager 88 { 89 /*** 90 * Check whether a specified user's account exists. 91 * 92 * The login name is used for looking up the account. 93 * 94 * @param user The user to be checked. 95 * @return true if the specified account exists 96 * @throws DataBackendException if there was an error accessing 97 * the data backend. 98 */ 99 public boolean accountExists( User user ) 100 throws DataBackendException 101 { 102 return accountExists(user.getUserName()); 103 } 104 105 /*** 106 * Check whether a specified user's account exists. 107 * 108 * The login name is used for looking up the account. 109 * 110 * @param usename The name of the user to be checked. 111 * @return true if the specified account exists 112 * @throws DataBackendException if there was an error accessing 113 * the data backend. 114 */ 115 public boolean accountExists( String username ) 116 throws DataBackendException 117 { 118 Criteria criteria = new Criteria(); 119 criteria.add(TurbineUserPeer.USERNAME, username); 120 List users; 121 try 122 { 123 users = TurbineUserPeer.doSelect(criteria); 124 } 125 catch(Exception e) 126 { 127 throw new DataBackendException( 128 "Failed to check account's presence", e); 129 } 130 if ( users.size() > 1 ) 131 { 132 throw new DataBackendException( 133 "Multiple Users with same username '" + username + "'"); 134 } 135 return(users.size() == 1); 136 } 137 138 /*** 139 * Retrieve a user from persistent storage using username as the 140 * key. 141 * 142 * @param username the name of the user. 143 * @return an User object. 144 * @exception UnknownEntityException if the user's account does not 145 * exist in the database. 146 * @exception DataBackendException if there is a problem accessing the 147 * storage. 148 */ 149 public User retrieve( String username ) 150 throws UnknownEntityException, DataBackendException 151 { 152 Criteria criteria = new Criteria(); 153 criteria.add( TurbineUserPeer.USERNAME, username ); 154 List users; 155 try 156 { 157 users = TurbineUserPeer.doSelect(criteria); 158 } 159 catch(Exception e) 160 { 161 throw new DataBackendException("Failed to retrieve user '" + 162 username + "'", e); 163 } 164 if ( users.size() > 1 ) 165 { 166 throw new DataBackendException( 167 "Multiple Users with same username '" + username + "'"); 168 } 169 if ( users.size() == 1 ) 170 { 171 return (User)users.get(0); 172 } 173 throw new UnknownEntityException("Unknown user '" + username + "'"); 174 } 175 176 /*** 177 * Retrieve a set of users that meet the specified criteria. 178 * 179 * As the keys for the criteria, you should use the constants that 180 * are defined in {@link User} interface, plus the names 181 * of the custom attributes you added to your user representation 182 * in the data storage. Use verbatim names of the attributes - 183 * without table name prefix in case of DB implementation. 184 * 185 * @param criteria The criteria of selection. 186 * @return a List of users meeting the criteria. 187 * @throws DataBackendException if there is a problem accessing the 188 * storage. 189 */ 190 public User[] retrieve( Criteria criteria ) 191 throws DataBackendException 192 { 193 Iterator keys = criteria.keySet().iterator(); 194 while(keys.hasNext()) 195 { 196 String key = (String)keys.next(); 197 // set the table name for all attached criterion 198 Criteria.Criterion[] criterion = criteria 199 .getCriterion(key).getAttachedCriterion(); 200 for (int i=0;i<criterion.length;i++) 201 { 202 String table = criterion[i].getTable(); 203 if ( table == null || "".equals(table) ) 204 { 205 criterion[i].setTable(TurbineUserPeer.getTableName()); 206 } 207 } 208 } 209 List users = new ArrayList(0); 210 try 211 { 212 users = TurbineUserPeer.doSelect(criteria); 213 } 214 catch(Exception e) 215 { 216 throw new DataBackendException("Failed to retrieve users", e); 217 } 218 return (User[])users.toArray(new User[0]); 219 } 220 221 /*** 222 * Retrieve a user from persistent storage using username as the 223 * key, and authenticate the user. The implementation may chose 224 * to authenticate to the server as the user whose data is being 225 * retrieved. 226 * 227 * @param username the name of the user. 228 * @param password the user supplied password. 229 * @return an User object. 230 * @exception PasswordMismatchException if the supplied password was 231 * incorrect. 232 * @exception UnknownEntityException if the user's account does not 233 * exist in the database. 234 * @exception DataBackendException if there is a problem accessing the 235 * storage. 236 */ 237 public User retrieve( String username, String password ) 238 throws PasswordMismatchException, UnknownEntityException, 239 DataBackendException 240 { 241 User user = retrieve(username); 242 authenticate(user, password); 243 return user; 244 } 245 246 /*** 247 * Save an User object to persistent storage. User's account is 248 * required to exist in the storage. 249 * 250 * @param user an User object to store. 251 * @exception UnknownEntityException if the user's account does not 252 * exist in the database. 253 * @exception DataBackendException if there is a problem accessing the 254 * storage. 255 */ 256 public void store(User user) 257 throws UnknownEntityException, DataBackendException 258 { 259 if(!accountExists(user)) 260 { 261 throw new UnknownEntityException("The account '" + 262 user.getUserName() + "' does not exist"); 263 } 264 Criteria criteria = TurbineUserPeer.buildCriteria(user); 265 try 266 { 267 TurbineUserPeer.doUpdate(criteria); 268 } 269 catch(Exception e) 270 { 271 throw new DataBackendException("Failed to save user object", e); 272 } 273 } 274 275 /*** 276 * Authenticate an User with the specified password. If authentication 277 * is successful the method returns nothing. If there are any problems, 278 * exception was thrown. 279 * 280 * @param user an User object to authenticate. 281 * @param password the user supplied password. 282 * @exception PasswordMismatchException if the supplied password was 283 * incorrect. 284 * @exception UnknownEntityException if the user's account does not 285 * exist in the database. 286 * @exception DataBackendException if there is a problem accessing the 287 * storage. 288 */ 289 public void authenticate( User user, String password ) 290 throws PasswordMismatchException, UnknownEntityException, 291 DataBackendException 292 { 293 if(!accountExists(user)) 294 { 295 throw new UnknownEntityException("The account '" + 296 user.getUserName() + "' does not exist"); 297 } 298 String encrypted = TurbineSecurity.encryptPassword(password); 299 if(!user.getPassword().equals(encrypted)) 300 { 301 throw new PasswordMismatchException("The passwords do not match"); 302 } 303 } 304 305 /*** 306 * Change the password for an User. 307 * 308 * @param user an User to change password for. 309 * @param password the new password. 310 * @exception PasswordMismatchException if the supplied password was 311 * incorrect. 312 * @exception UnknownEntityException if the user's account does not 313 * exist in the database. 314 * @exception DataBackendException if there is a problem accessing the 315 * storage. 316 */ 317 public void changePassword( User user, String oldPassword, 318 String newPassword ) 319 throws PasswordMismatchException, UnknownEntityException, 320 DataBackendException 321 { 322 String encrypted = TurbineSecurity.encryptPassword(oldPassword); 323 if(!accountExists(user)) 324 { 325 throw new UnknownEntityException("The account '" + 326 user.getUserName() + "' does not exist"); 327 } 328 if(!user.getPassword().equals(encrypted)) 329 { 330 throw new PasswordMismatchException( 331 "The supplied old password for '" + user.getUserName() + 332 "' was incorrect"); 333 } 334 user.setPassword(TurbineSecurity.encryptPassword(newPassword)); 335 // save the changes in the database imediately, to prevent the password 336 // being 'reverted' to the old value if the user data is lost somehow 337 // before it is saved at session's expiry. 338 store(user); 339 } 340 341 /*** 342 * Forcibly sets new password for an User. 343 * 344 * This is supposed by the administrator to change the forgotten or 345 * compromised passwords. Certain implementatations of this feature 346 * would require administrative level access to the authenticating 347 * server / program. 348 * 349 * @param user an User to change password for. 350 * @param password the new password. 351 * @exception UnknownEntityException if the user's record does not 352 * exist in the database. 353 * @exception DataBackendException if there is a problem accessing the 354 * storage. 355 */ 356 public void forcePassword( User user, String password ) 357 throws UnknownEntityException, DataBackendException 358 { 359 if(!accountExists(user)) 360 { 361 throw new UnknownEntityException("The account '" + 362 user.getUserName() + "' does not exist"); 363 } 364 user.setPassword(TurbineSecurity.encryptPassword(password)); 365 // save the changes in the database immediately, to prevent the 366 // password being 'reverted' to the old value if the user data 367 // is lost somehow before it is saved at session's expiry. 368 store(user); 369 } 370 371 /*** 372 * Creates new user account with specified attributes. 373 * 374 * @param user the object describing account to be created. 375 * @throws DataBackendException if there was an error accessing 376 the data backend. 377 * @throws EntityExistsException if the user account already exists. 378 */ 379 public void createAccount( User user, String initialPassword ) 380 throws EntityExistsException, DataBackendException 381 { 382 if(accountExists(user)) 383 { 384 throw new EntityExistsException("The account '" + 385 user.getUserName() + "' already exists"); 386 } 387 String encrypted = TurbineSecurity.encryptPassword(initialPassword); 388 user.setPassword(encrypted); 389 Criteria criteria = TurbineUserPeer.buildCriteria(user); 390 try 391 { 392 // we can safely assume that BaseObject derivate is used as User 393 // implementation with this UserManager 394 ((BaseObject)user).setPrimaryKey( 395 TurbineUserPeer.doInsert(criteria)); 396 } 397 catch(Exception e) 398 { 399 throw new DataBackendException("Failed to create account '" + 400 user.getUserName() + "'", e); 401 } 402 } 403 404 /*** 405 * Removes an user account from the system. 406 * 407 * @param user the object describing the account to be removed. 408 * @throws DataBackendException if there was an error accessing 409 the data backend. 410 * @throws UnknownEntityException if the user account is not present. 411 */ 412 public void removeAccount( User user ) 413 throws UnknownEntityException, DataBackendException 414 { 415 if(!accountExists(user)) 416 { 417 throw new UnknownEntityException("The account '" + 418 user.getUserName() + "' does not exist"); 419 } 420 Criteria criteria = new Criteria(); 421 criteria.add(TurbineUserPeer.USERNAME, user.getUserName()); 422 try 423 { 424 TurbineUserPeer.doDelete(criteria); 425 } 426 catch(Exception e) 427 { 428 throw new DataBackendException("Failed to remove account '" + 429 user.getUserName() + "'", e); 430 } 431 } 432 }

This page was automatically generated by Maven