001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/security/owsrequestvalidator/wms/GetLegendGraphicRequestValidator.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.security.owsrequestvalidator.wms;
037    
038    import static org.deegree.security.drm.model.RightType.GETLEGENDGRAPHIC;
039    
040    import java.net.URL;
041    import java.util.HashMap;
042    import java.util.List;
043    import java.util.Map;
044    
045    import org.deegree.datatypes.QualifiedName;
046    import org.deegree.datatypes.Types;
047    import org.deegree.framework.util.StringTools;
048    import org.deegree.framework.xml.XMLParsingException;
049    import org.deegree.graphics.sld.SLDFactory;
050    import org.deegree.model.feature.Feature;
051    import org.deegree.model.feature.FeatureFactory;
052    import org.deegree.model.feature.FeatureProperty;
053    import org.deegree.model.feature.schema.FeatureType;
054    import org.deegree.model.feature.schema.PropertyType;
055    import org.deegree.ogcwebservices.InvalidParameterValueException;
056    import org.deegree.ogcwebservices.OGCWebServiceRequest;
057    import org.deegree.ogcwebservices.wms.operation.GetLegendGraphic;
058    import org.deegree.security.UnauthorizedException;
059    import org.deegree.security.drm.model.User;
060    import org.deegree.security.owsproxy.Condition;
061    import org.deegree.security.owsproxy.OperationParameter;
062    import org.deegree.security.owsproxy.Request;
063    import org.deegree.security.owsrequestvalidator.Messages;
064    import org.deegree.security.owsrequestvalidator.Policy;
065    
066    /**
067     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
068     * @author last edited by: $Author: mschneider $
069     *
070     * @version 1.1, $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
071     *
072     * @since 1.1
073     */
074    
075    class GetLegendGraphicRequestValidator extends AbstractWMSRequestValidator {
076    
077        // known condition parameter
078        private static final String LAYER = "layers";
079    
080        private static final String SLD = "sld";
081    
082        private static final String INVALIDSLD = Messages.getString( "GetLegendGraphicRequestValidator.INVALIDSLD" );
083    
084        private static final String INVALIDLAYER = Messages.getString( "GetLegendGraphicRequestValidator.INVALIDLAYER" );
085    
086        private static final String INVALIDSTYLE = Messages.getString( "GetLegendGraphicRequestValidator.INVALIDSTYLE" );
087    
088        private static FeatureType glgFT = null;
089    
090        static {
091            if ( glgFT == null ) {
092                glgFT = GetLegendGraphicRequestValidator.createFeatureType();
093            }
094        }
095    
096        /**
097         * @param policy
098         */
099        public GetLegendGraphicRequestValidator( Policy policy ) {
100            super( policy );
101        }
102    
103        /**
104         * validates the incomming GetLegendGraphic request against the policy assigend to a validator
105         *
106         * @param request
107         *            request to validate
108         * @param user
109         *            name of the user who likes to perform the request (can be null)
110         */
111        @Override
112        public void validateRequest( OGCWebServiceRequest request, User user )
113                                throws InvalidParameterValueException, UnauthorizedException {
114    
115            userCoupled = false;
116            Request req = policy.getRequest( "WMS", "GetLegendGraphic" );
117            // request is valid because no restrictions are made
118            if ( req.isAny() || req.getPreConditions().isAny() ) {
119                return;
120            }
121            Condition condition = req.getPreConditions();
122    
123            GetLegendGraphic wmsreq = (GetLegendGraphic) request;
124    
125            validateVersion( condition, wmsreq.getVersion() );
126            validateLayer( condition, wmsreq.getLayer(), wmsreq.getStyle() );
127            validateExceptions( condition, wmsreq.getExceptions() );
128            validateFormat( condition, wmsreq.getFormat() );
129            validateMaxWidth( condition, wmsreq.getWidth() );
130            validateMaxHeight( condition, wmsreq.getHeight() );
131            validateSLD( condition, wmsreq.getSLD() );
132    
133            if ( userCoupled ) {
134                validateAgainstRightsDB( wmsreq, user );
135            }
136    
137        }
138    
139        /**
140         * validates if the requested layer is valid against the policy/condition. If the passed user <> null this is
141         * checked against the user- and rights-management system/repository
142         *
143         * @param condition
144         * @param layer
145         * @throws InvalidParameterValueException
146         */
147        private void validateLayer( Condition condition, String layer, String style )
148                                throws InvalidParameterValueException {
149    
150            OperationParameter op = condition.getOperationParameter( LAYER );
151    
152            // version is valid because no restrictions are made
153            if ( op.isAny() ) {
154                return;
155            }
156    
157            List<String> v = op.getValues();
158    
159            // seperate layers from assigned styles
160            Map<String, String> map = new HashMap<String, String>();
161            for ( int i = 0; i < v.size(); i++ ) {
162                String[] tmp = StringTools.toArray( v.get( i ), "|", false );
163                map.put( tmp[0], tmp[1] );
164            }
165    
166            String vs = map.get( layer );
167    
168            if ( vs == null ) {
169                if ( !op.isUserCoupled() ) {
170                    throw new InvalidParameterValueException( INVALIDLAYER + layer );
171                }
172                userCoupled = true;
173            } else if ( !style.equalsIgnoreCase( "default" ) && vs.indexOf( "$any$" ) < 0 && vs.indexOf( style ) < 0 ) {
174                if ( !op.isUserCoupled() ) {
175                    // a style is valid for a layer if it's the default style
176                    // or the layer accepts any style or a style is explicit defined
177                    // to be valid
178                    throw new InvalidParameterValueException( INVALIDSTYLE + layer + ':' + style );
179                }
180                userCoupled = true;
181            }
182    
183        }
184    
185        /**
186         * checks if the passed reference to a SLD document is valid against the defined in the policy. If
187         * <tt>user</ff> != <tt>null</tt> the valid sld reference addresses will be read from the user/rights repository
188         *
189         * @param condition
190         *            condition containing the definition of the valid sldRef
191         * @param sldRef
192         * @throws InvalidParameterValueException
193         */
194        private void validateSLD( Condition condition, URL sldRef )
195                                throws InvalidParameterValueException {
196    
197            OperationParameter op = condition.getOperationParameter( SLD );
198    
199            if ( op == null && sldRef != null ) {
200                throw new InvalidParameterValueException( INVALIDSLD + sldRef );
201            }
202    
203            // sldRef is valid because no restrictions are made
204            if ( sldRef == null || op.isAny() )
205                return;
206    
207            List<String> list = op.getValues();
208            String port = null;
209            if ( sldRef.getPort() != -1 ) {
210                port = ":" + sldRef.getPort();
211            } else {
212                port = ":80";
213            }
214            String addr = sldRef.getProtocol() + "://" + sldRef.getHost() + port;
215            if ( !list.contains( addr ) ) {
216                if ( !op.isUserCoupled() ) {
217                    throw new InvalidParameterValueException( INVALIDSLD + sldRef );
218                }
219                userCoupled = true;
220            }
221    
222            try {
223                SLDFactory.createSLD( sldRef );
224            } catch ( XMLParsingException e ) {
225                String s = org.deegree.i18n.Messages.getMessage( "WMS_SLD_IS_NOT_VALID", sldRef );
226                throw new InvalidParameterValueException( s );
227            }
228        }
229    
230        /**
231         * validates the passed WMS GetMap request against a User- and Rights-Management DB.
232         *
233         * @param wmsreq
234         * @throws InvalidParameterValueException
235         */
236        private void validateAgainstRightsDB( GetLegendGraphic wmsreq, User user )
237                                throws InvalidParameterValueException, UnauthorizedException {
238    
239            if ( user == null ) {
240                throw new UnauthorizedException( "no access to anonymous user" );
241            }
242    
243            // create feature that describes the map request
244            FeatureProperty[] fps = new FeatureProperty[7];
245            fps[0] = FeatureFactory.createFeatureProperty( new QualifiedName( "version" ), wmsreq.getVersion() );
246            fps[1] = FeatureFactory.createFeatureProperty( new QualifiedName( "width" ), new Integer( wmsreq.getWidth() ) );
247            fps[2] = FeatureFactory.createFeatureProperty( new QualifiedName( "height" ), new Integer( wmsreq.getHeight() ) );
248            fps[3] = FeatureFactory.createFeatureProperty( new QualifiedName( "format" ), wmsreq.getFormat() );
249            fps[4] = FeatureFactory.createFeatureProperty( new QualifiedName( "exceptions" ), wmsreq.getExceptions() );
250            fps[5] = FeatureFactory.createFeatureProperty( new QualifiedName( "sld" ), wmsreq.getSLD() );
251            fps[6] = FeatureFactory.createFeatureProperty( new QualifiedName( "style" ), wmsreq.getStyle() );
252            Feature feature = FeatureFactory.createFeature( "id", glgFT, fps );
253            if ( securityConfig.getProxiedUrl() == null ) {
254                handleUserCoupledRules( user, feature, wmsreq.getLayer(), "Layer", GETLEGENDGRAPHIC );
255            } else {
256                handleUserCoupledRules( user, feature, "[" + securityConfig.getProxiedUrl() + "]:" + wmsreq.getLayer(),
257                                        "Layer", GETLEGENDGRAPHIC );
258            }
259    
260        }
261    
262        /**
263         * creates a feature type that matches the parameters of a GetLagendGraphic request
264         *
265         * @return created <tt>FeatureType</tt>
266         */
267        private static FeatureType createFeatureType() {
268            PropertyType[] ftps = new PropertyType[7];
269            ftps[0] = FeatureFactory.createSimplePropertyType( new QualifiedName( "version" ), Types.VARCHAR, false );
270            ftps[1] = FeatureFactory.createSimplePropertyType( new QualifiedName( "width" ), Types.INTEGER, false );
271            ftps[2] = FeatureFactory.createSimplePropertyType( new QualifiedName( "height" ), Types.INTEGER, false );
272            ftps[3] = FeatureFactory.createSimplePropertyType( new QualifiedName( "format" ), Types.VARCHAR, false );
273            ftps[4] = FeatureFactory.createSimplePropertyType( new QualifiedName( "exceptions" ), Types.VARCHAR, false );
274            ftps[5] = FeatureFactory.createSimplePropertyType( new QualifiedName( "sld" ), Types.VARCHAR, false );
275            ftps[6] = FeatureFactory.createSimplePropertyType( new QualifiedName( "style" ), Types.VARCHAR, false );
276    
277            return FeatureFactory.createFeatureType( "GetLegendGraphic", false, ftps );
278        }
279    
280    }