001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/portal/standard/security/control/InitRightsEditorListener.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.Iterator; 041 import java.util.LinkedList; 042 import java.util.Map; 043 044 import javax.servlet.ServletRequest; 045 046 import org.deegree.datatypes.QualifiedName; 047 import org.deegree.enterprise.control.AbstractListener; 048 import org.deegree.enterprise.control.FormEvent; 049 import org.deegree.enterprise.control.RPCException; 050 import org.deegree.enterprise.control.RPCMethodCall; 051 import org.deegree.enterprise.control.RPCParameter; 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.model.filterencoding.ComplexFilter; 057 import org.deegree.model.filterencoding.Filter; 058 import org.deegree.model.filterencoding.Literal; 059 import org.deegree.model.filterencoding.LogicalOperation; 060 import org.deegree.model.filterencoding.Operation; 061 import org.deegree.model.filterencoding.OperationDefines; 062 import org.deegree.model.filterencoding.PropertyIsCOMPOperation; 063 import org.deegree.model.filterencoding.PropertyName; 064 import org.deegree.model.filterencoding.SpatialOperation; 065 import org.deegree.model.spatialschema.Envelope; 066 import org.deegree.model.spatialschema.Position; 067 import org.deegree.ogcbase.PropertyPath; 068 import org.deegree.ogcbase.PropertyPathFactory; 069 import org.deegree.security.GeneralSecurityException; 070 import org.deegree.security.drm.SecurityAccess; 071 import org.deegree.security.drm.model.Right; 072 import org.deegree.security.drm.model.RightType; 073 import org.deegree.security.drm.model.Role; 074 import org.deegree.security.drm.model.SecuredObject; 075 import org.deegree.security.drm.model.Service; 076 import org.deegree.security.drm.model.User; 077 078 /** 079 * This <code>Listener</code> reacts on RPC-EditRole events, extracts the submitted role-id and passes the role + known 080 * securable objects on the JSP. 081 * <p> 082 * Access constraints: 083 * <ul> 084 * <li>only users that have the 'SEC_ADMIN'-role are allowed</li> 085 * </ul> 086 * 087 * @author <a href="mschneider@lat-lon.de">Markus Schneider</a> 088 * @author last edited by: $Author: mschneider $ 089 * 090 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $ 091 */ 092 public class InitRightsEditorListener extends AbstractListener { 093 094 private static final ILogger LOG = LoggerFactory.getLogger( InitRightsEditorListener.class ); 095 096 @Override 097 public void actionPerformed( FormEvent event ) { 098 099 ServletRequest request = getRequest(); 100 try { 101 // perform access check 102 SecurityAccess access = SecurityHelper.acquireAccess( this ); 103 SecurityHelper.checkForAdminRole( access ); 104 User user = access.getUser(); 105 106 RPCWebEvent ev = (RPCWebEvent) event; 107 RPCMethodCall rpcCall = ev.getRPCMethodCall(); 108 RPCParameter[] params = rpcCall.getParameters(); 109 110 if ( params.length != 1 ) { 111 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_WRONG_PARAM_NUM" ) ); 112 } 113 if ( params[0].getType() != String.class ) { 114 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_STRING" ) ); 115 } 116 int roleId = -1; 117 try { 118 roleId = Integer.parseInt( (String) params[0].getValue() ); 119 } catch ( NumberFormatException e ) { 120 throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_WRONG_ROLE_VALUE" ) ); 121 } 122 123 // get Role to be edited 124 Role role = access.getRoleById( roleId ); 125 126 // check if user has the right to update the role 127 if ( !user.hasRight( access, RightType.UPDATE, role ) ) { 128 throw new GeneralSecurityException( Messages.getMessage( "IGEO_STD_SEC_MISSING_RIGHT", role.getName() ) ); 129 } 130 131 String s = (String) request.getAttribute( "supportManyServices" ); 132 boolean manyServices = false; 133 if ( s != null ) { 134 manyServices = s.equalsIgnoreCase( "true" ); 135 } 136 if ( manyServices ) { 137 LinkedList<Service> services = access.getAllServices(); 138 request.setAttribute( "SERVICES", services ); 139 } 140 141 SecuredObject[] layers = access.getAllSecuredObjects( ClientHelper.TYPE_LAYER ); 142 SecuredObjectRight[] getMapRights = new SecuredObjectRight[layers.length]; 143 for ( int i = 0; i < layers.length; i++ ) { 144 Right right = role.getRights( access, layers[i] ).getRight( layers[i], RightType.GETMAP ); 145 boolean isAccessible = right != null; 146 Map <String, String[]> constraintsMap = new HashMap(); 147 if ( right != null && right.getConstraints() != null ) { 148 constraintsMap = buildConstraintsMap( right.getConstraints() ); 149 } 150 151 if ( ILogger.LOG_DEBUG == LOG.getLevel() ) { 152 LOG.logDebug( "---------------------" ); 153 if(constraintsMap == null ){ 154 LOG.logDebug( "no constraints" ); 155 } else { 156 for ( String key : constraintsMap.keySet() ) { 157 Object value = constraintsMap.get( key ); 158 System.out.println (key + "=" + value); 159 LOG.logDebug( key, " = ", value ); 160 } 161 } 162 LOG.logDebug( "---------------------" ); 163 } 164 getMapRights[i] = new SecuredObjectRight( isAccessible, layers[i], constraintsMap ); 165 } 166 167 SecuredObject[] featureTypes = access.getAllSecuredObjects( ClientHelper.TYPE_FEATURETYPE ); 168 SecuredObjectRight[] getFeatureRights = new SecuredObjectRight[featureTypes.length]; 169 boolean[] deleteRights = new boolean[featureTypes.length]; 170 boolean[] insertRights = new boolean[featureTypes.length]; 171 boolean[] updateRights = new boolean[featureTypes.length]; 172 for ( int i = 0; i < featureTypes.length; i++ ) { 173 Right right = role.getRights( access, featureTypes[i] ).getRight( featureTypes[i], RightType.GETFEATURE ); 174 boolean isAccessible = right != null ? true : false; 175 Map constraints = new HashMap(); 176 getFeatureRights[i] = new SecuredObjectRight( isAccessible, featureTypes[i], constraints ); 177 right = role.getRights( access, featureTypes[i] ).getRight( featureTypes[i], RightType.INSERT ); 178 insertRights[i] = right != null ? true : false; 179 right = role.getRights( access, featureTypes[i] ).getRight( featureTypes[i], RightType.UPDATE ); 180 updateRights[i] = right != null ? true : false; 181 right = role.getRights( access, featureTypes[i] ).getRight( featureTypes[i], RightType.DELETE ); 182 deleteRights[i] = right != null ? true : false; 183 } 184 185 request.setAttribute( "ROLE", role ); 186 request.setAttribute( "RIGHTS_GET_MAP", getMapRights ); 187 request.setAttribute( "RIGHTS_GET_FEATURE", getFeatureRights ); 188 request.setAttribute( "RIGHTS_DELETE_FEATURE", deleteRights ); 189 request.setAttribute( "RIGHTS_INSERT_FEATURE", insertRights ); 190 request.setAttribute( "RIGHTS_UPDATE_FEATURE", updateRights ); 191 } catch ( RPCException e ) { 192 LOG.logError( e.getMessage(), e ); 193 request.setAttribute( "SOURCE", this.getClass().getName() ); 194 request.setAttribute( "MESSAGE", Messages.getMessage( "IGEO_STD_SEC_ERROR_RIGHTSEDITOR_REQUEST", 195 e.getMessage() ) ); 196 setNextPage( "error.jsp" ); 197 } catch ( GeneralSecurityException e ) { 198 LOG.logError( e.getMessage(), e ); 199 request.setAttribute( "SOURCE", this.getClass().getName() ); 200 request.setAttribute( "MESSAGE", Messages.getMessage( "IGEO_STD_SEC_ERROR_RIGHTSEDITOR", e.getMessage() ) ); 201 setNextPage( "error.jsp" ); 202 } catch ( Exception e ) { 203 LOG.logError( e.getMessage(), e ); 204 } 205 206 } 207 208 /** 209 * Reconstructs the constraints map (keys are Strings, values are arrays of Strings) from the given 210 * <code>Filter</code> expression. This only works if the expression meets the very format used by the 211 * <code>StoreRightsListener</code>. 212 * 213 * @param filter 214 * @return Map 215 * @throws SecurityException 216 */ 217 private Map buildConstraintsMap( Filter filter ) 218 throws SecurityException { 219 Map<String, String[]> constraintsMap = new HashMap<String, String[]>(); 220 if ( filter instanceof ComplexFilter ) { 221 Operation operation = ( (ComplexFilter) filter ).getOperation(); 222 if ( operation.getOperatorId() == OperationDefines.AND ) { 223 LogicalOperation andOperation = (LogicalOperation) operation; 224 Iterator it = andOperation.getArguments().iterator(); 225 while ( it.hasNext() ) { 226 addConstraintToMap( (Operation) it.next(), constraintsMap ); 227 } 228 } else { 229 addConstraintToMap( operation, constraintsMap ); 230 } 231 } 232 return constraintsMap; 233 } 234 235 /** 236 * Extracts the constraint in the given <code>Operation</code> and adds it to the also supplied <code>Map</code>. 237 * The <code>Operation</code> must be of type OperationDefines.OR (with children that are all of type 238 * <code>PropertyIsCOMPOperations</code> or <code>BBOX</code>) or of type <code>PropertyIsCOMPOperation</code>( 239 * <code>BBOX</code>), in any other case this method will fail. 240 * 241 * @param operation 242 * @param map 243 * @throws SecurityException 244 */ 245 private void addConstraintToMap( Operation operation, Map<String, String[]> map ) 246 throws SecurityException { 247 248 PropertyPath constraintName = null; 249 String[] parameters = new String[1]; 250 251 if ( operation instanceof PropertyIsCOMPOperation ) { 252 PropertyIsCOMPOperation comparison = (PropertyIsCOMPOperation) operation; 253 try { 254 constraintName = ( (PropertyName) comparison.getFirstExpression() ).getValue(); 255 parameters[0] = ( (Literal) comparison.getSecondExpression() ).getValue(); 256 } catch ( ClassCastException e ) { 257 LOG.logDebug( e.getMessage(), e ); 258 throw new SecurityException( "Unable to reconstruct constraint map from stored filter expression." ); 259 } 260 } else if ( operation.getOperatorId() == OperationDefines.BBOX 261 || operation.getOperatorId() == OperationDefines.WITHIN 262 || operation.getOperatorId() == OperationDefines.CONTAINS ) { 263 constraintName = PropertyPathFactory.createPropertyPath( new QualifiedName( "bbox" ) ); 264 SpatialOperation spatialOperation = (SpatialOperation) operation; 265 Envelope envelope = spatialOperation.getGeometry().getEnvelope(); 266 try { 267 Position max = envelope.getMax(); 268 Position min = envelope.getMin(); 269 parameters = new String[4]; 270 parameters[0] = "" + min.getX(); 271 parameters[1] = "" + min.getY(); 272 parameters[2] = "" + max.getX(); 273 parameters[3] = "" + max.getY(); 274 } catch ( ClassCastException e ) { 275 LOG.logDebug( e.getMessage(), e ); 276 throw new SecurityException( "Unable to reconstruct constraint map from stored filter expression." ); 277 } 278 } else if ( operation.getOperatorId() == OperationDefines.OR ) { 279 LogicalOperation logical = (LogicalOperation) operation; 280 Iterator it = logical.getArguments().iterator(); 281 ArrayList<String> parameterList = new ArrayList<String>( 10 ); 282 while ( it.hasNext() ) { 283 try { 284 PropertyIsCOMPOperation argument = (PropertyIsCOMPOperation) it.next(); 285 PropertyName propertyName = (PropertyName) argument.getFirstExpression(); 286 if ( constraintName != null && ( !constraintName.equals( propertyName.getValue() ) ) ) { 287 throw new SecurityException( 288 "Unable to reconstruct constraint map from stored filter expression." ); 289 } 290 constraintName = propertyName.getValue(); 291 parameterList.add( ( (Literal) argument.getSecondExpression() ).getValue() ); 292 } catch ( ClassCastException e ) { 293 LOG.logDebug( e.getMessage(), e ); 294 throw new SecurityException( "Unable to reconstruct constraint map from stored filter expression. " 295 + "Invalid filter format." ); 296 } 297 } 298 parameters = parameterList.toArray( new String[parameterList.size()] ); 299 } else { 300 LOG.logDebug( "OperatorId = " + operation.getOperatorId() ); 301 throw new SecurityException( "Unable to reconstruct constraint map from stored filter expression: " 302 + operation ); 303 } 304 map.put( constraintName.getAsString(), parameters ); 305 } 306 }