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 }