001package org.apache.turbine.services.security;
002
003
004/*
005 * Licensed to the Apache Software Foundation (ASF) under one
006 * or more contributor license agreements.  See the NOTICE file
007 * distributed with this work for additional information
008 * regarding copyright ownership.  The ASF licenses this file
009 * to you under the Apache License, Version 2.0 (the
010 * "License"); you may not use this file except in compliance
011 * with the License.  You may obtain a copy of the License at
012 *
013 *   http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing,
016 * software distributed under the License is distributed on an
017 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
018 * KIND, either express or implied.  See the License for the
019 * specific language governing permissions and limitations
020 * under the License.
021 */
022
023
024import org.apache.commons.configuration.Configuration;
025import org.apache.commons.logging.Log;
026import org.apache.commons.logging.LogFactory;
027import org.apache.fulcrum.security.GroupManager;
028import org.apache.fulcrum.security.PermissionManager;
029import org.apache.fulcrum.security.RoleManager;
030import org.apache.fulcrum.security.acl.AccessControlList;
031import org.apache.fulcrum.security.entity.Group;
032import org.apache.fulcrum.security.entity.Permission;
033import org.apache.fulcrum.security.entity.Role;
034import org.apache.fulcrum.security.model.turbine.TurbineModelManager;
035import org.apache.fulcrum.security.model.turbine.entity.TurbineRole;
036import org.apache.fulcrum.security.util.DataBackendException;
037import org.apache.fulcrum.security.util.EntityExistsException;
038import org.apache.fulcrum.security.util.GroupSet;
039import org.apache.fulcrum.security.util.PasswordMismatchException;
040import org.apache.fulcrum.security.util.PermissionSet;
041import org.apache.fulcrum.security.util.RoleSet;
042import org.apache.fulcrum.security.util.UnknownEntityException;
043import org.apache.turbine.om.security.User;
044import org.apache.turbine.services.InitializationException;
045import org.apache.turbine.services.ServiceManager;
046import org.apache.turbine.services.TurbineBaseService;
047import org.apache.turbine.services.TurbineServices;
048
049/**
050 * This is a common subset of SecurityService implementation.
051 *
052 * Provided functionality includes:
053 * <ul>
054 * <li> methods for retrieving User objects, that delegates functionality
055 *      to the pluggable implementations of the User interface.
056 * <li> synchronization mechanism for methods reading/modifying the security
057 *      information, that guarantees that multiple threads may read the
058 *      information concurrently, but threads that modify the information
059 *      acquires exclusive access.
060 * <li> implementation of convenience methods for retrieving security entities
061 *      that maintain in-memory caching of objects for fast access.
062 * </ul>
063 *
064 * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
065 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
066 * @author <a href="mailto:marco@intermeta.de">Marco Kn&uuml;ttel</a>
067 * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
068 * @version $Id: DefaultSecurityService.java 1821872 2018-01-22 14:35:04Z gk $
069 */
070public class DefaultSecurityService
071        extends TurbineBaseService
072        implements SecurityService
073{
074    /** The number of threads concurrently reading security information */
075    private int readerCount = 0;
076
077    /** The instance of UserManager the SecurityService uses */
078    private UserManager userManager = null;
079
080    /** The instance of GroupManager the SecurityService uses */
081    private GroupManager groupManager;
082
083    /** The instance of RoleManager the SecurityService uses */
084    private RoleManager roleManager;
085
086    /** The instance of PermissionManager the SecurityService uses */
087    private PermissionManager permissionManager;
088
089    /** The instance of ModelManager the SecurityService uses */
090    private TurbineModelManager modelManager;
091
092    /**
093     * The Group object that represents the <a href="#global">global group</a>.
094     */
095    private static volatile Group globalGroup = null;
096
097    /** Logging */
098    private static Log log = LogFactory.getLog(DefaultSecurityService.class);
099
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}