    001    package org.apache.turbine.services.security.ldap;
    002
    003    /*
    004     * Licensed to the Apache Software Foundation (ASF) under one
    005     * or more contributor license agreements.  See the NOTICE file
    006     * distributed with this work for additional information
    007     * regarding copyright ownership.  The ASF licenses this file
    008     * to you under the Apache License, Version 2.0 (the
    009     * "License"); you may not use this file except in compliance
    010     * with the License.  You may obtain a copy of the License at
    011     *
    012     *   http://www.apache.org/licenses/LICENSE-2.0
    013     *
    014     * Unless required by applicable law or agreed to in writing,
    015     * software distributed under the License is distributed on an
    016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    017     * KIND, either express or implied.  See the License for the
    018     * specific language governing permissions and limitations
    019     * under the License.
    020     */
    021
    022    import java.util.Hashtable;
    023    import java.util.Iterator;
    024    import java.util.List;
    025    import java.util.Vector;
    026    import javax.naming.NameAlreadyBoundException;
    027    import javax.naming.NamingEnumeration;
    028    import javax.naming.NamingException;
    029    import javax.naming.directory.Attribute;
    030    import javax.naming.directory.Attributes;
    031    import javax.naming.directory.BasicAttribute;
    032    import javax.naming.directory.BasicAttributes;
    033    import javax.naming.directory.DirContext;
    034    import javax.naming.directory.SearchControls;
    035    import javax.naming.directory.SearchResult;
    036
    037    import org.apache.commons.logging.Log;
    038    import org.apache.commons.logging.LogFactory;
    039    import org.apache.turbine.om.security.Group;
    040    import org.apache.turbine.om.security.Permission;
    041    import org.apache.turbine.om.security.Role;
    042    import org.apache.turbine.om.security.TurbineGroup;
    043    import org.apache.turbine.om.security.TurbinePermission;
    044    import org.apache.turbine.om.security.TurbineRole;
    045    import org.apache.turbine.om.security.User;
    046    import org.apache.turbine.services.security.BaseSecurityService;
    047    import org.apache.turbine.services.security.TurbineSecurity;
    048    import org.apache.turbine.util.security.AccessControlList;
    049    import org.apache.turbine.util.security.DataBackendException;
    050    import org.apache.turbine.util.security.EntityExistsException;
    051    import org.apache.turbine.util.security.GroupSet;
    052    import org.apache.turbine.util.security.PermissionSet;
    053    import org.apache.turbine.util.security.RoleSet;
    054    import org.apache.turbine.util.security.UnknownEntityException;
    055
    056    /**
    057     * An implementation of SecurityService that uses LDAP as a backend.
    058     *
    059     * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
    060     * @author <a href="mailto:tadewunmi@gluecode.com">Tracy M. Adewunmi </a>
    061     * @author <a href="mailto:lflournoy@gluecode.com">Leonard J. Flournoy </a>
    062     * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
    063     * @author <a href="mailto:marco@intermeta.de">Marco Kn&uuml;ttel</a>
    064     * @author <a href="mailto:hhernandez@itweb.com.mx">Humberto Hernandez</a>
    065     * @version $Id: LDAPSecurityService.java 1096130 2011-04-23 10:37:19Z ludwig $
    066     */
    067    public class LDAPSecurityService extends BaseSecurityService
    068    {
    069
    070        /** Logging */
    071        private static Log log = LogFactory.getLog(LDAPSecurityService.class);
    072
    073        /*
    074         * -----------------------------------------------------------------------
    075         *  C R E A T I O N  O F  A C C E S S  C O N T R O L  L I S T
    076         * -----------------------------------------------------------------------
    077         */
    078
    079        /**
    080         * Constructs an AccessControlList for a specific user.
    081         *
    082         * This method creates a snapshot of the state of security information
    083         * concerning this user, at the moment of invocation and stores it
    084         * into an AccessControlList object.
    085         *
    086         * @param user the user for whom the AccessControlList are to be retrieved
    087         * @throws DataBackendException if there was an error accessing the backend.
    088         * @throws UnknownEntityException if user account is not present.
    089         * @return an AccessControlList for a specific user.
    090         */
    091        public AccessControlList getACL(User user)
    092                throws DataBackendException, UnknownEntityException
    093        {
    094            if (!TurbineSecurity.accountExists(user))
    095            {
    096                throw new UnknownEntityException("The account '"
    097                        + user.getName() + "' does not exist");
    098            }
    099            try
    100            {
    101                Hashtable roles = new Hashtable();
    102                Hashtable permissions = new Hashtable();
    103
    104                // notify the state modifiers (writers) that we want to create
    105                // the snapshot.
    106                lockShared();
    107
    108                // construct the snapshot:
    109                // foreach group in the system
    110                Iterator groupsIterator = getAllGroups().iterator();
    111
    112                while (groupsIterator.hasNext())
    113                {
    114                    Group group = (Group) groupsIterator.next();
    115
    116                    // get roles of user in the group
    117                    RoleSet groupRoles = getRoles(user, group);
    118
    119                    // put the Set into roles(group)
    120                    roles.put(group, groupRoles);
    121                    // collect all permissoins in this group
    122                    PermissionSet groupPermissions = new PermissionSet();
    123                    // foreach role in Set
    124                    Iterator rolesIterator = groupRoles.iterator();
    125
    126                    while (rolesIterator.hasNext())
    127                    {
    128                        Role role = (Role) rolesIterator.next();
    129                        // get permissions of the role
    130                        PermissionSet rolePermissions = getPermissions(role);
    131
    132                        groupPermissions.add(rolePermissions);
    133                    }
    134                    // put the Set into permissions(group)
    135                    permissions.put(group, groupPermissions);
    136                }
    137                return getAclInstance(roles, permissions);
    138            }
    139            catch (Exception e)
    140            {
    141                throw new DataBackendException("Failed to build ACL for user '"
    142                        + user.getName() + "'", e);
    143            }
    144            finally
    145            {
    146                // notify the state modifiers that we are done creating
    147                // the snapshot.
    148                unlockShared();
    149            }
    150        }
    151
    152        /*
    153         * -----------------------------------------------------------------------
    154         * S E C U R I T Y  M A N A G E M E N T
    155         * -----------------------------------------------------------------------
    156         */
    157
    158        /**
    159         * Grant an User a Role in a Group.
    160         *
    161         * @param user the user.
    162         * @param group the group.
    163         * @param role the role.
    164         * @throws DataBackendException if there was an error accessing the backend.
    165         * @throws UnknownEntityException if user account, group or role
    166         *         is not present.
    167         */
    168        public synchronized void grant(User user, Group group, Role role)
    169                throws DataBackendException, UnknownEntityException
    170        {
    171            try
    172            {
    173                lockExclusive();
    174
    175                String userName = user.getName();
    176                String roleName = role.getName();
    177                String groupName = group.getName();
    178
    179                if (!accountExists(user))
    180                {
    181                    throw new UnknownEntityException(
    182                            "User '" + userName + "' does not exist");
    183                }
    184
    185                if (!checkExists(role))
    186                {
    187                    throw new UnknownEntityException(
    188                            "Role '" + roleName + "' does not exist");
    189                }
    190
    191                if (!checkExists(group))
    192                {
    193                    throw new UnknownEntityException(
    194                            "Group '" + groupName + "' does not exist");
    195                }
    196
    197                // Make the distinguished name.
    198                String dn = "turbineGroupName=" + groupName + ","
    199                        + LDAPSecurityConstants.getNameAttribute()
    200                        + "=" + userName + ","
    201                        + LDAPSecurityConstants.getBaseSearch();
    202
    203
    204                // Connect to LDAP.
    205                DirContext ctx = LDAPUserManager.bindAsAdmin();
    206
    207                // Make the attributes.
    208                Attributes attrs = new BasicAttributes();
    209
    210                attrs.put(new BasicAttribute("turbineRoleName", roleName));
    211                attrs.put(new BasicAttribute("objectClass", "turbineUserGroup"));
    212                attrs.put(new BasicAttribute("turbineUserUniqueId", userName));
    213                try
    214                {
    215                    // Add the turbineUserGroup.
    216                    ctx.bind(dn, null, attrs);
    217                }
    218                catch (NameAlreadyBoundException ex)
    219                {
    220                    // Since turbineUserGroup had already been created
    221                    // then just add the role name attribute.
    222                    attrs = new BasicAttributes();
    223                    attrs.put(new BasicAttribute("turbineRoleName", roleName));
    224                    ctx.modifyAttributes(dn, DirContext.ADD_ATTRIBUTE, attrs);
    225                }
    226
    227            }
    228            catch (NamingException ex)
    229            {
    230                throw new DataBackendException("NamingException caught", ex);
    231            }
    232            finally
    233            {
    234                unlockExclusive();
    235            }
    236        }
    237
    238        /**
    239         * Revoke a Role in a Group from an User.
    240         *
    241         * @param user the user.
    242         * @param group the group.
    243         * @param role the role.
    244         * @throws DataBackendException if there was an error accessing the backend.
    245         * @throws UnknownEntityException if user account, group or role is
    246         *         not present.
    247         */
    248        public synchronized void revoke(User user, Group group, Role role)
    249                throws DataBackendException, UnknownEntityException
    250        {
    251            try
    252            {
    253                lockExclusive();
    254
    255                String userName = user.getName();
    256                String roleName = role.getName();
    257                String groupName = group.getName();
    258
    259                if (!accountExists(user))
    260                {
    261                    throw new UnknownEntityException(
    262                            "User '" + userName + "' does not exist");
    263                }
    264
    265                if (!checkExists(role))
    266                {
    267                    throw new UnknownEntityException(
    268                            "Role '" + roleName + "' does not exist");
    269                }
    270
    271                if (!checkExists(group))
    272                {
    273                    throw new UnknownEntityException(
    274                            "Group '" + groupName + "' does not exist");
    275                }
    276
    277                // Make the distinguished name.
    278                String dn = "turbineGroupName=" + groupName + ","
    279                        + LDAPSecurityConstants.getNameAttribute()
    280                        + "=" + userName + ","
    281                        + LDAPSecurityConstants.getBaseSearch();
    282
    283                // Make the attributes.
    284                Attributes attrs = new BasicAttributes();
    285
    286                attrs.put(new BasicAttribute("turbineRoleName", roleName));
    287
    288                // Connect to LDAP.
    289                DirContext ctx = LDAPUserManager.bindAsAdmin();
    290
    291                // Remove the role.
    292                ctx.modifyAttributes(dn, DirContext.REMOVE_ATTRIBUTE, attrs);
    293
    294            }
    295            catch (NamingException ex)
    296            {
    297                throw new DataBackendException("NamingException caught", ex);
    298            }
    299            finally
    300            {
    301                unlockExclusive();
    302            }
    303        }
    304
    305        /**
    306         * Grants a Role a Permission
    307         *
    308         * @param role the Role.
    309         * @param permission the Permission.
    310         * @throws DataBackendException if there was an error accessing the backend.
    311         * @throws UnknownEntityException if role or permission is not present.
    312         */
    313        public synchronized void grant(Role role, Permission permission)
    314                throws DataBackendException, UnknownEntityException
    315        {
    316            try
    317            {
    318                lockExclusive();
    319
    320                String roleName = role.getName();
    321                String permName = permission.getName();
    322
    323                if (!checkExists(role))
    324                {
    325                    throw new UnknownEntityException(
    326                            "Role '" + roleName + "' does not exist");
    327                }
    328
    329                if (!checkExists(permission))
    330                {
    331                    throw new UnknownEntityException(
    332                            "Permission '" + permName + "' does not exist");
    333                }
    334
    335                // Make the distinguished name.
    336                String dn = "turbineRoleName=" + roleName + ","
    337                        + LDAPSecurityConstants.getBaseSearch();
    338
    339                // Make the attributes.
    340                Attributes attrs = new BasicAttributes();
    341
    342                attrs.put(new BasicAttribute("turbinePermissionName", permName));
    343
    344                // Connect to LDAP.
    345                DirContext ctx = LDAPUserManager.bindAsAdmin();
    346
    347                // Add the permission.
    348                ctx.modifyAttributes(dn, DirContext.ADD_ATTRIBUTE, attrs);
    349
    350            }
    351            catch (NamingException ex)
    352            {
    353                throw new DataBackendException("NamingException caught", ex);
    354            }
    355            finally
    356            {
    357                unlockExclusive();
    358            }
    359        }
    360
    361        /**
    362         * Revokes a Permission from a Role.
    363         *
    364         * @param role the Role.
    365         * @param permission the Permission.
    366         * @throws DataBackendException if there was an error accessing the backend.
    367         * @throws UnknownEntityException if role or permission is not present.
    368         */
    369        public synchronized void revoke(Role role, Permission permission)
    370                throws DataBackendException, UnknownEntityException
    371        {
    372            try
    373            {
    374                lockExclusive();
    375
    376                String roleName = role.getName();
    377                String permName = permission.getName();
    378
    379                if (!checkExists(role))
    380                {
    381                    throw new UnknownEntityException(
    382                            "Role '" + roleName + "' does not exist");
    383                }
    384
    385                if (!checkExists(permission))
    386                {
    387                    throw new UnknownEntityException(
    388                            "Permission '" + permName + "' does not exist");
    389                }
    390
    391                // Make the distinguished name.
    392                String dn = "turbineRoleName=" + roleName + ","
    393                        + LDAPSecurityConstants.getBaseSearch();
    394
    395                // Make the attributes.
    396                Attributes attrs = new BasicAttributes();
    397
    398                attrs.put(new BasicAttribute("turbinePermissionName", permName));
    399
    400                // Connect to LDAP.
    401                DirContext ctx = LDAPUserManager.bindAsAdmin();
    402
    403                // Remove the permission.
    404                ctx.modifyAttributes(dn, DirContext.REMOVE_ATTRIBUTE, attrs);
    405
    406            }
    407            catch (NamingException ex)
    408            {
    409                throw new DataBackendException("NamingException caught", ex);
    410            }
    411            finally
    412            {
    413                unlockExclusive();
    414            }
    415        }
    416
    417        /*
    418         * -----------------------------------------------------------------------
    419         * G R O U P / R O L E / P E R M I S S I O N  M A N A G E M E N T
    420         * -----------------------------------------------------------------------
    421         */
    422
    423        /**
    424         * Retrieves a new Group. It creates
    425         * a new Group based on the Services Group implementation. It does not
    426         * create a new Group in the system though. Use addGroup for that.
    427         * <strong>Not implemented</strong>
    428         *
    429         * @param groupName The name of the Group to be retrieved.
    430         * @return a Group.
    431         */
    432        public Group getNewGroup(String groupName)
    433        {
    434            return (Group) new TurbineGroup(groupName);
    435        }
    436
    437        /**
    438         * Retrieves a new Role. It creates
    439         * a new Role based on the Services Role implementation. It does not
    440         * create a new Role in the system though. Use addRole for that.
    441         * <strong>Not implemented</strong>
    442         *
    443         * @param roleName The name of the Group to be retrieved.
    444         * @return a Role.
    445         */
    446        public Role getNewRole(String roleName)
    447        {
    448            return (Role) new TurbineRole(roleName);
    449        }
    450
    451        /**
    452         * Retrieves a new Permission. It creates
    453         * a new Permission based on the Services Permission implementation. It
    454         * does not create a new Permission in the system though. Use create for
    455         * that.
    456         * <strong>Not implemented</strong>
    457         *
    458         * @param permissionName The name of the Permission to be retrieved.
    459         * @return a Permission
    460         */
    461        public Permission getNewPermission(String permissionName)
    462        {
    463            return (Permission) new TurbinePermission(permissionName);
    464        }
    465
    466        /**
    467         * Retrieve a set of Groups that meet the specified Criteria.
    468         *
    469         * @param criteria Criteria of Group selection.
    470         * @return a set of Groups that meet the specified Criteria.
    471         * @throws DataBackendException if there is problem with the Backend.
    472         */
    473        public GroupSet getGroups(Object criteria)
    474                throws DataBackendException
    475        {
    476            Vector groups = new Vector();
    477
    478            try
    479            {
    480                DirContext ctx = LDAPUserManager.bindAsAdmin();
    481
    482                String baseSearch = LDAPSecurityConstants.getBaseSearch();
    483                String filter = "(objectclass=turbineGroup)";
    484
    485                /*
    486                 * Create the default search controls.
    487                 */
    488                SearchControls ctls = new SearchControls();
    489
    490                NamingEnumeration answer = ctx.search(baseSearch, filter, ctls);
    491
    492                while (answer.hasMore())
    493                {
    494                    SearchResult sr = (SearchResult) answer.next();
    495                    Attributes attribs = sr.getAttributes();
    496                    Attribute attr = attribs.get("turbineGroupName");
    497
    498                    if (attr != null && attr.get() != null)
    499                    {
    500                        Group group = getNewGroup(attr.get().toString());
    501
    502                        groups.add(group);
    503                    }
    504                }
    505            }
    506            catch (NamingException ex)
    507            {
    508                throw new DataBackendException("NamingException caught", ex);
    509            }
    510            return new GroupSet(groups);
    511        }
    512
    513        /** Get the Roles that a user belongs in a specific group.
    514         * @param user The user.
    515         * @param group The group
    516         * @throws DataBackendException if there is a problem with
    517         *     the LDAP service.
    518         * @return a RoleSet.
    519         */
    520        private RoleSet getRoles(User user, Group group)
    521                throws DataBackendException
    522        {
    523            Vector roles = new Vector(0);
    524
    525            try
    526            {
    527                DirContext ctx = LDAPUserManager.bindAsAdmin();
    528
    529                String baseSearch = LDAPSecurityConstants.getBaseSearch();
    530                String filter = "(& ";
    531
    532                filter += "(objectclass=turbineUserGroup)";
    533                filter += "(turbineUserUniqueId=" + user.getName() + ")";
    534                filter += "(turbineGroupName=" + group.getName() + ")";
    535                filter += ")";
    536
    537                /*
    538                 * Create the default search controls.
    539                 */
    540                SearchControls ctls = new SearchControls();
    541
    542                ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    543
    544                NamingEnumeration answer = ctx.search(baseSearch, filter, ctls);
    545
    546                while (answer.hasMore())
    547                {
    548                    SearchResult sr = (SearchResult) answer.next();
    549                    Attributes attribs = sr.getAttributes();
    550                    Attribute attr = attribs.get("turbineRoleName");
    551
    552                    if (attr != null)
    553                    {
    554                        NamingEnumeration values = attr.getAll();
    555
    556                        while (values.hasMore())
    557                        {
    558                            Role role = getNewRole(values.next().toString());
    559
    560                            roles.add(role);
    561                        }
    562                    }
    563                    else
    564                    {
    565                        log.error("Role doesn't have a name");
    566                    }
    567                }
    568            }
    569            catch (NamingException ex)
    570            {
    571                throw new DataBackendException(
    572                        "NamingException caught:", ex);
    573            }
    574
    575            return new RoleSet(roles);
    576        }
    577
    578        /**
    579         * Retrieve a set of Roles that meet the specified Criteria.
    580         *
    581         * @param criteria Criteria of Roles selection.
    582         * @return a set of Roles that meet the specified Criteria.
    583         * @throws DataBackendException if there is a problem with the Backend.
    584         */
    585        public RoleSet getRoles(Object criteria) throws DataBackendException
    586        {
    587            Vector roles = new Vector(0);
    588
    589            try
    590            {
    591                DirContext ctx = LDAPUserManager.bindAsAdmin();
    592
    593                String baseSearch = LDAPSecurityConstants.getBaseSearch();
    594                String filter = "(objectclass=turbineRole)";
    595
    596                /*
    597                 * Create the default search controls.
    598                 */
    599                SearchControls ctls = new SearchControls();
    600
    601                NamingEnumeration answer = ctx.search(baseSearch, filter, ctls);
    602
    603                while (answer.hasMore())
    604                {
    605                    SearchResult sr = (SearchResult) answer.next();
    606                    Attributes attribs = sr.getAttributes();
    607                    Attribute attr = attribs.get("turbineRoleName");
    608
    609                    if (attr != null && attr.get() != null)
    610                    {
    611                        Role role = getNewRole(attr.get().toString());
    612
    613                        roles.add(role);
    614                    }
    615                    else
    616                    {
    617                        log.error("Role doesn't have a name");
    618                    }
    619                }
    620            }
    621            catch (NamingException ex)
    622            {
    623                throw new DataBackendException("NamingException caught", ex);
    624            }
    625
    626            return new RoleSet(roles);
    627        }
    628
    629        /**
    630         * Retrieve a set of Permissions that meet the specified Criteria.
    631         *
    632         * @param criteria Criteria of Permissions selection.
    633         * @return a set of Permissions that meet the specified Criteria.
    634         * @throws DataBackendException if there is a problem with the Backend.
    635         */
    636        public PermissionSet getPermissions(Object criteria)
    637                throws DataBackendException
    638        {
    639            Vector permissions = new Vector();
    640
    641            try
    642            {
    643                DirContext ctx = LDAPUserManager.bindAsAdmin();
    644
    645                String baseSearch = LDAPSecurityConstants.getBaseSearch();
    646                String filter = "(objectClass=turbinePermission)";
    647
    648                /*
    649                 * Create the default search controls.
    650                 */
    651                SearchControls ctls = new SearchControls();
    652
    653                NamingEnumeration answer = ctx.search(baseSearch, filter, ctls);
    654
    655                while (answer.hasMore())
    656                {
    657                    SearchResult sr = (SearchResult) answer.next();
    658                    Attributes attribs = sr.getAttributes();
    659                    Attribute attr = attribs.get("turbinePermissionName");
    660
    661                    if (attr != null && attr.get() != null)
    662                    {
    663                        Permission perm = getNewPermission(attr.get().toString());
    664
    665                        permissions.add(perm);
    666                    }
    667                    else
    668                    {
    669                        log.error("Permission doesn't have a name");
    670                    }
    671                }
    672            }
    673            catch (NamingException ex)
    674            {
    675                throw new DataBackendException(
    676                        "The LDAP server specified is unavailable", ex);
    677            }
    678            return new PermissionSet(permissions);
    679        }
    680
    681        /**
    682         * Retrieves all permissions associated with a role.
    683         *
    684         * @param role the role name, for which the permissions are to be retrieved.
    685         * @throws DataBackendException if there was an error accessing the backend.
    686         * @throws UnknownEntityException if the role is not present.
    687         * @return a PermissionSet.
    688         */
    689        public PermissionSet getPermissions(Role role)
    690                throws DataBackendException, UnknownEntityException
    691        {
    692            Hashtable permissions = new Hashtable();
    693
    694            try
    695            {
    696                DirContext ctx = LDAPUserManager.bindAsAdmin();
    697
    698                String baseSearch = LDAPSecurityConstants.getBaseSearch();
    699                String filter = "(& ";
    700
    701                filter += "(objectClass=turbineRole)";
    702                filter += "(turbineRoleName=" + role.getName() + ")";
    703                filter += ")";
    704
    705                /*
    706                 * Create the default search controls.
    707                 */
    708                SearchControls ctls = new SearchControls();
    709
    710                NamingEnumeration answer = ctx.search(baseSearch, filter, ctls);
    711
    712                while (answer.hasMore())
    713                {
    714                    SearchResult sr = (SearchResult) answer.next();
    715                    Attributes attribs = sr.getAttributes();
    716                    Attribute attr = attribs.get("turbinePermissionName");
    717
    718                    if (attr != null)
    719                    {
    720                        NamingEnumeration values = attr.getAll();
    721
    722                        while (values.hasMore())
    723                        {
    724                            String permName = values.next().toString();
    725                            Permission perm = getNewPermission(permName);
    726
    727                            permissions.put(perm.getName(), perm);
    728                        }
    729                    }
    730                }
    731            }
    732            catch (NamingException ex)
    733            {
    734                throw new DataBackendException(
    735                        "The LDAP server specified is unavailable", ex);
    736            }
    737            return new PermissionSet(permissions.values());
    738        }
    739
    740        /**
    741         * Stores Group's attributes. The Groups is required to exist in the system.
    742         *
    743         * @param group The Group to be stored.
    744         * @throws DataBackendException if there was an error accessing the backend.
    745         * @throws UnknownEntityException if the group does not exist.
    746         */
    747        public void saveGroup(Group group) throws DataBackendException,
    748                UnknownEntityException
    749        {
    750            // Not implemented yet.
    751        }
    752
    753        /**
    754         * Stores Role's attributes. The Roles is required to exist in the system.
    755         *
    756         * @param role The Role to be stored.
    757         * @throws DataBackendException if there was an error accessing the backend.
    758         * @throws UnknownEntityException if the role does not exist.
    759         */
    760        public void saveRole(Role role) throws DataBackendException,
    761                UnknownEntityException
    762        {
    763            // Not implemented yet.
    764        }
    765
    766        /**
    767         * Stores Permission's attributes. The Permissions is required to exist in
    768         * the system.
    769         *
    770         * @param permission The Permission to be stored.
    771         * @throws DataBackendException if there was an error accessing the backend.
    772         * @throws UnknownEntityException if the permission does not exist.
    773         */
    774        public void savePermission(Permission permission)
    775                throws DataBackendException, UnknownEntityException
    776        {
    777            // Not implemented yet.
    778        }
    779
    780        /**
    781         * Creates a new group with specified attributes.
    782         * <strong>Not implemented</strong>
    783         *
    784         * @param group the object describing the group to be created.
    785         * @return a new Group object that has id set up properly.
    786         * @throws DataBackendException if there was an error accessing the backend.
    787         * @throws EntityExistsException if the group already exists.
    788         */
    789        public synchronized Group addGroup(Group group)
    790                throws DataBackendException, EntityExistsException
    791        {
    792            try
    793            {
    794                lockExclusive();
    795
    796                String groupName = group.getName();
    797
    798                if (checkExists(group))
    799                {
    800                    throw new EntityExistsException(
    801                            "Group '" + groupName + "' already exists");
    802                }
    803
    804                // Make the distinguished name.
    805                String dn = "turbineGroupName=" + groupName + ","
    806                        + LDAPSecurityConstants.getBaseSearch();
    807
    808                // Make the attributes.
    809                Attributes attrs = new BasicAttributes();
    810
    811                attrs.put(new BasicAttribute("objectClass", "turbineGroup"));
    812                attrs.put(new BasicAttribute("turbineGroupName", groupName));
    813
    814                // Connect to LDAP.
    815                DirContext ctx = LDAPUserManager.bindAsAdmin();
    816
    817                // Add the group in LDAP.
    818                ctx.bind(dn, null, attrs);
    819
    820                // Add the group to system-wide cache.
    821                getAllGroups().add(group);
    822
    823                return group;
    824            }
    825            catch (NamingException ex)
    826            {
    827                throw new DataBackendException("NamingException caught", ex);
    828            }
    829            finally
    830            {
    831                unlockExclusive();
    832            }
    833        }
    834
    835        /**
    836         * Creates a new role with specified attributes.
    837         *
    838         * @param role the object describing the role to be created.
    839         * @return a new Role object that has id set up properly.
    840         * @throws DataBackendException if there was an error accessing the backend.
    841         * @throws EntityExistsException if the role already exists.
    842         */
    843        public synchronized Role addRole(Role role)
    844                throws DataBackendException, EntityExistsException
    845        {
    846            try
    847            {
    848                lockExclusive();
    849
    850                String roleName = role.getName();
    851
    852                if (checkExists(role))
    853                {
    854                    throw new EntityExistsException(
    855                            "Role '" + roleName + "' already exists");
    856                }
    857
    858                // Make the distinguished name.
    859                String dn = "turbineRoleName=" + roleName + ","
    860                        + LDAPSecurityConstants.getBaseSearch();
    861
    862                // Make the attributes.
    863                Attributes attrs = new BasicAttributes();
    864
    865                attrs.put(new BasicAttribute("objectClass", "turbineRole"));
    866                attrs.put(new BasicAttribute("turbineRoleName", roleName));
    867
    868                // Connect to LDAP.
    869                DirContext ctx = LDAPUserManager.bindAsAdmin();
    870
    871                // Add the role in LDAP.
    872                ctx.bind(dn, null, attrs);
    873
    874                // Add the role to system-wide cache.
    875                getAllRoles().add(role);
    876
    877                return role;
    878            }
    879            catch (NamingException ex)
    880            {
    881                throw new DataBackendException("NamingException caught", ex);
    882            }
    883            finally
    884            {
    885                unlockExclusive();
    886            }
    887        }
    888
    889        /**
    890         * Creates a new permission with specified attributes.
    891         * <strong>Not implemented</strong>
    892         *
    893         * @param permission the object describing the permission to be created.
    894         * @return a new Permission object that has id set up properly.
    895         * @throws DataBackendException if there was an error accessing the backend.
    896         * @throws EntityExistsException if the permission already exists.
    897         */
    898        public synchronized Permission addPermission(Permission permission)
    899                throws DataBackendException, EntityExistsException
    900        {
    901            try
    902            {
    903                lockExclusive();
    904
    905                String permName = permission.getName();
    906
    907                if (checkExists(permission))
    908                {
    909                    throw new EntityExistsException(
    910                            "Permission '" + permName + "' already exists");
    911                }
    912
    913                // Make the distinguished name.
    914                String dn = "turbinePermissionName=" + permName + ","
    915                        + LDAPSecurityConstants.getBaseSearch();
    916
    917                // Make the attributes.
    918                Attributes attrs = new BasicAttributes();
    919
    920                attrs.put(new BasicAttribute("objectClass", "turbinePermission"));
    921                attrs.put(new BasicAttribute("turbinePermissionName", permName));
    922
    923                DirContext ctx = LDAPUserManager.bindAsAdmin();
    924
    925                // Add the permission in LDAP.
    926                ctx.bind(dn, null, attrs);
    927
    928                // add the permission to system-wide cache
    929                getAllPermissions().add(permission);
    930
    931                return permission;
    932            }
    933            catch (NamingException ex)
    934            {
    935                throw new DataBackendException("NamingException caught", ex);
    936            }
    937            finally
    938            {
    939                unlockExclusive();
    940            }
    941        }
    942
    943        /**
    944         * Removes a Group from the system.
    945         *
    946         * @param group object describing group to be removed.
    947         * @throws DataBackendException if there was an error accessing the backend.
    948         * @throws UnknownEntityException if the group does not exist.
    949         */
    950        public synchronized void removeGroup(Group group)
    951                throws DataBackendException, UnknownEntityException
    952        {
    953            try
    954            {
    955                lockExclusive();
    956
    957                String groupName = group.getName();
    958
    959                if (!checkExists(group))
    960                {
    961                    throw new UnknownEntityException(
    962                            "Group '" + groupName + "' does not exist");
    963                }
    964
    965                // Make the distinguished name.
    966                String dn = "turbineGroupName=" + groupName + ","
    967                        + LDAPSecurityConstants.getBaseSearch();
    968
    969                DirContext ctx = LDAPUserManager.bindAsAdmin();
    970
    971                // Remove the group from LDAP.
    972                ctx.unbind(dn);
    973
    974                // Remove the group from system-wide cache.
    975                getAllGroups().remove(group);
    976            }
    977            catch (NamingException ex)
    978            {
    979                throw new DataBackendException("NamingException caught", ex);
    980            }
    981            finally
    982            {
    983                unlockExclusive();
    984            }
    985        }
    986
    987        /**
    988         * Removes a Role from the system.
    989         *
    990         * @param role object describing role to be removed.
    991         * @throws DataBackendException if there was an error accessing the backend.
    992         * @throws UnknownEntityException if the role does not exist.
    993         */
    994        public synchronized void removeRole(Role role)
    995                throws DataBackendException, UnknownEntityException
    996        {
    997            try
    998            {
    999                lockExclusive();
    1000
    1001                String roleName = role.getName();
    1002
    1003                if (!checkExists(role))
    1004                {
    1005                    throw new UnknownEntityException(
    1006                            "Role '" + roleName + "' does not exist");
    1007                }
    1008
    1009                // Make the distinguished name.
    1010                String dn = "turbineRoleName=" + roleName + ","
    1011                        + LDAPSecurityConstants.getBaseSearch();
    1012
    1013                DirContext ctx = LDAPUserManager.bindAsAdmin();
    1014
    1015                // Remove the role from LDAP.
    1016                ctx.unbind(dn);
    1017
    1018                // Remove the role from system-wide cache.
    1019                getAllRoles().remove(role);
    1020            }
    1021            catch (NamingException ex)
    1022            {
    1023                throw new DataBackendException("NamingException caught", ex);
    1024            }
    1025            finally
    1026            {
    1027                unlockExclusive();
    1028            }
    1029        }
    1030
    1031        /**
    1032         * Removes a Permission from the system.
    1033         *
    1034         * @param permission object describing permission to be removed.
    1035         * @throws DataBackendException if there was an error accessing the backend.
    1036         * @throws UnknownEntityException if the permission does not exist.
    1037         */
    1038        public synchronized void removePermission(Permission permission)
    1039                throws DataBackendException, UnknownEntityException
    1040        {
    1041            try
    1042            {
    1043                lockExclusive();
    1044
    1045                String permName = permission.getName();
    1046
    1047                if (!checkExists(permission))
    1048                {
    1049                    throw new UnknownEntityException(
    1050                            "Permission '" + permName + "' does not exist");
    1051                }
    1052
    1053                // Make the distinguished name.
    1054                String dn = "turbinePermissionName=" + permName + ","
    1055                        + LDAPSecurityConstants.getBaseSearch();
    1056
    1057                DirContext ctx = LDAPUserManager.bindAsAdmin();
    1058
    1059                // Remove the permission in LDAP.
    1060                ctx.unbind(dn);
    1061
    1062                // Remove the permission from system-wide cache.
    1063                getAllPermissions().remove(permission);
    1064            }
    1065            catch (NamingException ex)
    1066            {
    1067                throw new DataBackendException("NamingException caught", ex);
    1068            }
    1069            finally
    1070            {
    1071                unlockExclusive();
    1072            }
    1073        }
    1074
    1075        /**
    1076         * Renames an existing Group.
    1077         *
    1078         * @param group object describing the group to be renamed.
    1079         * @param name the new name for the group.
    1080         * @throws DataBackendException if there was an error accessing the backend.
    1081         * @throws UnknownEntityException if the group does not exist.
    1082         */
    1083        public synchronized void renameGroup(Group group, String name)
    1084                throws DataBackendException, UnknownEntityException
    1085        {
    1086            // Not implemented yet.
    1087        }
    1088
    1089        /**
    1090         * Renames an existing Role.
    1091         *
    1092         * @param role object describing the role to be renamed.
    1093         * @param name the new name for the role.
    1094         * @throws DataBackendException if there was an error accessing the backend.
    1095         * @throws UnknownEntityException if the role does not exist.
    1096         */
    1097        public synchronized void renameRole(Role role, String name)
    1098                throws DataBackendException, UnknownEntityException
    1099        {
    1100            // Not implemented yet.
    1101        }
    1102
    1103        /**
    1104         * Renames an existing Permission.
    1105         *
    1106         * @param permission object describing the permission to be renamed.
    1107         * @param name the new name for the permission.
    1108         * @throws DataBackendException if there was an error accessing the backend.
    1109         * @throws UnknownEntityException if the permission does not exist.
    1110         */
    1111        public synchronized void renamePermission(Permission permission,
    1112                                                  String name)
    1113                throws DataBackendException, UnknownEntityException
    1114        {
    1115            // Not implemented yet.
    1116        }
    1117
    1118        /**
    1119         * Revoke all the roles to a user
    1120         * @param user the user.
    1121         * @throws DataBackendException if there is an error with the data backend.
    1122         * @throws UnkownEntityException if the role or a permission is not found.
    1123         */
    1124        public void revokeAll(User user)
    1125                throws DataBackendException, UnknownEntityException
    1126        {
    1127            Iterator groupsIterator = getAllGroups().iterator();
    1128            while (groupsIterator.hasNext())
    1129            {
    1130                Group group = (Group) groupsIterator.next();
    1131                Iterator rolesIterator = getRoles(user, group).iterator();
    1132                while (rolesIterator.hasNext())
    1133                {
    1134                    Role role = (Role) rolesIterator.next();
    1135                    revoke(user, group, role);
    1136                }
    1137            }
    1138        }
    1139
    1140        /**
    1141         * Revoke all the permissions to a role.
    1142         * @param role the role.
    1143         * @throws DataBackendException if there is an error with the data backend.
    1144         * @throws UnkownEntityException if the role or a permission is not found.
    1145         */
    1146        public void revokeAll(Role role)
    1147                throws DataBackendException, UnknownEntityException
    1148        {
    1149            PermissionSet permissions = getPermissions(role);
    1150            Iterator permIterator = permissions.iterator();
    1151            while (permIterator.hasNext())
    1152            {
    1153                Permission perm = (Permission) permIterator.next();
    1154                revoke(role, perm);
    1155            }
    1156        }
    1157
    1158        /**
    1159         * Revoke all the roles to a group.
    1160         * @param group the group.
    1161         * @throws DataBackendException if there is an error with the data backend.
    1162         * @throws UnkownEntityException if the role or a permission is not found.
    1163         */
    1164        public void revokeAll(Group group)
    1165                throws DataBackendException, UnknownEntityException
    1166        {
    1167            for (Iterator it = getUserList(new Object()).iterator();
    1168                 it.hasNext();)
    1169            {
    1170                User user = (User) it.next();
    1171                for (Iterator rolesIterator = getRoles(user, group).iterator();
    1172                     rolesIterator.hasNext();)
    1173                {
    1174                    Role role = (Role) rolesIterator.next();
    1175                    revoke(user, group, role);
    1176                }
    1177            }
    1178        }
    1179
    1180        /**
    1181         * Determines if the <code>Role</code> exists in the security system.
    1182         *
    1183         * @param role a <code>Role</code> value
    1184         * @return true if the role exists in the system, false otherwise
    1185         * @throws DataBackendException if there is an error with LDAP
    1186         */
    1187        public boolean checkExists(Role role)
    1188                throws DataBackendException
    1189        {
    1190            RoleSet roleSet = getRoles(new Object());
    1191
    1192            return roleSet.contains(role);
    1193        }
    1194
    1195        /**
    1196         * Determines if the <code>Group</code> exists in the security system.
    1197         *
    1198         * @param group a <code>Group</code> value
    1199         * @return true if the group exists in the system, false otherwise
    1200         * @throws DataBackendException if there is an error with LDAP
    1201         */
    1202        public boolean checkExists(Group group)
    1203                throws DataBackendException
    1204        {
    1205            GroupSet groupSet = getGroups(new Object());
    1206
    1207            return groupSet.contains(group);
    1208        }
    1209
    1210        /**
    1211         * Determines if the <code>Permission</code> exists in the security system.
    1212         *
    1213         * @param permission a <code>Permission</code> value
    1214         * @return true if the permission exists in the system, false otherwise
    1215         * @throws DataBackendException if there is an error with LDAP
    1216         */
    1217        public boolean checkExists(Permission permission)
    1218                throws DataBackendException
    1219        {
    1220            PermissionSet permissionSet = getPermissions(new Object());
    1221
    1222            return permissionSet.contains(permission);
    1223        }
    1224
    1225
    1226        /* (non-Javadoc)
    1227         * @see org.apache.turbine.services.security.SecurityService#getAllGroups()
    1228         */
    1229        public GroupSet getAllGroups() throws DataBackendException {
    1230            // TODO Auto-generated method stub
    1231            return null;
    1232        }
    1233        /* (non-Javadoc)
    1234         * @see org.apache.turbine.services.security.SecurityService#getAllPermissions()
    1235         */
    1236        public PermissionSet getAllPermissions() throws DataBackendException {
    1237            // TODO Auto-generated method stub
    1238            return null;
    1239        }
    1240        /* (non-Javadoc)
    1241         * @see org.apache.turbine.services.security.SecurityService#getAllRoles()
    1242         */
    1243        public RoleSet getAllRoles() throws DataBackendException {
    1244            // TODO Auto-generated method stub
    1245            return null;
    1246        }
    1247        /* (non-Javadoc)
    1248         * @see org.apache.turbine.services.security.SecurityService#getUserList(java.lang.Object)
    1249         */
    1250        public List getUserList(Object criteria) throws DataBackendException {
    1251            // TODO Auto-generated method stub
    1252            return null;
    1253        }
    1254    }