001 //$HeadURL: http://svn.wald.intevation.org/svn/deegree/base/trunk/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.RightSet; 087 import org.deegree.security.drm.model.SecuredObject; 088 import org.deegree.security.drm.model.User; 089 import org.deegree.security.owsproxy.Condition; 090 import org.deegree.security.owsproxy.OperationParameter; 091 import org.deegree.security.owsproxy.Request; 092 import org.deegree.security.owsrequestvalidator.wms.GetMapRequestValidator; 093 import org.w3c.dom.Document; 094 095 /** 096 * 097 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a> 098 * @author last edited by: $Author: aschmitz $ 099 * 100 * @version $Revision: 32121 $, $Date: 2011-10-10 16:51:09 +0200 (Mo, 10 Okt 2011) $ 101 */ 102 public class GetCapabilitiesResponseValidator extends ResponseValidator { 103 104 private static final ILogger LOG = LoggerFactory.getLogger( GetCapabilitiesResponseValidator.class ); 105 106 private static final String INVALIDSERVICE = Messages.getString( "GetCapabilitiesResponseValidator.INVALIDSERVICE" ); 107 108 private String proxyURL = null; 109 110 private String proxiedURL; 111 112 /** 113 * @param policy 114 * @param proxyURL 115 */ 116 public GetCapabilitiesResponseValidator( Policy policy, String proxyURL ) { 117 super( policy ); 118 this.proxyURL = proxyURL; 119 this.proxiedURL = this.getPolicy().getSecurityConfig().getProxiedUrl(); 120 } 121 122 /** 123 * validates the passed object as a response to a OWS request. The validity of the response may is assigned to 124 * specific user rights. If the passed user is <>null this will be evaluated. <br> 125 * the reponse may contain three valid kinds of objects: 126 * <ul> 127 * <li>a serialized image 128 * <li>a xml encoded exception 129 * <li>a svg-encoded vector image 130 * </ul> 131 * Each of these types can be identified by the mime-type of the response that is also passed to the method. <br> 132 * If something basic went wrong it is possible that not further specified kind of object is passed as response. In 133 * this case the method will throw an <tt>InvalidParameterValueException</tt> to avoid sending bad responses to the 134 * client. 135 * 136 * @param service 137 * service which produced the response (WMS, WFS ...) 138 * @param response 139 * @param mime 140 * mime-type of the response 141 * @param user 142 * @return the new response array 143 * @throws InvalidParameterValueException 144 * @throws UnauthorizedException 145 * @see GetMapRequestValidator#validateRequest(OGCWebServiceRequest, User) 146 */ 147 @Override 148 public byte[] validateResponse( String service, byte[] response, String mime, User user ) 149 throws InvalidParameterValueException, UnauthorizedException { 150 151 Request req = policy.getRequest( service, "GetCapabilities" ); 152 if ( req == null ) { 153 throw new InvalidParameterValueException( INVALIDSERVICE + service ); 154 } 155 // request is valid because no restrictions are made 156 if ( req.isAny() || req.getPostConditions().isAny() ) { 157 return response; 158 } 159 160 if ( MimeTypeMapper.isKnownOGCType( mime ) ) { 161 // if the mime-type is a known OGC mime-type it must be an XML 162 // document. probably it is a capabilities document but it also 163 // could be an 164 response = validateXML( service, response, user ); 165 } else if ( mime.equals( "text/xml" ) ) { 166 // if the mime-type isn't an image type but 'text/xml' 167 // it could be an exception 168 response = validateXML( service, response, user ); 169 } else { 170 throw new InvalidParameterValueException( UNKNOWNMIMETYPE + mime ); 171 } 172 173 return response; 174 } 175 176 /** 177 * splits document string into 'core' capabilities document and xml header 178 * 179 * @param xml 180 * @return the splitted document 181 * @throws InvalidParameterValueException 182 */ 183 private String[] clearCapabilities( byte[] xml ) 184 throws InvalidParameterValueException { 185 InputStreamReader isr = new InputStreamReader( new ByteArrayInputStream( xml ) ); 186 StringBuffer sb = new StringBuffer( 50000 ); 187 int c = 0; 188 try { 189 while ( ( c = isr.read() ) > -1 ) { 190 sb.append( (char) c ); 191 } 192 isr.close(); 193 } catch ( IOException e ) { 194 String s = Messages.format( "GetCapabilitiesResponseValidator.CAPAREAD", e.getMessage() ); 195 throw new InvalidParameterValueException( s ); 196 } 197 // WMS <= 1.1.1 198 int pos = sb.indexOf( "<WMT_MS_Capabilities" ); 199 // WMS 1.3 200 if ( pos < 0 ) { 201 pos = sb.indexOf( "WMS_Capabilities" ); 202 } 203 // WFS 1.1.0 204 if ( pos < 0 ) { 205 pos = sb.indexOf( "WFS_Capabilities" ); 206 } 207 // CSW 2.0.0 208 if ( pos < 0 ) { 209 pos = sb.indexOf( "Capabilities" ); 210 } 211 // WCS 1.0.0 212 if ( pos < 0 ) { 213 pos = sb.indexOf( "WCS_Capabilities" ); 214 } 215 216 // just if pos is > -1 it makes sense to find the starting 217 // index of the root element 218 if ( pos > -1 ) { 219 pos = pos + 4; 220 char ch = '$'; 221 // find starting index of the root element 222 while ( ch != '<' && pos > 0 ) { 223 pos--; 224 ch = sb.charAt( pos ); 225 } 226 // if the least char read does not equal '<' the parsed document 227 // is not an XML document 228 if ( ch != '<' ) { 229 pos = -1; 230 } 231 } 232 String[] o = new String[2]; 233 if ( pos > 0 ) { 234 // XML header / doctype 235 o[0] = sb.substring( 0, pos ); 236 } else { 237 o[0] = ""; 238 } 239 if ( pos > -1 ) { 240 // xml document starting at the root element 241 o[1] = sb.substring( pos ); 242 } else { 243 // no XML document 244 o[0] = "ERROR"; 245 o[1] = sb.toString(); 246 } 247 248 return o; 249 } 250 251 /** 252 * validates the passed xml to be valid against the policy 253 * 254 * @param service 255 * service which produced the response (WMS, WFS ...) 256 * @param xml 257 * @param user 258 * @throws InvalidParameterValueException 259 */ 260 private byte[] validateXML( String service, byte[] xml, User user ) 261 throws InvalidParameterValueException, UnauthorizedException { 262 263 String[] st = clearCapabilities( xml ); 264 if ( st[0].equals( "ERROR" ) ) { 265 LOG.logError( st[1] ); 266 String s = Messages.format( "GetCapabilitiesResponseValidator.NOCAPADOC", st[1] ); 267 throw new InvalidParameterValueException( s ); 268 } 269 Document doc = null; 270 try { 271 XMLFragment frag = new XMLFragment(); 272 frag.load( new StringReader( st[1] ), XMLFragment.DEFAULT_URL ); 273 doc = frag.getRootElement().getOwnerDocument(); 274 } catch ( Exception e ) { 275 LOG.logError( e.getMessage(), e ); 276 String s = Messages.getString( "GetCapabilitiesResponseValidator.ALLCAPAPARSE" ); 277 throw new InvalidParameterValueException( s ); 278 } 279 String root = doc.getDocumentElement().getNodeName(); 280 if ( root.equalsIgnoreCase( "Exception" ) ) { 281 // if the xml contains a exception the reponse is valid! 282 } else if ( "WMS".equals( service ) ) { 283 try { 284 xml = validateWMSCapabilities( doc, user ); 285 } catch ( XMLParsingException e ) { 286 LOG.logError( e.getMessage(), e ); 287 throw new InvalidParameterValueException( "invalid WMS capabilities" ); 288 } 289 } else if ( "WFS".equals( service ) ) { 290 xml = validateWFSCapabilities( doc, user ); 291 } else if ( "WCS".equals( service ) ) { 292 xml = validateWCSCapabilities( doc, user ); 293 } else if ( "CSW".equals( service ) ) { 294 xml = validateCSWCapabilities( doc ); 295 } 296 297 StringBuffer sb = new StringBuffer( xml.length + st[0].length() ); 298 sb.append( st[0] ); 299 String s = new String( xml ); 300 int p = s.indexOf( "?>" ); 301 if ( p > -1 ) { 302 sb.append( s.substring( p + 2, s.length() ) ); 303 } else { 304 sb.append( s ); 305 } 306 s = sb.toString(); 307 if ( s.indexOf( "<?xml version" ) > 1 ) { 308 s = StringTools.replace( s, "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>", "", false ); 309 s = StringTools.replace( s, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "", false ); 310 } 311 312 // TODO 313 // regular expression 314 // s = sb.toString().replaceAll( "<?...?>", "" ); 315 316 return s.getBytes(); 317 } 318 319 /** 320 * 321 * @param doc 322 * @param user 323 * @return nothing, an exception is thrown 324 */ 325 private byte[] validateWCSCapabilities( Document doc, User user ) { 326 // TODO 327 // implement support for WCS 328 throw new UnsupportedOperationException(); 329 } 330 331 /** 332 * validates the passed xml to be valid against the policy 333 * 334 * @param user 335 * @throws InvalidParameterValueException 336 * @throws XMLParsingException 337 */ 338 private byte[] validateWMSCapabilities( Document doc, User user ) 339 throws InvalidParameterValueException, UnauthorizedException, XMLParsingException { 340 341 WMSCapabilitiesDocument cdoc = WMSCapabilitiesDocumentFactory.getWMSCapabilitiesDocument( doc.getDocumentElement() ); 342 WMSCapabilities capa = null; 343 try { 344 capa = (WMSCapabilities) cdoc.parseCapabilities(); 345 } catch ( InvalidCapabilitiesException e ) { 346 LOG.logError( e.getMessage(), e ); 347 String s = Messages.format( "GetCapabilitiesResponseValidator.WMSCAPAPARSE", e.getMessage() ); 348 throw new InvalidParameterValueException( s ); 349 } 350 capa = filterWMSLayers( capa, user ); 351 352 List<Operation> ops = capa.getOperationMetadata().getOperations(); 353 for ( Operation operation : ops ) { 354 setNewOnlineResource( operation ); 355 } 356 357 ByteArrayOutputStream bos = new ByteArrayOutputStream( 50000 ); 358 byte[] b; 359 try { 360 cdoc = XMLFactory.export( capa ); 361 Properties properties = new Properties(); 362 // setting this to system charset is no problem, as later on it will be converted to a different encoding 363 // again anyway 364 // not using byte arrays might solve the problems here... 365 properties.setProperty( OutputKeys.ENCODING, getSystemCharset() ); 366 cdoc.write( bos, properties ); 367 b = bos.toByteArray(); 368 bos.close(); 369 } catch ( Exception e ) { 370 LOG.logError( e.getMessage(), e ); 371 String s = Messages.format( "GetCapabilitiesResponseValidator.WMSCAPAEXPORT", e.getMessage() ); 372 throw new InvalidParameterValueException( s ); 373 } 374 375 return b; 376 377 } 378 379 /** 380 * 381 * @param op 382 */ 383 private void setNewOnlineResource( Operation op ) { 384 if ( op.getDCP() != null ) { 385 List<DCP> dcps = op.getDCP(); 386 for ( DCP dcp : dcps ) { 387 HTTP http = (HTTP) dcp; 388 List<OnlineResource> links = http.getLinks(); 389 try { 390 int size = links.size(); 391 links.clear(); 392 OnlineResource proxy = new OnlineResource( new Linkage( new URL( proxyURL ) ) ); 393 for ( int i = 0; i < size; ++i ) 394 links.add( proxy ); 395 } catch ( MalformedURLException e1 ) { 396 LOG.logError( e1.getLocalizedMessage(), e1 ); 397 } 398 } 399 } 400 } 401 402 /** 403 * Sets the proxy online resource in the old owscommon Operation class. To be removed soon! 404 * 405 * @param op 406 */ 407 private void setNewOnlineResourceInOldOperation( org.deegree.ogcwebservices.getcapabilities.Operation op ) { 408 if ( op.getDCPs() != null ) { 409 for ( int i = 0; i < op.getDCPs().length; i++ ) { 410 org.deegree.ogcwebservices.getcapabilities.HTTP http = (org.deegree.ogcwebservices.getcapabilities.HTTP) op.getDCPs()[i].getProtocol(); 411 try { 412 if ( http.getGetOnlineResources().length > 0 ) { 413 URL urls[] = new URL[http.getGetOnlineResources().length]; 414 for ( int k = 0; k < http.getGetOnlineResources().length; ++k ) 415 urls[k] = new URL( proxyURL ); 416 http.setGetOnlineResources( urls ); 417 } 418 if ( http.getPostOnlineResources().length > 0 ) { 419 URL urls[] = new URL[http.getPostOnlineResources().length]; 420 for ( int k = 0; k < http.getPostOnlineResources().length; ++k ) 421 urls[k] = new URL( proxyURL ); 422 http.setPostOnlineResources( urls ); 423 } 424 } catch ( MalformedURLException e1 ) { 425 e1.printStackTrace(); 426 } 427 } 428 } 429 } 430 431 /** 432 * validates the passed xml to be valid against the policy 433 * 434 * @param user 435 * @throws InvalidParameterValueException 436 * @throws UnauthorizedException 437 */ 438 private byte[] validateWFSCapabilities( Document doc, User user ) 439 throws InvalidParameterValueException, UnauthorizedException { 440 441 WFSCapabilities capa = null; 442 try { 443 WFSCapabilitiesDocument capaDoc = new WFSCapabilitiesDocument(); 444 capaDoc.setRootElement( doc.getDocumentElement() ); 445 capa = (WFSCapabilities) capaDoc.parseCapabilities(); 446 } catch ( Exception e ) { 447 LOG.logError( e.getMessage(), e ); 448 String s = Messages.format( "GetCapabilitiesResponseValidator.INVALIDWFSCAPA", e.getMessage() ); 449 throw new InvalidParameterValueException( s ); 450 } 451 452 capa = filterWFSFeatureType( capa, user ); 453 454 org.deegree.ogcwebservices.getcapabilities.Operation[] ops = capa.getOperationsMetadata().getOperations(); 455 for ( int i = 0; i < ops.length; i++ ) { 456 setNewOnlineResourceInOldOperation( ops[i] ); 457 } 458 459 WFSCapabilitiesDocument capaDoc = null; 460 try { 461 capaDoc = org.deegree.ogcwebservices.wfs.XMLFactory.export( capa ); 462 } catch ( Exception e ) { 463 throw new InvalidParameterValueException( e ); 464 } 465 ByteArrayOutputStream bos = new ByteArrayOutputStream( 20000 ); 466 PrintWriter pr = new PrintWriter( bos ); 467 capaDoc.write( pr ); 468 return bos.toByteArray(); 469 470 } 471 472 /** 473 * validates the passed xml to be valid against the policy 474 * 475 * @param doc 476 * @return the new response 477 * @throws InvalidParameterValueException 478 */ 479 private byte[] validateCSWCapabilities( Document doc ) 480 throws InvalidParameterValueException { 481 CatalogueCapabilities capa = null; 482 try { 483 CatalogueCapabilitiesDocument capaDoc = new CatalogueCapabilitiesDocument(); 484 capaDoc.setRootElement( doc.getDocumentElement() ); 485 capa = (CatalogueCapabilities) capaDoc.parseCapabilities(); 486 } catch ( Exception e ) { 487 LOG.logError( e.getMessage(), e ); 488 throw new InvalidParameterValueException( 489 Messages.format( "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 RightSet rights = user.getRights( access, secObj, GETMAP ); 629 if ( secObj == null || rights == null ) { 630 // remove the layer from the capabilities if it's not known 631 // by the DRM registry or if the user doesn't have a GetMap 632 // right on it 633 layer.removeLayer( layers[i].getName() ); 634 } 635 } else { 636 removeWMSLayer( layers[i], user, access ); 637 if ( layers[i].getLayer().length == 0 && layers[i].getName() == null ) { 638 layer.removeLayerByTitle( layers[i].getTitle() ); 639 } 640 } 641 } 642 return layer; 643 } 644 645 /** 646 * @param capa 647 * @param user 648 * @return the new capabilities 649 * @throws UnauthorizedException 650 */ 651 private WFSCapabilities filterWFSFeatureType( WFSCapabilities capa, User user ) 652 throws UnauthorizedException { 653 654 Request req = policy.getRequest( "WFS", "GetCapabilities" ); 655 Condition con = req.getPostConditions(); 656 OperationParameter op = con.getOperationParameter( "featureTypes" ); 657 if ( op.isAny() ) 658 return capa; 659 660 if ( op.isUserCoupled() && user != null ) { 661 try { 662 SecurityAccessManager sam = SecurityAccessManager.getInstance(); 663 SecurityAccess access = sam.acquireAccess( user ); 664 FeatureTypeList ftl = capa.getFeatureTypeList(); 665 WFSFeatureType[] ft = ftl.getFeatureTypes(); 666 StringBuffer sb = new StringBuffer( 200 ); 667 for ( int i = 0; i < ft.length; i++ ) { 668 SecuredObject secObj = null; 669 try { 670 // must be in try-catch block because an exception will be thrown 671 // if no SecuredObject with the passed layer exists 672 sb.delete( 0, sb.length() ); 673 sb.append( '{' ).append( ft[i].getName().getNamespace().toASCIIString() ); 674 sb.append( "}:" ).append( ft[i].getName().getLocalName() ); 675 if ( policy.getSecurityConfig().getProxiedUrl() == null ) { 676 secObj = access.getSecuredObjectByName( sb.toString(), "Featuretype" ); 677 } else { 678 secObj = access.getSecuredObjectByName( "[" + policy.getSecurityConfig().getProxiedUrl() 679 + "]:" + sb, "Featuretype" ); 680 } 681 } catch ( Exception e ) { 682 LOG.logDebug( "Lookup failed? ", e.getLocalizedMessage() ); 683 } 684 if ( secObj == null || user.getRights( access, secObj, GETFEATURE ) == null ) { 685 ftl.removeFeatureType( ft[i] ); 686 } 687 } 688 } catch ( Exception e ) { 689 LOG.logError( e.getMessage(), e ); 690 throw new UnauthorizedException( Messages.format( "GetCapabilitiesResponseValidator.INVALIDUSER", user ) ); 691 } 692 } else { 693 // get list of valid wms layers 694 List<String> list = op.getValues(); 695 FeatureTypeList ftl = capa.getFeatureTypeList(); 696 WFSFeatureType[] ft = ftl.getFeatureTypes(); 697 StringBuffer sb = new StringBuffer( 200 ); 698 for ( int i = 0; i < ft.length; i++ ) { 699 sb.delete( 0, sb.length() ); 700 sb.append( '{' ).append( ft[i].getName().getNamespace().toASCIIString() ); 701 sb.append( "}:" ).append( ft[i].getName().getLocalName() ); 702 if ( !list.contains( sb.toString() ) ) { 703 ftl.removeFeatureType( ft[i] ); 704 } 705 } 706 } 707 708 return capa; 709 } 710 }