001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/portal/standard/security/control/StoreGroupsListener.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.portal.standard.security.control; 037 038 import java.util.ArrayList; 039 040 import org.deegree.enterprise.control.AbstractListener; 041 import org.deegree.enterprise.control.FormEvent; 042 import org.deegree.enterprise.control.RPCException; 043 import org.deegree.enterprise.control.RPCMember; 044 import org.deegree.enterprise.control.RPCMethodCall; 045 import org.deegree.enterprise.control.RPCParameter; 046 import org.deegree.enterprise.control.RPCStruct; 047 import org.deegree.enterprise.control.RPCWebEvent; 048 import org.deegree.framework.log.ILogger; 049 import org.deegree.framework.log.LoggerFactory; 050 import org.deegree.i18n.Messages; 051 import org.deegree.security.GeneralSecurityException; 052 import org.deegree.security.UnauthorizedException; 053 import org.deegree.security.drm.SecurityAccessManager; 054 import org.deegree.security.drm.SecurityTransaction; 055 import org.deegree.security.drm.model.Group; 056 import org.deegree.security.drm.model.User; 057 058 /** 059 * This <code>Listener</code> reacts on RPC-StoreGroups events, extracts the contained user/group 060 * relations and updates the <code>SecurityManager</code> accordingly. 061 * 062 * Access constraints: 063 * <ul> 064 * <li>only users that have the 'SEC_ADMIN'-role are allowed</li> 065 * </ul> 066 * 067 * @author <a href="mschneider@lat-lon.de">Markus Schneider </a> 068 * @author last edited by: $Author: mschneider $ 069 * 070 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $ 071 */ 072 public class StoreGroupsListener extends AbstractListener { 073 074 private static final ILogger LOG = LoggerFactory.getLogger( StoreGroupsListener.class ); 075 076 @Override 077 public void actionPerformed( FormEvent event ) { 078 079 SecurityAccessManager manager = null; 080 SecurityTransaction transaction = null; 081 082 try { 083 RPCWebEvent ev = (RPCWebEvent) event; 084 RPCMethodCall rpcCall = ev.getRPCMethodCall(); 085 RPCParameter[] params = rpcCall.getParameters(); 086 087 // values are Integers (groupIds) or Strings (groupNames) 088 Object[] groups = new Object[params.length]; 089 // values of the ArrayLists are Integers (groupIds) 090 ArrayList[] userMembersIds = new ArrayList[params.length]; 091 // values of the ArrayLists are Integers (userIds) 092 ArrayList[] groupMembersIds = new ArrayList[params.length]; 093 094 for ( int i = 0; i < params.length; i++ ) { 095 ArrayList<Integer> userMemberList = new ArrayList<Integer>( 200 ); 096 ArrayList<Integer> groupMemberList = new ArrayList<Integer>( 200 ); 097 userMembersIds[i] = userMemberList; 098 groupMembersIds[i] = groupMemberList; 099 if ( !( params[0].getValue() instanceof RPCStruct ) ) { 100 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_STRUCT" ) ); 101 } 102 RPCStruct struct = (RPCStruct) params[i].getValue(); 103 104 // extract group-id / group-name 105 extractGroupInfo( groups, i, struct ); 106 107 // extract user members 108 extractUsers( userMemberList, struct ); 109 110 // extract group members 111 extractGroups( groupMemberList, struct ); 112 113 } 114 115 // get Transaction and perform access check 116 manager = SecurityAccessManager.getInstance(); 117 transaction = SecurityHelper.acquireTransaction( this ); 118 SecurityHelper.checkForAdminRole( transaction ); 119 120 // remove deleted groups 121 removeDeletedGroups( transaction, groups ); 122 123 // save all submitted groups (and their members) 124 saveSubmittedGroups( transaction, groups, userMembersIds, groupMembersIds ); 125 Group[] cycle = transaction.findGroupCycle(); 126 manager.commitTransaction( transaction ); 127 transaction = null; 128 129 StringBuffer sb = new StringBuffer( 200 ); 130 sb.append( Messages.getMessage( "IGEO_STD_SEC_SUCCESS_STOREGROUPS" ) ); 131 132 if ( cycle != null ) { 133 sb.append( "<br><p><h4>" ); 134 sb.append( Messages.getMessage( "IGEO_STD_SEC_SUCCESS_STOREGROUPS_ADDTXT" ) ); 135 sb.append( "<br><code>" ); 136 for ( int i = 0; i < cycle.length; i++ ) { 137 sb.append( cycle[i].getName() ); 138 if ( i != cycle.length - 1 ) { 139 sb.append( " -> " ); 140 } 141 } 142 sb.append( "</code></h4></p>" ); 143 } 144 145 getRequest().setAttribute( "MESSAGE", sb.toString() ); 146 } catch ( RPCException e ) { 147 getRequest().setAttribute( "SOURCE", this.getClass().getName() ); 148 getRequest().setAttribute( "MESSAGE", 149 Messages.getMessage( "IGEO_STD_SEC_ERROR_CHANGE_REQ", 150 e.getMessage() ) ); 151 setNextPage( "error.jsp" ); 152 LOG.logDebug( e.getMessage(), e ); 153 154 } catch ( GeneralSecurityException e ) { 155 getRequest().setAttribute( "SOURCE", this.getClass().getName() ); 156 getRequest().setAttribute( "MESSAGE", 157 Messages.getMessage( "IGEO_STD_SEC_ERROR_CHANGE", 158 e.getMessage() ) ); 159 setNextPage( "error.jsp" ); 160 LOG.logDebug( e.getMessage(), e ); 161 } finally { 162 if ( manager != null && transaction != null ) { 163 try { 164 manager.abortTransaction( transaction ); 165 } catch ( GeneralSecurityException ex ) { 166 LOG.logDebug( ex.getMessage(), ex ); 167 } 168 } 169 } 170 } 171 172 private void saveSubmittedGroups( SecurityTransaction transaction, Object[] groups, 173 ArrayList[] userMembersIds, ArrayList[] groupMembersIds ) 174 throws GeneralSecurityException, UnauthorizedException { 175 for ( int i = 0; i < groups.length; i++ ) { 176 Group group; 177 if ( groups[i] instanceof Integer ) { 178 group = transaction.getGroupById( ( (Integer) groups[i] ).intValue() ); 179 } else { 180 group = transaction.registerGroup( (String) groups[i], (String) groups[i] ); 181 } 182 183 // set user members 184 User[] userMembers = new User[userMembersIds[i].size()]; 185 for ( int j = 0; j < userMembersIds[i].size(); j++ ) { 186 int userId = ( (Integer) userMembersIds[i].get( j ) ).intValue(); 187 userMembers[j] = transaction.getUserById( userId ); 188 } 189 transaction.setUsersInGroup( group, userMembers ); 190 191 // set group members 192 Group[] groupMembers = new Group[groupMembersIds[i].size()]; 193 for ( int j = 0; j < groupMembersIds[i].size(); j++ ) { 194 int groupId = ( (Integer) groupMembersIds[i].get( j ) ).intValue(); 195 groupMembers[j] = transaction.getGroupById( groupId ); 196 } 197 transaction.setGroupsInGroup( group, groupMembers ); 198 } 199 } 200 201 private void removeDeletedGroups( SecurityTransaction transaction, Object[] groups ) 202 throws GeneralSecurityException, UnauthorizedException { 203 Group[] oldGroups = transaction.getAllGroups(); 204 for ( int i = 0; i < oldGroups.length; i++ ) { 205 if ( oldGroups[i].getID() != Group.ID_SEC_ADMIN ) { 206 boolean deleted = true; 207 for ( int j = 0; j < groups.length; j++ ) { 208 if ( groups[j] instanceof Integer ) { 209 if ( ( (Integer) groups[j] ).intValue() == oldGroups[i].getID() ) { 210 deleted = false; 211 } 212 } 213 } 214 if ( deleted ) { 215 transaction.deregisterGroup( oldGroups[i] ); 216 } 217 } 218 } 219 } 220 221 private void extractGroups( ArrayList<Integer> groupMemberList, RPCStruct struct ) 222 throws RPCException { 223 RPCMember groupMembers = struct.getMember( "groupMembers" ); 224 if ( !( groupMembers.getValue() instanceof RPCParameter[] ) ) { 225 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_ARRAY", 226 "groupMembers" ) ); 227 } 228 RPCParameter[] memberArray = (RPCParameter[]) groupMembers.getValue(); 229 for ( int j = 0; j < memberArray.length; j++ ) { 230 if ( !( memberArray[j].getValue() instanceof String ) ) { 231 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_ARRAY_VALUES", 232 "groupMembers", "String" ) ); 233 } 234 try { 235 groupMemberList.add( new Integer( (String) memberArray[j].getValue() ) ); 236 } catch ( NumberFormatException e ) { 237 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_INVALID_ARRAY_VALUES", 238 "groupMembers", "Integer" ) ); 239 } 240 } 241 } 242 243 private void extractUsers( ArrayList<Integer> userMemberList, RPCStruct struct ) 244 throws RPCException { 245 RPCMember userMembers = struct.getMember( "userMembers" ); 246 if ( !( userMembers.getValue() instanceof RPCParameter[] ) ) { 247 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_ARRAY", 248 "userMembers" ) ); 249 } 250 RPCParameter[] memberArray = (RPCParameter[]) userMembers.getValue(); 251 for ( int j = 0; j < memberArray.length; j++ ) { 252 if ( !( memberArray[j].getValue() instanceof String ) ) { 253 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_ARRAY_VALUES", 254 "userMembers", "String" ) ); 255 } 256 try { 257 userMemberList.add( new Integer( (String) memberArray[j].getValue() ) ); 258 } catch ( NumberFormatException e ) { 259 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_INVALID_ARRAY_VALUES", 260 "userMembers", "Integer" ) ); 261 } 262 } 263 } 264 265 private void extractGroupInfo( Object[] groups, int index, RPCStruct struct ) 266 throws RPCException { 267 268 RPCMember groupId = struct.getMember( "groupId" ); 269 RPCMember groupName = struct.getMember( "groupName" ); 270 if ( ( groupId == null && groupName == null ) || ( groupId != null && groupName != null ) ) { 271 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_GROUPS" ) ); 272 } 273 if ( groupId != null ) { 274 if ( !( groupId.getValue() instanceof String ) ) { 275 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_GROUP_PARAM", 276 "groupId", "String" ) ); 277 } 278 try { 279 groups[index] = ( new Integer( (String) groupId.getValue() ) ); 280 } catch ( NumberFormatException e ) { 281 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_GROUP_PARAM", 282 "groupId", "Integer" ) ); 283 } 284 } else { 285 if ( !( groupName.getValue() instanceof String ) ) { 286 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_GROUP_PARAM", 287 "groupName", "String" ) ); 288 } 289 290 groups[index] = groupName.getValue(); 291 } 292 } 293 }