View Javadoc
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 org.apache.commons.configuration.Configuration;
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.apache.fulcrum.security.GroupManager;
28  import org.apache.fulcrum.security.PermissionManager;
29  import org.apache.fulcrum.security.RoleManager;
30  import org.apache.fulcrum.security.acl.AccessControlList;
31  import org.apache.fulcrum.security.entity.Group;
32  import org.apache.fulcrum.security.entity.Permission;
33  import org.apache.fulcrum.security.entity.Role;
34  import org.apache.fulcrum.security.model.turbine.TurbineModelManager;
35  import org.apache.fulcrum.security.model.turbine.entity.TurbineRole;
36  import org.apache.fulcrum.security.util.DataBackendException;
37  import org.apache.fulcrum.security.util.EntityExistsException;
38  import org.apache.fulcrum.security.util.GroupSet;
39  import org.apache.fulcrum.security.util.PasswordMismatchException;
40  import org.apache.fulcrum.security.util.PermissionSet;
41  import org.apache.fulcrum.security.util.RoleSet;
42  import org.apache.fulcrum.security.util.UnknownEntityException;
43  import org.apache.turbine.om.security.User;
44  import org.apache.turbine.services.InitializationException;
45  import org.apache.turbine.services.ServiceManager;
46  import org.apache.turbine.services.TurbineBaseService;
47  import org.apache.turbine.services.TurbineServices;
48  
49  /**
50   * This is a common subset of SecurityService implementation.
51   *
52   * Provided functionality includes:
53   * <ul>
54   * <li> methods for retrieving User objects, that delegates functionality
55   *      to the pluggable implementations of the User interface.
56   * <li> synchronization mechanism for methods reading/modifying the security
57   *      information, that guarantees that multiple threads may read the
58   *      information concurrently, but threads that modify the information
59   *      acquires exclusive access.
60   * <li> implementation of convenience methods for retrieving security entities
61   *      that maintain in-memory caching of objects for fast access.
62   * </ul>
63   *
64   * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
65   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
66   * @author <a href="mailto:marco@intermeta.de">Marco Kn&uuml;ttel</a>
67   * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
68   * @version $Id: DefaultSecurityService.java 1821872 2018-01-22 14:35:04Z gk $
69   */
70  public class DefaultSecurityService
71          extends TurbineBaseService
72          implements SecurityService
73  {
74      /** The number of threads concurrently reading security information */
75      private int readerCount = 0;
76  
77      /** The instance of UserManager the SecurityService uses */
78      private UserManager userManager = null;
79  
80      /** The instance of GroupManager the SecurityService uses */
81      private GroupManager groupManager;
82  
83      /** The instance of RoleManager the SecurityService uses */
84      private RoleManager roleManager;
85  
86      /** The instance of PermissionManager the SecurityService uses */
87      private PermissionManager permissionManager;
88  
89      /** The instance of ModelManager the SecurityService uses */
90      private TurbineModelManager modelManager;
91  
92      /**
93       * The Group object that represents the <a href="#global">global group</a>.
94       */
95      private static volatile Group globalGroup = null;
96  
97      /** Logging */
98      private static Log log = LogFactory.getLog(DefaultSecurityService.class);
99  
100     /**
101      * Initializes the SecurityService, locating the appropriate UserManager
102      * This is a zero parameter variant which queries the Turbine Servlet
103      * for its config.
104      *
105      * @throws InitializationException Something went wrong in the init stage
106      */
107     @Override
108     public void init()
109             throws InitializationException
110     {
111         ServiceManager manager = TurbineServices.getInstance();
112 
113         this.groupManager = (GroupManager)manager.getService(GroupManager.ROLE);
114         this.roleManager = (RoleManager)manager.getService(RoleManager.ROLE);
115         this.permissionManager = (PermissionManager)manager.getService(PermissionManager.ROLE);
116         this.modelManager = (TurbineModelManager)manager.getService(TurbineModelManager.ROLE);
117 
118         Configuration conf = getConfiguration();
119 
120         String userManagerClassName = conf.getString(
121                 SecurityService.USER_MANAGER_KEY,
122                 SecurityService.USER_MANAGER_DEFAULT);
123 
124         try
125         {
126             this.userManager =
127                     (UserManager) Class.forName(userManagerClassName).newInstance();
128 
129             userManager.init(conf);
130         }
131         catch (Exception e)
132         {
133             throw new InitializationException("Failed to instantiate UserManager", e);
134         }
135 
136         setInit(true);
137     }
138 
139     /**
140      * Construct a blank User object.
141      *
142      * @return an object implementing User interface.
143      * @throws UnknownEntityException if the object could not be instantiated.
144      */
145     @Override
146     public <U extends User> U getUserInstance()
147             throws UnknownEntityException
148     {
149         U user;
150         try
151         {
152             user = getUserManager().getUserInstance();
153         }
154         catch (DataBackendException e)
155         {
156             throw new UnknownEntityException(
157                     "Failed instantiate an User implementation object", e);
158         }
159         return user;
160     }
161 
162     /**
163      * Construct a blank User object.
164      *
165      * @param userName The name of the user.
166      *
167      * @return an object implementing User interface.
168      *
169      * @throws UnknownEntityException if the object could not be instantiated.
170      */
171     @Override
172     public <U extends User> U getUserInstance(String userName)
173             throws UnknownEntityException
174     {
175         U user;
176         try
177         {
178             user = getUserManager().getUserInstance(userName);
179         }
180         catch (DataBackendException e)
181         {
182             throw new UnknownEntityException(
183                     "Failed instantiate an User implementation object", e);
184         }
185         return user;
186     }
187 
188     /**
189      * Construct a blank Group object.
190      *
191      * @return an object implementing Group interface.
192      * @throws UnknownEntityException if the object could not be instantiated.
193      */
194     @Override
195     public <G extends Group> G getGroupInstance()
196             throws UnknownEntityException
197     {
198         G group;
199         try
200         {
201             group = groupManager.getGroupInstance();
202         }
203         catch (Exception e)
204         {
205             throw new UnknownEntityException("Failed to instantiate a Group implementation object", e);
206         }
207         return group;
208     }
209 
210     /**
211      * Construct a blank Group object.
212      *
213      * @param groupName The name of the Group
214      *
215      * @return an object implementing Group interface.
216      *
217      * @throws UnknownEntityException if the object could not be instantiated.
218      */
219     @Override
220     public <G extends Group> G getGroupInstance(String groupName)
221             throws UnknownEntityException
222     {
223         G group;
224         try
225         {
226             group = groupManager.getGroupInstance(groupName);
227         }
228         catch (Exception e)
229         {
230             throw new UnknownEntityException("Failed to instantiate a Group implementation object", e);
231         }
232         return group;
233     }
234 
235     /**
236      * Construct a blank Permission object.
237      *
238      * @return an object implementing Permission interface.
239      * @throws UnknownEntityException if the object could not be instantiated.
240      */
241     @Override
242     public <P extends Permission> P getPermissionInstance()
243             throws UnknownEntityException
244     {
245         P permission;
246         try
247         {
248             permission = permissionManager.getPermissionInstance();
249         }
250         catch (Exception e)
251         {
252             throw new UnknownEntityException("Failed to instantiate a Permission implementation object", e);
253         }
254         return permission;
255     }
256 
257     /**
258      * Construct a blank Permission object.
259      *
260      * @param permName The name of the permission.
261      *
262      * @return an object implementing Permission interface.
263      * @throws UnknownEntityException if the object could not be instantiated.
264      */
265     @Override
266     public <P extends Permission> P getPermissionInstance(String permName)
267             throws UnknownEntityException
268     {
269         P permission;
270         try
271         {
272             permission = permissionManager.getPermissionInstance(permName);
273         }
274         catch (Exception e)
275         {
276             throw new UnknownEntityException("Failed to instantiate a Permission implementation object", e);
277         }
278         return permission;
279     }
280 
281     /**
282      * Construct a blank Role object.
283      *
284      * @return an object implementing Role interface.
285      * @throws UnknownEntityException if the object could not be instantiated.
286      */
287     @Override
288     public <R extends Role> R getRoleInstance()
289             throws UnknownEntityException
290     {
291         R role;
292         try
293         {
294             role = roleManager.getRoleInstance();
295         }
296         catch (Exception e)
297         {
298             throw new UnknownEntityException("Failed to instantiate a Role implementation object", e);
299         }
300         return role;
301     }
302 
303     /**
304      * Construct a blank Role object.
305      *
306      * @param roleName The name of the role.
307      *
308      * @return an object implementing Role interface.
309      *
310      * @throws UnknownEntityException if the object could not be instantiated.
311      */
312     @Override
313     public <R extends Role> R getRoleInstance(String roleName)
314             throws UnknownEntityException
315     {
316         R role;
317         try
318         {
319             role = roleManager.getRoleInstance(roleName);
320         }
321         catch (Exception e)
322         {
323             throw new UnknownEntityException("Failed to instantiate a Role implementation object", e);
324         }
325         return role;
326     }
327 
328     /**
329      * Returns the configured UserManager.
330      *
331      * @return An UserManager object
332      */
333     @Override
334     public UserManager getUserManager()
335     {
336         return userManager;
337     }
338 
339     /**
340      * Check whether a specified user's account exists.
341      *
342      * The login name is used for looking up the account.
343      *
344      * @param user The user to be checked.
345      * @return true if the specified account exists
346      * @throws DataBackendException if there was an error accessing the data
347      *         backend.
348      */
349     @Override
350     public boolean accountExists(User user)
351             throws DataBackendException
352     {
353         return getUserManager().accountExists(user);
354     }
355 
356     /**
357      * Check whether a specified user's account exists.
358      *
359      * The login name is used for looking up the account.
360      *
361      * @param userName The name of the user to be checked.
362      * @return true if the specified account exists
363      * @throws DataBackendException if there was an error accessing the data
364      *         backend.
365      */
366     @Override
367     public boolean accountExists(String userName)
368             throws DataBackendException
369     {
370         return getUserManager().accountExists(userName);
371     }
372 
373     /**
374      * Authenticates an user, and constructs an User object to represent
375      * him/her.
376      *
377      * @param username The user name.
378      * @param password The user password.
379      * @return An authenticated Turbine User.
380      * @throws PasswordMismatchException if the supplied password was incorrect.
381      * @throws UnknownEntityException if the user's account does not
382      *            exist in the database.
383      * @throws DataBackendException if there is a problem accessing the storage.
384      */
385     @Override
386     public <U extends User> U getAuthenticatedUser(String username, String password)
387             throws DataBackendException, UnknownEntityException,
388                    PasswordMismatchException
389     {
390         return getUserManager().retrieve(username, password);
391     }
392 
393     /**
394      * Constructs an User object to represent a registered user of the
395      * application.
396      *
397      * @param username The user name.
398      * @return A Turbine User.
399      * @throws UnknownEntityException if the user's account does not exist
400      * @throws DataBackendException if there is a problem accessing the storage.
401      */
402     @Override
403     public <U extends User> U getUser(String username)
404             throws DataBackendException, UnknownEntityException
405     {
406         return getUserManager().retrieve(username);
407     }
408 
409     /**
410      * Constructs an User object to represent an anonymous user of the
411      * application.
412      *
413      * @return An anonymous Turbine User.
414      * @throws UnknownEntityException if the implementation of User interface
415      *         could not be determined, or does not exist.
416      */
417     @Override
418     public <U extends User> U getAnonymousUser()
419             throws UnknownEntityException
420     {
421         return getUserManager().getAnonymousUser();
422     }
423 
424     /**
425      * Checks whether a passed user object matches the anonymous user pattern
426      * according to the configured user manager
427      *
428      * @param user An user object
429      *
430      * @return True if this is an anonymous user
431      *
432      */
433     @Override
434     public boolean isAnonymousUser(User user)
435     {
436         return getUserManager().isAnonymousUser(user);
437     }
438 
439     /**
440      * Saves User's data in the permanent storage. The user account is required
441      * to exist in the storage.
442      *
443      * @param user the User object to save
444      * @throws UnknownEntityException if the user's account does not
445      *         exist in the database.
446      * @throws DataBackendException if there is a problem accessing the storage.
447      */
448     @Override
449     public void saveUser(User user)
450             throws UnknownEntityException, DataBackendException
451     {
452         getUserManager().store(user);
453     }
454 
455     /**
456      * Saves User data when the session is unbound. The user account is required
457      * to exist in the storage.
458      *
459      * LastLogin, AccessCounter, persistent pull tools, and any data stored
460      * in the permData hashmap that is not mapped to a column will be saved.
461      *
462      * @throws UnknownEntityException if the user's account does not
463      *            exist in the database.
464      * @throws DataBackendException if there is a problem accessing the
465      *            storage.
466      */
467     @Override
468     public void saveOnSessionUnbind(User user)
469             throws UnknownEntityException, DataBackendException
470     {
471         getUserManager().saveOnSessionUnbind(user);
472     }
473 
474     /**
475      * Creates new user account with specified attributes.
476      *
477      * @param user the object describing account to be created.
478      * @param password The password to use for the account.
479      *
480      * @throws DataBackendException if there was an error accessing the
481      *         data backend.
482      * @throws EntityExistsException if the user account already exists.
483      */
484     @Override
485     public void addUser(User user, String password)
486             throws UnknownEntityException,DataBackendException, EntityExistsException
487     {
488         getUserManager().createAccount(user, password);
489     }
490 
491     /**
492      * Removes an user account from the system.
493      *
494      * @param user the object describing the account to be removed.
495      * @throws DataBackendException if there was an error accessing the data
496      *         backend.
497      * @throws UnknownEntityException if the user account is not present.
498      */
499     @Override
500     public void removeUser(User user)
501             throws DataBackendException, UnknownEntityException
502     {
503         if (user == null) {
504             throw new UnknownEntityException("user is null");
505         }
506         // revoke all roles form the user
507         modelManager.revokeAll(user.getUserDelegate());
508         getUserManager().removeAccount(user);
509     }
510 
511     /**
512      * Change the password for an User.
513      *
514      * @param user an User to change password for.
515      * @param oldPassword the current password supplied by the user.
516      * @param newPassword the current password requested by the user.
517      * @throws PasswordMismatchException if the supplied password was incorrect.
518      * @throws UnknownEntityException if the user's record does not
519      *            exist in the database.
520      * @throws DataBackendException if there is a problem accessing the storage.
521      */
522     @Override
523     public void changePassword(User user, String oldPassword,
524             String newPassword)
525             throws PasswordMismatchException, UnknownEntityException,
526                    DataBackendException
527     {
528         getUserManager().changePassword(user, oldPassword, newPassword);
529     }
530 
531     /**
532      * Forcibly sets new password for an User.
533      *
534      * This is supposed by the administrator to change the forgotten or
535      * compromised passwords. Certain implementatations of this feature
536      * would require administrative level access to the authenticating
537      * server / program.
538      *
539      * @param user an User to change password for.
540      * @param password the new password.
541      * @throws UnknownEntityException if the user's record does not
542      *            exist in the database.
543      * @throws DataBackendException if there is a problem accessing the storage.
544      */
545     @Override
546     public void forcePassword(User user, String password)
547             throws UnknownEntityException, DataBackendException
548     {
549         getUserManager().forcePassword(user, password);
550     }
551 
552     /**
553      * Acquire a shared lock on the security information repository.
554      *
555      * Methods that read security information need to invoke this
556      * method at the beginning of their body.
557      */
558     protected synchronized void lockShared()
559     {
560         readerCount++;
561     }
562 
563     /**
564      * Release a shared lock on the security information repository.
565      *
566      * Methods that read security information need to invoke this
567      * method at the end of their body.
568      */
569     protected synchronized void unlockShared()
570     {
571         readerCount--;
572         this.notify();
573     }
574 
575     /**
576      * Acquire an exclusive lock on the security information repository.
577      *
578      * Methods that modify security information need to invoke this
579      * method at the beginning of their body. Note! Those methods must
580      * be <code>synchronized</code> themselves!
581      */
582     protected void lockExclusive()
583     {
584         while (readerCount > 0)
585         {
586             try
587             {
588                 this.wait();
589             }
590             catch (InterruptedException e)
591             {
592                 // ignore
593             }
594         }
595     }
596 
597     /**
598      * Release an exclusive lock on the security information repository.
599      *
600      * This method is provided only for completeness. It does not really
601      * do anything. Note! Methods that modify security information
602      * must be <code>synchronized</code>!
603      */
604     protected void unlockExclusive()
605     {
606         // do nothing
607     }
608 
609     /**
610      * Provides a reference to the Group object that represents the
611      * <a href="#global">global group</a>.
612      *
613      * @return a Group object that represents the global group.
614      */
615     @Override
616     public <G extends Group> G getGlobalGroup()
617     {
618         if (globalGroup == null)
619         {
620             synchronized (DefaultSecurityService.class)
621             {
622                 if (globalGroup == null)
623                 {
624                     try
625                     {
626                         globalGroup = modelManager.getGlobalGroup();
627                     }
628                     catch (DataBackendException e)
629                     {
630                         log.error("Failed to retrieve global group object: ", e);
631                     }
632                 }
633             }
634         }
635         @SuppressWarnings("unchecked")
636         G g = (G)globalGroup;
637         return g;
638     }
639 
640     /**
641      * Retrieve a Group object with specified name.
642      *
643      * @param name the name of the Group.
644      * @return an object representing the Group with specified name.
645      * @throws DataBackendException if there was an error accessing the
646      *         data backend.
647      * @throws UnknownEntityException if the group does not exist.
648      */
649     @Override
650     public <G extends Group> G getGroupByName(String name)
651             throws DataBackendException, UnknownEntityException
652     {
653         return groupManager.getGroupByName(name);
654     }
655 
656     /**
657      * Retrieve a Group object with specified Id.
658      *
659      * @param id the id of the Group.
660      * @return an object representing the Group with specified name.
661      * @throws UnknownEntityException if the permission does not
662      *            exist in the database.
663      * @throws DataBackendException if there is a problem accessing the
664      *            storage.
665      */
666     @Override
667     public <G extends Group> G getGroupById(int id)
668             throws DataBackendException, UnknownEntityException
669     {
670         return groupManager.getGroupById(Integer.valueOf(id));
671     }
672 
673     /**
674      * Retrieve a Role object with specified name.
675      *
676      * @param name the name of the Role.
677      * @return an object representing the Role with specified name.
678      * @throws DataBackendException if there was an error accessing the
679      *         data backend.
680      * @throws UnknownEntityException if the role does not exist.
681      */
682     @Override
683     public <R extends Role> R getRoleByName(String name)
684             throws DataBackendException, UnknownEntityException
685     {
686         R role = roleManager.getRoleByName(name);
687         if (role instanceof TurbineRole)
688         {
689             ((TurbineRole)role).setPermissions(getPermissions(role));
690         }
691         return role;
692     }
693 
694     /**
695      * Retrieve a Role object with specified Id.
696      * @param id the id of the Role.
697      * @return an object representing the Role with specified name.
698      * @throws UnknownEntityException if the permission does not
699      *            exist in the database.
700      * @throws DataBackendException if there is a problem accessing the
701      *            storage.
702      */
703     @Override
704     public <R extends Role> R getRoleById(int id)
705             throws DataBackendException,
706                    UnknownEntityException
707     {
708         R role = roleManager.getRoleById(Integer.valueOf(id));
709         if (role instanceof TurbineRole)
710         {
711             ((TurbineRole)role).setPermissions(getPermissions(role));
712         }
713         return role;
714     }
715 
716     /**
717      * Retrieve a Permission object with specified name.
718      *
719      * @param name the name of the Permission.
720      * @return an object representing the Permission with specified name.
721      * @throws DataBackendException if there was an error accessing the
722      *         data backend.
723      * @throws UnknownEntityException if the permission does not exist.
724      */
725     @Override
726     public <P extends Permission> P getPermissionByName(String name)
727             throws DataBackendException, UnknownEntityException
728     {
729         return permissionManager.getPermissionByName(name);
730     }
731 
732     /**
733      * Retrieve a Permission object with specified Id.
734      *
735      * @param id the id of the Permission.
736      * @return an object representing the Permission with specified name.
737      * @throws UnknownEntityException if the permission does not
738      *            exist in the database.
739      * @throws DataBackendException if there is a problem accessing the
740      *            storage.
741      */
742     @Override
743     public <P extends Permission> P getPermissionById(int id)
744             throws DataBackendException,
745                    UnknownEntityException
746     {
747         return permissionManager.getPermissionById(Integer.valueOf(id));
748     }
749 
750     /**
751      * Retrieves all groups defined in the system.
752      *
753      * @return the names of all groups defined in the system.
754      * @throws DataBackendException if there was an error accessing the
755      *         data backend.
756      */
757     @Override
758     public GroupSet getAllGroups() throws DataBackendException
759     {
760         return groupManager.getAllGroups();
761     }
762 
763     /**
764      * Retrieves all roles defined in the system.
765      *
766      * @return the names of all roles defined in the system.
767      * @throws DataBackendException if there was an error accessing the
768      *         data backend.
769      */
770     @Override
771     public RoleSet getAllRoles() throws DataBackendException
772     {
773         return roleManager.getAllRoles();
774     }
775 
776     /**
777      * Retrieves all permissions defined in the system.
778      *
779      * @return the names of all roles defined in the system.
780      * @throws DataBackendException if there was an error accessing the
781      *         data backend.
782      */
783     @Override
784     public PermissionSet getAllPermissions() throws DataBackendException
785     {
786         return permissionManager.getAllPermissions();
787     }
788 
789     /*-----------------------------------------------------------------------
790     Creation of AccessControlLists
791     -----------------------------------------------------------------------*/
792 
793     /**
794      * Constructs an AccessControlList for a specific user.
795      *
796      * @param user the user for whom the AccessControlList are to be retrieved
797      * @return The AccessControList object constructed from the user object.
798      * @throws DataBackendException if there was an error accessing the data
799      *         backend.
800      * @throws UnknownEntityException if user account is not present.
801      */
802     @Override
803     public <A extends AccessControlList> A getACL(User user)
804         throws DataBackendException, UnknownEntityException
805     {
806         return getUserManager().getACL(user);
807     }
808 
809     /*-----------------------------------------------------------------------
810     Security management
811     -----------------------------------------------------------------------*/
812 
813     /**
814      * Grant an User a Role in a Group.
815      *
816      * @param user the user.
817      * @param group the group.
818      * @param role the role.
819      * @throws DataBackendException if there was an error accessing the data
820      *         backend.
821      * @throws UnknownEntityException if user account, group or role is not
822      *         present.
823      */
824     @Override
825     public void grant(User user, Group group, Role role)
826     throws DataBackendException, UnknownEntityException
827     {
828         if (user == null) {
829             throw new UnknownEntityException("user is null");
830         }
831         modelManager.grant(user.getUserDelegate(), group, role);
832     }
833 
834     /**
835      * Revoke a Role in a Group from an User.
836      *
837      * @param user the user.
838      * @param group the group.
839      * @param role the role.
840      * @throws DataBackendException if there was an error accessing the data
841      *         backend.
842      * @throws UnknownEntityException if user account, group or role is not
843      *         present.
844      */
845     @Override
846     public void revoke(User user, Group group, Role role)
847         throws DataBackendException, UnknownEntityException
848     {
849         if (user == null) {
850             throw new UnknownEntityException("user is null");
851         }
852         modelManager.revoke(user.getUserDelegate(), group, role);
853     }
854     
855     /**
856      * Replaces transactionally the first role with second role for the given user. 
857      * 
858      * @param user the user.
859      * @param role the old role
860      * @param newRole the new role
861      * 
862      * @throws DataBackendException
863      * @throws UnknownEntityException
864      */
865     @Override
866     public void replaceRole(User user, Role role, Role newRole)
867                     throws DataBackendException, UnknownEntityException
868     {
869         modelManager.replace( user, role, newRole );
870     }
871 
872     /**
873      * Revokes all roles from an User.
874      *
875      * This method is used when deleting an account.
876      *
877      * @param user the User.
878      * @throws DataBackendException if there was an error accessing the data
879      *         backend.
880      * @throws UnknownEntityException if the account is not present.
881      */
882     @Override
883     public void revokeAll(User user)
884         throws DataBackendException, UnknownEntityException
885     {
886         if (user == null) {
887             throw new UnknownEntityException("user is null");
888         }
889         modelManager.revokeAll(user.getUserDelegate());
890     }
891 
892     /**
893      * Grants a Role a Permission
894      *
895      * @param role the Role.
896      * @param permission the Permission.
897      * @throws DataBackendException if there was an error accessing the data
898      *         backend.
899      * @throws UnknownEntityException if role or permission is not present.
900      */
901     @Override
902     public void grant(Role role, Permission permission)
903         throws DataBackendException, UnknownEntityException
904     {
905         modelManager.grant(role, permission);
906     }
907 
908     /**
909      * Revokes a Permission from a Role.
910      *
911      * @param role the Role.
912      * @param permission the Permission.
913      * @throws DataBackendException if there was an error accessing the data
914      *         backend.
915      * @throws UnknownEntityException if role or permission is not present.
916      */
917     @Override
918     public void revoke(Role role, Permission permission)
919         throws DataBackendException, UnknownEntityException
920     {
921         modelManager.revoke(role, permission);
922     }
923 
924     /**
925      * Revokes all permissions from a Role.
926      *
927      * This method is used when deleting a Role.
928      *
929      * @param role the Role
930      * @throws DataBackendException if there was an error accessing the data
931      *         backend.
932      * @throws  UnknownEntityException if the Role is not present.
933      */
934     @Override
935     public void revokeAll(Role role)
936         throws DataBackendException, UnknownEntityException
937     {
938         modelManager.revokeAll(role);
939     }
940     
941     /**
942      * Revokes by default all permissions from a Role and if flag is set
943      * all group and user relationships with this role
944      * 
945      * This method is used when deleting a Role.
946      * 
947      * @param role
948      *            the Role
949      * @param cascadeDelete
950      *             if <code>true </code> removes all groups and user for this role.
951      * @throws DataBackendException
952      *             if there was an error accessing the data backend.
953      * @throws UnknownEntityException
954      *             if the Role is not present.
955      */
956     @Override
957     public void revokeAll( Role role, boolean cascadeDelete )
958         throws DataBackendException, UnknownEntityException 
959     {
960         modelManager.revokeAll(role, cascadeDelete);
961     }
962 
963     /**
964      * Retrieves all permissions associated with a role.
965      *
966      * @param role the role name, for which the permissions are to be retrieved.
967      * @return the Permissions for the specified role
968      * @throws DataBackendException if there was an error accessing the data
969      *         backend.
970      * @throws UnknownEntityException if the role is not present.
971      */
972     @Override
973     public PermissionSet getPermissions(Role role)
974             throws DataBackendException, UnknownEntityException
975     {
976         return ((TurbineRole)role).getPermissions();
977     }
978 
979     /**
980      * Creates a new group with specified attributes.
981      *
982      * @param group the object describing the group to be created.
983      * @throws DataBackendException if there was an error accessing the data
984      *         backend.
985      * @throws EntityExistsException if the group already exists.
986      */
987     @Override
988     public <G extends Group> G addGroup(G group)
989             throws DataBackendException, EntityExistsException
990     {
991         return groupManager.addGroup(group);
992     }
993 
994     /**
995      * Creates a new role with specified attributes.
996      *
997      * @param role the objects describing the role to be created.
998      * @throws DataBackendException if there was an error accessing the data
999      *         backend.
1000      * @throws EntityExistsException if the role already exists.
1001      */
1002     @Override
1003     public <R extends Role> R addRole(R role)
1004             throws DataBackendException, EntityExistsException
1005     {
1006         return roleManager.addRole(role);
1007     }
1008 
1009     /**
1010      * Creates a new permission with specified attributes.
1011      *
1012      * @param permission the objects describing the permission to be created.
1013      * @throws DataBackendException if there was an error accessing the data
1014      *         backend.
1015      * @throws EntityExistsException if the permission already exists.
1016      */
1017     @Override
1018     public <P extends Permission> P addPermission(P permission)
1019             throws DataBackendException, EntityExistsException
1020     {
1021         return permissionManager.addPermission(permission);
1022     }
1023 
1024     /**
1025      * Removes a Group from the system.
1026      *
1027      * @param group the object describing group to be removed.
1028      * @throws DataBackendException if there was an error accessing the data
1029      *         backend.
1030      * @throws UnknownEntityException if the group does not exist.
1031      */
1032     @Override
1033     public void removeGroup(Group group)
1034             throws DataBackendException, UnknownEntityException
1035     {
1036         groupManager.removeGroup(group);
1037     }
1038 
1039     /**
1040      * Removes a Role from the system.
1041      *
1042      * @param role The object describing the role to be removed.
1043      * @throws DataBackendException if there was an error accessing the data backend.
1044      * @throws UnknownEntityException if the role does not exist.
1045      */
1046     @Override
1047     public void removeRole(Role role)
1048             throws DataBackendException, UnknownEntityException
1049     {
1050         roleManager.removeRole(role);
1051     }
1052 
1053     /**
1054      * Removes a Permission from the system.
1055      *
1056      * @param permission The object describing the permission to be removed.
1057      * @throws DataBackendException if there was an error accessing the data
1058      *         backend.
1059      * @throws UnknownEntityException if the permission does not exist.
1060      */
1061     @Override
1062     public void removePermission(Permission permission)
1063             throws DataBackendException, UnknownEntityException
1064     {
1065         permissionManager.removePermission(permission);
1066     }
1067 
1068     /**
1069      * Renames an existing Group.
1070      *
1071      * @param group The object describing the group to be renamed.
1072      * @param name the new name for the group.
1073      * @throws DataBackendException if there was an error accessing the data
1074      *         backend.
1075      * @throws UnknownEntityException if the group does not exist.
1076      */
1077     @Override
1078     public void renameGroup(Group group, String name)
1079             throws DataBackendException, UnknownEntityException
1080     {
1081         groupManager.renameGroup(group, name);
1082     }
1083 
1084     /**
1085      * Renames an existing Role.
1086      *
1087      * @param role The object describing the role to be renamed.
1088      * @param name the new name for the role.
1089      * @throws DataBackendException if there was an error accessing the data
1090      *         backend.
1091      * @throws UnknownEntityException if the role does not exist.
1092      */
1093     @Override
1094     public void renameRole(Role role, String name)
1095             throws DataBackendException, UnknownEntityException
1096     {
1097         roleManager.renameRole(role, name);
1098     }
1099 
1100     /**
1101      * Renames an existing Permission.
1102      *
1103      * @param permission The object describing the permission to be renamed.
1104      * @param name the new name for the permission.
1105      * @throws DataBackendException if there was an error accessing the data
1106      *         backend.
1107      * @throws UnknownEntityException if the permission does not exist.
1108      */
1109     @Override
1110     public void renamePermission(Permission permission, String name)
1111             throws DataBackendException, UnknownEntityException
1112     {
1113         permissionManager.renamePermission(permission, name);
1114     }
1115 }