    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/security/drm/SecurityAccess.java $
    002    /*----------------------------------------------------------------------------
    003     This file is part of deegree, http://deegree.org/
    004     Copyright (C) 2001-2009 by:
    005       Department of Geography, University of Bonn
    006     and
    007       lat/lon GmbH
    008
    009     This library is free software; you can redistribute it and/or modify it under
    010     the terms of the GNU Lesser General Public License as published by the Free
    011     Software Foundation; either version 2.1 of the License, or (at your option)
    012     any later version.
    013     This library is distributed in the hope that it will be useful, but WITHOUT
    014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
    016     details.
    017     You should have received a copy of the GNU Lesser General Public License
    018     along with this library; if not, write to the Free Software Foundation, Inc.,
    019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    020
    021     Contact information:
    022
    023     lat/lon GmbH
    024     Aennchenstr. 19, 53177 Bonn
    025     Germany
    026     http://lat-lon.de/
    027
    028     Department of Geography, University of Bonn
    029     Prof. Dr. Klaus Greve
    030     Postfach 1147, 53001 Bonn
    031     Germany
    032     http://www.geographie.uni-bonn.de/deegree/
    033
    034     e-mail: info@deegree.org
    035    ----------------------------------------------------------------------------*/
    036    package org.deegree.security.drm;
    037
    038    import java.util.HashSet;
    039    import java.util.Iterator;
    040    import java.util.LinkedList;
    041    import java.util.Stack;
    042
    043    import org.deegree.security.GeneralSecurityException;
    044    import org.deegree.security.UnauthorizedException;
    045    import org.deegree.security.drm.model.Group;
    046    import org.deegree.security.drm.model.Privilege;
    047    import org.deegree.security.drm.model.RightType;
    048    import org.deegree.security.drm.model.Role;
    049    import org.deegree.security.drm.model.SecurableObject;
    050    import org.deegree.security.drm.model.SecuredObject;
    051    import org.deegree.security.drm.model.Service;
    052    import org.deegree.security.drm.model.User;
    053
    054    /**
    055     *
    056     *
    057     *
    058     * @version $Revision: 18195 $
    059     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
    060     * @author last edited by: $Author: mschneider $
    061     *
    062     * @version 1.0. $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
    063     *
    064     * @since 2.0
    065     */
    066    public class SecurityAccess {
    067
    068        protected User user;
    069
    070        protected SecurityRegistry registry;
    071
    072        SecurityAccess( User user, SecurityRegistry registry ) {
    073            this.user = user;
    074            this.registry = registry;
    075        }
    076
    077        /**
    078         * @return probably the admin user
    079         */
    080        public User getUser() {
    081            return user;
    082        }
    083
    084        /**
    085         * @param name
    086         * @return the user
    087         * @throws GeneralSecurityException
    088         */
    089        public User getUserByName( String name )
    090                                throws GeneralSecurityException {
    091            return registry.getUserByName( this, name );
    092        }
    093
    094        /**
    095         * @param id
    096         * @return the user
    097         * @throws GeneralSecurityException
    098         */
    099        public User getUserById( int id )
    100                                throws GeneralSecurityException {
    101            return registry.getUserById( this, id );
    102        }
    103
    104        /**
    105         * @param name
    106         * @return the group
    107         * @throws GeneralSecurityException
    108         */
    109        public Group getGroupByName( String name )
    110                                throws GeneralSecurityException {
    111            return registry.getGroupByName( this, name );
    112        }
    113
    114        /**
    115         * @param id
    116         * @return the group
    117         * @throws GeneralSecurityException
    118         */
    119        public Group getGroupById( int id )
    120                                throws GeneralSecurityException {
    121            return registry.getGroupById( this, id );
    122        }
    123
    124        /**
    125         * @param name
    126         * @return the role
    127         * @throws GeneralSecurityException
    128         */
    129        public Role getRoleByName( String name )
    130                                throws GeneralSecurityException {
    131            return registry.getRoleByName( this, name );
    132        }
    133
    134        /**
    135         * @param ns
    136         * @return the roles
    137         * @throws GeneralSecurityException
    138         */
    139        public Role[] getRolesByNS( String ns )
    140                                throws GeneralSecurityException {
    141            return registry.getRolesByNS( this, ns );
    142        }
    143
    144        /**
    145         * @param id
    146         * @return the role
    147         * @throws GeneralSecurityException
    148         */
    149        public Role getRoleById( int id )
    150                                throws GeneralSecurityException {
    151            return registry.getRoleById( this, id );
    152        }
    153
    154        /**
    155         * @param name
    156         * @return the right
    157         * @throws GeneralSecurityException
    158         */
    159        public RightType getRightByName( String name )
    160                                throws GeneralSecurityException {
    161            return registry.getRightTypeByName( this, name );
    162        }
    163
    164        /**
    165         * @param name
    166         * @return the privilege
    167         * @throws GeneralSecurityException
    168         */
    169        public Privilege getPrivilegeByName( String name )
    170                                throws GeneralSecurityException {
    171            return registry.getPrivilegeByName( this, name );
    172        }
    173
    174        /**
    175         * @param id
    176         * @return the object
    177         * @throws GeneralSecurityException
    178         */
    179        public SecuredObject getSecuredObjectById( int id )
    180                                throws GeneralSecurityException {
    181            return registry.getSecuredObjectById( this, id );
    182        }
    183
    184        /**
    185         * @param name
    186         * @param type
    187         * @return the object
    188         * @throws GeneralSecurityException
    189         */
    190        public SecuredObject getSecuredObjectByName( String name, String type )
    191                                throws GeneralSecurityException {
    192            return registry.getSecuredObjectByName( this, name, type );
    193        }
    194
    195        /**
    196         * @param ns
    197         * @param type
    198         * @return the objects
    199         * @throws GeneralSecurityException
    200         */
    201        public SecuredObject[] getSecuredObjectsByNS( String ns, String type )
    202                                throws GeneralSecurityException {
    203            return registry.getSecuredObjectsByNS( this, ns, type );
    204        }
    205
    206        /**
    207         * @return the users
    208         * @throws GeneralSecurityException
    209         */
    210        public User[] getAllUsers()
    211                                throws GeneralSecurityException {
    212            return registry.getAllUsers( this );
    213        }
    214
    215        /**
    216         * @return all groups
    217         * @throws GeneralSecurityException
    218         */
    219        public Group[] getAllGroups()
    220                                throws GeneralSecurityException {
    221            return registry.getAllGroups( this );
    222        }
    223
    224        /**
    225         * @param type
    226         * @return all secured objects
    227         * @throws GeneralSecurityException
    228         */
    229        public SecuredObject[] getAllSecuredObjects( String type )
    230                                throws GeneralSecurityException {
    231            return registry.getAllSecuredObjects( this, type );
    232        }
    233
    234        /**
    235         * Retrieves all <code>Role</code> s from the <code>Registry</code>, except those that are only used internally
    236         * (these have a namespace starting with the $ symbol);
    237         *
    238         * @return all roles
    239         *
    240         * @throws GeneralSecurityException
    241         */
    242        public Role[] getAllRoles()
    243                                throws GeneralSecurityException {
    244            return registry.getAllRoles( this );
    245        }
    246
    247        /**
    248         * Returns all <code>Role</code> s that the given <code>User</code> is associated with (directly and via group
    249         * memberships).
    250         *
    251         * @param user
    252         * @return all his roles
    253         * @throws GeneralSecurityException
    254         */
    255        public Role[] getAllRolesForUser( User user )
    256                                throws GeneralSecurityException {
    257
    258            HashSet<Group> allGroups = new HashSet<Group>();
    259            Stack<Group> groupStack = new Stack<Group>();
    260            Group[] groups = registry.getGroupsForUser( this, user );
    261            for ( int i = 0; i < groups.length; i++ ) {
    262                groupStack.push( groups[i] );
    263            }
    264
    265            // collect all groups that user is member of
    266            while ( !groupStack.isEmpty() ) {
    267                Group currentGroup = groupStack.pop();
    268                allGroups.add( currentGroup );
    269                groups = registry.getGroupsForGroup( this, currentGroup );
    270                for ( int i = 0; i < groups.length; i++ ) {
    271                    if ( !allGroups.contains( groups[i] ) ) {
    272                        allGroups.add( groups[i] );
    273                        groupStack.push( groups[i] );
    274                    }
    275                }
    276            }
    277
    278            HashSet<Role> allRoles = new HashSet<Role>();
    279
    280            // add all directly associated roles
    281            Role[] roles = registry.getRolesForUser( this, user );
    282            for ( int i = 0; i < roles.length; i++ ) {
    283                allRoles.add( roles[i] );
    284            }
    285
    286            // add all roles that are associated via group membership
    287            Iterator<Group> it = allGroups.iterator();
    288            while ( it.hasNext() ) {
    289                Group group = it.next();
    290                roles = registry.getRolesForGroup( this, group );
    291                for ( int i = 0; i < roles.length; i++ ) {
    292                    allRoles.add( roles[i] );
    293                }
    294            }
    295            return allRoles.toArray( new Role[allRoles.size()] );
    296        }
    297
    298        /**
    299         * Returns all <code>Role</code> s that the given <code>Group</code> is associated with (directly and via group
    300         * memberships).
    301         *
    302         * @param group
    303         * @return all their roles
    304         * @throws GeneralSecurityException
    305         */
    306        public Role[] getAllRolesForGroup( Group group )
    307                                throws GeneralSecurityException {
    308
    309            HashSet<Group> allGroups = new HashSet<Group>();
    310            Stack<Group> groupStack = new Stack<Group>();
    311            groupStack.push( group );
    312
    313            while ( !groupStack.isEmpty() ) {
    314                Group currentGroup = groupStack.pop();
    315                Group[] groups = registry.getGroupsForGroup( this, currentGroup );
    316                for ( int i = 0; i < groups.length; i++ ) {
    317                    if ( !allGroups.contains( groups[i] ) ) {
    318                        allGroups.add( groups[i] );
    319                        groupStack.push( groups[i] );
    320                    }
    321                }
    322            }
    323
    324            HashSet<Role> allRoles = new HashSet<Role>();
    325            Iterator<Group> it = allGroups.iterator();
    326            while ( it.hasNext() ) {
    327                Role[] roles = registry.getRolesForGroup( this, it.next() );
    328                for ( int i = 0; i < roles.length; i++ ) {
    329                    allRoles.add( roles[i] );
    330                }
    331            }
    332            return allRoles.toArray( new Role[allRoles.size()] );
    333        }
    334
    335        /**
    336         * Tries to find a cyle in the groups relations of the <code>Registry</code>.
    337         *
    338         * @return indicates the cycle's nodes (groups)
    339         * @throws GeneralSecurityException
    340         */
    341        public Group[] findGroupCycle()
    342                                throws GeneralSecurityException {
    343            Group[] allGroups = getAllGroups();
    344            for ( int i = 0; i < allGroups.length; i++ ) {
    345                Stack<Group> path = new Stack<Group>();
    346                if ( findGroupCycle( allGroups[i], path ) ) {
    347                    return path.toArray( new Group[path.size()] );
    348                }
    349            }
    350            return null;
    351        }
    352
    353        /**
    354         * Recursion part for the <code>findGroupCycle</code> -algorithm.
    355         * <p>
    356         * Modified depth first search.
    357         *
    358         * @param group
    359         * @param path
    360         * @return true if cycle
    361         * @throws GeneralSecurityException
    362         */
    363        private boolean findGroupCycle( Group group, Stack<Group> path )
    364                                throws GeneralSecurityException {
    365            if ( path.contains( group ) ) {
    366                path.push( group );
    367                return true;
    368            }
    369            path.push( group );
    370            Group[] members = registry.getGroupsForGroup( this, group );
    371            for ( int i = 0; i < members.length; i++ ) {
    372                if ( findGroupCycle( members[i], path ) ) {
    373                    return true;
    374                }
    375            }
    376            path.pop();
    377            return false;
    378        }
    379
    380        /**
    381         * Checks if the associated <code>User</code> has a certain <code>Privilege</code>.
    382         *
    383         * @param privilege
    384         * @throws GeneralSecurityException
    385         *             if holder does not have the privilege
    386         */
    387        protected void checkForPrivilege( Privilege privilege )
    388                                throws GeneralSecurityException {
    389            if ( !user.hasPrivilege( this, privilege ) ) {
    390                throw new GeneralSecurityException( "The requested operation requires the privilege '"
    391                                                    + privilege.getName() + "'." );
    392            }
    393        }
    394
    395        /**
    396         * Checks if the associated <code>User</code> has a certain <code>Right</code> on the given
    397         * <code>SecurableObject</code>.
    398         *
    399         * @param right
    400         * @param object
    401         * @throws GeneralSecurityException
    402         *             this is a UnauthorizedException if the holder does not have the right
    403         */
    404        protected void checkForRight( RightType right, SecurableObject object )
    405                                throws UnauthorizedException, GeneralSecurityException {
    406            if ( !user.hasRight( this, right, object ) ) {
    407                throw new UnauthorizedException( "The requested operation requires the right '" + right.getName()
    408                                                 + "' on the object '" + object.getName() + "'." );
    409            }
    410        }
    411
    412        /**
    413         * @param address
    414         * @return the service
    415         * @throws GeneralSecurityException
    416         */
    417        public Service getServiceByAddress( String address )
    418                                throws GeneralSecurityException {
    419            return registry.getServiceByAddress( this, address );
    420        }
    421
    422        /**
    423         * @return all services
    424         * @throws GeneralSecurityException
    425         */
    426        public LinkedList<Service> getAllServices()
    427                                throws GeneralSecurityException {
    428            return registry.getAllServices( this );
    429        }
    430
    431    }