001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_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 }