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