001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_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 }