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 }