    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 1524210 2013-09-17 20:22:56Z tv $
    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 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    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}