View Javadoc

    1   package org.apache.turbine.services.security.torque;
    2
    3   /*
    4    * Licensed to the Apache Software Foundation (ASF) under one
    5    * or more contributor license agreements.  See the NOTICE file
    6    * distributed with this work for additional information
    7    * regarding copyright ownership.  The ASF licenses this file
    8    * to you under the Apache License, Version 2.0 (the
    9    * "License"); you may not use this file except in compliance
    10   * with the License.  You may obtain a copy of the License at
    11   *
    12   *   http://www.apache.org/licenses/LICENSE-2.0
    13   *
    14   * Unless required by applicable law or agreed to in writing,
    15   * software distributed under the License is distributed on an
    16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    17   * KIND, either express or implied.  See the License for the
    18   * specific language governing permissions and limitations
    19   * under the License.
    20   */
    21
    22  import java.util.ArrayList;
    23  import java.util.Hashtable;
    24  import java.util.Iterator;
    25  import java.util.List;
    26
    27  import org.apache.commons.configuration.Configuration;
    28  import org.apache.commons.lang.StringUtils;
    29  import org.apache.commons.logging.Log;
    30  import org.apache.commons.logging.LogFactory;
    31  import org.apache.torque.TorqueException;
    32  import org.apache.torque.om.NumberKey;
    33  import org.apache.torque.om.Persistent;
    34  import org.apache.torque.util.Criteria;
    35  import org.apache.turbine.om.security.Group;
    36  import org.apache.turbine.om.security.Permission;
    37  import org.apache.turbine.om.security.Role;
    38  import org.apache.turbine.om.security.User;
    39  import org.apache.turbine.services.InitializationException;
    40  import org.apache.turbine.services.security.BaseSecurityService;
    41  import org.apache.turbine.services.security.TurbineSecurity;
    42  import org.apache.turbine.services.security.torque.om.TurbineRolePermissionPeer;
    43  import org.apache.turbine.services.security.torque.om.TurbineUserGroupRolePeer;
    44  import org.apache.turbine.util.security.AccessControlList;
    45  import org.apache.turbine.util.security.DataBackendException;
    46  import org.apache.turbine.util.security.EntityExistsException;
    47  import org.apache.turbine.util.security.GroupSet;
    48  import org.apache.turbine.util.security.PermissionSet;
    49  import org.apache.turbine.util.security.RoleSet;
    50  import org.apache.turbine.util.security.UnknownEntityException;
    51
    52  /**
    53   * An implementation of SecurityService that uses torque objects.
    54   *
    55   * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
    56   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
    57   * @author <a href="mailto:marco@intermeta.de">Marco Kn&uuml;ttel</a>
    58   * @version $Id: TorqueSecurityService.java 1096130 2011-04-23 10:37:19Z ludwig $
    59   */
    60  public class TorqueSecurityService
    61      extends BaseSecurityService
    62  {
    63      /** Logging */
    64      private static Log log = LogFactory.getLog(TorqueSecurityService.class);
    65
    66      /**
    67       * Initializes the TorqueSecurityService, loading the various class objects
    68       * representing the security entity peer classes
    69       *
    70       * @exception InitializationException A problem occured during initialization
    71       */
    72
    73      public void init()
    74          throws InitializationException
    75      {
    76          Configuration conf = getConfiguration();
    77
    78          GroupPeerManager.init(conf);
    79          RolePeerManager.init(conf);
    80          PermissionPeerManager.init(conf);
    81
    82          /* At the end, because it calls setInit(true)! */
    83          super.init();
    84      }
    85
    86
    87      /*-----------------------------------------------------------------------
    88        Creation of AccessControlLists
    89        -----------------------------------------------------------------------*/
    90
    91      /**
    92       * Constructs an AccessControlList for a specific user.
    93       *
    94       * This method creates a snapshot of the state of security information
    95       * concerning this user, at the moment of invocation and stores it
    96       * into an AccessControlList object.
    97       *
    98       * @param user the user for whom the AccessControlList are to be retrieved
    99       * @return A new AccessControlList object.
    100      * @throws DataBackendException if there was an error accessing the data
    101      *         backend.
    102      * @throws UnknownEntityException if user account is not present.
    103      */
    104     public AccessControlList getACL(User user)
    105         throws DataBackendException, UnknownEntityException
    106     {
    107         if (!TurbineSecurity.accountExists(user))
    108         {
    109             throw new UnknownEntityException("The account '"
    110                                              + user.getName() + "' does not exist");
    111         }
    112         try
    113         {
    114             Hashtable roles = new Hashtable();
    115             Hashtable permissions = new Hashtable();
    116             // notify the state modifiers (writers) that we want to create
    117             // the snapshot.
    118             lockShared();
    119
    120             // construct the snapshot:
    121
    122             // foreach group in the system
    123             for (Iterator groupsIterator = getAllGroups().iterator();
    124                  groupsIterator.hasNext();)
    125             {
    126                 Group group = (Group) groupsIterator.next();
    127                 // get roles of user in the group
    128                 RoleSet groupRoles = RolePeerManager.retrieveSet(user, group);
    129                 // put the Set into roles(group)
    130                 roles.put(group, groupRoles);
    131                 // collect all permissions in this group
    132                 PermissionSet groupPermissions = new PermissionSet();
    133                 // foreach role in Set
    134                 for (Iterator rolesIterator = groupRoles.iterator();
    135                      rolesIterator.hasNext();)
    136                 {
    137                     Role role = (Role) rolesIterator.next();
    138                     // get permissions of the role
    139                     PermissionSet rolePermissions =
    140                         PermissionPeerManager.retrieveSet(role);
    141                     groupPermissions.add(rolePermissions);
    142                 }
    143                 // put the Set into permissions(group)
    144                 permissions.put(group, groupPermissions);
    145             }
    146             return getAclInstance(roles, permissions);
    147         }
    148         catch (Exception e)
    149         {
    150             throw new DataBackendException("Failed to build ACL for user '" +
    151                                            user.getName() + "'" , e);
    152         }
    153         finally
    154         {
    155             // notify the state modifiers that we are done creating the snapshot.
    156             unlockShared();
    157         }
    158     }
    159
    160     /*-----------------------------------------------------------------------
    161       Security management
    162       -----------------------------------------------------------------------*/
    163
    164     /**
    165      * Grant an User a Role in a Group.
    166      *
    167      * @param user the user.
    168      * @param group the group.
    169      * @param role the role.
    170      * @throws DataBackendException if there was an error accessing the data
    171      *         backend.
    172      * @throws UnknownEntityException if user account, group or role is not
    173      *         present.
    174      */
    175     public synchronized void grant(User user, Group group, Role role)
    176         throws DataBackendException, UnknownEntityException
    177     {
    178         boolean userExists = false;
    179         boolean groupExists = false;
    180         boolean roleExists = false;
    181         try
    182         {
    183             lockExclusive();
    184             userExists = TurbineSecurity.accountExists(user);
    185             groupExists = checkExists(group);
    186             roleExists = checkExists(role);
    187             if (userExists && groupExists && roleExists)
    188             {
    189                 Criteria criteria = new Criteria();
    190                 criteria.add(TurbineUserGroupRolePeer.USER_ID,
    191                              ((Persistent) user).getPrimaryKey());
    192                 criteria.add(TurbineUserGroupRolePeer.GROUP_ID,
    193                              ((Persistent) group).getPrimaryKey());
    194                 criteria.add(TurbineUserGroupRolePeer.ROLE_ID,
    195                              ((Persistent) role).getPrimaryKey());
    196                 TurbineUserGroupRolePeer.doInsert(criteria);
    197                 return;
    198             }
    199         }
    200         catch (Exception e)
    201         {
    202             throw new DataBackendException("grant(User,Group,Role) failed", e);
    203         }
    204         finally
    205         {
    206             unlockExclusive();
    207         }
    208         if (!userExists)
    209         {
    210             throw new UnknownEntityException("Unknown user '"
    211                                              + user.getName() + "'");
    212         }
    213         if (!groupExists)
    214         {
    215             throw new UnknownEntityException("Unknown group '"
    216                                              + group.getName() + "'");
    217         }
    218         if (!roleExists)
    219         {
    220             throw new UnknownEntityException("Unknown role '"
    221                                              + role.getName() + "'");
    222         }
    223     }
    224
    225     /**
    226      * Revoke a Role in a Group from an User.
    227      *
    228      * @param user the user.
    229      * @param group the group.
    230      * @param role the role.
    231      * @throws DataBackendException if there was an error accessing the data
    232      *         backend.
    233      * @throws UnknownEntityException if user account, group or role is not
    234      *         present.
    235      */
    236     public synchronized void revoke(User user, Group group, Role role)
    237         throws DataBackendException, UnknownEntityException
    238     {
    239         boolean userExists = false;
    240         boolean groupExists = false;
    241         boolean roleExists = false;
    242         try
    243         {
    244             lockExclusive();
    245             userExists = TurbineSecurity.accountExists(user);
    246             groupExists = checkExists(group);
    247             roleExists = checkExists(role);
    248             if (userExists && groupExists && roleExists)
    249             {
    250                 Criteria criteria = new Criteria();
    251                 criteria.add(TurbineUserGroupRolePeer.USER_ID,
    252                              ((Persistent) user).getPrimaryKey());
    253                 criteria.add(TurbineUserGroupRolePeer.GROUP_ID,
    254                              ((Persistent) group).getPrimaryKey());
    255                 criteria.add(TurbineUserGroupRolePeer.ROLE_ID,
    256                              ((Persistent) role).getPrimaryKey());
    257                 TurbineUserGroupRolePeer.doDelete(criteria);
    258                 return;
    259             }
    260         }
    261         catch (Exception e)
    262         {
    263             throw new DataBackendException("revoke(User,Role,Group) failed", e);
    264         }
    265         finally
    266         {
    267             unlockExclusive();
    268         }
    269         if (!userExists)
    270         {
    271             throw new UnknownEntityException("Unknown user '"
    272                                              + user.getName() + "'");
    273         }
    274         if (!groupExists)
    275         {
    276             throw new UnknownEntityException("Unknown group '"
    277                                              + group.getName() + "'");
    278         }
    279         if (!roleExists)
    280         {
    281             throw new UnknownEntityException("Unknown role '"
    282                                              + role.getName() + "'");
    283         }
    284     }
    285
    286     /**
    287      * Revokes all roles from an User.
    288      *
    289      * This method is used when deleting an account.
    290      *
    291      * @param user the User.
    292      * @throws DataBackendException if there was an error accessing the data
    293      *         backend.
    294      * @throws UnknownEntityException if the account is not present.
    295      */
    296     public synchronized void revokeAll(User user)
    297         throws DataBackendException, UnknownEntityException
    298     {
    299         boolean userExists = false;
    300         try
    301         {
    302             lockExclusive();
    303             userExists = TurbineSecurity.accountExists(user);
    304             if (userExists)
    305             {
    306                 // The following would not work, due to an annoying misfeature
    307                 // of Village. Village allows only a single row to be deleted at
    308                 // a time. I wish that it was possible to disable this
    309                 // behaviour!
    310
    311                 // Criteria criteria = new Criteria();
    312                 // criteria.add(UserGroupRolePeer.USER_ID,
    313                 //           ((Persistent) user).getPrimaryKey());
    314                 // UserGroupRolePeer.doDelete(criteria);
    315                 int id = ((NumberKey) ((Persistent) user)
    316                           .getPrimaryKey()).intValue();
    317                 TurbineUserGroupRolePeer.deleteAll(
    318                     TurbineUserGroupRolePeer.TABLE_NAME,
    319                     TurbineUserGroupRolePeer.USER_ID, id);
    320                 return;
    321             }
    322         }
    323         catch (Exception e)
    324         {
    325             throw new DataBackendException("revokeAll(User) failed", e);
    326         }
    327         finally
    328         {
    329             unlockExclusive();
    330         }
    331         throw new UnknownEntityException("Unknown user '"
    332                                          + user.getName() + "'");
    333     }
    334
    335     /**
    336      * Grants a Role a Permission
    337      *
    338      * @param role the Role.
    339      * @param permission the Permission.
    340      * @throws DataBackendException if there was an error accessing the data
    341      *         backend.
    342      * @throws UnknownEntityException if role or permission is not present.
    343      */
    344     public synchronized void grant(Role role, Permission permission)
    345         throws DataBackendException, UnknownEntityException
    346     {
    347         boolean roleExists = false;
    348         boolean permissionExists = false;
    349         try
    350         {
    351             lockExclusive();
    352             roleExists = checkExists(role);
    353             permissionExists = checkExists(permission);
    354             if (roleExists && permissionExists)
    355             {
    356                 Criteria criteria = new Criteria();
    357                 criteria.add(TurbineRolePermissionPeer.ROLE_ID,
    358                              ((Persistent) role).getPrimaryKey());
    359                 criteria.add(TurbineRolePermissionPeer.PERMISSION_ID,
    360                              ((Persistent) permission).getPrimaryKey());
    361                 TurbineRolePermissionPeer.doInsert(criteria);
    362                 return;
    363             }
    364         }
    365         catch (Exception e)
    366         {
    367             throw new DataBackendException("grant(Role,Permission) failed", e);
    368         }
    369         finally
    370         {
    371             unlockExclusive();
    372         }
    373         if (!roleExists)
    374         {
    375             throw new UnknownEntityException("Unknown role '"
    376                                              + role.getName() + "'");
    377         }
    378         if (!permissionExists)
    379         {
    380             throw new UnknownEntityException("Unknown permission '"
    381                                              + permission.getName() + "'");
    382         }
    383     }
    384
    385     /**
    386      * Revokes a Permission from a Role.
    387      *
    388      * @param role the Role.
    389      * @param permission the Permission.
    390      * @throws DataBackendException if there was an error accessing the data
    391      *         backend.
    392      * @throws UnknownEntityException if role or permission is not present.
    393      */
    394     public synchronized void revoke(Role role, Permission permission)
    395         throws DataBackendException, UnknownEntityException
    396     {
    397         boolean roleExists = false;
    398         boolean permissionExists = false;
    399         try
    400         {
    401             lockExclusive();
    402             roleExists = checkExists(role);
    403             permissionExists = checkExists(permission);
    404             if (roleExists && permissionExists)
    405             {
    406                 Criteria criteria = new Criteria();
    407                 criteria.add(TurbineRolePermissionPeer.ROLE_ID,
    408                              ((Persistent) role).getPrimaryKey());
    409                 criteria.add(TurbineRolePermissionPeer.PERMISSION_ID,
    410                              ((Persistent) permission).getPrimaryKey());
    411                 TurbineRolePermissionPeer.doDelete(criteria);
    412                 return;
    413             }
    414         }
    415         catch (Exception e)
    416         {
    417             throw new DataBackendException("revoke(Role,Permission) failed", e);
    418         }
    419         finally
    420         {
    421             unlockExclusive();
    422         }
    423         if (!roleExists)
    424         {
    425             throw new UnknownEntityException("Unknown role '"
    426                                              + role.getName() + "'");
    427         }
    428         if (!permissionExists)
    429         {
    430             throw new UnknownEntityException("Unknown permission '"
    431                                              + permission.getName() + "'");
    432         }
    433     }
    434
    435     /**
    436      * Revokes all permissions from a Role.
    437      *
    438      * This method is user when deleting a Role.
    439      *
    440      * @param role the Role
    441      * @throws DataBackendException if there was an error accessing the data
    442      *         backend.
    443      * @throws UnknownEntityException if the Role is not present.
    444      */
    445     public synchronized void revokeAll(Role role)
    446         throws DataBackendException, UnknownEntityException
    447     {
    448         boolean roleExists = false;
    449         try
    450         {
    451             lockExclusive();
    452             roleExists = checkExists(role);
    453             if (roleExists)
    454             {
    455                 // The following would not work, due to an annoying misfeature
    456                 // of Village. see revokeAll( user )
    457
    458                 // Criteria criteria = new Criteria();
    459                 // criteria.add(RolePermissionPeer.ROLE_ID,
    460                 //         role.getPrimaryKey());
    461                 // RolePermissionPeer.doDelete(criteria);
    462
    463                 int id = ((NumberKey) ((Persistent) role)
    464                           .getPrimaryKey()).intValue();
    465                 TurbineRolePermissionPeer.deleteAll(
    466                     TurbineRolePermissionPeer.TABLE_NAME,
    467                     TurbineRolePermissionPeer.ROLE_ID, id);
    468                 return;
    469             }
    470         }
    471         catch (Exception e)
    472         {
    473             throw new DataBackendException("revokeAll(Role) failed", e);
    474         }
    475         finally
    476         {
    477             unlockExclusive();
    478         }
    479         throw new UnknownEntityException("Unknown role '"
    480                                          + role.getName() + "'");
    481     }
    482
    483     /*-----------------------------------------------------------------------
    484       Group/Role/Permission management
    485       -----------------------------------------------------------------------*/
    486
    487     /**
    488      * Retrieve a set of Groups that meet the specified Criteria.
    489      *
    490      * @param criteria A Criteria of Group selection.
    491      * @return a set of Groups that meet the specified Criteria.
    492      * @throws DataBackendException if there was an error accessing the data
    493      *         backend.
    494      */
    495     public GroupSet getGroups(Object criteria)
    496         throws DataBackendException
    497     {
    498         if (criteria instanceof Criteria)
    499         {
    500             Criteria torqueCriteria = new Criteria();
    501             Criteria c = (Criteria)criteria;
    502             Iterator keys = c.keySet().iterator();
    503             while (keys.hasNext())
    504             {
    505                 String key = (String) keys.next();
    506                 torqueCriteria.put(GroupPeerManager.getColumnName(key),
    507                         c.get(key));
    508             }
    509             List groups = new ArrayList(0);
    510             try
    511             {
    512                 groups = GroupPeerManager.doSelect(torqueCriteria);
    513             }
    514             catch (TorqueException e)
    515             {
    516                 throw new DataBackendException("getGroups(Object) failed", e);
    517             }
    518
    519             return new GroupSet(groups);
    520         }
    521         else
    522         {
    523             throw new DataBackendException(
    524                     "getGroups(Object) failed with invalid criteria");
    525         }
    526     }
    527
    528     /**
    529      * Retrieve a set of Roles that meet the specified Criteria.
    530      *
    531      * @param criteria A Criteria of Roles selection.
    532      * @return a set of Roles that meet the specified Criteria.
    533      * @throws DataBackendException if there was an error accessing the data
    534      *         backend.
    535      */
    536     public RoleSet getRoles(Object criteria)
    537         throws DataBackendException
    538     {
    539         if (criteria instanceof Criteria)
    540         {
    541             Criteria torqueCriteria = new Criteria();
    542             Criteria c = (Criteria)criteria;
    543             Iterator keys = c.keySet().iterator();
    544             while (keys.hasNext())
    545             {
    546                 String key = (String) keys.next();
    547                 torqueCriteria.put(RolePeerManager.getColumnName(key),
    548                         c.get(key));
    549             }
    550             List roles = new ArrayList(0);
    551             try
    552             {
    553                 roles = RolePeerManager.doSelect(torqueCriteria);
    554             }
    555             catch (TorqueException e)
    556             {
    557                 throw new DataBackendException("getRoles(Criteria) failed", e);
    558             }
    559             return new RoleSet(roles);
    560         }
    561         else
    562         {
    563             throw new DataBackendException(
    564                     "getRoles(Object) failed with invalid criteria");
    565         }
    566     }
    567
    568     /**
    569      * Retrieve a set of Permissions that meet the specified Criteria.
    570      *
    571      * @param criteria A Criteria of Permissions selection.
    572      * @return a set of Permissions that meet the specified Criteria.
    573      * @throws DataBackendException if there was an error accessing the data
    574      *         backend.
    575      */
    576     public PermissionSet getPermissions(Object criteria)
    577         throws DataBackendException
    578     {
    579         if (criteria instanceof Criteria)
    580         {
    581             Criteria torqueCriteria = new Criteria();
    582             Criteria c = (Criteria)criteria;
    583             Iterator keys = c.keySet().iterator();
    584             while (keys.hasNext())
    585             {
    586                 String key = (String) keys.next();
    587                 torqueCriteria.put(PermissionPeerManager.getColumnName(key),
    588                         c.get(key));
    589             }
    590             List permissions = new ArrayList(0);
    591             try
    592             {
    593                 permissions = PermissionPeerManager.doSelect(torqueCriteria);
    594             }
    595             catch (TorqueException e)
    596             {
    597                 throw new DataBackendException(
    598                     "getPermissions(Object) failed", e);
    599             }
    600
    601             return new PermissionSet(permissions);
    602         }
    603         else
    604         {
    605             throw new DataBackendException(
    606                     "getPermissions(Object) failed with invalid criteria");
    607         }
    608     }
    609
    610     /**
    611      * Retrieves all permissions associated with a role.
    612      *
    613      * @param role the role name, for which the permissions are to be retrieved.
    614      * @return A Permission set for the Role.
    615      * @throws DataBackendException if there was an error accessing the data
    616      *         backend.
    617      * @throws UnknownEntityException if the role is not present.
    618      */
    619     public PermissionSet getPermissions(Role role)
    620         throws DataBackendException, UnknownEntityException
    621     {
    622         boolean roleExists = false;
    623         try
    624         {
    625             lockShared();
    626             roleExists = checkExists(role);
    627             if (roleExists)
    628             {
    629                 return PermissionPeerManager.retrieveSet(role);
    630             }
    631         }
    632         catch (Exception e)
    633         {
    634             throw new DataBackendException("getPermissions(Role) failed", e);
    635         }
    636         finally
    637         {
    638             unlockShared();
    639         }
    640         throw new UnknownEntityException("Unknown role '"
    641                                          + role.getName() + "'");
    642     }
    643
    644     /**
    645      * Stores Group's attributes. The Groups is required to exist in the system.
    646      *
    647      * @param group The Group to be stored.
    648      * @throws DataBackendException if there was an error accessing the data
    649      *         backend.
    650      * @throws UnknownEntityException if the group does not exist.
    651      */
    652     public void saveGroup(Group group)
    653         throws DataBackendException, UnknownEntityException
    654     {
    655         boolean groupExists = false;
    656         try
    657         {
    658             groupExists = checkExists(group);
    659             if (groupExists)
    660             {
    661                 Criteria criteria = GroupPeerManager.buildCriteria(group);
    662                 GroupPeerManager.doUpdate(criteria);
    663                 return;
    664             }
    665         }
    666         catch (Exception e)
    667         {
    668             throw new DataBackendException("saveGroup(Group) failed", e);
    669         }
    670         throw new UnknownEntityException("Unknown group '" + group + "'");
    671     }
    672
    673     /**
    674      * Stores Role's attributes. The Roles is required to exist in the system.
    675      *
    676      * @param role The Role to be stored.
    677      * @throws DataBackendException if there was an error accessing the data
    678      *         backend.
    679      * @throws UnknownEntityException if the role does not exist.
    680      */
    681     public void saveRole(Role role)
    682         throws DataBackendException, UnknownEntityException
    683     {
    684         boolean roleExists = false;
    685         try
    686         {
    687             roleExists = checkExists(role);
    688             if (roleExists)
    689             {
    690                 Criteria criteria = RolePeerManager.buildCriteria(role);
    691                 RolePeerManager.doUpdate(criteria);
    692                 return;
    693             }
    694         }
    695         catch (Exception e)
    696         {
    697             throw new DataBackendException("saveRole(Role) failed", e);
    698         }
    699         throw new UnknownEntityException("Unknown role '" + role + "'");
    700     }
    701
    702     /**
    703      * Stores Permission's attributes. The Permissions is required to exist in
    704      * the system.
    705      *
    706      * @param permission The Permission to be stored.
    707      * @throws DataBackendException if there was an error accessing the data
    708      *         backend.
    709      * @throws UnknownEntityException if the permission does not exist.
    710      */
    711     public void savePermission(Permission permission)
    712         throws DataBackendException, UnknownEntityException
    713     {
    714         boolean permissionExists = false;
    715         try
    716         {
    717             permissionExists = checkExists(permission);
    718             if (permissionExists)
    719             {
    720                 Criteria criteria = PermissionPeerManager.buildCriteria(permission);
    721                 PermissionPeerManager.doUpdate(criteria);
    722                 return;
    723             }
    724         }
    725         catch (Exception e)
    726         {
    727             throw new DataBackendException(
    728                 "savePermission(Permission) failed", e);
    729         }
    730         throw new UnknownEntityException("Unknown permission '"
    731                                          + permission + "'");
    732     }
    733
    734     /**
    735      * Creates a new group with specified attributes.
    736      *
    737      * @param group the object describing the group to be created.
    738      * @return a new Group object that has id set up properly.
    739      * @throws DataBackendException if there was an error accessing the data
    740      *         backend.
    741      * @throws EntityExistsException if the group already exists.
    742      */
    743     public synchronized Group addGroup(Group group)
    744         throws DataBackendException,
    745                EntityExistsException
    746     {
    747         boolean groupExists = false;
    748
    749         if (StringUtils.isEmpty(group.getName()))
    750         {
    751             throw new DataBackendException("Could not create "
    752                                            + "a group with empty name!");
    753         }
    754
    755         try
    756         {
    757             lockExclusive();
    758             groupExists = checkExists(group);
    759             if (!groupExists)
    760             {
    761                 // add a row to the table
    762                 Criteria criteria = GroupPeerManager.buildCriteria(group);
    763                 GroupPeerManager.doInsert(criteria);
    764                 // try to get the object back using the name as key.
    765                 criteria = new Criteria();
    766                 criteria.add(GroupPeerManager.getNameColumn(),
    767                              group.getName());
    768                 List results = GroupPeerManager.doSelect(criteria);
    769                 if (results.size() != 1)
    770                 {
    771                     throw new DataBackendException(
    772                         "Internal error - query returned "
    773                         + results.size() + " rows");
    774                 }
    775                 Group newGroup = (Group) results.get(0);
    776                 // add the group to system-wide cache
    777                 getAllGroups().add(newGroup);
    778                 // return the object with correct id
    779                 return newGroup;
    780             }
    781         }
    782         catch (Exception e)
    783         {
    784             throw new DataBackendException("addGroup(Group) failed", e);
    785         }
    786         finally
    787         {
    788             unlockExclusive();
    789         }
    790         // the only way we could get here without return/throw tirggered
    791         // is that the groupExists was true.
    792         throw new EntityExistsException("Group '" + group + "' already exists");
    793     }
    794
    795     /**
    796      * Creates a new role with specified attributes.
    797      *
    798      * @param role the object describing the role to be created.
    799      * @return a new Role object that has id set up properly.
    800      * @throws DataBackendException if there was an error accessing the data
    801      *         backend.
    802      * @throws EntityExistsException if the role already exists.
    803      */
    804     public synchronized Role addRole(Role role)
    805         throws DataBackendException, EntityExistsException
    806     {
    807         boolean roleExists = false;
    808
    809         if (StringUtils.isEmpty(role.getName()))
    810         {
    811             throw new DataBackendException("Could not create "
    812                                            + "a role with empty name!");
    813         }
    814
    815         try
    816         {
    817             lockExclusive();
    818             roleExists = checkExists(role);
    819             if (!roleExists)
    820             {
    821                 // add a row to the table
    822                 Criteria criteria = RolePeerManager.buildCriteria(role);
    823                 RolePeerManager.doInsert(criteria);
    824                 // try to get the object back using the name as key.
    825                 criteria = new Criteria();
    826                 criteria.add(RolePeerManager.getNameColumn(), role.getName());
    827                 List results = RolePeerManager.doSelect(criteria);
    828                 if (results.size() != 1)
    829                 {
    830                     throw new DataBackendException(
    831                         "Internal error - query returned "
    832                         + results.size() + " rows");
    833                 }
    834                 Role newRole = (Role) results.get(0);
    835                 // add the role to system-wide cache
    836                 getAllRoles().add(newRole);
    837                 // return the object with correct id
    838                 return newRole;
    839             }
    840         }
    841         catch (Exception e)
    842         {
    843             throw new DataBackendException("addRole(Role) failed", e);
    844         }
    845         finally
    846         {
    847             unlockExclusive();
    848         }
    849         // the only way we could get here without return/throw tirggered
    850         // is that the roleExists was true.
    851         throw new EntityExistsException("Role '" + role + "' already exists");
    852     }
    853
    854     /**
    855      * Creates a new permission with specified attributes.
    856      *
    857      * @param permission the object describing the permission to be created.
    858      * @return a new Permission object that has id set up properly.
    859      * @throws DataBackendException if there was an error accessing the data
    860      *         backend.
    861      * @throws EntityExistsException if the permission already exists.
    862      */
    863     public synchronized Permission addPermission(Permission permission)
    864         throws DataBackendException, EntityExistsException
    865     {
    866         boolean permissionExists = false;
    867
    868         if (StringUtils.isEmpty(permission.getName()))
    869         {
    870             throw new DataBackendException("Could not create "
    871                                            + "a permission with empty name!");
    872         }
    873
    874         try
    875         {
    876             lockExclusive();
    877             permissionExists = checkExists(permission);
    878             if (!permissionExists)
    879             {
    880                 // add a row to the table
    881                 Criteria criteria = PermissionPeerManager.buildCriteria(permission);
    882                 PermissionPeerManager.doInsert(criteria);
    883                 // try to get the object back using the name as key.
    884                 criteria = new Criteria();
    885                 criteria.add(PermissionPeerManager.getNameColumn(),
    886                              permission.getName());
    887                 List results = PermissionPeerManager.doSelect(criteria);
    888                 if (results.size() != 1)
    889                 {
    890                     throw new DataBackendException(
    891                         "Internal error - query returned "
    892                         + results.size() + " rows");
    893                 }
    894                 Permission newPermission = (Permission) results.get(0);
    895                 // add the permission to system-wide cache
    896                 getAllPermissions().add(newPermission);
    897                 // return the object with correct id
    898                 return newPermission;
    899             }
    900         }
    901         catch (Exception e)
    902         {
    903             throw new DataBackendException(
    904                 "addPermission(Permission) failed", e);
    905         }
    906         finally
    907         {
    908             unlockExclusive();
    909         }
    910         // the only way we could get here without return/throw tirggered
    911         // is that the permissionExists was true.
    912         throw new EntityExistsException("Permission '" + permission
    913                                         + "' already exists");
    914     }
    915
    916     /**
    917      * Removes a Group from the system.
    918      *
    919      * @param group The object describing the group to be removed.
    920      * @throws DataBackendException if there was an error accessing the data
    921      *         backend.
    922      * @throws UnknownEntityException if the group does not exist.
    923      */
    924     public synchronized void removeGroup(Group group)
    925         throws DataBackendException, UnknownEntityException
    926     {
    927         boolean groupExists = false;
    928         try
    929         {
    930             lockExclusive();
    931             groupExists = checkExists(group);
    932             if (groupExists)
    933             {
    934                 Criteria criteria = GroupPeerManager.buildCriteria(group);
    935                 GroupPeerManager.doDelete(criteria);
    936                 getAllGroups().remove(group);
    937                 return;
    938             }
    939         }
    940         catch (Exception e)
    941         {
    942             log.error("Failed to delete a Group");
    943             log.error(e);
    944             throw new DataBackendException("removeGroup(Group) failed", e);
    945         }
    946         finally
    947         {
    948             unlockExclusive();
    949         }
    950         throw new UnknownEntityException("Unknown group '" + group + "'");
    951     }
    952
    953     /**
    954      * Removes a Role from the system.
    955      *
    956      * @param role The object describing the role to be removed.
    957      * @throws DataBackendException if there was an error accessing the data
    958      *         backend.
    959      * @throws UnknownEntityException if the role does not exist.
    960      */
    961     public synchronized void removeRole(Role role)
    962         throws DataBackendException, UnknownEntityException
    963     {
    964         boolean roleExists = false;
    965         try
    966         {
    967             lockExclusive();
    968             roleExists = checkExists(role);
    969             if (roleExists)
    970             {
    971                 // revoke all permissions from the role to be deleted
    972                 revokeAll(role);
    973                 Criteria criteria = RolePeerManager.buildCriteria(role);
    974                 RolePeerManager.doDelete(criteria);
    975                 getAllRoles().remove(role);
    976                 return;
    977             }
    978         }
    979         catch (Exception e)
    980         {
    981             throw new DataBackendException("removeRole(Role)", e);
    982         }
    983         finally
    984         {
    985             unlockExclusive();
    986         }
    987         throw new UnknownEntityException("Unknown role '" + role + "'");
    988     }
    989
    990     /**
    991      * Removes a Permission from the system.
    992      *
    993      * @param permission The object describing the permission to be removed.
    994      * @throws DataBackendException if there was an error accessing the data
    995      *         backend.
    996      * @throws UnknownEntityException if the permission does not exist.
    997      */
    998     public synchronized void removePermission(Permission permission)
    999         throws DataBackendException, UnknownEntityException
    1000     {
    1001         boolean permissionExists = false;
    1002         try
    1003         {
    1004             lockExclusive();
    1005             permissionExists = checkExists(permission);
    1006             if (permissionExists)
    1007             {
    1008                 Criteria criteria = PermissionPeerManager.buildCriteria(permission);
    1009                 PermissionPeerManager.doDelete(criteria);
    1010                 getAllPermissions().remove(permission);
    1011                 return;
    1012             }
    1013         }
    1014         catch (Exception e)
    1015         {
    1016             throw new DataBackendException("removePermission(Permission)", e);
    1017         }
    1018         finally
    1019         {
    1020             unlockExclusive();
    1021         }
    1022         throw new UnknownEntityException("Unknown permission '"
    1023                                          + permission + "'");
    1024     }
    1025
    1026     /**
    1027      * Renames an existing Group.
    1028      *
    1029      * @param group The object describing the group to be renamed.
    1030      * @param name the new name for the group.
    1031      * @throws DataBackendException if there was an error accessing the data
    1032      *         backend.
    1033      * @throws UnknownEntityException if the group does not exist.
    1034      */
    1035     public synchronized void renameGroup(Group group, String name)
    1036         throws DataBackendException, UnknownEntityException
    1037     {
    1038         boolean groupExists = false;
    1039         try
    1040         {
    1041             lockExclusive();
    1042             groupExists = checkExists(group);
    1043             if (groupExists)
    1044             {
    1045                 group.setName(name);
    1046                 Criteria criteria = GroupPeerManager.buildCriteria(group);
    1047                 GroupPeerManager.doUpdate(criteria);
    1048                 return;
    1049             }
    1050         }
    1051         catch (Exception e)
    1052         {
    1053             throw new DataBackendException("renameGroup(Group,String)", e);
    1054         }
    1055         finally
    1056         {
    1057             unlockExclusive();
    1058         }
    1059         throw new UnknownEntityException("Unknown group '" + group + "'");
    1060     }
    1061
    1062     /**
    1063      * Renames an existing Role.
    1064      *
    1065      * @param role The object describing the role to be renamed.
    1066      * @param name the new name for the role.
    1067      * @throws DataBackendException if there was an error accessing the data
    1068      *         backend.
    1069      * @throws UnknownEntityException if the role does not exist.
    1070      */
    1071     public synchronized void renameRole(Role role, String name)
    1072         throws DataBackendException, UnknownEntityException
    1073     {
    1074         boolean roleExists = false;
    1075         try
    1076         {
    1077             lockExclusive();
    1078             roleExists = checkExists(role);
    1079             if (roleExists)
    1080             {
    1081                 role.setName(name);
    1082                 Criteria criteria = RolePeerManager.buildCriteria(role);
    1083                 RolePeerManager.doUpdate(criteria);
    1084                 return;
    1085             }
    1086         }
    1087         catch (Exception e)
    1088         {
    1089             throw new DataBackendException("renameRole(Role,String)", e);
    1090         }
    1091         finally
    1092         {
    1093             unlockExclusive();
    1094         }
    1095         throw new UnknownEntityException("Unknown role '" + role + "'");
    1096     }
    1097
    1098     /**
    1099      * Renames an existing Permission.
    1100      *
    1101      * @param permission The object describing the permission to be renamed.
    1102      * @param name the new name for the permission.
    1103      * @throws DataBackendException if there was an error accessing the data
    1104      *         backend.
    1105      * @throws UnknownEntityException if the permission does not exist.
    1106      */
    1107     public synchronized void renamePermission(Permission permission,
    1108                                               String name)
    1109         throws DataBackendException, UnknownEntityException
    1110     {
    1111         boolean permissionExists = false;
    1112         try
    1113         {
    1114             lockExclusive();
    1115             permissionExists = checkExists(permission);
    1116             if (permissionExists)
    1117             {
    1118                 permission.setName(name);
    1119                 Criteria criteria = PermissionPeerManager.buildCriteria(permission);
    1120                 PermissionPeerManager.doUpdate(criteria);
    1121                 return;
    1122             }
    1123         }
    1124         catch (Exception e)
    1125         {
    1126             throw new DataBackendException(
    1127                 "renamePermission(Permission,name)", e);
    1128         }
    1129         finally
    1130         {
    1131             unlockExclusive();
    1132         }
    1133         throw new UnknownEntityException("Unknown permission '"
    1134                                          + permission + "'");
    1135     }
    1136
    1137     /* Service specific implementation methods */
    1138
    1139     /**
    1140      * Determines if the <code>Group</code> exists in the security system.
    1141      *
    1142      * @param group a <code>Group</code> value
    1143      * @return true if the group exists in the system, false otherwise
    1144      * @throws DataBackendException when more than one Group with
    1145      *         the same name exists.
    1146      * @throws Exception A generic exception.
    1147      */
    1148     protected boolean checkExists(Group group)
    1149         throws DataBackendException, Exception
    1150     {
    1151         return GroupPeerManager.checkExists(group);
    1152     }
    1153
    1154     /**
    1155      * Determines if the <code>Role</code> exists in the security system.
    1156      *
    1157      * @param role a <code>Role</code> value
    1158      * @return true if the role exists in the system, false otherwise
    1159      * @throws DataBackendException when more than one Role with
    1160      *         the same name exists.
    1161      * @throws Exception A generic exception.
    1162      */
    1163     protected boolean checkExists(Role role)
    1164         throws DataBackendException, Exception
    1165     {
    1166         return RolePeerManager.checkExists(role);
    1167     }
    1168
    1169     /**
    1170      * Determines if the <code>Permission</code> exists in the security system.
    1171      *
    1172      * @param permission a <code>Permission</code> value
    1173      * @return true if the permission exists in the system, false otherwise
    1174      * @throws DataBackendException when more than one Permission with
    1175      *         the same name exists.
    1176      * @throws Exception A generic exception.
    1177      */
    1178     protected boolean checkExists(Permission permission)
    1179         throws DataBackendException, Exception
    1180     {
    1181         return PermissionPeerManager.checkExists(permission);
    1182     }
    1183
    1184
    1185     /**
    1186      * Retrieves all groups defined in the system.
    1187      *
    1188      * @return the names of all groups defined in the system.
    1189      * @throws DataBackendException if there was an error accessing the
    1190      *         data backend.
    1191      */
    1192     public GroupSet getAllGroups() throws DataBackendException
    1193     {
    1194         return getGroups(new Criteria());
    1195     }
    1196
    1197
    1198     /**
    1199      * Retrieves all permissions defined in the system.
    1200      *
    1201      * @return the names of all roles defined in the system.
    1202      * @throws DataBackendException if there was an error accessing the
    1203      *         data backend.
    1204      */
    1205     public PermissionSet getAllPermissions() throws DataBackendException
    1206     {
    1207         return getPermissions(new Criteria());
    1208     }
    1209
    1210
    1211     /**
    1212      * Retrieves all roles defined in the system.
    1213      *
    1214      * @return the names of all roles defined in the system.
    1215      * @throws DataBackendException if there was an error accessing the
    1216      *         data backend.
    1217      */
    1218     public RoleSet getAllRoles() throws DataBackendException
    1219     {
    1220         return getRoles(new Criteria());
    1221     }
    1222
    1223
    1224     /**
    1225      * Retrieve a set of users that meet the specified criteria.
    1226      *
    1227      * As the keys for the criteria, you should use the constants that
    1228      * are defined in {@link User} interface, plus the names
    1229      * of the custom attributes you added to your user representation
    1230      * in the data storage. Use verbatim names of the attributes -
    1231      * without table name prefix in case of Torque implementation.
    1232      *
    1233      * @param criteria The criteria of selection.
    1234      * @return a List of users meeting the criteria.
    1235      * @throws DataBackendException if there is a problem accessing the
    1236      *         storage.
    1237      */
    1238     public List getUserList(Object criteria) throws DataBackendException
    1239     {
    1240         return getUserManager().retrieveList(criteria);
    1241     }
    1242
    1243 }