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 }