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 }