001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_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: 25547 $, $Date: 2010-07-27 17:11:57 +0200 (Di, 27 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 String externalForm = link.toExternalForm();
558 if ( externalForm.startsWith( proxiedURL ) ) {
559 url.setOnlineResource( new URL( externalForm.replace( proxiedURL, proxyURL ) ) );
560 } else if ( externalForm.contains( "GetLegendGraphic" ) ) {
561 String[] parts = externalForm.split( "\\?" );
562 url.setOnlineResource( new URL( proxyURL + "?" + parts[1] ) );
563 }
564 } catch ( MalformedURLException e ) {
565 LOG.logDebug( "A modified legend URL could not be created." );
566 }
567 }
568 }
569 }
570 }
571 for ( Layer l : layer.getLayer() ) {
572 updateLegendURLs( l );
573 }
574 }
575
576 /**
577 * recursive method that removes all 'named' layers (layers that has a name in addtion to a title) from the layer
578 * tree thats root node (layer) is passed to the method and that not present in the passed <tt>List</tt>
579 *
580 * @param layer
581 * @param validLayers
582 */
583 private Layer removeWMSLayer( Layer layer, List<?> validLayers ) {
584 Layer[] layers = layer.getLayer();
585 for ( int i = 0; i < layers.length; i++ ) {
586 if ( layers[i].getName() != null && !validLayers.contains( layers[i].getName() ) ) {
587 layer.removeLayer( layers[i].getName() );
588 } else {
589 removeWMSLayer( layers[i], validLayers );
590 if ( layers[i].getLayer().length == 0 && layers[i].getName() == null ) {
591 layer.removeLayerByTitle( layers[i].getTitle() );
592 }
593 }
594 }
595 return layer;
596 }
597
598 /**
599 * recursive method that removes all 'named' layers (layers that has a name in addition to a title) from the layer
600 * tree thats root node (layer) is passed to the method and the passed user doesn't have a GetMap right on.
601 *
602 * @param layer
603 * layer to validate
604 * @param user
605 * user whose rights are considered
606 * @param access
607 * object to access DRM registry
608 *
609 */
610 private Layer removeWMSLayer( Layer layer, User user, SecurityAccess access )
611 throws GeneralSecurityException {
612 Layer[] layers = layer.getLayer();
613 for ( int i = 0; i < layers.length; i++ ) {
614 if ( layers[i].getName() != null ) {
615 SecuredObject secObj = null;
616 try {
617 // must be in try-catch block because an exception will be thrown
618 // if no SecuredObject with the passed layer exists
619 if ( policy.getSecurityConfig().getProxiedUrl() == null ) {
620 secObj = access.getSecuredObjectByName( layers[i].getName(), "Layer" );
621 } else {
622 secObj = access.getSecuredObjectByName( "[" + policy.getSecurityConfig().getProxiedUrl() + "]:"
623 + layers[i].getName(), "Layer" );
624 }
625 } catch ( Exception e ) {
626 LOG.logDebug( "Lookup failed? ", e.getLocalizedMessage() );
627 }
628 if ( secObj == null || user.getRights( access, secObj ).getRight( secObj, GETMAP ) == null ) {
629 // remove the layer from the capabilities if it's not known
630 // by the DRM registry or if the user doesn't have a GetMap
631 // right on it
632 layer.removeLayer( layers[i].getName() );
633 }
634 } else {
635 removeWMSLayer( layers[i], user, access );
636 if ( layers[i].getLayer().length == 0 && layers[i].getName() == null ) {
637 layer.removeLayerByTitle( layers[i].getTitle() );
638 }
639 }
640 }
641 return layer;
642 }
643
644 /**
645 * @param capa
646 * @param user
647 * @return the new capabilities
648 * @throws UnauthorizedException
649 */
650 private WFSCapabilities filterWFSFeatureType( WFSCapabilities capa, User user )
651 throws UnauthorizedException {
652
653 Request req = policy.getRequest( "WFS", "GetCapabilities" );
654 Condition con = req.getPostConditions();
655 OperationParameter op = con.getOperationParameter( "featureTypes" );
656 if ( op.isAny() )
657 return capa;
658
659 if ( op.isUserCoupled() && user != null ) {
660 try {
661 SecurityAccessManager sam = SecurityAccessManager.getInstance();
662 SecurityAccess access = sam.acquireAccess( user );
663 FeatureTypeList ftl = capa.getFeatureTypeList();
664 WFSFeatureType[] ft = ftl.getFeatureTypes();
665 StringBuffer sb = new StringBuffer( 200 );
666 for ( int i = 0; i < ft.length; i++ ) {
667 SecuredObject secObj = null;
668 try {
669 // must be in try-catch block because an exception will be thrown
670 // if no SecuredObject with the passed layer exists
671 sb.delete( 0, sb.length() );
672 sb.append( '{' ).append( ft[i].getName().getNamespace().toASCIIString() );
673 sb.append( "}:" ).append( ft[i].getName().getLocalName() );
674 if ( policy.getSecurityConfig().getProxiedUrl() == null ) {
675 secObj = access.getSecuredObjectByName( sb.toString(), "Featuretype" );
676 } else {
677 secObj = access.getSecuredObjectByName( "[" + policy.getSecurityConfig().getProxiedUrl()
678 + "]:" + sb, "Featuretype" );
679 }
680 } catch ( Exception e ) {
681 LOG.logDebug( "Lookup failed? ", e.getLocalizedMessage() );
682 }
683 if ( secObj == null || user.getRights( access, secObj ).getRight( secObj, GETFEATURE ) == null ) {
684 ftl.removeFeatureType( ft[i] );
685 }
686 }
687 } catch ( Exception e ) {
688 LOG.logError( e.getMessage(), e );
689 throw new UnauthorizedException( Messages.format( "GetCapabilitiesResponseValidator.INVALIDUSER", user ) );
690 }
691 } else {
692 // get list of valid wms layers
693 List<String> list = op.getValues();
694 FeatureTypeList ftl = capa.getFeatureTypeList();
695 WFSFeatureType[] ft = ftl.getFeatureTypes();
696 StringBuffer sb = new StringBuffer( 200 );
697 for ( int i = 0; i < ft.length; i++ ) {
698 sb.delete( 0, sb.length() );
699 sb.append( '{' ).append( ft[i].getName().getNamespace().toASCIIString() );
700 sb.append( "}:" ).append( ft[i].getName().getLocalName() );
701 if ( !list.contains( sb.toString() ) ) {
702 ftl.removeFeatureType( ft[i] );
703 }
704 }
705 }
706
707 return capa;
708 }
709 }