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 }