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