001    //$HeadURL: http://svn.wald.intevation.org/svn/deegree/base/trunk/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.ArrayList;
039    import java.util.HashSet;
040    import java.util.Iterator;
041    import java.util.LinkedList;
042    import java.util.List;
043    import java.util.Stack;
044    
045    import org.deegree.security.GeneralSecurityException;
046    import org.deegree.security.UnauthorizedException;
047    import org.deegree.security.drm.model.Group;
048    import org.deegree.security.drm.model.Privilege;
049    import org.deegree.security.drm.model.RightType;
050    import org.deegree.security.drm.model.Role;
051    import org.deegree.security.drm.model.SecurableObject;
052    import org.deegree.security.drm.model.SecuredObject;
053    import org.deegree.security.drm.model.Service;
054    import org.deegree.security.drm.model.User;
055    
056    /**
057     * 
058     * 
059     * 
060     * @version $Revision: 32117 $
061     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
062     * @author last edited by: $Author: aschmitz $
063     * 
064     * @version 1.0. $Revision: 32117 $, $Date: 2011-10-10 13:51:31 +0200 (Mo, 10 Okt 2011) $
065     * 
066     * @since 2.0
067     */
068    public class SecurityAccess {
069    
070        protected User user;
071    
072        protected SecurityRegistry registry;
073    
074        SecurityAccess( User user, SecurityRegistry registry ) {
075            this.user = user;
076            this.registry = registry;
077        }
078    
079        /**
080         * @return probably the admin user
081         */
082        public User getUser() {
083            return user;
084        }
085    
086        /**
087         * @param name
088         * @return the user
089         * @throws GeneralSecurityException
090         */
091        public User getUserByName( String name )
092                                throws GeneralSecurityException {
093            return registry.getUserByName( this, name );
094        }
095    
096        /**
097         * @param id
098         * @return the user
099         * @throws GeneralSecurityException
100         */
101        public User getUserById( int id )
102                                throws GeneralSecurityException {
103            return registry.getUserById( this, id );
104        }
105    
106        /**
107         * @param name
108         * @return the group
109         * @throws GeneralSecurityException
110         */
111        public Group getGroupByName( String name )
112                                throws GeneralSecurityException {
113            return registry.getGroupByName( this, name );
114        }
115    
116        /**
117         * @param id
118         * @return the group
119         * @throws GeneralSecurityException
120         */
121        public Group getGroupById( int id )
122                                throws GeneralSecurityException {
123            return registry.getGroupById( this, id );
124        }
125    
126        /**
127         * @param name
128         * @return the role
129         * @throws GeneralSecurityException
130         */
131        public Role getRoleByName( String name )
132                                throws GeneralSecurityException {
133            return registry.getRoleByName( this, name );
134        }
135    
136        /**
137         * @param ns
138         * @return the roles
139         * @throws GeneralSecurityException
140         */
141        public Role[] getRolesByNS( String ns )
142                                throws GeneralSecurityException {
143            return registry.getRolesByNS( this, ns );
144        }
145    
146        /**
147         * @param id
148         * @return the role
149         * @throws GeneralSecurityException
150         */
151        public Role getRoleById( int id )
152                                throws GeneralSecurityException {
153            return registry.getRoleById( this, id );
154        }
155    
156        /**
157         * @param name
158         * @return the right
159         * @throws GeneralSecurityException
160         */
161        public RightType getRightByName( String name )
162                                throws GeneralSecurityException {
163            return registry.getRightTypeByName( this, name );
164        }
165    
166        /**
167         * @param name
168         * @return the privilege
169         * @throws GeneralSecurityException
170         */
171        public Privilege getPrivilegeByName( String name )
172                                throws GeneralSecurityException {
173            return registry.getPrivilegeByName( this, name );
174        }
175    
176        /**
177         * @param id
178         * @return the object
179         * @throws GeneralSecurityException
180         */
181        public SecuredObject getSecuredObjectById( int id )
182                                throws GeneralSecurityException {
183            return registry.getSecuredObjectById( this, id );
184        }
185    
186        /**
187         * @param name
188         * @param type
189         * @return the object
190         * @throws GeneralSecurityException
191         */
192        public SecuredObject getSecuredObjectByName( String name, String type )
193                                throws GeneralSecurityException {
194            return registry.getSecuredObjectByName( this, name, type );
195        }
196    
197        /**
198         * @param ns
199         * @param type
200         * @return the objects
201         * @throws GeneralSecurityException
202         */
203        public SecuredObject[] getSecuredObjectsByNS( String ns, String type )
204                                throws GeneralSecurityException {
205            return registry.getSecuredObjectsByNS( this, ns, type );
206        }
207    
208        /**
209         * @return the users
210         * @throws GeneralSecurityException
211         */
212        public User[] getAllUsers()
213                                throws GeneralSecurityException {
214            return registry.getAllUsers( this );
215        }
216    
217        /**
218         * @return all groups
219         * @throws GeneralSecurityException
220         */
221        public Group[] getAllGroups()
222                                throws GeneralSecurityException {
223            return registry.getAllGroups( this );
224        }
225    
226        /**
227         * @param type
228         * @return all secured objects
229         * @throws GeneralSecurityException
230         */
231        public SecuredObject[] getAllSecuredObjects( String type )
232                                throws GeneralSecurityException {
233            return registry.getAllSecuredObjects( this, type );
234        }
235    
236        /**
237         * Retrieves all <code>Role</code> s from the <code>Registry</code>, except those that are only used internally
238         * (these have a namespace starting with the $ symbol);
239         * 
240         * @return all roles
241         * 
242         * @throws GeneralSecurityException
243         */
244        public Role[] getAllRoles()
245                                throws GeneralSecurityException {
246            return registry.getAllRoles( this );
247        }
248    
249        /**
250         * Returns all <code>Role</code> s that the given <code>User</code> is associated with (directly and via group
251         * memberships).
252         * 
253         * @param user
254         * @return all his roles
255         * @throws GeneralSecurityException
256         */
257        public Role[] getAllRolesForUser( User user )
258                                throws GeneralSecurityException {
259            // long l = System.currentTimeMillis();
260            // counts number of accesses against SecurityRegistry
261            int count = 0;
262            HashSet<Group> allGroups = new HashSet<Group>();
263            Group[] groups = registry.getGroupsForUser( this, user );
264            count++;
265            for ( Group group : groups ) {
266                allGroups.add( group );
267            }
268    
269            groups = registry.getGroupsForGroups( this, allGroups.toArray( new Group[allGroups.size()] ) );
270            count++;
271            List<Group> tmp = new ArrayList<Group>( 200 );
272            do {
273                tmp.clear();
274                for ( Group group : groups ) {
275                    if ( !allGroups.contains( group ) ) {
276                        allGroups.add( group );
277                        tmp.add( group );
278                    }
279                }
280                if ( tmp.size() > 0 ) {
281                    groups = registry.getGroupsForGroups( this, tmp.toArray( new Group[tmp.size()] ) );
282                    count++;
283                }
284            } while ( tmp.size() > 0 );
285    
286            // Stack<Group> groupStack = new Stack<Group>();
287            // for ( int i = 0; i < groups.length; i++ ) {
288            // groupStack.push( groups[i] );
289            // }
290            //
291            // // collect all groups that user is member of
292            // while ( !groupStack.isEmpty() ) {
293            // Group currentGroup = groupStack.pop();
294            //
295            // allGroups.add( currentGroup );
296            // groups = registry.getGroupsForGroup( this, currentGroup );
297            // count++;
298            // for ( int i = 0; i < groups.length; i++ ) {
299            // if ( !allGroups.contains( groups[i] ) ) {
300            // allGroups.add( groups[i] );
301            // groupStack.push( groups[i] );
302            // }
303            // }
304            // }
305    
306            HashSet<Role> allRoles = new HashSet<Role>();
307    
308            // add all directly associated roles
309            Role[] roles = registry.getRolesForUser( this, user );
310            count++;
311            for ( int i = 0; i < roles.length; i++ ) {
312                allRoles.add( roles[i] );
313            }
314    
315            // add all roles that are associated via group membership
316            // Iterator<Group> it = allGroups.iterator();
317            // while ( it.hasNext() ) {
318            // Group group = it.next();
319            // roles = registry.getRolesForGroup( this, group );
320            // count++;
321            // for ( int i = 0; i < roles.length; i++ ) {
322            // allRoles.add( roles[i] );
323            // }
324            // }
325            roles = registry.getRolesForGroups( this, allGroups.toArray( new Group[allGroups.size()] ) );
326            for ( Role role : roles ) {
327                allRoles.add( role );
328            }
329            // System.out.println( "=========  getAllRolesForUser ===============" );
330            // System.out.println( count );
331            // System.out.println( ( System.currentTimeMillis() - l ) );
332            // System.out.println( "=============================================" );
333            return allRoles.toArray( new Role[allRoles.size()] );
334        }
335    
336        /**
337         * Returns all <code>Role</code> s that the given <code>Group</code> is associated with (directly and via group
338         * memberships).
339         * 
340         * @param group
341         * @return all their roles
342         * @throws GeneralSecurityException
343         */
344        public Role[] getAllRolesForGroup( Group group )
345                                throws GeneralSecurityException {
346    
347            HashSet<Group> allGroups = new HashSet<Group>();
348            Stack<Group> groupStack = new Stack<Group>();
349            groupStack.push( group );
350    
351            while ( !groupStack.isEmpty() ) {
352                Group currentGroup = groupStack.pop();
353                Group[] groups = registry.getGroupsForGroup( this, currentGroup );
354                for ( int i = 0; i < groups.length; i++ ) {
355                    if ( !allGroups.contains( groups[i] ) ) {
356                        allGroups.add( groups[i] );
357                        groupStack.push( groups[i] );
358                    }
359                }
360            }
361    
362            HashSet<Role> allRoles = new HashSet<Role>();
363            Iterator<Group> it = allGroups.iterator();
364            while ( it.hasNext() ) {
365                Role[] roles = registry.getRolesForGroup( this, it.next() );
366                for ( int i = 0; i < roles.length; i++ ) {
367                    allRoles.add( roles[i] );
368                }
369            }
370            return allRoles.toArray( new Role[allRoles.size()] );
371        }
372    
373        /**
374         * Tries to find a cyle in the groups relations of the <code>Registry</code>.
375         * 
376         * @return indicates the cycle's nodes (groups)
377         * @throws GeneralSecurityException
378         */
379        public Group[] findGroupCycle()
380                                throws GeneralSecurityException {
381            Group[] allGroups = getAllGroups();
382            for ( int i = 0; i < allGroups.length; i++ ) {
383                Stack<Group> path = new Stack<Group>();
384                if ( findGroupCycle( allGroups[i], path ) ) {
385                    return path.toArray( new Group[path.size()] );
386                }
387            }
388            return null;
389        }
390    
391        /**
392         * Recursion part for the <code>findGroupCycle</code> -algorithm.
393         * <p>
394         * Modified depth first search.
395         * 
396         * @param group
397         * @param path
398         * @return true if cycle
399         * @throws GeneralSecurityException
400         */
401        private boolean findGroupCycle( Group group, Stack<Group> path )
402                                throws GeneralSecurityException {
403            if ( path.contains( group ) ) {
404                path.push( group );
405                return true;
406            }
407            path.push( group );
408            Group[] members = registry.getGroupsForGroup( this, group );
409            for ( int i = 0; i < members.length; i++ ) {
410                if ( findGroupCycle( members[i], path ) ) {
411                    return true;
412                }
413            }
414            path.pop();
415            return false;
416        }
417    
418        /**
419         * Checks if the associated <code>User</code> has a certain <code>Privilege</code>.
420         * 
421         * @param privilege
422         * @throws GeneralSecurityException
423         *             if holder does not have the privilege
424         */
425        protected void checkForPrivilege( Privilege privilege )
426                                throws GeneralSecurityException {
427            if ( !user.hasPrivilege( this, privilege ) ) {
428                throw new GeneralSecurityException( "The requested operation requires the privilege '"
429                                                    + privilege.getName() + "'." );
430            }
431        }
432    
433        /**
434         * Checks if the associated <code>User</code> has a certain <code>Right</code> on the given
435         * <code>SecurableObject</code>.
436         * 
437         * @param right
438         * @param object
439         * @throws GeneralSecurityException
440         *             this is a UnauthorizedException if the holder does not have the right
441         */
442        protected void checkForRight( RightType right, SecurableObject object )
443                                throws UnauthorizedException, GeneralSecurityException {
444            if ( !user.hasRight( this, right, object ) ) {
445                throw new UnauthorizedException( "The requested operation requires the right '" + right.getName()
446                                                 + "' on the object '" + object.getName() + "'." );
447            }
448        }
449    
450        /**
451         * @param address
452         * @return the service
453         * @throws GeneralSecurityException
454         */
455        public Service getServiceByAddress( String address )
456                                throws GeneralSecurityException {
457            return registry.getServiceByAddress( this, address );
458        }
459    
460        public Service getServiceById( int id )
461                                throws GeneralSecurityException {
462            return registry.getServiceById( this, id );
463        }
464    
465        /**
466         * @return all services
467         * @throws GeneralSecurityException
468         */
469        public LinkedList<Service> getAllServices()
470                                throws GeneralSecurityException {
471            return registry.getAllServices( this );
472        }
473    
474        /**
475         * @param role
476         * @return the appropriate services
477         * @throws GeneralSecurityException
478         */
479        public LinkedList<Service> getRolesServices( Role role )
480                                throws GeneralSecurityException {
481            return registry.getRolesServices( this, role );
482        }
483    
484        public boolean hasServiceRight( Service service, Role role, RightType right )
485                                throws GeneralSecurityException {
486            return registry.hasServiceRight( this, service, role, right );
487        }
488    
489        public String getConstraints( Role role, Service service )
490                                throws GeneralSecurityException {
491            return registry.getConstraints( this, role, service );
492        }
493    
494    }