    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}