001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/portal/standard/security/control/StoreSecuredObjectsListener.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 import java.util.HashMap;
040 import java.util.HashSet;
041 import java.util.Iterator;
042 import java.util.Map;
043 import java.util.Set;
044
045 import org.deegree.enterprise.control.AbstractListener;
046 import org.deegree.enterprise.control.FormEvent;
047 import org.deegree.enterprise.control.RPCException;
048 import org.deegree.enterprise.control.RPCMember;
049 import org.deegree.enterprise.control.RPCMethodCall;
050 import org.deegree.enterprise.control.RPCParameter;
051 import org.deegree.enterprise.control.RPCStruct;
052 import org.deegree.enterprise.control.RPCWebEvent;
053 import org.deegree.framework.log.ILogger;
054 import org.deegree.framework.log.LoggerFactory;
055 import org.deegree.i18n.Messages;
056 import org.deegree.security.GeneralSecurityException;
057 import org.deegree.security.drm.SecurityAccessManager;
058 import org.deegree.security.drm.SecurityTransaction;
059 import org.deegree.security.drm.model.SecuredObject;
060
061 /**
062 * This <code>Listener</code> reacts on 'storeSecuredObjects' events, extracts the contained
063 * Layer/FeatureType definitions and updates the <code>SecurityManager</code> accordingly.
064 *
065 * Access constraints:
066 * <ul>
067 * <li>only users that have the 'SEC_ADMIN'-role are allowed</li>
068 * </ul>
069 *
070 * @author <a href="mschneider@lat-lon.de">Markus Schneider </a>
071 * @author last edited by: $Author: mschneider $
072 *
073 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
074 */
075 public class StoreSecuredObjectsListener extends AbstractListener {
076
077 private static final ILogger LOG = LoggerFactory.getLogger( StoreSecuredObjectsListener.class );
078
079 /*
080 * (non-Javadoc)
081 *
082 * @see org.deegree.enterprise.control.WebListener#actionPerformed(org.deegree.enterprise.control.FormEvent)
083 */
084 @Override
085 public void actionPerformed( FormEvent event ) {
086
087 // keys are Strings (types), values are ArrayLists (which contain Strings)
088 Map<String,ArrayList<String>> newObjectTypes = new HashMap<String,ArrayList<String>>();
089 // keys are Strings (types), values are ArrayLists (which contain Integers)
090 Map<String,ArrayList<Integer>> oldObjectTypes = new HashMap<String, ArrayList<Integer>>();
091
092 SecurityAccessManager manager = null;
093 SecurityTransaction transaction = null;
094
095 try {
096 RPCWebEvent ev = (RPCWebEvent) event;
097 RPCMethodCall rpcCall = ev.getRPCMethodCall();
098 RPCParameter[] params = rpcCall.getParameters();
099
100 for ( int i = 0; i < params.length; i++ ) {
101 if ( !( params[0].getValue() instanceof RPCStruct ) ) {
102 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_STRUCT" ) );
103 }
104 RPCStruct struct = (RPCStruct) params[i].getValue();
105
106 // extract details of one SecuredObject
107 RPCMember idRPC = struct.getMember( "id" );
108 RPCMember nameRPC = struct.getMember( "name" );
109 RPCMember typeRPC = struct.getMember( "type" );
110
111 int id;
112 String name = null;
113 String type = null;
114
115 // extract id
116 if ( idRPC == null ) {
117 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_MEMBER", "object", "id" ) );
118 }
119 if ( !( idRPC.getValue() instanceof String ) ) {
120 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_WRONG_MEMBER", "id", "string" ) );
121 }
122 try {
123 id = Integer.parseInt( ( (String) idRPC.getValue() ) );
124 } catch ( NumberFormatException e ) {
125 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_WRONG_MEMBER", "id", "integer" ) );
126 }
127 // extract name
128 if ( nameRPC != null ) {
129 if ( !( nameRPC.getValue() instanceof String ) ) {
130 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_WRONG_MEMBER", "name", "string" ) );
131 }
132 name = (String) nameRPC.getValue();
133 }
134 // extract type
135 if ( typeRPC != null ) {
136 if ( !( typeRPC.getValue() instanceof String ) ) {
137 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_WRONG_MEMBER", "type", "string" ) );
138 }
139 type = (String) typeRPC.getValue();
140
141 }
142 if ( name == null ) {
143 throw new GeneralSecurityException( Messages.getMessage( "IGEO_STD_SEC_MISSING_MEMBER",
144 "SecuredObject", "name" ) );
145 }
146 if ( type == null ) {
147 throw new GeneralSecurityException( Messages.getMessage( "IGEO_STD_SEC_MISSING_MEMBER",
148 "SecuredObject", "type" ) );
149 }
150
151 // new or existing SecuredObject?
152 if ( id == -1 ) {
153 ArrayList<String> list = newObjectTypes.get( type );
154 if ( list == null ) {
155 list = new ArrayList<String>( 20 );
156 newObjectTypes.put( type, list );
157 }
158 list.add( name );
159 } else {
160 ArrayList<Integer> list = oldObjectTypes.get( type );
161 if ( list == null ) {
162 list = new ArrayList<Integer>( 20 );
163 oldObjectTypes.put( type, list );
164 }
165 list.add( new Integer( id ) );
166 }
167 }
168
169 // get Transaction and perform access check
170 manager = SecurityAccessManager.getInstance();
171 transaction = SecurityHelper.acquireTransaction( this );
172 SecurityHelper.checkForAdminRole( transaction );
173
174 // remove deleted Layers
175 SecuredObject[] obsoleteLayers = getObjectsToDelete(
176 oldObjectTypes.get( ClientHelper.TYPE_LAYER ),
177 transaction.getAllSecuredObjects( ClientHelper.TYPE_LAYER ) );
178 for ( int i = 0; i < obsoleteLayers.length; i++ ) {
179 transaction.deregisterSecuredObject( obsoleteLayers[i] );
180 }
181
182 // register new Layers
183 ArrayList newLayerList = newObjectTypes.get( ClientHelper.TYPE_LAYER );
184 if ( newLayerList != null ) {
185 Iterator it = newLayerList.iterator();
186 while ( it.hasNext() ) {
187 String name = (String) it.next();
188 transaction.registerSecuredObject( ClientHelper.TYPE_LAYER, name, name );
189 }
190 }
191
192 // remove deleted FeatureTypes
193 SecuredObject[] obsoleteFeatureTypes = getObjectsToDelete(
194 oldObjectTypes.get( ClientHelper.TYPE_FEATURETYPE ),
195 transaction.getAllSecuredObjects( ClientHelper.TYPE_FEATURETYPE ) );
196 for ( int i = 0; i < obsoleteFeatureTypes.length; i++ ) {
197 transaction.deregisterSecuredObject( obsoleteFeatureTypes[i] );
198 }
199
200 // register new FeatureTypes
201 ArrayList newFeatureTypeList = newObjectTypes.get( ClientHelper.TYPE_FEATURETYPE );
202 if ( newFeatureTypeList != null ) {
203 Iterator it = newFeatureTypeList.iterator();
204 while ( it.hasNext() ) {
205 String name = (String) it.next();
206 transaction.registerSecuredObject( ClientHelper.TYPE_FEATURETYPE, name, name );
207 }
208 }
209
210 manager.commitTransaction( transaction );
211 transaction = null;
212
213 getRequest().setAttribute( "MESSAGE", Messages.getMessage( "IGEO_STD_SEC_SUCCESS_INITSECOBJEDITOR" ) );
214 } catch ( RPCException e ) {
215 getRequest().setAttribute( "SOURCE", this.getClass().getName() );
216 getRequest().setAttribute( "MESSAGE", Messages.getMessage( "IGEO_STD_SEC_ERROR_CHANGE_REQ", e.getMessage() ) );
217 setNextPage( "error.jsp" );
218 LOG.logError( e.getMessage(), e );
219 } catch ( GeneralSecurityException e ) {
220 getRequest().setAttribute( "SOURCE", this.getClass().getName() );
221 getRequest().setAttribute( "MESSAGE", Messages.getMessage( "IGEO_STD_SEC_ERROR_CHANGE", e.getMessage() ) );
222 setNextPage( "error.jsp" );
223 LOG.logError( e.getMessage(), e );
224 } finally {
225 if ( manager != null && transaction != null ) {
226 try {
227 manager.abortTransaction( transaction );
228 } catch ( GeneralSecurityException ex ) {
229 LOG.logError( ex.getMessage() );
230 }
231 }
232 }
233 }
234
235 private SecuredObject[] getObjectsToDelete( ArrayList<Integer> remainingObjects, SecuredObject[] presentObjects ) {
236 Set<Integer> lookup = new HashSet<Integer>();
237 ArrayList<SecuredObject> deleteList = new ArrayList<SecuredObject>( 10 );
238 if ( remainingObjects != null ) {
239 lookup = new HashSet<Integer>( remainingObjects );
240 }
241 for ( int i = 0; i < presentObjects.length; i++ ) {
242 if ( !lookup.contains( new Integer( presentObjects[i].getID() ) ) ) {
243 deleteList.add( presentObjects[i] );
244 }
245 }
246 return deleteList.toArray( new SecuredObject[deleteList.size()] );
247 }
248 }