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