001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_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    }