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