Coverage Report - org.apache.turbine.services.security.DefaultUserManager
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultUserManager
58%
47/81
25%
4/16
1,955
 
 1  
 package org.apache.turbine.services.security;
 2  
 
 3  
 
 4  
 /*
 5  
  * Licensed to the Apache Software Foundation (ASF) under one
 6  
  * or more contributor license agreements.  See the NOTICE file
 7  
  * distributed with this work for additional information
 8  
  * regarding copyright ownership.  The ASF licenses this file
 9  
  * to you under the Apache License, Version 2.0 (the
 10  
  * "License"); you may not use this file except in compliance
 11  
  * with the License.  You may obtain a copy of the License at
 12  
  *
 13  
  *   http://www.apache.org/licenses/LICENSE-2.0
 14  
  *
 15  
  * Unless required by applicable law or agreed to in writing,
 16  
  * software distributed under the License is distributed on an
 17  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 18  
  * KIND, either express or implied.  See the License for the
 19  
  * specific language governing permissions and limitations
 20  
  * under the License.
 21  
  */
 22  
 
 23  
 
 24  
 import java.util.ArrayList;
 25  
 import java.util.List;
 26  
 
 27  
 import org.apache.commons.configuration.Configuration;
 28  
 import org.apache.commons.logging.Log;
 29  
 import org.apache.commons.logging.LogFactory;
 30  
 import org.apache.fulcrum.factory.FactoryService;
 31  
 import org.apache.fulcrum.security.acl.AccessControlList;
 32  
 import org.apache.fulcrum.security.model.turbine.TurbineUserManager;
 33  
 import org.apache.fulcrum.security.model.turbine.entity.TurbineUser;
 34  
 import org.apache.fulcrum.security.util.DataBackendException;
 35  
 import org.apache.fulcrum.security.util.EntityExistsException;
 36  
 import org.apache.fulcrum.security.util.PasswordMismatchException;
 37  
 import org.apache.fulcrum.security.util.UnknownEntityException;
 38  
 import org.apache.fulcrum.security.util.UserSet;
 39  
 import org.apache.turbine.om.security.TurbineUserDelegate;
 40  
 import org.apache.turbine.om.security.User;
 41  
 import org.apache.turbine.services.InitializationException;
 42  
 import org.apache.turbine.services.ServiceManager;
 43  
 import org.apache.turbine.services.TurbineServices;
 44  
 import org.apache.turbine.util.ObjectUtils;
 45  
 
 46  
 /**
 47  
  * Default user manager.
 48  
  *
 49  
  * The user manager wraps Fulcrum security user objects into
 50  
  * Turbine-specific ones.
 51  
  *
 52  
  *
 53  
  * <ol><li>either in a method with the same name (and very similar signature)
 54  
  * <li>or mapped to method names as listed below:
 55  
  *
 56  
  * <ul>
 57  
  * <li>method(s) in this manager -> Fulcrum manager method(s)
 58  
  * <li>{@link #createAccount(User, String)}createAccount -> addUser(User, String)
 59  
  * <li>{@link #removeAccount(User)} -> removeUser(User)
 60  
  * <li>{@link #store(User)} -> saveUser(User)
 61  
  * <li>{@link #retrieve(String)} and {@link #retrieve(String, String)} -> getUser(String), getUser(String, String)
 62  
  * <li>{@link #retrieveList(Object)} ->getAllUsers()
 63  
  * <li>{@link #accountExists(String)}, {@link #accountExists(User)} -> checkExists(String), checkExists(User)
 64  
  *
 65  
  * In this way all public methods of Fulcrum {@link TurbineUserManager} interface are used by reference of the Fulcrum delegate {@link #umDelegate}
 66  
  * and wrapped by this manager.
 67  
  *
 68  
  * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
 69  
  * @version $Id: PassiveUserManager.java 1096130 2011-04-23 10:37:19Z ludwig $
 70  
  */
 71  5
 public class DefaultUserManager implements UserManager
 72  
 {
 73  
     /** Fulcrum user manager instance to delegate to */
 74  5
     private TurbineUserManager umDelegate = null;
 75  
 
 76  5
     private FactoryService factoryService = null;
 77  
 
 78  
     /** The user class, which the UserManager uses as wrapper for Fulcrum {@link TurbineUser} */
 79  
     private String userWrapperClass;
 80  
 
 81  
 
 82  
     /** Logging */
 83  5
     private static Log log = LogFactory.getLog(DefaultUserManager.class);
 84  
 
 85  
     /**
 86  
      * Wrap a Fulcrum user object into a Turbine user object
 87  
      *
 88  
      * @param user the user object to delegate to
 89  
      *
 90  
      * @return the wrapped object
 91  
      */
 92  
     protected <U extends User> U wrap(TurbineUser user)
 93  
     {
 94  
             // U u = (U)new DefaultUserImpl(user);
 95  
         @SuppressWarnings("unchecked")
 96  8
         U u = (U) getUserWrapper(user);
 97  8
         return u;
 98  
     }
 99  
 
 100  
     /**
 101  
      * Exception could be ignored, as it is tested before in {@link #init(Configuration)}.
 102  
      *
 103  
      * @param user the user object to wrap
 104  
      * @return instance extending {@link User}
 105  
      */
 106  
     @SuppressWarnings("unchecked")
 107  
         public <U extends User> U getUserWrapper(TurbineUser user)
 108  
     {
 109  
                 try
 110  
                 {
 111  8
             Object params[] = new Object[] { user };
 112  8
             String signature[] = new String[] { TurbineUser.class.getName() };
 113  8
             return (U) factoryService.getInstance(getUserWrapperClass(), params, signature);
 114  
                 }
 115  0
                 catch (Exception e)
 116  
                 {
 117  0
                         log.error("after init/late instantiation exception", e);
 118  0
                         return null; // (U)new DefaultUserImpl(user);
 119  
                 }
 120  
         }
 121  
 
 122  
     /**
 123  
      * Get the wrapper class for user objects
 124  
      *
 125  
      * @return the wrapper class name
 126  
      */
 127  
     public String getUserWrapperClass()
 128  
     {
 129  8
                 return userWrapperClass;
 130  
         }
 131  
 
 132  
     /**
 133  
      * Set the wrapper class for user objects
 134  
      *
 135  
      * @param userWrapperClass2 the wrapper class name
 136  
      */
 137  
     public void setUserWrapperClass(String userWrapperClass2)
 138  
     {
 139  5
                 userWrapperClass = userWrapperClass2;
 140  5
         }
 141  
 
 142  
         /**
 143  
      * Initializes the UserManager
 144  
      *
 145  
      * @param conf A Configuration object to init this Manager
 146  
      */
 147  
     @Override
 148  
     public void init(Configuration conf) throws InitializationException
 149  
     {
 150  5
         ServiceManager manager = TurbineServices.getInstance();
 151  5
         this.umDelegate = (TurbineUserManager)manager.getService(TurbineUserManager.ROLE);
 152  
 
 153  5
         String userWrapperClass = conf.getString(
 154  
                 SecurityService.USER_WRAPPER_KEY,
 155  
                 SecurityService.USER_WRAPPER_DEFAULT);
 156  
 
 157  
 //        String userClass = conf.getString(
 158  
 //                SecurityService.USER_KEY,
 159  
 //                SecurityService.USER_DEFAULT);
 160  
 
 161  
         try
 162  
         {
 163  5
                 factoryService = (FactoryService)manager.getService(FactoryService.ROLE);
 164  
 
 165  
             //  check instantiation
 166  
 
 167  
                 // should provide default constructor
 168  5
                 TurbineUser turbineUser = umDelegate.getUserInstance();
 169  
                                 //(TurbineUser) factoryService.getInstance(userClass);
 170  5
             Object params[] = new Object[] { turbineUser };
 171  5
             String signature[] = new String[] { TurbineUser.class.getName() };
 172  
 
 173  
             // Just check if exceptions would occur
 174  5
             factoryService.getInstance(userWrapperClass, params, signature);
 175  
 
 176  5
             this.setUserWrapperClass(userWrapperClass);
 177  
         }
 178  0
         catch (Exception e)
 179  
             {
 180  0
                throw new InitializationException("Failed to instantiate user wrapper class", e);
 181  5
             }
 182  
 
 183  5
     }
 184  
 
 185  
 
 186  
         /**
 187  
      * Check whether a specified user's account exists.
 188  
      *
 189  
      * The login name is used for looking up the account.
 190  
      *
 191  
      * @param user The user to be checked.
 192  
      * @return true if the specified account exists
 193  
      * @throws DataBackendException if there was an error accessing the data backend.
 194  
      */
 195  
     @Override
 196  
     public boolean accountExists(User user)
 197  
             throws DataBackendException
 198  
     {
 199  2
         if (user == null) {
 200  0
             return false;
 201  
         }
 202  2
         return umDelegate.checkExists(user.getUserDelegate());
 203  
     }
 204  
 
 205  
     /**
 206  
      * Check whether a specified user's account exists.
 207  
      *
 208  
      * The login name is used for looking up the account.
 209  
      *
 210  
      * @param userName The name of the user to be checked.
 211  
      * @return true if the specified account exists
 212  
      * @throws DataBackendException if there was an error accessing the data backend.
 213  
      */
 214  
     @Override
 215  
     public boolean accountExists(String userName)
 216  
             throws DataBackendException
 217  
     {
 218  2
         return umDelegate.checkExists(userName);
 219  
     }
 220  
 
 221  
     /**
 222  
      * Retrieve a user from persistent storage using username as the
 223  
      * key.
 224  
      *
 225  
      * @param username the name of the user.
 226  
      * @return an User object.
 227  
      * @throws UnknownEntityException if the user's record does not
 228  
      *            exist in the database.
 229  
      * @throws DataBackendException if there is a problem accessing the
 230  
      *            storage.
 231  
      */
 232  
     @Override
 233  
     public <U extends User> U retrieve(String username)
 234  
             throws UnknownEntityException, DataBackendException
 235  
     {
 236  1
         TurbineUser u = umDelegate.getUser(username);
 237  1
         return wrap(u);
 238  
     }
 239  
 
 240  
     /**
 241  
      * Retrieve a set of users that meet the specified criteria.
 242  
      *
 243  
      * As the keys for the criteria, you should use the constants that
 244  
      * are defined in {@link User} interface, plus the names
 245  
      * of the custom attributes you added to your user representation
 246  
      * in the data storage. Use verbatim names of the attributes -
 247  
      * without table name prefix in case of DB implementation.
 248  
      *
 249  
      * @param criteria The criteria of selection.
 250  
      * @return a List of users meeting the criteria.
 251  
      * @throws DataBackendException if there is a problem accessing the
 252  
      *         storage.
 253  
      */
 254  
     @Override
 255  
     public List<? extends User> retrieveList(Object criteria)
 256  
             throws DataBackendException
 257  
     {
 258  0
         UserSet<org.apache.fulcrum.security.entity.User> uset = umDelegate.getAllUsers();
 259  0
         List<User> userList = new ArrayList<User>();
 260  
 
 261  0
         for (org.apache.fulcrum.security.entity.User u : uset)
 262  
         {
 263  0
             TurbineUser tu = (TurbineUser)u;
 264  0
             userList.add(wrap(tu));
 265  0
         }
 266  
 
 267  0
         return userList;
 268  
     }
 269  
 
 270  
     /**
 271  
      * Retrieve a user from persistent storage using username as the
 272  
      * key, and authenticate the user. The implementation may chose
 273  
      * to authenticate to the server as the user whose data is being
 274  
      * retrieved.
 275  
      *
 276  
      * @param username the name of the user.
 277  
      * @param password the user supplied password.
 278  
      * @return an User object.
 279  
      * @throws PasswordMismatchException if the supplied password was
 280  
      *            incorrect.
 281  
      * @throws UnknownEntityException if the user's record does not
 282  
      *            exist in the database.
 283  
      * @throws DataBackendException if there is a problem accessing the
 284  
      *            storage.
 285  
      */
 286  
     @Override
 287  
     public <U extends User> U retrieve(String username, String password)
 288  
             throws PasswordMismatchException, UnknownEntityException,
 289  
             DataBackendException
 290  
     {
 291  1
         TurbineUser u = umDelegate.getUser(username, password);
 292  1
         return wrap(u);
 293  
     }
 294  
 
 295  
     /**
 296  
      * Save an User object to persistent storage. User's record is
 297  
      * required to exist in the storage.
 298  
      *
 299  
      * @param user an User object to store.
 300  
      * @throws UnknownEntityException if the user's record does not
 301  
      *            exist in the database.
 302  
      * @throws DataBackendException if there is a problem accessing the
 303  
      *            storage.
 304  
      */
 305  
     @Override
 306  
     public void store(User user)
 307  
             throws UnknownEntityException, DataBackendException
 308  
     {
 309  1
         if (user == null) {
 310  0
             throw new UnknownEntityException("user is null");
 311  
         }
 312  
         try
 313  
         {
 314  1
             user.setObjectdata(ObjectUtils.serializeMap(user.getPermStorage()));
 315  
         }
 316  0
         catch (Exception e)
 317  
         {
 318  0
             throw new DataBackendException("Could not serialize permanent storage", e);
 319  1
         }
 320  
 
 321  1
         umDelegate.saveUser(((TurbineUserDelegate)user).getUserDelegate());
 322  1
     }
 323  
 
 324  
     /**
 325  
      * Saves User data when the session is unbound. The user account is required
 326  
      * to exist in the storage.
 327  
      *
 328  
      * LastLogin, AccessCounter, persistent pull tools, and any data stored
 329  
      * in the permData hashtable that is not mapped to a column will be saved.
 330  
      *
 331  
      * @throws UnknownEntityException if the user's account does not
 332  
      *            exist in the database.
 333  
      * @throws DataBackendException if there is a problem accessing the
 334  
      *            storage.
 335  
      */
 336  
     @Override
 337  
     public void saveOnSessionUnbind(User user)
 338  
             throws UnknownEntityException, DataBackendException
 339  
     {
 340  0
         store(user);
 341  0
     }
 342  
 
 343  
     /**
 344  
      * Authenticate an User with the specified password. If authentication
 345  
      * is successful the method returns nothing. If there are any problems,
 346  
      * exception was thrown.
 347  
      *
 348  
      * @param user an User object to authenticate.
 349  
      * @param password the user supplied password.
 350  
      * @throws PasswordMismatchException if the supplied password was
 351  
      *            incorrect.
 352  
      * @throws UnknownEntityException if the user's record does not
 353  
      *            exist in the database.
 354  
      * @throws DataBackendException if there is a problem accessing the
 355  
      *            storage.
 356  
      */
 357  
     @Override
 358  
     public void authenticate(User user, String password)
 359  
             throws PasswordMismatchException, UnknownEntityException,
 360  
             DataBackendException
 361  
     {
 362  0
         umDelegate.authenticate(user, password);
 363  0
     }
 364  
 
 365  
     /**
 366  
      * Creates new user account with specified attributes.
 367  
      *
 368  
      * @param user the object describing account to be created.
 369  
      * @param initialPassword The password to use for the object creation
 370  
      *
 371  
      * @throws DataBackendException if there was an error accessing the data backend.
 372  
      * @throws EntityExistsException if the user account already exists.
 373  
      */
 374  
     @Override
 375  
     public void createAccount(User user, String initialPassword)
 376  
             throws UnknownEntityException, EntityExistsException, DataBackendException
 377  
     {
 378  3
         if (user == null) {
 379  0
             throw new UnknownEntityException("user is null");
 380  
         }
 381  3
         umDelegate.addUser(user.getUserDelegate(), initialPassword);
 382  3
     }
 383  
 
 384  
     /**
 385  
      * Removes an user account from the system.
 386  
      *
 387  
      * @param user the object describing the account to be removed.
 388  
      * @throws DataBackendException if there was an error accessing the data backend.
 389  
      * @throws UnknownEntityException if the user account is not present.
 390  
      */
 391  
     @Override
 392  
     public void removeAccount(User user)
 393  
             throws UnknownEntityException, DataBackendException
 394  
     {
 395  0
         if (user == null) {
 396  0
             throw new UnknownEntityException("user is null");
 397  
         }
 398  0
         umDelegate.removeUser(user.getUserDelegate());
 399  0
     }
 400  
 
 401  
     /**
 402  
      * Change the password for an User.
 403  
      *
 404  
      * @param user an User to change password for.
 405  
      * @param oldPassword the current password supplied by the user.
 406  
      * @param newPassword the current password requested by the user.
 407  
      * @throws PasswordMismatchException if the supplied password was
 408  
      *            incorrect.
 409  
      * @throws UnknownEntityException if the user's record does not
 410  
      *            exist in the database.
 411  
      * @throws DataBackendException if there is a problem accessing the
 412  
      *            storage.
 413  
      */
 414  
     @Override
 415  
     public void changePassword(User user, String oldPassword,
 416  
                                String newPassword)
 417  
             throws PasswordMismatchException, UnknownEntityException,
 418  
             DataBackendException
 419  
     {
 420  0
         if (user == null) {
 421  0
             throw new UnknownEntityException("user is null");
 422  
         }
 423  0
         umDelegate.changePassword(
 424  
                 ((TurbineUserDelegate)user).getUserDelegate(),
 425  
                 oldPassword, newPassword);
 426  0
     }
 427  
 
 428  
     /**
 429  
      * Forcibly sets new password for an User.
 430  
      *
 431  
      * This is supposed by the administrator to change the forgotten or
 432  
      * compromised passwords. Certain implementations of this feature
 433  
      * would require administrative level access to the authenticating
 434  
      * server / program.
 435  
      *
 436  
      * @param user an User to change password for.
 437  
      * @param password the new password.
 438  
      * @throws UnknownEntityException if the user's record does not
 439  
      *            exist in the database.
 440  
      * @throws DataBackendException if there is a problem accessing the
 441  
      *            storage.
 442  
      */
 443  
     @Override
 444  
     public void forcePassword(User user, String password)
 445  
             throws UnknownEntityException, DataBackendException
 446  
     {
 447  0
         if (user == null) {
 448  0
             throw new UnknownEntityException("user is null");
 449  
         }
 450  0
         umDelegate.forcePassword(user.getUserDelegate(), password);
 451  0
     }
 452  
 
 453  
     /**
 454  
      * Constructs an User object to represent an anonymous user of the
 455  
      * application.
 456  
      *
 457  
      * @return An anonymous Turbine User.
 458  
      * @throws UnknownEntityException
 459  
      *             if the anonymous User object couldn't be constructed.
 460  
      */
 461  
     @Override
 462  
     public <U extends User> U getAnonymousUser() throws UnknownEntityException
 463  
     {
 464  4
         TurbineUser u = umDelegate.getAnonymousUser();
 465  4
         return wrap(u);
 466  
     }
 467  
 
 468  
     /**
 469  
      * Checks whether a passed user object matches the anonymous user pattern
 470  
      * according to the configured user manager
 471  
      *
 472  
      * @param u a user object
 473  
      *
 474  
      * @return True if this is an anonymous user
 475  
      *
 476  
      */
 477  
     @Override
 478  
     public boolean isAnonymousUser(User u)
 479  
     {
 480  4
         return umDelegate.isAnonymousUser(u);
 481  
     }
 482  
 
 483  
     /**
 484  
      * Construct a blank User object.
 485  
      *
 486  
      * This method calls getUserClass, and then creates a new object using the
 487  
      * default constructor.
 488  
      *
 489  
      * @return an object implementing User interface.
 490  
      * @throws DataBackendException
 491  
      *             if the object could not be instantiated.
 492  
      */
 493  
     @Override
 494  
     public <U extends User> U getUserInstance() throws DataBackendException
 495  
     {
 496  1
         TurbineUser u = umDelegate.getUserInstance();
 497  1
         return wrap(u);
 498  
     }
 499  
 
 500  
     /**
 501  
      * Construct a blank User object.
 502  
      *
 503  
      * This method calls getUserClass, and then creates a new object using the
 504  
      * default constructor.
 505  
      *
 506  
      * @param userName
 507  
      *            The name of the user.
 508  
      *
 509  
      * @return an object implementing User interface.
 510  
      * @throws DataBackendException
 511  
      *             if the object could not be instantiated.
 512  
      */
 513  
     @Override
 514  
     public <U extends User> U getUserInstance(String userName) throws DataBackendException
 515  
     {
 516  1
         TurbineUser u = umDelegate.getUserInstance(userName);
 517  1
         return wrap(u);
 518  
     }
 519  
 
 520  
     /**
 521  
      * Return a Class object representing the system's chosen implementation of
 522  
      * of ACL interface.
 523  
      *
 524  
      * @return systems's chosen implementation of ACL interface.
 525  
      * @throws UnknownEntityException
 526  
      *             if the implementation of ACL interface could not be
 527  
      *             determined, or does not exist.
 528  
      */
 529  
     @Override
 530  
     public <A extends AccessControlList> A getACL(User user) throws UnknownEntityException
 531  
     {
 532  1
         if (user == null) {
 533  0
             throw new UnknownEntityException("user is null");
 534  
         }
 535  1
         return umDelegate.getACL(user.getUserDelegate());
 536  
     }
 537  
 }