001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/security/owsrequestvalidator/GetCapabilitiesResponseValidator.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;
037
038 import static org.deegree.framework.util.CharsetUtils.getSystemCharset;
039 import static org.deegree.security.drm.model.RightType.GETFEATURE;
040 import static org.deegree.security.drm.model.RightType.GETMAP;
041
042 import java.io.ByteArrayInputStream;
043 import java.io.ByteArrayOutputStream;
044 import java.io.IOException;
045 import java.io.InputStreamReader;
046 import java.io.PrintWriter;
047 import java.io.StringReader;
048 import java.net.MalformedURLException;
049 import java.net.URL;
050 import java.util.List;
051 import java.util.Properties;
052
053 import javax.xml.transform.OutputKeys;
054
055 import org.deegree.framework.log.ILogger;
056 import org.deegree.framework.log.LoggerFactory;
057 import org.deegree.framework.util.MimeTypeMapper;
058 import org.deegree.framework.util.StringTools;
059 import org.deegree.framework.xml.XMLFragment;
060 import org.deegree.framework.xml.XMLParsingException;
061 import org.deegree.model.metadata.iso19115.Linkage;
062 import org.deegree.model.metadata.iso19115.OnlineResource;
063 import org.deegree.ogcwebservices.InvalidParameterValueException;
064 import org.deegree.ogcwebservices.OGCWebServiceRequest;
065 import org.deegree.ogcwebservices.csw.capabilities.CatalogueCapabilities;
066 import org.deegree.ogcwebservices.csw.capabilities.CatalogueCapabilitiesDocument;
067 import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException;
068 import org.deegree.ogcwebservices.wfs.capabilities.FeatureTypeList;
069 import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities;
070 import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument;
071 import org.deegree.ogcwebservices.wfs.capabilities.WFSFeatureType;
072 import org.deegree.ogcwebservices.wms.XMLFactory;
073 import org.deegree.ogcwebservices.wms.capabilities.Layer;
074 import org.deegree.ogcwebservices.wms.capabilities.LegendURL;
075 import org.deegree.ogcwebservices.wms.capabilities.Style;
076 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilities;
077 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument;
078 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocumentFactory;
079 import org.deegree.owscommon_new.DCP;
080 import org.deegree.owscommon_new.HTTP;
081 import org.deegree.owscommon_new.Operation;
082 import org.deegree.security.GeneralSecurityException;
083 import org.deegree.security.UnauthorizedException;
084 import org.deegree.security.drm.SecurityAccess;
085 import org.deegree.security.drm.SecurityAccessManager;
086 import org.deegree.security.drm.model.SecuredObject;
087 import org.deegree.security.drm.model.User;
088 import org.deegree.security.owsproxy.Condition;
089 import org.deegree.security.owsproxy.OperationParameter;
090 import org.deegree.security.owsproxy.Request;
091 import org.deegree.security.owsrequestvalidator.wms.GetMapRequestValidator;
092 import org.w3c.dom.Document;
093
094 /**
095 *
096 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
097 * @author last edited by: $Author: aschmitz $
098 *
099 * @version $Revision: 25268 $, $Date: 2010-07-13 10:43:16 +0200 (Di, 13. Jul 2010) $
100 */
101 public class GetCapabilitiesResponseValidator extends ResponseValidator {
102
103 private static final ILogger LOG = LoggerFactory.getLogger( GetCapabilitiesResponseValidator.class );
104
105 private static final String INVALIDSERVICE = Messages.getString( "GetCapabilitiesResponseValidator.INVALIDSERVICE" );
106
107 private String proxyURL = null;
108
109 private String proxiedURL;
110
111 /**
112 * @param policy
113 * @param proxyURL
114 */
115 public GetCapabilitiesResponseValidator( Policy policy, String proxyURL ) {
116 super( policy );
117 this.proxyURL = proxyURL;
118 this.proxiedURL = this.getPolicy().getSecurityConfig().getProxiedUrl();
119 }
120
121 /**
122 * validates the passed object as a response to a OWS request. The validity of the response may is assigned to
123 * specific user rights. If the passed user is <>null this will be evaluated. <br>
124 * the reponse may contain three valid kinds of objects:
125 * <ul>
126 * <li>a serialized image
127 * <li>a xml encoded exception
128 * <li>a svg-encoded vector image
129 * </ul>
130 * Each of these types can be identified by the mime-type of the response that is also passed to the method. <br>
131 * If something basic went wrong it is possible that not further specified kind of object is passed as response. In
132 * this case the method will throw an <tt>InvalidParameterValueException</tt> to avoid sending bad responses to the
133 * client.
134 *
135 * @param service
136 * service which produced the response (WMS, WFS ...)
137 * @param response
138 * @param mime
139 * mime-type of the response
140 * @param user
141 * @return the new response array
142 * @throws InvalidParameterValueException
143 * @throws UnauthorizedException
144 * @see GetMapRequestValidator#validateRequest(OGCWebServiceRequest, User)
145 */
146 @Override
147 public byte[] validateResponse( String service, byte[] response, String mime, User user )
148 throws InvalidParameterValueException, UnauthorizedException {
149
150 Request req = policy.getRequest( service, "GetCapabilities" );
151 if ( req == null ) {
152 throw new InvalidParameterValueException( INVALIDSERVICE + service );
153 }
154 // request is valid because no restrictions are made
155 if ( req.isAny() || req.getPostConditions().isAny() ) {
156 return response;
157 }
158
159 if ( MimeTypeMapper.isKnownOGCType( mime ) ) {
160 // if the mime-type is a known OGC mime-type it must be an XML
161 // document. probably it is a capabilities document but it also
162 // could be an
163 response = validateXML( service, response, user );
164 } else if ( mime.equals( "text/xml" ) ) {
165 // if the mime-type isn't an image type but 'text/xml'
166 // it could be an exception
167 response = validateXML( service, response, user );
168 } else {
169 throw new InvalidParameterValueException( UNKNOWNMIMETYPE + mime );
170 }
171
172 return response;
173 }
174
175 /**
176 * splits document string into 'core' capabilities document and xml header
177 *
178 * @param xml
179 * @return the splitted document
180 * @throws InvalidParameterValueException
181 */
182 private String[] clearCapabilities( byte[] xml )
183 throws InvalidParameterValueException {
184 InputStreamReader isr = new InputStreamReader( new ByteArrayInputStream( xml ) );
185 StringBuffer sb = new StringBuffer( 50000 );
186 int c = 0;
187 try {
188 while ( ( c = isr.read() ) > -1 ) {
189 sb.append( (char) c );
190 }
191 isr.close();
192 } catch ( IOException e ) {
193 String s = Messages.format( "GetCapabilitiesResponseValidator.CAPAREAD", e.getMessage() );
194 throw new InvalidParameterValueException( s );
195 }
196 // WMS <= 1.1.1
197 int pos = sb.indexOf( "<WMT_MS_Capabilities" );
198 // WMS 1.3
199 if ( pos < 0 ) {
200 pos = sb.indexOf( "WMS_Capabilities" );
201 }
202 // WFS 1.1.0
203 if ( pos < 0 ) {
204 pos = sb.indexOf( "WFS_Capabilities" );
205 }
206 // CSW 2.0.0
207 if ( pos < 0 ) {
208 pos = sb.indexOf( "Capabilities" );
209 }
210 // WCS 1.0.0
211 if ( pos < 0 ) {
212 pos = sb.indexOf( "WCS_Capabilities" );
213 }
214
215 // just if pos is > -1 it makes sense to find the starting
216 // index of the root element
217 if ( pos > -1 ) {
218 pos = pos + 4;
219 char ch = '$';
220 // find starting index of the root element
221 while ( ch != '<' && pos > 0 ) {
222 pos--;
223 ch = sb.charAt( pos );
224 }
225 // if the least char read does not equal '<' the parsed document
226 // is not an XML document
227 if ( ch != '<' ) {
228 pos = -1;
229 }
230 }
231 String[] o = new String[2];
232 if ( pos > 0 ) {
233 // XML header / doctype
234 o[0] = sb.substring( 0, pos );
235 } else {
236 o[0] = "";
237 }
238 if ( pos > -1 ) {
239 // xml document starting at the root element
240 o[1] = sb.substring( pos );
241 } else {
242 // no XML document
243 o[0] = "ERROR";
244 o[1] = sb.toString();
245 }
246
247 return o;
248 }
249
250 /**
251 * validates the passed xml to be valid against the policy
252 *
253 * @param service
254 * service which produced the response (WMS, WFS ...)
255 * @param xml
256 * @param user
257 * @throws InvalidParameterValueException
258 */
259 private byte[] validateXML( String service, byte[] xml, User user )
260 throws InvalidParameterValueException, UnauthorizedException {
261
262 String[] st = clearCapabilities( xml );
263 if ( st[0].equals( "ERROR" ) ) {
264 LOG.logError( st[1] );
265 String s = Messages.format( "GetCapabilitiesResponseValidator.NOCAPADOC", st[1] );
266 throw new InvalidParameterValueException( s );
267 }
268 Document doc = null;
269 try {
270 XMLFragment frag = new XMLFragment();
271 frag.load( new StringReader( st[1] ), XMLFragment.DEFAULT_URL );
272 doc = frag.getRootElement().getOwnerDocument();
273 } catch ( Exception e ) {
274 LOG.logError( e.getMessage(), e );
275 String s = Messages.getString( "GetCapabilitiesResponseValidator.ALLCAPAPARSE" );
276 throw new InvalidParameterValueException( s );
277 }
278 String root = doc.getDocumentElement().getNodeName();
279 if ( root.equalsIgnoreCase( "Exception" ) ) {
280 // if the xml contains a exception the reponse is valid!
281 } else if ( "WMS".equals( service ) ) {
282 try {
283 xml = validateWMSCapabilities( doc, user );
284 } catch ( XMLParsingException e ) {
285 LOG.logError( e.getMessage(), e );
286 throw new InvalidParameterValueException( "invalid WMS capabilities" );
287 }
288 } else if ( "WFS".equals( service ) ) {
289 xml = validateWFSCapabilities( doc, user );
290 } else if ( "WCS".equals( service ) ) {
291 xml = validateWCSCapabilities( doc, user );
292 } else if ( "CSW".equals( service ) ) {
293 xml = validateCSWCapabilities( doc );
294 }
295
296 StringBuffer sb = new StringBuffer( xml.length + st[0].length() );
297 sb.append( st[0] );
298 String s = new String( xml );
299 int p = s.indexOf( "?>" );
300 if ( p > -1 ) {
301 sb.append( s.substring( p + 2, s.length() ) );
302 } else {
303 sb.append( s );
304 }
305 s = sb.toString();
306 if ( s.indexOf( "<?xml version" ) > 1 ) {
307 s = StringTools.replace( s, "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>", "", false );
308 s = StringTools.replace( s, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "", false );
309 }
310
311 // TODO
312 // regular expression
313 // s = sb.toString().replaceAll( "<?...?>", "" );
314
315 return s.getBytes();
316 }
317
318 /**
319 *
320 * @param doc
321 * @param user
322 * @return nothing, an exception is thrown
323 */
324 private byte[] validateWCSCapabilities( Document doc, User user ) {
325 // TODO
326 // implement support for WCS
327 throw new UnsupportedOperationException();
328 }
329
330 /**
331 * validates the passed xml to be valid against the policy
332 *
333 * @param user
334 * @throws InvalidParameterValueException
335 * @throws XMLParsingException
336 */
337 private byte[] validateWMSCapabilities( Document doc, User user )
338 throws InvalidParameterValueException, UnauthorizedException, XMLParsingException {
339
340 WMSCapabilitiesDocument cdoc = WMSCapabilitiesDocumentFactory.getWMSCapabilitiesDocument( doc.getDocumentElement() );
341 WMSCapabilities capa = null;
342 try {
343 capa = (WMSCapabilities) cdoc.parseCapabilities();
344 } catch ( InvalidCapabilitiesException e ) {
345 LOG.logError( e.getMessage(), e );
346 String s = Messages.format( "GetCapabilitiesResponseValidator.WMSCAPAPARSE", e.getMessage() );
347 throw new InvalidParameterValueException( s );
348 }
349 capa = filterWMSLayers( capa, user );
350
351 List<Operation> ops = capa.getOperationMetadata().getOperations();
352 for ( Operation operation : ops ) {
353 setNewOnlineResource( operation );
354 }
355
356 ByteArrayOutputStream bos = new ByteArrayOutputStream( 50000 );
357 byte[] b;
358 try {
359 cdoc = XMLFactory.export( capa );
360 Properties properties = new Properties();
361 // setting this to system charset is no problem, as later on it will be converted to a different encoding
362 // again anyway
363 // not using byte arrays might solve the problems here...
364 properties.setProperty( OutputKeys.ENCODING, getSystemCharset() );
365 cdoc.write( bos, properties );
366 b = bos.toByteArray();
367 bos.close();
368 } catch ( Exception e ) {
369 LOG.logError( e.getMessage(), e );
370 String s = Messages.format( "GetCapabilitiesResponseValidator.WMSCAPAEXPORT", e.getMessage() );
371 throw new InvalidParameterValueException( s );
372 }
373
374 return b;
375
376 }
377
378 /**
379 *
380 * @param op
381 */
382 private void setNewOnlineResource( Operation op ) {
383 if ( op.getDCP() != null ) {
384 List<DCP> dcps = op.getDCP();
385 for ( DCP dcp : dcps ) {
386 HTTP http = (HTTP) dcp;
387 List<OnlineResource> links = http.getLinks();
388 try {
389 int size = links.size();
390 links.clear();
391 OnlineResource proxy = new OnlineResource( new Linkage( new URL( proxyURL ) ) );
392 for ( int i = 0; i < size; ++i )
393 links.add( proxy );
394 } catch ( MalformedURLException e1 ) {
395 LOG.logError( e1.getLocalizedMessage(), e1 );
396 }
397 }
398 }
399 }
400
401 /**
402 * Sets the proxy online resource in the old owscommon Operation class. To be removed soon!
403 *
404 * @param op
405 */
406 private void setNewOnlineResourceInOldOperation( org.deegree.ogcwebservices.getcapabilities.Operation op ) {
407 if ( op.getDCPs() != null ) {
408 for ( int i = 0; i < op.getDCPs().length; i++ ) {
409 org.deegree.ogcwebservices.getcapabilities.HTTP http = (org.deegree.ogcwebservices.getcapabilities.HTTP) op.getDCPs()[i].getProtocol();
410 try {
411 if ( http.getGetOnlineResources().length > 0 ) {
412 URL urls[] = new URL[http.getGetOnlineResources().length];
413 for ( int k = 0; k < http.getGetOnlineResources().length; ++k )
414 urls[k] = new URL( proxyURL );
415 http.setGetOnlineResources( urls );
416 }
417 if ( http.getPostOnlineResources().length > 0 ) {
418 URL urls[] = new URL[http.getPostOnlineResources().length];
419 for ( int k = 0; k < http.getPostOnlineResources().length; ++k )
420 urls[k] = new URL( proxyURL );
421 http.setPostOnlineResources( urls );
422 }
423 } catch ( MalformedURLException e1 ) {
424 e1.printStackTrace();
425 }
426 }
427 }
428 }
429
430 /**
431 * validates the passed xml to be valid against the policy
432 *
433 * @param user
434 * @throws InvalidParameterValueException
435 * @throws UnauthorizedException
436 */
437 private byte[] validateWFSCapabilities( Document doc, User user )
438 throws InvalidParameterValueException, UnauthorizedException {
439
440 WFSCapabilities capa = null;
441 try {
442 WFSCapabilitiesDocument capaDoc = new WFSCapabilitiesDocument();
443 capaDoc.setRootElement( doc.getDocumentElement() );
444 capa = (WFSCapabilities) capaDoc.parseCapabilities();
445 } catch ( Exception e ) {
446 LOG.logError( e.getMessage(), e );
447 String s = Messages.format( "GetCapabilitiesResponseValidator.INVALIDWFSCAPA", e.getMessage() );
448 throw new InvalidParameterValueException( s );
449 }
450
451 capa = filterWFSFeatureType( capa, user );
452
453 org.deegree.ogcwebservices.getcapabilities.Operation[] ops = capa.getOperationsMetadata().getOperations();
454 for ( int i = 0; i < ops.length; i++ ) {
455 setNewOnlineResourceInOldOperation( ops[i] );
456 }
457
458 WFSCapabilitiesDocument capaDoc = null;
459 try {
460 capaDoc = org.deegree.ogcwebservices.wfs.XMLFactory.export( capa );
461 } catch ( Exception e ) {
462 throw new InvalidParameterValueException( e );
463 }
464 ByteArrayOutputStream bos = new ByteArrayOutputStream( 20000 );
465 PrintWriter pr = new PrintWriter( bos );
466 capaDoc.write( pr );
467 return bos.toByteArray();
468
469 }
470
471 /**
472 * validates the passed xml to be valid against the policy
473 *
474 * @param doc
475 * @return the new response
476 * @throws InvalidParameterValueException
477 */
478 private byte[] validateCSWCapabilities( Document doc )
479 throws InvalidParameterValueException {
480 CatalogueCapabilities capa = null;
481 try {
482 CatalogueCapabilitiesDocument capaDoc = new CatalogueCapabilitiesDocument();
483 capaDoc.setRootElement( doc.getDocumentElement() );
484 capa = (CatalogueCapabilities) capaDoc.parseCapabilities();
485 } catch ( Exception e ) {
486 LOG.logError( e.getMessage(), e );
487 throw new InvalidParameterValueException(
488 Messages.format(
489 "GetCapabilitiesResponseValidator.INVALIDWFSCAPA",
490 e.getMessage() ) );
491 }
492
493 org.deegree.ogcwebservices.getcapabilities.Operation[] ops = capa.getOperationsMetadata().getOperations();
494 for ( int i = 0; i < ops.length; i++ ) {
495 setNewOnlineResourceInOldOperation( ops[i] );
496 }
497
498 CatalogueCapabilitiesDocument capaDoc = null;
499 try {
500 capaDoc = org.deegree.ogcwebservices.csw.XMLFactory_2_0_0.export( capa, null );
501 } catch ( Exception e ) {
502 throw new InvalidParameterValueException( e );
503 }
504 ByteArrayOutputStream bos = new ByteArrayOutputStream( 20000 );
505 PrintWriter pr = new PrintWriter( bos );
506 capaDoc.write( pr );
507 return bos.toByteArray();
508 }
509
510 /**
511 * filters the wms capabilities to rturn just the valid layers
512 *
513 * @param capa
514 * @param user
515 */
516 private WMSCapabilities filterWMSLayers( WMSCapabilities capa, User user )
517 throws UnauthorizedException {
518
519 Request req = policy.getRequest( "WMS", "GetCapabilities" );
520 Condition con = req.getPostConditions();
521 OperationParameter op = con.getOperationParameter( "layers" );
522 if ( op.isAny() )
523 return capa;
524
525 Layer layer = capa.getLayer();
526 if ( op.isUserCoupled() && user != null ) {
527 try {
528 SecurityAccessManager sam = SecurityAccessManager.getInstance();
529 SecurityAccess access = sam.acquireAccess( user );
530 // call recursive method to remove all 'named' layers not
531 // included in the list from the capabilities
532 layer = removeWMSLayer( layer, user, access );
533 updateLegendURLs( layer );
534 } catch ( Exception e ) {
535 LOG.logError( e.getMessage(), e );
536 throw new UnauthorizedException( Messages.format( "GetCapabilitiesResponseValidator.INVALIDUSER", user ) );
537 }
538 } else {
539 // get list of valid wms layers
540 List<?> list = op.getValues();
541 // call recursive method to remove all 'named' layers not
542 // included in the list from the capabilities
543 layer = removeWMSLayer( layer, list );
544 }
545 capa.setLayer( layer );
546 return capa;
547
548 }
549
550 private void updateLegendURLs( Layer layer ) {
551 if ( proxiedURL != null && layer.getStyles() != null ) {
552 for ( Style style : layer.getStyles() ) {
553 if ( style.getLegendURL() != null ) {
554 for ( LegendURL url : style.getLegendURL() ) {
555 URL link = url.getOnlineResource();
556 try {
557 if ( link.toExternalForm().startsWith( proxiedURL ) ) {
558 url.setOnlineResource( new URL( link.toExternalForm().replace( proxiedURL, proxyURL ) ) );
559 }
560 } catch ( MalformedURLException e ) {
561 LOG.logDebug( "A modified legend URL could not be created." );
562 }
563 }
564 }
565 }
566 }
567 for ( Layer l : layer.getLayer() ) {
568 updateLegendURLs( l );
569 }
570 }
571
572 /**
573 * recursive method that removes all 'named' layers (layers that has a name in addtion to a title) from the layer
574 * tree thats root node (layer) is passed to the method and that not present in the passed <tt>List</tt>
575 *
576 * @param layer
577 * @param validLayers
578 */
579 private Layer removeWMSLayer( Layer layer, List<?> validLayers ) {
580 Layer[] layers = layer.getLayer();
581 for ( int i = 0; i < layers.length; i++ ) {
582 if ( layers[i].getName() != null && !validLayers.contains( layers[i].getName() ) ) {
583 layer.removeLayer( layers[i].getName() );
584 } else {
585 removeWMSLayer( layers[i], validLayers );
586 if ( layers[i].getLayer().length == 0 && layers[i].getName() == null ) {
587 layer.removeLayerByTitle( layers[i].getTitle() );
588 }
589 }
590 }
591 return layer;
592 }
593
594 /**
595 * recursive method that removes all 'named' layers (layers that has a name in addition to a title) from the layer
596 * tree thats root node (layer) is passed to the method and the passed user doesn't have a GetMap right on.
597 *
598 * @param layer
599 * layer to validate
600 * @param user
601 * user whose rights are considered
602 * @param access
603 * object to access DRM registry
604 *
605 */
606 private Layer removeWMSLayer( Layer layer, User user, SecurityAccess access )
607 throws GeneralSecurityException {
608 Layer[] layers = layer.getLayer();
609 for ( int i = 0; i < layers.length; i++ ) {
610 if ( layers[i].getName() != null ) {
611 SecuredObject secObj = null;
612 try {
613 // must be in try-catch block because an exception will be thrown
614 // if no SecuredObject with the passed layer exists
615 if ( policy.getSecurityConfig().getProxiedUrl() == null ) {
616 secObj = access.getSecuredObjectByName( layers[i].getName(), "Layer" );
617 } else {
618 secObj = access.getSecuredObjectByName( "[" + policy.getSecurityConfig().getProxiedUrl() + "]:"
619 + layers[i].getName(), "Layer" );
620 }
621 } catch ( Exception e ) {
622 LOG.logDebug( "Lookup failed? ", e.getLocalizedMessage() );
623 }
624 if ( secObj == null || user.getRights( access, secObj ).getRight( secObj, GETMAP ) == null ) {
625 // remove the layer from the capabilities if it's not known
626 // by the DRM registry or if the user doesn't have a GetMap
627 // right on it
628 layer.removeLayer( layers[i].getName() );
629 }
630 } else {
631 removeWMSLayer( layers[i], user, access );
632 if ( layers[i].getLayer().length == 0 && layers[i].getName() == null ) {
633 layer.removeLayerByTitle( layers[i].getTitle() );
634 }
635 }
636 }
637 return layer;
638 }
639
640 /**
641 * @param capa
642 * @param user
643 * @return the new capabilities
644 * @throws UnauthorizedException
645 */
646 private WFSCapabilities filterWFSFeatureType( WFSCapabilities capa, User user )
647 throws UnauthorizedException {
648
649 Request req = policy.getRequest( "WFS", "GetCapabilities" );
650 Condition con = req.getPostConditions();
651 OperationParameter op = con.getOperationParameter( "featureTypes" );
652 if ( op.isAny() )
653 return capa;
654
655 if ( op.isUserCoupled() && user != null ) {
656 try {
657 SecurityAccessManager sam = SecurityAccessManager.getInstance();
658 SecurityAccess access = sam.acquireAccess( user );
659 FeatureTypeList ftl = capa.getFeatureTypeList();
660 WFSFeatureType[] ft = ftl.getFeatureTypes();
661 StringBuffer sb = new StringBuffer( 200 );
662 for ( int i = 0; i < ft.length; i++ ) {
663 SecuredObject secObj = null;
664 try {
665 // must be in try-catch block because an exception will be thrown
666 // if no SecuredObject with the passed layer exists
667 sb.delete( 0, sb.length() );
668 sb.append( '{' ).append( ft[i].getName().getNamespace().toASCIIString() );
669 sb.append( "}:" ).append( ft[i].getName().getLocalName() );
670 if ( policy.getSecurityConfig().getProxiedUrl() == null ) {
671 secObj = access.getSecuredObjectByName( sb.toString(), "Featuretype" );
672 } else {
673 secObj = access.getSecuredObjectByName( "[" + policy.getSecurityConfig().getProxiedUrl()
674 + "]:" + sb, "Featuretype" );
675 }
676 } catch ( Exception e ) {
677 LOG.logDebug( "Lookup failed? ", e.getLocalizedMessage() );
678 }
679 if ( secObj == null || user.getRights( access, secObj ).getRight( secObj, GETFEATURE ) == null ) {
680 ftl.removeFeatureType( ft[i] );
681 }
682 }
683 } catch ( Exception e ) {
684 LOG.logError( e.getMessage(), e );
685 throw new UnauthorizedException( Messages.format( "GetCapabilitiesResponseValidator.INVALIDUSER", user ) );
686 }
687 } else {
688 // get list of valid wms layers
689 List<String> list = op.getValues();
690 FeatureTypeList ftl = capa.getFeatureTypeList();
691 WFSFeatureType[] ft = ftl.getFeatureTypes();
692 StringBuffer sb = new StringBuffer( 200 );
693 for ( int i = 0; i < ft.length; i++ ) {
694 sb.delete( 0, sb.length() );
695 sb.append( '{' ).append( ft[i].getName().getNamespace().toASCIIString() );
696 sb.append( "}:" ).append( ft[i].getName().getLocalName() );
697 if ( !list.contains( sb.toString() ) ) {
698 ftl.removeFeatureType( ft[i] );
699 }
700 }
701 }
702
703 return capa;
704 }
705 }