Coverage report

  %line %branch
org.apache.turbine.services.security.BaseSecurityService
68% 
96% 

 1  
 package org.apache.turbine.services.security;
 2  
 
 3  
 /*
 4  
  * Copyright 2001-2005 The Apache Software Foundation.
 5  
  *
 6  
  * Licensed under the Apache License, Version 2.0 (the "License")
 7  
  * you may not use this file except in compliance with the License.
 8  
  * You may obtain a copy of the License at
 9  
  *
 10  
  *     http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing, software
 13  
  * distributed under the License is distributed on an "AS IS" BASIS,
 14  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  
  * See the License for the specific language governing permissions and
 16  
  * limitations under the License.
 17  
  */
 18  
 
 19  
 import java.util.List;
 20  
 import java.util.Map;
 21  
 
 22  
 import javax.servlet.ServletConfig;
 23  
 
 24  
 import org.apache.commons.configuration.Configuration;
 25  
 
 26  
 import org.apache.commons.lang.StringUtils;
 27  
 
 28  
 import org.apache.commons.logging.Log;
 29  
 import org.apache.commons.logging.LogFactory;
 30  
 
 31  
 import org.apache.torque.util.Criteria;
 32  
 
 33  
 import org.apache.turbine.om.security.Group;
 34  
 import org.apache.turbine.om.security.Permission;
 35  
 import org.apache.turbine.om.security.Role;
 36  
 import org.apache.turbine.om.security.User;
 37  
 import org.apache.turbine.services.InitializationException;
 38  
 import org.apache.turbine.services.TurbineBaseService;
 39  
 import org.apache.turbine.services.TurbineServices;
 40  
 import org.apache.turbine.services.crypto.CryptoAlgorithm;
 41  
 import org.apache.turbine.services.crypto.CryptoService;
 42  
 import org.apache.turbine.services.crypto.TurbineCrypto;
 43  
 import org.apache.turbine.services.factory.FactoryService;
 44  
 import org.apache.turbine.util.security.AccessControlList;
 45  
 import org.apache.turbine.util.security.DataBackendException;
 46  
 import org.apache.turbine.util.security.EntityExistsException;
 47  
 import org.apache.turbine.util.security.GroupSet;
 48  
 import org.apache.turbine.util.security.PasswordMismatchException;
 49  
 import org.apache.turbine.util.security.PermissionSet;
 50  
 import org.apache.turbine.util.security.RoleSet;
 51  
 import org.apache.turbine.util.security.UnknownEntityException;
 52  
 
 53  
 /**
 54  
  * This is a common subset of SecurityService implementation.
 55  
  *
 56  
  * Provided functionality includes:
 57  
  * <ul>
 58  
  * <li> methods for retrieving User objects, that delegates functionality
 59  
  *      to the pluggable implementations of the User interface.
 60  
  * <li> synchronization mechanism for methods reading/modifying the security
 61  
  *      information, that guarantees that multiple threads may read the
 62  
  *      information concurrently, but threads that modify the information
 63  
  *      acquires exclusive access.
 64  
  * <li> implementation of convenience methods for retrieving security entities
 65  
  *      that maintain in-memory caching of objects for fast access.
 66  
  * </ul>
 67  
  *
 68  
  * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
 69  
  * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
 70  
  * @author <a href="mailto:marco@intermeta.de">Marco Kn&uuml;ttel</a>
 71  
  * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
 72  
  * @version $Id: BaseSecurityService.java 264148 2005-08-29 14:21:04Z henning $
 73  
  */
 74  39
 public abstract class BaseSecurityService
 75  
         extends TurbineBaseService
 76  
         implements SecurityService
 77  
 {
 78  
     /** The number of threads concurrently reading security information */
 79  18
     private int readerCount = 0;
 80  
 
 81  
     /** The instance of UserManager the SecurityService uses */
 82  18
     private UserManager userManager = null;
 83  
 
 84  
     /** The class of User the SecurityService uses */
 85  18
     private Class userClass = null;
 86  
 
 87  
     /** The class of Group the SecurityService uses */
 88  18
     private Class groupClass = null;
 89  
 
 90  
     /** The class of Permission the SecurityService uses */
 91  18
     private Class permissionClass = null;
 92  
 
 93  
     /** The class of Role the SecurityService uses */
 94  18
     private Class roleClass = null;
 95  
 
 96  
     /** The class of ACL the SecurityService uses */
 97  18
     private Class aclClass = null;
 98  
 
 99  
     /** A factory to construct ACL Objects */
 100  18
     private FactoryService aclFactoryService = null;
 101  
 
 102  
     /**
 103  
      * The Group object that represents the <a href="#global">global group</a>.
 104  
      */
 105  27
     private static Group globalGroup = null;
 106  
 
 107  
     /** Logging */
 108  30
     private static Log log = LogFactory.getLog(BaseSecurityService.class);
 109  
 
 110  
     /**
 111  
      * This method provides client-side encryption of passwords.
 112  
      *
 113  
      * If <code>secure.passwords</code> are enabled in TurbineResources,
 114  
      * the password will be encrypted, if not, it will be returned unchanged.
 115  
      * The <code>secure.passwords.algorithm</code> property can be used
 116  
      * to chose which digest algorithm should be used for performing the
 117  
      * encryption. <code>SHA</code> is used by default.
 118  
      *
 119  
      * @param password the password to process
 120  
      * @return processed password
 121  
      */
 122  
     public String encryptPassword(String password)
 123  
     {
 124  16
         return encryptPassword(password, null);
 125  
     }
 126  
 
 127  
     /**
 128  
      * This method provides client-side encryption of passwords.
 129  
      *
 130  
      * If <code>secure.passwords</code> are enabled in TurbineResources,
 131  
      * the password will be encrypted, if not, it will be returned unchanged.
 132  
      * The <code>secure.passwords.algorithm</code> property can be used
 133  
      * to chose which digest algorithm should be used for performing the
 134  
      * encryption. <code>SHA</code> is used by default.
 135  
      *
 136  
      * The used algorithms must be prepared to accept null as a
 137  
      * valid parameter for salt. All algorithms in the Fulcrum Cryptoservice
 138  
      * accept this.
 139  
      *
 140  
      * @param password the password to process
 141  
      * @param salt     algorithms that needs a salt can provide one here
 142  
      * @return processed password
 143  
      */
 144  
 
 145  
     public String encryptPassword(String password, String salt)
 146  
     {
 147  34
         if (password == null)
 148  
         {
 149  0
             return null;
 150  
         }
 151  34
         String secure = getConfiguration().getString(
 152  
                 SecurityService.SECURE_PASSWORDS_KEY,
 153  
                 SecurityService.SECURE_PASSWORDS_DEFAULT).toLowerCase();
 154  
 
 155  34
         String algorithm = getConfiguration().getString(
 156  
                 SecurityService.SECURE_PASSWORDS_ALGORITHM_KEY,
 157  
                 SecurityService.SECURE_PASSWORDS_ALGORITHM_DEFAULT);
 158  
 
 159  34
         CryptoService cs = TurbineCrypto.getService();
 160  
 
 161  34
         if (cs != null && (secure.equals("true") || secure.equals("yes")))
 162  
         {
 163  
             try
 164  
             {
 165  0
                 CryptoAlgorithm ca = cs.getCryptoAlgorithm(algorithm);
 166  
 
 167  0
                 ca.setSeed(salt);
 168  
 
 169  0
                 String result = ca.encrypt(password);
 170  
 
 171  0
                 return result;
 172  
             }
 173  0
             catch (Exception e)
 174  
             {
 175  0
                 log.error("Unable to encrypt password: ", e);
 176  
 
 177  0
                 return null;
 178  
             }
 179  
         }
 180  
         else
 181  
         {
 182  34
             return password;
 183  
         }
 184  
     }
 185  
 
 186  
     /**
 187  
      * Checks if a supplied password matches the encrypted password
 188  
      *
 189  
      * @param checkpw      The clear text password supplied by the user
 190  
      * @param encpw        The current, encrypted password
 191  
      *
 192  
      * @return true if the password matches, else false
 193  
      *
 194  
      */
 195  
 
 196  
     public boolean checkPassword(String checkpw, String encpw)
 197  
     {
 198  18
         String result = encryptPassword(checkpw, encpw);
 199  
 
 200  18
         return (result == null) ? false : result.equals(encpw);
 201  
     }
 202  
 
 203  
     /**
 204  
      * Initializes the SecurityService, locating the apropriate UserManager
 205  
      * This is a zero parameter variant which queries the Turbine Servlet
 206  
      * for its config.
 207  
      *
 208  
      * @throws InitializationException Something went wrong in the init stage
 209  
      */
 210  
     public void init()
 211  
             throws InitializationException
 212  
     {
 213  18
         Configuration conf = getConfiguration();
 214  
 
 215  18
         String userManagerClassName = conf.getString(
 216  
                 SecurityService.USER_MANAGER_KEY,
 217  
                 SecurityService.USER_MANAGER_DEFAULT);
 218  
 
 219  18
         String userClassName = conf.getString(
 220  
                 SecurityService.USER_CLASS_KEY,
 221  
                 SecurityService.USER_CLASS_DEFAULT);
 222  
 
 223  18
         String groupClassName = conf.getString(
 224  
                 SecurityService.GROUP_CLASS_KEY,
 225  
                 SecurityService.GROUP_CLASS_DEFAULT);
 226  
 
 227  18
         String permissionClassName = conf.getString(
 228  
                 SecurityService.PERMISSION_CLASS_KEY,
 229  
                 SecurityService.PERMISSION_CLASS_DEFAULT);
 230  
 
 231  18
         String roleClassName = conf.getString(
 232  
                 SecurityService.ROLE_CLASS_KEY,
 233  
                 SecurityService.ROLE_CLASS_DEFAULT);
 234  
 
 235  18
         String aclClassName = conf.getString(
 236  
                 SecurityService.ACL_CLASS_KEY,
 237  
                 SecurityService.ACL_CLASS_DEFAULT);
 238  
 
 239  
         try
 240  
         {
 241  18
             userClass = Class.forName(userClassName);
 242  18
             groupClass = Class.forName(groupClassName);
 243  18
             permissionClass = Class.forName(permissionClassName);
 244  18
             roleClass = Class.forName(roleClassName);
 245  18
             aclClass = Class.forName(aclClassName);
 246  9
         }
 247  0
         catch (Exception e)
 248  
         {
 249  0
             if (userClass == null)
 250  
             {
 251  0
                 throw new InitializationException(
 252  
                         "Failed to create a Class object for User implementation", e);
 253  
             }
 254  0
             if (groupClass == null)
 255  
             {
 256  0
                 throw new InitializationException(
 257  
                         "Failed to create a Class object for Group implementation", e);
 258  
             }
 259  0
             if (permissionClass == null)
 260  
             {
 261  0
                 throw new InitializationException(
 262  
                         "Failed to create a Class object for Permission implementation", e);
 263  
             }
 264  0
             if (roleClass == null)
 265  
             {
 266  0
                 throw new InitializationException(
 267  
                         "Failed to create a Class object for Role implementation", e);
 268  
             }
 269  0
             if (aclClass == null)
 270  
             {
 271  0
                 throw new InitializationException(
 272  
                         "Failed to create a Class object for ACL implementation", e);
 273  
             }
 274  9
         }
 275  
 
 276  
         try
 277  
         {
 278  18
             UserManager userManager =
 279  
                     (UserManager) Class.forName(userManagerClassName).newInstance();
 280  
 
 281  18
             userManager.init(conf);
 282  
 
 283  18
             setUserManager(userManager);
 284  9
         }
 285  0
         catch (Exception e)
 286  
         {
 287  0
             throw new InitializationException("Failed to instantiate UserManager", e);
 288  9
         }
 289  
 
 290  
         try
 291  
         {
 292  18
             aclFactoryService = (FactoryService) TurbineServices.getInstance().
 293  
                     getService(FactoryService.SERVICE_NAME);
 294  9
         }
 295  0
         catch (Exception e)
 296  
         {
 297  0
             throw new InitializationException(
 298  
                     "BaseSecurityService.init: Failed to get the Factory Service object", e);
 299  9
         }
 300  
 
 301  18
         setInit(true);
 302  18
     }
 303  
 
 304  
     /**
 305  
      * Initializes the SecurityService, locating the apropriate UserManager
 306  
      *
 307  
      * @param config a ServletConfig, to enforce early initialization
 308  
      * @throws InitializationException Something went wrong in the init stage
 309  
      * @deprecated use init() instead.
 310  
      */
 311  
     public void init(ServletConfig config) throws InitializationException
 312  
     {
 313  0
         init();
 314  0
     }
 315  
 
 316  
     /**
 317  
      * Return a Class object representing the system's chosen implementation of
 318  
      * of User interface.
 319  
      *
 320  
      * @return systems's chosen implementation of User interface.
 321  
      * @throws UnknownEntityException if the implementation of User interface
 322  
      *         could not be determined, or does not exist.
 323  
      */
 324  
     public Class getUserClass()
 325  
             throws UnknownEntityException
 326  
     {
 327  312
         if (userClass == null)
 328  
         {
 329  0
             throw new UnknownEntityException(
 330  
                     "Failed to create a Class object for User implementation");
 331  
         }
 332  312
         return userClass;
 333  
     }
 334  
 
 335  
     /**
 336  
      * Construct a blank User object.
 337  
      *
 338  
      * This method calls getUserClass, and then creates a new object using
 339  
      * the default constructor.
 340  
      *
 341  
      * @return an object implementing User interface.
 342  
      * @throws UnknownEntityException if the object could not be instantiated.
 343  
      */
 344  
     public User getUserInstance()
 345  
             throws UnknownEntityException
 346  
     {
 347  
         User user;
 348  
         try
 349  
         {
 350  24
             user = (User) getUserClass().newInstance();
 351  12
         }
 352  0
         catch (Exception e)
 353  
         {
 354  0
             throw new UnknownEntityException(
 355  
                     "Failed instantiate an User implementation object", e);
 356  12
         }
 357  24
         return user;
 358  
     }
 359  
 
 360  
     /**
 361  
      * Construct a blank User object.
 362  
      *
 363  
      * This method calls getUserClass, and then creates a new object using
 364  
      * the default constructor.
 365  
      *
 366  
      * @param userName The name of the user.
 367  
      *
 368  
      * @return an object implementing User interface.
 369  
      *
 370  
      * @throws UnknownEntityException if the object could not be instantiated.
 371  
      */
 372  
     public User getUserInstance(String userName)
 373  
             throws UnknownEntityException
 374  
     {
 375  0
         User user = getUserInstance();
 376  0
         user.setName(userName);
 377  0
         return user;
 378  
     }
 379  
 
 380  
     /**
 381  
      * Return a Class object representing the system's chosen implementation of
 382  
      * of Group interface.
 383  
      *
 384  
      * @return systems's chosen implementation of Group interface.
 385  
      * @throws UnknownEntityException if the implementation of Group interface
 386  
      *         could not be determined, or does not exist.
 387  
      */
 388  
     public Class getGroupClass()
 389  
             throws UnknownEntityException
 390  
     {
 391  240
         if (groupClass == null)
 392  
         {
 393  0
             throw new UnknownEntityException(
 394  
                     "Failed to create a Class object for Group implementation");
 395  
         }
 396  240
         return groupClass;
 397  
     }
 398  
 
 399  
     /**
 400  
      * Construct a blank Group object.
 401  
      *
 402  
      * This method calls getGroupClass, and then creates a new object using
 403  
      * the default constructor.
 404  
      *
 405  
      * @return an object implementing Group interface.
 406  
      * @throws UnknownEntityException if the object could not be instantiated.
 407  
      */
 408  
     public Group getGroupInstance()
 409  
             throws UnknownEntityException
 410  
     {
 411  
         Group group;
 412  
         try
 413  
         {
 414  16
             group = (Group) getGroupClass().newInstance();
 415  8
         }
 416  0
         catch (Exception e)
 417  
         {
 418  0
             throw new UnknownEntityException("Failed to instantiate a Group implementation object", e);
 419  8
         }
 420  16
         return group;
 421  
     }
 422  
 
 423  
     /**
 424  
      * Construct a blank Group object.
 425  
      *
 426  
      * This method calls getGroupClass, and then creates a new object using
 427  
      * the default constructor.
 428  
      *
 429  
      * @param groupName The name of the Group
 430  
      *
 431  
      * @return an object implementing Group interface.
 432  
      *
 433  
      * @throws UnknownEntityException if the object could not be instantiated.
 434  
      */
 435  
     public Group getGroupInstance(String groupName)
 436  
             throws UnknownEntityException
 437  
     {
 438  8
         Group group = getGroupInstance();
 439  8
         group.setName(groupName);
 440  8
         return group;
 441  
     }
 442  
 
 443  
     /**
 444  
      * Return a Class object representing the system's chosen implementation of
 445  
      * of Permission interface.
 446  
      *
 447  
      * @return systems's chosen implementation of Permission interface.
 448  
      * @throws UnknownEntityException if the implementation of Permission interface
 449  
      *         could not be determined, or does not exist.
 450  
      */
 451  
     public Class getPermissionClass()
 452  
             throws UnknownEntityException
 453  
     {
 454  316
         if (permissionClass == null)
 455  
         {
 456  0
             throw new UnknownEntityException(
 457  
                     "Failed to create a Class object for Permission implementation");
 458  
         }
 459  316
         return permissionClass;
 460  
     }
 461  
 
 462  
     /**
 463  
      * Construct a blank Permission object.
 464  
      *
 465  
      * This method calls getPermissionClass, and then creates a new object using
 466  
      * the default constructor.
 467  
      *
 468  
      * @return an object implementing Permission interface.
 469  
      * @throws UnknownEntityException if the object could not be instantiated.
 470  
      */
 471  
     public Permission getPermissionInstance()
 472  
             throws UnknownEntityException
 473  
     {
 474  
         Permission permission;
 475  
         try
 476  
         {
 477  16
             permission = (Permission) getPermissionClass().newInstance();
 478  8
         }
 479  0
         catch (Exception e)
 480  
         {
 481  0
             throw new UnknownEntityException("Failed to instantiate a Permission implementation object", e);
 482  8
         }
 483  16
         return permission;
 484  
     }
 485  
 
 486  
     /**
 487  
      * Construct a blank Permission object.
 488  
      *
 489  
      * This method calls getPermissionClass, and then creates a new object using
 490  
      * the default constructor.
 491  
      *
 492  
      * @param permName The name of the permission.
 493  
      *
 494  
      * @return an object implementing Permission interface.
 495  
      * @throws UnknownEntityException if the object could not be instantiated.
 496  
      */
 497  
     public Permission getPermissionInstance(String permName)
 498  
             throws UnknownEntityException
 499  
     {
 500  8
         Permission perm = getPermissionInstance();
 501  8
         perm.setName(permName);
 502  8
         return perm;
 503  
     }
 504  
 
 505  
     /**
 506  
      * Return a Class object representing the system's chosen implementation of
 507  
      * of Role interface.
 508  
      *
 509  
      * @return systems's chosen implementation of Role interface.
 510  
      * @throws UnknownEntityException if the implementation of Role interface
 511  
      *         could not be determined, or does not exist.
 512  
      */
 513  
     public Class getRoleClass()
 514  
             throws UnknownEntityException
 515  
     {
 516  192
         if (roleClass == null)
 517  
         {
 518  0
             throw new UnknownEntityException(
 519  
                     "Failed to create a Class object for Role implementation");
 520  
         }
 521  192
         return roleClass;
 522  
     }
 523  
 
 524  
     /**
 525  
      * Construct a blank Role object.
 526  
      *
 527  
      * This method calls getRoleClass, and then creates a new object using
 528  
      * the default constructor.
 529  
      *
 530  
      * @return an object implementing Role interface.
 531  
      * @throws UnknownEntityException if the object could not be instantiated.
 532  
      */
 533  
     public Role getRoleInstance()
 534  
             throws UnknownEntityException
 535  
     {
 536  
         Role role;
 537  
 
 538  
         try
 539  
         {
 540  16
             role = (Role) getRoleClass().newInstance();
 541  8
         }
 542  0
         catch (Exception e)
 543  
         {
 544  0
             throw new UnknownEntityException("Failed to instantiate a Role implementation object", e);
 545  8
         }
 546  16
         return role;
 547  
     }
 548  
 
 549  
     /**
 550  
      * Construct a blank Role object.
 551  
      *
 552  
      * This method calls getRoleClass, and then creates a new object using
 553  
      * the default constructor.
 554  
      *
 555  
      * @param roleName The name of the role.
 556  
      *
 557  
      * @return an object implementing Role interface.
 558  
      *
 559  
      * @throws UnknownEntityException if the object could not be instantiated.
 560  
      */
 561  
     public Role getRoleInstance(String roleName)
 562  
             throws UnknownEntityException
 563  
     {
 564  8
         Role role = getRoleInstance();
 565  8
         role.setName(roleName);
 566  8
         return role;
 567  
     }
 568  
 
 569  
     /**
 570  
      * Return a Class object representing the system's chosen implementation of
 571  
      * of ACL interface.
 572  
      *
 573  
      * @return systems's chosen implementation of ACL interface.
 574  
      * @throws UnknownEntityException if the implementation of ACL interface
 575  
      *         could not be determined, or does not exist.
 576  
      */
 577  
     public Class getAclClass()
 578  
             throws UnknownEntityException
 579  
     {
 580  4
         if (aclClass == null)
 581  
         {
 582  0
             throw new UnknownEntityException(
 583  
                     "Failed to create a Class object for ACL implementation");
 584  
         }
 585  4
         return aclClass;
 586  
     }
 587  
 
 588  
     /**
 589  
      * Construct a new ACL object.
 590  
      *
 591  
      * This constructs a new ACL object from the configured class and
 592  
      * initializes it with the supplied roles and permissions.
 593  
      *
 594  
      * @param roles The roles that this ACL should contain
 595  
      * @param permissions The permissions for this ACL
 596  
      *
 597  
      * @return an object implementing ACL interface.
 598  
      * @throws UnknownEntityException if the object could not be instantiated.
 599  
      */
 600  
     public AccessControlList getAclInstance(Map roles, Map permissions)
 601  
             throws UnknownEntityException
 602  
     {
 603  20
         Object[] objects = {roles, permissions};
 604  20
         String[] signatures = {Map.class.getName(), Map.class.getName()};
 605  
         AccessControlList accessControlList;
 606  
 
 607  
         try
 608  
         {
 609  20
             accessControlList =
 610  
                     (AccessControlList) aclFactoryService.getInstance(aclClass.getName(),
 611  
                             objects,
 612  
                             signatures);
 613  10
         }
 614  0
         catch (Exception e)
 615  
         {
 616  0
             throw new UnknownEntityException(
 617  
                     "Failed to instantiate an ACL implementation object", e);
 618  10
         }
 619  
 
 620  20
         return accessControlList;
 621  
     }
 622  
 
 623  
     /**
 624  
      * Returns the configured UserManager.
 625  
      *
 626  
      * @return An UserManager object
 627  
      */
 628  
     public UserManager getUserManager()
 629  
     {
 630  180
         return userManager;
 631  
     }
 632  
 
 633  
     /**
 634  
      * Configure a new user Manager.
 635  
      *
 636  
      * @param userManager An UserManager object
 637  
      */
 638  
     public void setUserManager(UserManager userManager)
 639  
     {
 640  18
         this.userManager = userManager;
 641  18
     }
 642  
 
 643  
     /**
 644  
      * Check whether a specified user's account exists.
 645  
      *
 646  
      * The login name is used for looking up the account.
 647  
      *
 648  
      * @param user The user to be checked.
 649  
      * @return true if the specified account exists
 650  
      * @throws DataBackendException if there was an error accessing the data
 651  
      *         backend.
 652  
      */
 653  
     public boolean accountExists(User user)
 654  
             throws DataBackendException
 655  
     {
 656  38
         return getUserManager().accountExists(user);
 657  
     }
 658  
 
 659  
     /**
 660  
      * Check whether a specified user's account exists.
 661  
      *
 662  
      * The login name is used for looking up the account.
 663  
      *
 664  
      * @param userName The name of the user to be checked.
 665  
      * @return true if the specified account exists
 666  
      * @throws DataBackendException if there was an error accessing the data
 667  
      *         backend.
 668  
      */
 669  
     public boolean accountExists(String userName)
 670  
             throws DataBackendException
 671  
     {
 672  4
         return getUserManager().accountExists(userName);
 673  
     }
 674  
 
 675  
     /**
 676  
      * Authenticates an user, and constructs an User object to represent
 677  
      * him/her.
 678  
      *
 679  
      * @param username The user name.
 680  
      * @param password The user password.
 681  
      * @return An authenticated Turbine User.
 682  
      * @throws PasswordMismatchException if the supplied password was incorrect.
 683  
      * @throws UnknownEntityException if the user's account does not
 684  
      *            exist in the database.
 685  
      * @throws DataBackendException if there is a problem accessing the storage.
 686  
      */
 687  
     public User getAuthenticatedUser(String username, String password)
 688  
             throws DataBackendException, UnknownEntityException,
 689  
                    PasswordMismatchException
 690  
     {
 691  4
         return getUserManager().retrieve(username, password);
 692  
     }
 693  
 
 694  
     /**
 695  
      * Constructs an User object to represent a registered user of the
 696  
      * application.
 697  
      *
 698  
      * @param username The user name.
 699  
      * @return A Turbine User.
 700  
      * @throws UnknownEntityException if the user's account does not exist
 701  
      * @throws DataBackendException if there is a problem accessing the storage.
 702  
      */
 703  
     public User getUser(String username)
 704  
             throws DataBackendException, UnknownEntityException
 705  
     {
 706  38
         return getUserManager().retrieve(username);
 707  
     }
 708  
 
 709  
     /**
 710  
      * Retrieve a set of users that meet the specified criteria.
 711  
      *
 712  
      * As the keys for the criteria, you should use the constants that
 713  
      * are defined in {@link User} interface, plus the names
 714  
      * of the custom attributes you added to your user representation
 715  
      * in the data storage. Use verbatim names of the attributes -
 716  
      * without table name prefix in case of DB implementation.
 717  
      *
 718  
      * @param criteria The criteria of selection.
 719  
      * @return a List of users meeting the criteria.
 720  
      * @throws DataBackendException if there is a problem accessing the
 721  
      *         storage.
 722  
      * @deprecated Use <a href="#getUserList">getUserList</a> instead.
 723  
      */
 724  
     public User[] getUsers(Criteria criteria)
 725  
             throws DataBackendException
 726  
     {
 727  2
         return (User []) getUserList(criteria).toArray(new User[0]);
 728  
     }
 729  
 
 730  
     /**
 731  
      * Retrieve a set of users that meet the specified criteria.
 732  
      *
 733  
      * As the keys for the criteria, you should use the constants that
 734  
      * are defined in {@link User} interface, plus the names
 735  
      * of the custom attributes you added to your user representation
 736  
      * in the data storage. Use verbatim names of the attributes -
 737  
      * without table name prefix in case of DB implementation.
 738  
      *
 739  
      * @param criteria The criteria of selection.
 740  
      * @return a List of users meeting the criteria.
 741  
      * @throws DataBackendException if there is a problem accessing the
 742  
      *         storage.
 743  
      */
 744  
     public List getUserList(Criteria criteria)
 745  
             throws DataBackendException
 746  
     {
 747  26
         return getUserManager().retrieveList(criteria);
 748  
     }
 749  
 
 750  
     /**
 751  
      * Constructs an User object to represent an anonymous user of the
 752  
      * application.
 753  
      *
 754  
      * @return An anonymous Turbine User.
 755  
      * @throws UnknownEntityException if the implementation of User interface
 756  
      *         could not be determined, or does not exist.
 757  
      */
 758  
     public User getAnonymousUser()
 759  
             throws UnknownEntityException
 760  
     {
 761  2
         User user = getUserInstance();
 762  2
         user.setName("");
 763  2
         return user;
 764  
     }
 765  
 
 766  
     /**
 767  
      * Checks whether a passed user object matches the anonymous user pattern
 768  
      * according to the configured user manager
 769  
      *
 770  
      * @param user An user object
 771  
      *
 772  
      * @return True if this is an anonymous user
 773  
      *
 774  
      */
 775  
     public boolean isAnonymousUser(User user)
 776  
     {
 777  
         // Either just null, the name is null or the name is the empty string
 778  4
         return (user == null) || StringUtils.isEmpty(user.getName());
 779  
     }
 780  
 
 781  
     /**
 782  
      * Saves User's data in the permanent storage. The user account is required
 783  
      * to exist in the storage.
 784  
      *
 785  
      * @param user the User object to save
 786  
      * @throws UnknownEntityException if the user's account does not
 787  
      *         exist in the database.
 788  
      * @throws DataBackendException if there is a problem accessing the storage.
 789  
      */
 790  
     public void saveUser(User user)
 791  
             throws UnknownEntityException, DataBackendException
 792  
     {
 793  4
         getUserManager().store(user);
 794  2
     }
 795  
 
 796  
     /**
 797  
      * Saves User data when the session is unbound. The user account is required
 798  
      * to exist in the storage.
 799  
      *
 800  
      * LastLogin, AccessCounter, persistent pull tools, and any data stored
 801  
      * in the permData hashtable that is not mapped to a column will be saved.
 802  
      *
 803  
      * @exception UnknownEntityException if the user's account does not
 804  
      *            exist in the database.
 805  
      * @exception DataBackendException if there is a problem accessing the
 806  
      *            storage.
 807  
      */
 808  
     public void saveOnSessionUnbind(User user)
 809  
             throws UnknownEntityException, DataBackendException
 810  
     {
 811  0
         userManager.saveOnSessionUnbind(user);
 812  0
     }
 813  
 
 814  
     /**
 815  
      * Creates new user account with specified attributes.
 816  
      *
 817  
      * @param user the object describing account to be created.
 818  
      * @param password The password to use for the account.
 819  
      *
 820  
      * @throws DataBackendException if there was an error accessing the
 821  
      *         data backend.
 822  
      * @throws EntityExistsException if the user account already exists.
 823  
      */
 824  
     public void addUser(User user, String password)
 825  
             throws DataBackendException, EntityExistsException
 826  
     {
 827  6
         getUserManager().createAccount(user, password);
 828  2
     }
 829  
 
 830  
     /**
 831  
      * Removes an user account from the system.
 832  
      *
 833  
      * @param user the object describing the account to be removed.
 834  
      * @throws DataBackendException if there was an error accessing the data
 835  
      *         backend.
 836  
      * @throws UnknownEntityException if the user account is not present.
 837  
      */
 838  
     public void removeUser(User user)
 839  
             throws DataBackendException, UnknownEntityException
 840  
     {
 841  
         // revoke all roles form the user
 842  4
         revokeAll(user);
 843  
 
 844  2
         getUserManager().removeAccount(user);
 845  2
     }
 846  
 
 847  
     /**
 848  
      * Change the password for an User.
 849  
      *
 850  
      * @param user an User to change password for.
 851  
      * @param oldPassword the current password supplied by the user.
 852  
      * @param newPassword the current password requested by the user.
 853  
      * @throws PasswordMismatchException if the supplied password was incorrect.
 854  
      * @throws UnknownEntityException if the user's record does not
 855  
      *            exist in the database.
 856  
      * @throws DataBackendException if there is a problem accessing the storage.
 857  
      */
 858  
     public void changePassword(User user, String oldPassword,
 859  
             String newPassword)
 860  
             throws PasswordMismatchException, UnknownEntityException,
 861  
                    DataBackendException
 862  
     {
 863  4
         getUserManager().changePassword(user, oldPassword, newPassword);
 864  2
     }
 865  
 
 866  
     /**
 867  
      * Forcibly sets new password for an User.
 868  
      *
 869  
      * This is supposed by the administrator to change the forgotten or
 870  
      * compromised passwords. Certain implementatations of this feature
 871  
      * would require administrative level access to the authenticating
 872  
      * server / program.
 873  
      *
 874  
      * @param user an User to change password for.
 875  
      * @param password the new password.
 876  
      * @throws UnknownEntityException if the user's record does not
 877  
      *            exist in the database.
 878  
      * @throws DataBackendException if there is a problem accessing the storage.
 879  
      */
 880  
     public void forcePassword(User user, String password)
 881  
             throws UnknownEntityException, DataBackendException
 882  
     {
 883  4
         getUserManager().forcePassword(user, password);
 884  4
     }
 885  
 
 886  
     /**
 887  
      * Acquire a shared lock on the security information repository.
 888  
      *
 889  
      * Methods that read security information need to invoke this
 890  
      * method at the beginning of their body.
 891  
      */
 892  
     protected synchronized void lockShared()
 893  
     {
 894  68
         readerCount++;
 895  68
     }
 896  
 
 897  
     /**
 898  
      * Release a shared lock on the security information repository.
 899  
      *
 900  
      * Methods that read security information need to invoke this
 901  
      * method at the end of their body.
 902  
      */
 903  
     protected synchronized void unlockShared()
 904  
     {
 905  68
         readerCount--;
 906  68
         this.notify();
 907  68
     }
 908  
 
 909  
     /**
 910  
      * Acquire an exclusive lock on the security information repository.
 911  
      *
 912  
      * Methods that modify security information need to invoke this
 913  
      * method at the beginning of their body. Note! Those methods must
 914  
      * be <code>synchronized</code> themselves!
 915  
      */
 916  
     protected void lockExclusive()
 917  
     {
 918  105
         while (readerCount > 0)
 919  
         {
 920  
             try
 921  
             {
 922  0
                 this.wait();
 923  
             }
 924  0
             catch (InterruptedException e)
 925  
             {
 926  0
             }
 927  
         }
 928  70
     }
 929  
 
 930  
     /**
 931  
      * Release an exclusive lock on the security information repository.
 932  
      *
 933  
      * This method is provided only for completeness. It does not really
 934  
      * do anything. Note! Methods that modify security information
 935  
      * must be <code>synchronized</code>!
 936  
      */
 937  
     protected void unlockExclusive()
 938  
     {
 939  
         // do nothing
 940  70
     }
 941  
 
 942  
     /**
 943  
      * Provides a reference to the Group object that represents the
 944  
      * <a href="#global">global group</a>.
 945  
      *
 946  
      * @return a Group object that represents the global group.
 947  
      */
 948  
     public Group getGlobalGroup()
 949  
     {
 950  4
         if (globalGroup == null)
 951  
         {
 952  2
             synchronized (BaseSecurityService.class)
 953  
             {
 954  2
                 if (globalGroup == null)
 955  
                 {
 956  
                     try
 957  
                     {
 958  2
                         globalGroup = getAllGroups()
 959  
                                 .getGroupByName(Group.GLOBAL_GROUP_NAME);
 960  1
                     }
 961  0
                     catch (DataBackendException e)
 962  
                     {
 963  0
                         log.error("Failed to retrieve global group object: ", e);
 964  1
                     }
 965  
                 }
 966  2
             }
 967  
         }
 968  4
         return globalGroup;
 969  
     }
 970  
 
 971  
     /**
 972  
      * Retrieve a Group object with specified name.
 973  
      *
 974  
      * @param name the name of the Group.
 975  
      * @return an object representing the Group with specified name.
 976  
      * @throws DataBackendException if there was an error accessing the
 977  
      *         data backend.
 978  
      * @throws UnknownEntityException if the group does not exist.
 979  
      * @deprecated Use <a href="#getGroupByName">getGroupByName</a> instead.
 980  
      */
 981  
     public Group getGroup(String name)
 982  
             throws DataBackendException, UnknownEntityException
 983  
     {
 984  0
         return getGroupByName(name);
 985  
     }
 986  
 
 987  
     /**
 988  
      * Retrieve a Group object with specified name.
 989  
      *
 990  
      * @param name the name of the Group.
 991  
      * @return an object representing the Group with specified name.
 992  
      * @throws DataBackendException if there was an error accessing the
 993  
      *         data backend.
 994  
      * @throws UnknownEntityException if the group does not exist.
 995  
      */
 996  
     public Group getGroupByName(String name)
 997  
             throws DataBackendException, UnknownEntityException
 998  
     {
 999  60
         Group group = getAllGroups().getGroupByName(name);
 1000  60
         if (group == null)
 1001  
         {
 1002  0
             throw new UnknownEntityException(
 1003  
                     "The specified group does not exist");
 1004  
         }
 1005  60
         return group;
 1006  
     }
 1007  
 
 1008  
     /**
 1009  
      * Retrieve a Group object with specified Id.
 1010  
      *
 1011  
      * @param id the id of the Group.
 1012  
      * @return an object representing the Group with specified name.
 1013  
      * @throws UnknownEntityException if the permission does not
 1014  
      *            exist in the database.
 1015  
      * @throws DataBackendException if there is a problem accessing the
 1016  
      *            storage.
 1017  
      */
 1018  
     public Group getGroupById(int id)
 1019  
             throws DataBackendException, UnknownEntityException
 1020  
     {
 1021  2
         Group group = getAllGroups().getGroupById(id);
 1022  2
         if (group == null)
 1023  
         {
 1024  0
             throw new UnknownEntityException(
 1025  
                     "The specified group does not exist");
 1026  
         }
 1027  2
         return group;
 1028  
     }
 1029  
 
 1030  
     /**
 1031  
      * Retrieve a Role object with specified name.
 1032  
      *
 1033  
      * @param name the name of the Role.
 1034  
      * @return an object representing the Role with specified name.
 1035  
      * @throws DataBackendException if there was an error accessing the
 1036  
      *         data backend.
 1037  
      * @throws UnknownEntityException if the role does not exist.
 1038  
      * @deprecated Use <a href="#getRoleByName">getRoleByName</a> instead.
 1039  
      */
 1040  
     public Role getRole(String name)
 1041  
             throws DataBackendException, UnknownEntityException
 1042  
     {
 1043  0
         return getRoleByName(name);
 1044  
     }
 1045  
 
 1046  
     /**
 1047  
      * Retrieve a Role object with specified name.
 1048  
      *
 1049  
      * @param name the name of the Role.
 1050  
      * @return an object representing the Role with specified name.
 1051  
      * @throws DataBackendException if there was an error accessing the
 1052  
      *         data backend.
 1053  
      * @throws UnknownEntityException if the role does not exist.
 1054  
      */
 1055  
     public Role getRoleByName(String name)
 1056  
             throws DataBackendException, UnknownEntityException
 1057  
     {
 1058  46
         Role role = getAllRoles().getRoleByName(name);
 1059  46
         if (role == null)
 1060  
         {
 1061  0
             throw new UnknownEntityException(
 1062  
                     "The specified role does not exist");
 1063  
         }
 1064  46
         role.setPermissions(getPermissions(role));
 1065  46
         return role;
 1066  
     }
 1067  
 
 1068  
     /**
 1069  
      * Retrieve a Role object with specified Id.
 1070  
      * @param id the id of the Role.
 1071  
      * @return an object representing the Role with specified name.
 1072  
      * @throws UnknownEntityException if the permission does not
 1073  
      *            exist in the database.
 1074  
      * @throws DataBackendException if there is a problem accessing the
 1075  
      *            storage.
 1076  
      */
 1077  
     public Role getRoleById(int id)
 1078  
             throws DataBackendException,
 1079  
                    UnknownEntityException
 1080  
     {
 1081  2
         Role role = getAllRoles().getRoleById(id);
 1082  2
         if (role == null)
 1083  
         {
 1084  0
             throw new UnknownEntityException(
 1085  
                     "The specified role does not exist");
 1086  
         }
 1087  2
         role.setPermissions(getPermissions(role));
 1088  2
         return role;
 1089  
     }
 1090  
 
 1091  
     /**
 1092  
      * Retrieve a Permission object with specified name.
 1093  
      *
 1094  
      * @param name the name of the Permission.
 1095  
      * @return an object representing the Permission with specified name.
 1096  
      * @throws DataBackendException if there was an error accessing the
 1097  
      *         data backend.
 1098  
      * @throws UnknownEntityException if the permission does not exist.
 1099  
      * @deprecated Use <a href="#getPermissionByName">getPermissionByName</a> instead.
 1100  
      */
 1101  
     public Permission getPermission(String name)
 1102  
             throws DataBackendException, UnknownEntityException
 1103  
     {
 1104  0
         return getPermissionByName(name);
 1105  
     }
 1106  
 
 1107  
     /**
 1108  
      * Retrieve a Permission object with specified name.
 1109  
      *
 1110  
      * @param name the name of the Permission.
 1111  
      * @return an object representing the Permission with specified name.
 1112  
      * @throws DataBackendException if there was an error accessing the
 1113  
      *         data backend.
 1114  
      * @throws UnknownEntityException if the permission does not exist.
 1115  
      */
 1116  
     public Permission getPermissionByName(String name)
 1117  
             throws DataBackendException, UnknownEntityException
 1118  
     {
 1119  40
         Permission permission = getAllPermissions().getPermissionByName(name);
 1120  40
         if (permission == null)
 1121  
         {
 1122  0
             throw new UnknownEntityException(
 1123  
                     "The specified permission does not exist");
 1124  
         }
 1125  40
         return permission;
 1126  
     }
 1127  
 
 1128  
     /**
 1129  
      * Retrieve a Permission object with specified Id.
 1130  
      *
 1131  
      * @param id the id of the Permission.
 1132  
      * @return an object representing the Permission with specified name.
 1133  
      * @throws UnknownEntityException if the permission does not
 1134  
      *            exist in the database.
 1135  
      * @throws DataBackendException if there is a problem accessing the
 1136  
      *            storage.
 1137  
      */
 1138  
     public Permission getPermissionById(int id)
 1139  
             throws DataBackendException,
 1140  
                    UnknownEntityException
 1141  
     {
 1142  2
         Permission permission = getAllPermissions().getPermissionById(id);
 1143  2
         if (permission == null)
 1144  
         {
 1145  0
             throw new UnknownEntityException(
 1146  
                     "The specified permission does not exist");
 1147  
         }
 1148  2
         return permission;
 1149  
     }
 1150  
 
 1151  
     /**
 1152  
      * Retrieves all groups defined in the system.
 1153  
      *
 1154  
      * @return the names of all groups defined in the system.
 1155  
      * @throws DataBackendException if there was an error accessing the
 1156  
      *         data backend.
 1157  
      */
 1158  
     public GroupSet getAllGroups()
 1159  
             throws DataBackendException
 1160  
     {
 1161  100
         return getGroups(new Criteria());
 1162  
     }
 1163  
 
 1164  
     /**
 1165  
      * Retrieves all roles defined in the system.
 1166  
      *
 1167  
      * @return the names of all roles defined in the system.
 1168  
      * @throws DataBackendException if there was an error accessing the
 1169  
      *         data backend.
 1170  
      */
 1171  
     public RoleSet getAllRoles()
 1172  
             throws DataBackendException
 1173  
     {
 1174  66
         return getRoles(new Criteria());
 1175  
     }
 1176  
 
 1177  
     /**
 1178  
      * Retrieves all permissions defined in the system.
 1179  
      *
 1180  
      * @return the names of all roles defined in the system.
 1181  
      * @throws DataBackendException if there was an error accessing the
 1182  
      *         data backend.
 1183  
      */
 1184  
     public PermissionSet getAllPermissions()
 1185  
             throws DataBackendException
 1186  
     {
 1187  60
         return getPermissions(new Criteria());
 1188  
     }
 1189  
 
 1190  
     /**
 1191  
      * @deprecated Use getGroupInstance(String name) instead.
 1192  
      */
 1193  
     public Group getNewGroup(String groupName)
 1194  
     {
 1195  
         try
 1196  
         {
 1197  0
             return getGroupInstance(groupName);
 1198  
         }
 1199  0
         catch (UnknownEntityException uee)
 1200  
         {
 1201  0
             uee.printStackTrace();
 1202  0
             return null;
 1203  
         }
 1204  
     }
 1205  
 
 1206  
     /**
 1207  
      * @deprecated Use getRoleInstance(String name) instead.
 1208  
      */
 1209  
     public Role getNewRole(String roleName)
 1210  
     {
 1211  
         try
 1212  
         {
 1213  0
             return getRoleInstance(roleName);
 1214  
         }
 1215  0
         catch (UnknownEntityException uee)
 1216  
         {
 1217  0
             return null;
 1218  
         }
 1219  
     }
 1220  
 
 1221  
     /**
 1222  
      * @deprecated Use getPermissionInstance(String name) instead.
 1223  
      */
 1224  
     public Permission getNewPermission(String permissionName)
 1225  
     {
 1226  
         try
 1227  
         {
 1228  0
             return getPermissionInstance(permissionName);
 1229  
         }
 1230  0
         catch (UnknownEntityException uee)
 1231  
         {
 1232  0
             return null;
 1233  
         }
 1234  
     }
 1235  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.