001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/security/owsrequestvalidator/wms/GetFeatureInfoRequestValidator.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2001-2008 by:
006 EXSE, Department of Geography, University of Bonn
007 http://www.giub.uni-bonn.de/deegree/
008 lat/lon GmbH
009 http://www.lat-lon.de
010
011 This library is free software; you can redistribute it and/or
012 modify it under the terms of the GNU Lesser General Public
013 License as published by the Free Software Foundation; either
014 version 2.1 of the License, or (at your option) any later version.
015
016 This library is distributed in the hope that it will be useful,
017 but WITHOUT ANY WARRANTY; without even the implied warranty of
018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019 Lesser General Public License for more details.
020
021 You should have received a copy of the GNU Lesser General Public
022 License along with this library; if not, write to the Free Software
023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024
025 Contact:
026
027 Andreas Poth
028 lat/lon GmbH
029 Aennchenstr. 19
030 53177 Bonn
031 Germany
032 E-Mail: poth@lat-lon.de
033
034 Prof. Dr. Klaus Greve
035 Department of Geography
036 University of Bonn
037 Meckenheimer Allee 166
038 53115 Bonn
039 Germany
040 E-Mail: greve@giub.uni-bonn.de
041
042 ---------------------------------------------------------------------------*/
043 package org.deegree.security.owsrequestvalidator.wms;
044
045 import java.util.List;
046
047 import org.deegree.datatypes.QualifiedName;
048 import org.deegree.datatypes.Types;
049 import org.deegree.model.feature.Feature;
050 import org.deegree.model.feature.FeatureFactory;
051 import org.deegree.model.feature.FeatureProperty;
052 import org.deegree.model.feature.schema.FeatureType;
053 import org.deegree.model.feature.schema.PropertyType;
054 import org.deegree.ogcwebservices.InvalidParameterValueException;
055 import org.deegree.ogcwebservices.OGCWebServiceRequest;
056 import org.deegree.ogcwebservices.wms.operation.GetFeatureInfo;
057 import org.deegree.ogcwebservices.wms.operation.GetMap;
058 import org.deegree.security.UnauthorizedException;
059 import org.deegree.security.drm.model.RightType;
060 import org.deegree.security.drm.model.User;
061 import org.deegree.security.owsproxy.Condition;
062 import org.deegree.security.owsproxy.OperationParameter;
063 import org.deegree.security.owsproxy.Request;
064 import org.deegree.security.owsrequestvalidator.Messages;
065 import org.deegree.security.owsrequestvalidator.Policy;
066 import org.deegree.security.owsrequestvalidator.RequestValidator;
067
068 /**
069 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
070 * @author last edited by: $Author: apoth $
071 *
072 * @version 1.1, $Revision: 9346 $, $Date: 2007-12-27 17:39:07 +0100 (Do, 27 Dez 2007) $
073 *
074 * @since 1.1
075 */
076
077 class GetFeatureInfoRequestValidator extends RequestValidator {
078
079 // known condition parameter
080 private static final String INFOLAYERS = "featureInfoLayers";
081
082 private static final String INFOFORMAT = "infoFormat";
083
084 private static final String FEATURECOUNT = "maxFeatureCount";
085
086 private static final String INVALIDCLICKPOINT = Messages.getString( "GetFeatureInfoRequestValidator.INVALIDCLICKPOINT" );
087
088 private static final String INVALIDLAYER = Messages.getString( "GetFeatureInfoRequestValidator.INVALIDLAYER" );
089
090 private static final String INVALIDFORMAT = Messages.getString( "GetFeatureInfoRequestValidator.INVALIDFORMAT" );
091
092 private static final String INAVLIDFEATURECOUNT = Messages.getString( "GetFeatureInfoRequestValidator.INAVLIDFEATURECOUNT" );
093
094 private static FeatureType gfiFT = null;
095
096 static {
097 if ( gfiFT == null ) {
098 gfiFT = GetFeatureInfoRequestValidator.createFeatureType();
099 }
100 }
101
102 /**
103 * @param policy
104 */
105 public GetFeatureInfoRequestValidator( Policy policy ) {
106 super( policy );
107 }
108
109 /**
110 * validates the incomming GetFeatureInfo request against the policy assigend to a
111 * validator
112 *
113 * @param request request to validate
114 * @param user name of the user who likes to perform the request (can be null)
115 */
116 public void validateRequest( OGCWebServiceRequest request, User user )
117 throws InvalidParameterValueException, UnauthorizedException {
118
119 userCoupled = false;
120 Request req = policy.getRequest( "WMS", "GetFeatureInfo" );
121 // request is valid because no restrictions are made
122 if ( req.isAny() )
123 return;
124 Condition condition = req.getPreConditions();
125
126 GetFeatureInfo wmsreq = (GetFeatureInfo) request;
127
128 // validate the GetMap request contained in the
129 // GetFeatureInfo request
130 GetMapRequestValidator gmrv = new GetMapRequestValidator( policy );
131 GetMap gmr = wmsreq.getGetMapRequestCopy();
132 gmrv.validateRequest( gmr, user );
133
134 validateXY( gmr, wmsreq );
135 validateInfoLayers( condition, wmsreq.getQueryLayers() );
136 validateInfoFormat( condition, wmsreq.getInfoFormat() );
137 validateFeatureCount( condition, wmsreq.getFeatureCount() );
138
139 if ( userCoupled ) {
140 validateAgainstRightsDB( wmsreq, user );
141 }
142
143 }
144
145 /**
146 * validates the click point (x,y coordinate) to be located within the map image that
147 * has been base of the GetFeatureInfo request
148 *
149 * @param gmr
150 * @param gfir
151 * @throws InvalidParameterValueException
152 */
153 private void validateXY( GetMap gmr, GetFeatureInfo gfir )
154 throws InvalidParameterValueException {
155
156 int x = gfir.getClickPoint().x;
157 int y = gfir.getClickPoint().y;
158
159 int width = gmr.getWidth();
160 int height = gmr.getHeight();
161
162 if ( x < 0 || x >= width || y < 0 || y >= height ) {
163 throw new InvalidParameterValueException( INVALIDCLICKPOINT );
164 }
165
166 }
167
168 /**
169 * validates if the requested info layers layers are valid against the
170 * policy/condition. If the passed user <>null this is checked against the user- and
171 * rights-management system/repository
172 *
173 * @param condition
174 * @param layers
175 * @throws InvalidParameterValueException
176 */
177 private void validateInfoLayers( Condition condition, String[] layers )
178 throws InvalidParameterValueException {
179
180 OperationParameter op = condition.getOperationParameter( INFOLAYERS );
181
182 // version is valid because no restrictions are made
183 if ( op.isAny() )
184 return;
185
186 List validLayers = op.getValues();
187 if ( op.isUserCoupled() ) {
188 userCoupled = true;
189 } else {
190 for ( int i = 0; i < layers.length; i++ ) {
191 if ( !validLayers.contains( layers[i] ) ) {
192 throw new InvalidParameterValueException( INVALIDLAYER + layers[i] );
193 }
194 }
195 }
196 }
197
198 /**
199 * checks if the passed format is valid against the format defined in the policy. If
200 * <tt>user</ff> != <tt>null</tt> format
201 * will be compared against the user/rights repository
202 *
203 * @param condition condition containing the definition of the valid format
204 * @param format
205 * @throws InvalidParameterValueException
206 */
207 private void validateInfoFormat( Condition condition, String format )
208 throws InvalidParameterValueException {
209
210 OperationParameter op = condition.getOperationParameter( INFOFORMAT );
211
212 // version is valid because no restrictions are made
213 if ( op.isAny() ) {
214 return;
215 }
216
217 List list = op.getValues();
218 if ( op.isUserCoupled() ) {
219 userCoupled = true;
220 } else {
221 if ( !list.contains( format ) ) {
222 throw new InvalidParameterValueException( INVALIDFORMAT + format );
223 }
224 }
225
226 }
227
228 /**
229 * checks if the passed featureCount is valid against the featureCount defined in the
230 * policy and if it is greater zero. If
231 * <tt>user</ff> != <tt>null</tt> featureCount will be compared
232 * against the user/rights repository
233 *
234 * @param condition
235 * @param featureCount
236 * @throws InvalidParameterValueException
237 */
238 private void validateFeatureCount( Condition condition, int featureCount )
239 throws InvalidParameterValueException {
240
241 OperationParameter op = condition.getOperationParameter( FEATURECOUNT );
242
243 // version is valid because no restrictions are made
244 if ( op.isAny() )
245 return;
246
247 if ( op.isUserCoupled() ) {
248 userCoupled = true;
249 } else {
250 if ( featureCount < 1 || featureCount > op.getFirstAsInt() ) {
251 throw new InvalidParameterValueException( INAVLIDFEATURECOUNT + featureCount );
252 }
253 }
254 }
255
256 /**
257 * validates the passed WMS GetMap request against a User- and Rights-Management DB.
258 *
259 * @param wmsreq
260 * @param user
261 * @throws InvalidParameterValueException
262 */
263 private void validateAgainstRightsDB( GetFeatureInfo wmsreq, User user )
264 throws InvalidParameterValueException, UnauthorizedException {
265
266 if ( user == null ) {
267 throw new UnauthorizedException( "no access to anonymous user" );
268 }
269
270 // create feature that describes the map request
271 FeatureProperty[] fps = new FeatureProperty[6];
272 fps[0] = FeatureFactory.createFeatureProperty( new QualifiedName( "version" ), wmsreq.getVersion() );
273 Integer x = new Integer( wmsreq.getClickPoint().x );
274 fps[1] = FeatureFactory.createFeatureProperty( new QualifiedName( "x" ), x );
275 Integer y = new Integer( wmsreq.getClickPoint().y );
276 fps[2] = FeatureFactory.createFeatureProperty( new QualifiedName( "y" ), y );
277 fps[3] = FeatureFactory.createFeatureProperty( new QualifiedName( "infoformat" ), wmsreq.getInfoFormat() );
278 fps[4] = FeatureFactory.createFeatureProperty( new QualifiedName( "exceptions" ), wmsreq.getExceptions() );
279 Integer fc = new Integer( wmsreq.getFeatureCount() );
280 fps[5] = FeatureFactory.createFeatureProperty( new QualifiedName( "featurecount" ), fc );
281
282 Feature feature = FeatureFactory.createFeature( "id", gfiFT, fps );
283 String[] layer = wmsreq.getQueryLayers();
284 for ( int i = 0; i < layer.length; i++ ) {
285 handleUserCoupledRules( user, feature, layer[i], "Layer", RightType.GETFEATUREINFO );
286 }
287 }
288
289 private static FeatureType createFeatureType() {
290 PropertyType[] ftps = new PropertyType[6];
291 ftps[0] = FeatureFactory.createSimplePropertyType( new QualifiedName( "version" ),
292 Types.INTEGER, false );
293 ftps[1] = FeatureFactory.createSimplePropertyType( new QualifiedName( "x" ), Types.INTEGER,
294 false );
295 ftps[2] = FeatureFactory.createSimplePropertyType( new QualifiedName( "y" ), Types.INTEGER,
296 false );
297 ftps[3] = FeatureFactory.createSimplePropertyType( new QualifiedName( "infoformat" ),
298 Types.VARCHAR, false );
299 ftps[4] = FeatureFactory.createSimplePropertyType( new QualifiedName( "exceptions" ),
300 Types.VARCHAR, false );
301 ftps[5] = FeatureFactory.createSimplePropertyType( new QualifiedName( "featurecount" ),
302 Types.INTEGER, false );
303
304 return FeatureFactory.createFeatureType( "GetFeatureInfo", false, ftps );
305 }
306
307 }