001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/security/owsrequestvalidator/GetCapabilitiesResponseValidator.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001-2008 by:
006     EXSE, Department of Geography, University of Bonn
007     http://www.giub.uni-bonn.de/deegree/
008     lat/lon GmbH
009     http://www.lat-lon.de
010    
011     This library is free software; you can redistribute it and/or
012     modify it under the terms of the GNU Lesser General Public
013     License as published by the Free Software Foundation; either
014     version 2.1 of the License, or (at your option) any later version.
015    
016     This library is distributed in the hope that it will be useful,
017     but WITHOUT ANY WARRANTY; without even the implied warranty of
018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019     Lesser General Public License for more details.
020    
021     You should have received a copy of the GNU Lesser General Public
022     License along with this library; if not, write to the Free Software
023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024    
025     Contact:
026    
027     Andreas Poth
028     lat/lon GmbH
029     Aennchenstr. 19
030     53177 Bonn
031     Germany
032     E-Mail: poth@lat-lon.de
033    
034     Prof. Dr. Klaus Greve
035     Department of Geography
036     University of Bonn
037     Meckenheimer Allee 166
038     53115 Bonn
039     Germany
040     E-Mail: greve@giub.uni-bonn.de
041    
042     ---------------------------------------------------------------------------*/
043    package org.deegree.security.owsrequestvalidator;
044    
045    import java.io.ByteArrayInputStream;
046    import java.io.ByteArrayOutputStream;
047    import java.io.IOException;
048    import java.io.InputStreamReader;
049    import java.io.PrintWriter;
050    import java.io.StringReader;
051    import java.net.MalformedURLException;
052    import java.net.URL;
053    import java.util.List;
054    import java.util.Properties;
055    
056    import javax.xml.transform.OutputKeys;
057    
058    import org.deegree.framework.log.ILogger;
059    import org.deegree.framework.log.LoggerFactory;
060    import org.deegree.framework.util.MimeTypeMapper;
061    import org.deegree.framework.util.StringTools;
062    import org.deegree.framework.xml.XMLFragment;
063    import org.deegree.framework.xml.XMLParsingException;
064    import org.deegree.model.metadata.iso19115.Linkage;
065    import org.deegree.model.metadata.iso19115.OnlineResource;
066    import org.deegree.ogcwebservices.InvalidParameterValueException;
067    import org.deegree.ogcwebservices.OGCWebServiceRequest;
068    import org.deegree.ogcwebservices.csw.capabilities.CatalogueCapabilities;
069    import org.deegree.ogcwebservices.csw.capabilities.CatalogueCapabilitiesDocument;
070    import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException;
071    import org.deegree.ogcwebservices.wfs.capabilities.FeatureTypeList;
072    import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities;
073    import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument;
074    import org.deegree.ogcwebservices.wfs.capabilities.WFSFeatureType;
075    import org.deegree.ogcwebservices.wms.XMLFactory;
076    import org.deegree.ogcwebservices.wms.capabilities.Layer;
077    import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilities;
078    import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument;
079    import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocumentFactory;
080    import org.deegree.owscommon_new.DCP;
081    import org.deegree.owscommon_new.HTTP;
082    import org.deegree.owscommon_new.Operation;
083    import org.deegree.security.GeneralSecurityException;
084    import org.deegree.security.UnauthorizedException;
085    import org.deegree.security.drm.SecurityAccess;
086    import org.deegree.security.drm.SecurityAccessManager;
087    import org.deegree.security.drm.model.RightType;
088    import org.deegree.security.drm.model.SecuredObject;
089    import org.deegree.security.drm.model.User;
090    import org.deegree.security.owsproxy.Condition;
091    import org.deegree.security.owsproxy.OperationParameter;
092    import org.deegree.security.owsproxy.Request;
093    import org.deegree.security.owsrequestvalidator.wms.GetMapRequestValidator;
094    import org.w3c.dom.Document;
095    
096    /**
097     * 
098     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
099     * @author last edited by: $Author: apoth $
100     * 
101     * @version $Revision: 9385 $, $Date: 2008-01-03 14:31:14 +0100 (Do, 03 Jan 2008) $
102     */
103    public class GetCapabilitiesResponseValidator extends ResponseValidator {
104    
105        private static final ILogger LOG = LoggerFactory.getLogger( GetCapabilitiesResponseValidator.class );
106    
107        private static final String INVALIDSERVICE = Messages.getString( "GetCapabilitiesResponseValidator.INVALIDSERVICE" );
108    
109        private String proxyURL = null;
110    
111        /**
112         * @param policy
113         * @param proxyURL
114         */
115        public GetCapabilitiesResponseValidator( Policy policy, String proxyURL ) {
116            super( policy );
117            this.proxyURL = proxyURL;
118        }
119    
120        /**
121         * validates the passed object as a response to a OWS request. The validity of the response may
122         * is assigned to specific user rights. If the passed user is <>null this will be evaluated.
123         * <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
131         * the method. <br>
132         * If something basic went wrong it is possible that not further specified kind of object is
133         * passed as response. In this case the method will throw an
134         * <tt>InvalidParameterValueException</tt> to avoid sending bad responses to the 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
143         * @throws InvalidParameterValueException
144         * @throws UnauthorizedException
145         * @see GetMapRequestValidator#validateRequest(OGCWebServiceRequest, User)
146         */
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() )
156                return response;
157    
158            if ( MimeTypeMapper.isKnownOGCType( mime ) ) {
159                // if the mime-type is a known OGC mime-type it must be an XML
160                // document. probably it is a capabilities document but it also
161                // could be an
162                response = validateXML( service, response, user );
163            } else if ( mime.equals( "text/xml" ) ) {
164                // if the mime-type isn't an image type but 'text/xml'
165                // it could be an exception
166                response = validateXML( service, response, user );
167            } else {
168                throw new InvalidParameterValueException( UNKNOWNMIMETYPE + mime );
169            }
170    
171            return response;
172        }
173    
174        /**
175         * splits document string into 'core' capabilities document and xml header
176         * 
177         * @param xml
178         * @return
179         * @throws InvalidParameterValueException
180         */
181        private String[] clearCapabilities( byte[] xml )
182                                throws InvalidParameterValueException {
183            InputStreamReader isr = new InputStreamReader( new ByteArrayInputStream( xml ) );
184            StringBuffer sb = new StringBuffer( 50000 );
185            int c = 0;
186            try {
187                while ( ( c = isr.read() ) > -1 ) {
188                    sb.append( (char) c );
189                }
190                isr.close();
191            } catch ( IOException e ) {
192                String s = Messages.format( "GetCapabilitiesResponseValidator.CAPAREAD", e.getMessage() );
193                throw new InvalidParameterValueException( s );
194            }
195            // WMS <= 1.1.1
196            int pos = sb.indexOf( "<WMT_MS_Capabilities" );
197            // WMS 1.3
198            if ( pos < 0 ) {
199                pos = sb.indexOf( "WMS_Capabilities" );
200            }
201            // WFS 1.1.0
202            if ( pos < 0 ) {
203                pos = sb.indexOf( "WFS_Capabilities" );
204            }
205            // CSW 2.0.0
206            if ( pos < 0 ) {
207                pos = sb.indexOf( "Capabilities" );
208            }
209            // WCS 1.0.0
210            if ( pos < 0 ) {
211                pos = sb.indexOf( "WCS_Capabilities" );
212            }
213    
214            // just if pos is > -1 it makes sense to find the starting
215            // index of the root element
216            if ( pos > -1 ) {
217                pos = pos + 4;
218                char ch = '$';
219                // find starting index of the root element
220                while ( ch != '<' && pos > 0 ) {
221                    pos--;
222                    ch = sb.charAt( pos );
223                }
224                // if the least char read does not equal '<' the parsed document
225                // is not an XML document
226                if ( ch != '<' ) {
227                    pos = -1;
228                }
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 mime
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                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
323         */
324        private byte[] validateWCSCapabilities( @SuppressWarnings("unused")
325        Document doc, @SuppressWarnings("unused")
326        User user ) {
327            // TODO
328            // implement support for WCS
329            throw new UnsupportedOperationException();
330        }
331    
332        /**
333         * validates the passed xml to be valid against the policy
334         * 
335         * @param xml
336         * @param user
337         * @throws InvalidParameterValueException
338         * @throws XMLParsingException
339         */
340        private byte[] validateWMSCapabilities( Document doc, User user )
341                                throws InvalidParameterValueException, UnauthorizedException, XMLParsingException {
342    
343            WMSCapabilitiesDocument cdoc = WMSCapabilitiesDocumentFactory.getWMSCapabilitiesDocument( doc.getDocumentElement() );
344            WMSCapabilities capa = null;
345            try {
346                capa = (WMSCapabilities) cdoc.parseCapabilities();
347            } catch ( InvalidCapabilitiesException e ) {
348                LOG.logError( e.getMessage(), e );
349                String s = Messages.format( "GetCapabilitiesResponseValidator.WMSCAPAPARSE", e.getMessage() );
350                throw new InvalidParameterValueException( s );
351            }
352            capa = filterWMSLayers( capa, user );
353    
354            List<Operation> ops = capa.getOperationMetadata().getOperations();
355            for ( Operation operation : ops ) {
356                setNewOnlineResource( operation );
357            }
358    
359            ByteArrayOutputStream bos = new ByteArrayOutputStream( 50000 );
360            byte[] b;
361            try {
362                cdoc = XMLFactory.export( capa );
363                // must be UTF-8 because the WMS Capabilities template uses
364                // UTF-8 encoding
365                Properties properties = new Properties();
366                properties.setProperty( OutputKeys.ENCODING, "UTF-8" );
367                cdoc.write( bos, properties );
368                b = bos.toByteArray();
369                bos.close();
370            } catch ( Exception e ) {
371                LOG.logError( e.getMessage(), e );
372                String s = Messages.format( "GetCapabilitiesResponseValidator.WMSCAPAEXPORT", e.getMessage() );
373                throw new InvalidParameterValueException( s );
374            }
375    
376            return b;
377    
378        }
379    
380        /**
381         * 
382         * @param op
383         */
384        private void setNewOnlineResource( Operation op ) {
385            if ( op.getDCP() != null ) {
386                List<DCP> dcps = op.getDCP();
387                for ( DCP dcp : dcps ) {
388                    HTTP http = (HTTP) dcp;
389                    List<OnlineResource> links = http.getLinks();
390                    try {
391                        int size = links.size();
392                        links.clear();
393                        OnlineResource proxy = new OnlineResource( new Linkage( new URL( proxyURL ) ) );
394                        for ( int i = 0; i < size; ++i )
395                            links.add( proxy );
396                    } catch ( MalformedURLException e1 ) {
397                        LOG.logError( e1.getLocalizedMessage(), e1 );
398                    }
399                }
400            }
401        }
402    
403        /**
404         * Sets the proxy online resource in the old owscommon Operation class. To be removed soon!
405         * 
406         * @param op
407         */
408        private void setNewOnlineResourceInOldOperation( org.deegree.ogcwebservices.getcapabilities.Operation op ) {
409            if ( op.getDCPs() != null ) {
410                for ( int i = 0; i < op.getDCPs().length; i++ ) {
411                    org.deegree.ogcwebservices.getcapabilities.HTTP http = (org.deegree.ogcwebservices.getcapabilities.HTTP) op.getDCPs()[i].getProtocol();
412                    try {
413                        if ( http.getGetOnlineResources().length > 0 ) {
414                            URL urls[] = new URL[http.getGetOnlineResources().length];
415                            for ( int k = 0; k < http.getGetOnlineResources().length; ++k )
416                                urls[k] = new URL( proxyURL );
417                            http.setGetOnlineResources( urls );
418                        }
419                        if ( http.getPostOnlineResources().length > 0 ) {
420                            URL urls[] = new URL[http.getPostOnlineResources().length];
421                            for ( int k = 0; k < http.getPostOnlineResources().length; ++k )
422                                urls[k] = new URL( proxyURL );
423                            http.setPostOnlineResources( urls );
424                        }
425                    } catch ( MalformedURLException e1 ) {
426                        e1.printStackTrace();
427                    }
428                }
429            }
430        }
431    
432        /**
433         * validates the passed xml to be valid against the policy
434         * 
435         * @param xml
436         * @param user
437         * @throws InvalidParameterValueException
438         * @throws UnauthorizedException
439         */
440        private byte[] validateWFSCapabilities( Document doc, User user )
441                                throws InvalidParameterValueException, UnauthorizedException {
442    
443            WFSCapabilities capa = null;
444            try {
445                WFSCapabilitiesDocument capaDoc = new WFSCapabilitiesDocument();
446                capaDoc.setRootElement( doc.getDocumentElement() );
447                capa = (WFSCapabilities) capaDoc.parseCapabilities();
448            } catch ( Exception e ) {
449                LOG.logError( e.getMessage(), e );
450                String s = Messages.format( "GetCapabilitiesResponseValidator.INVALIDWFSCAPA", e.getMessage() );
451                throw new InvalidParameterValueException( s );
452            }
453    
454            capa = filterWFSFeatureType( capa, user );
455    
456            org.deegree.ogcwebservices.getcapabilities.Operation[] ops = capa.getOperationsMetadata().getOperations();
457            for ( int i = 0; i < ops.length; i++ ) {
458                setNewOnlineResourceInOldOperation( ops[i] );
459            }
460    
461            WFSCapabilitiesDocument capaDoc = null;
462            try {
463                capaDoc = org.deegree.ogcwebservices.wfs.XMLFactory.export( capa );
464            } catch ( Exception e ) {
465                throw new InvalidParameterValueException( e );
466            }
467            ByteArrayOutputStream bos = new ByteArrayOutputStream( 20000 );
468            PrintWriter pr = new PrintWriter( bos );
469            capaDoc.write( pr );
470            return bos.toByteArray();
471    
472        }
473    
474        /**
475         * validates the passed xml to be valid against the policy
476         * 
477         * @param doc
478         * @return
479         * @throws InvalidParameterValueException
480         */
481        private byte[] validateCSWCapabilities( Document doc )
482                                throws InvalidParameterValueException {
483            CatalogueCapabilities capa = null;
484            try {
485                CatalogueCapabilitiesDocument capaDoc = new CatalogueCapabilitiesDocument();
486                capaDoc.setRootElement( doc.getDocumentElement() );
487                capa = (CatalogueCapabilities) capaDoc.parseCapabilities();
488            } catch ( Exception e ) {
489                LOG.logError( e.getMessage(), e );
490                throw new InvalidParameterValueException(
491                                                          Messages.format(
492                                                                           "GetCapabilitiesResponseValidator.INVALIDWFSCAPA",
493                                                                           e.getMessage() ) );
494            }
495    
496            org.deegree.ogcwebservices.getcapabilities.Operation[] ops = capa.getOperationsMetadata().getOperations();
497            for ( int i = 0; i < ops.length; i++ ) {
498                setNewOnlineResourceInOldOperation( ops[i] );
499            }
500    
501            CatalogueCapabilitiesDocument capaDoc = null;
502            try {
503                capaDoc = org.deegree.ogcwebservices.csw.XMLFactory_2_0_0.export( capa, null );
504            } catch ( Exception e ) {
505                throw new InvalidParameterValueException( e );
506            }
507            ByteArrayOutputStream bos = new ByteArrayOutputStream( 20000 );
508            PrintWriter pr = new PrintWriter( bos );
509            capaDoc.write( pr );
510            return bos.toByteArray();
511        }
512    
513        /**
514         * filters the wms capabilities to rturn just the valid layers
515         * 
516         * @param capa
517         * @param user
518         * @throws InvalidParameterValueException
519         */
520        private WMSCapabilities filterWMSLayers( WMSCapabilities capa, User user )
521                                throws UnauthorizedException {
522    
523            Request req = policy.getRequest( "WMS", "GetCapabilities" );
524            Condition con = req.getPostConditions();
525            OperationParameter op = con.getOperationParameter( "layers" );
526            if ( op.isAny() )
527                return capa;
528    
529            Layer layer = capa.getLayer();
530            if ( op.isUserCoupled() && user != null ) {
531                try {
532                    SecurityAccessManager sam = SecurityAccessManager.getInstance();
533                    SecurityAccess access = sam.acquireAccess( user );
534                    // call recursive method to remove all 'named' layers not
535                    // included in the list from the capabilities
536                    layer = removeWMSLayer( layer, user, access );
537                } catch ( Exception e ) {
538                    LOG.logError( e.getMessage(), e );
539                    throw new UnauthorizedException( Messages.format( "GetCapabilitiesResponseValidator.INVALIDUSER", user ) );
540                }
541            } else {
542                // get list of valid wms layers
543                List list = op.getValues();
544                // call recursive method to remove all 'named' layers not
545                // included in the list from the capabilities
546                layer = removeWMSLayer( layer, list );
547            }
548            capa.setLayer( layer );
549            return capa;
550    
551        }
552    
553        /**
554         * recursive method that removes all 'named' layers (layers that has a name in addtion to a
555         * title) from the layer tree thats root node (layer) is passed to the method and that not
556         * present in the passed <tt>List</tt>
557         * 
558         * @param layer
559         * @param validLayers
560         */
561        private Layer removeWMSLayer( Layer layer, List validLayers ) {
562            Layer[] layers = layer.getLayer();
563            for ( int i = 0; i < layers.length; i++ ) {
564                if ( layers[i].getName() != null && !validLayers.contains( layers[i].getName() ) ) {
565                    layer.removeLayer( layers[i].getName() );
566                } else {
567                    removeWMSLayer( layers[i], validLayers );
568                    if ( layers[i].getLayer().length == 0 && layers[i].getName() == null ) {
569                        layer.removeLayerByTitle( layers[i].getTitle() );
570                    }
571                }
572            }
573            return layer;
574        }
575    
576        /**
577         * recursive method that removes all 'named' layers (layers that has a name in addition to a
578         * title) from the layer tree thats root node (layer) is passed to the method and the passed
579         * user doesn't have a GetMap right on.
580         * 
581         * @param layer
582         *            layer to validate
583         * @param user
584         *            user whose rights are considered
585         * @param access
586         *            object to access DRM registry
587         * 
588         */
589        private Layer removeWMSLayer( Layer layer, User user, SecurityAccess access )
590                                throws GeneralSecurityException {
591            Layer[] layers = layer.getLayer();
592            for ( int i = 0; i < layers.length; i++ ) {
593                if ( layers[i].getName() != null ) {
594                    SecuredObject secObj = null;
595                    try {
596                        // must be in try-catch block because an exception will be thrown
597                        // if no SecuredObject with the passed layer exists
598                        secObj = access.getSecuredObjectByName( layers[i].getName(), "Layer" );
599                    } catch ( Exception e ) {
600                    }
601                    if ( secObj == null || user.getRights( access, secObj ).getRight( secObj, RightType.GETMAP ) == null ) {
602                        // remove the layer from the capabilities if it's not known
603                        // by the DRM registry or if the user doesn't have a GetMap
604                        // right on it
605                        layer.removeLayer( layers[i].getName() );
606                    }
607                } else {
608                    removeWMSLayer( layers[i], user, access );
609                    if ( layers[i].getLayer().length == 0 && layers[i].getName() == null ) {
610                        layer.removeLayerByTitle( layers[i].getTitle() );
611                    }
612                }
613            }
614            return layer;
615        }
616    
617        /**
618         * @param capa
619         * @param user
620         * @return
621         * @throws InvalidParameterValueException
622         * @throws UnauthorizedException
623         */
624        private WFSCapabilities filterWFSFeatureType( WFSCapabilities capa, User user )
625                                throws UnauthorizedException {
626    
627            Request req = policy.getRequest( "WFS", "GetCapabilities" );
628            Condition con = req.getPostConditions();
629            OperationParameter op = con.getOperationParameter( "featureTypes" );
630            if ( op.isAny() )
631                return capa;
632    
633            if ( op.isUserCoupled() && user != null ) {
634                try {
635                    SecurityAccessManager sam = SecurityAccessManager.getInstance();
636                    SecurityAccess access = sam.acquireAccess( user );
637                    FeatureTypeList ftl = capa.getFeatureTypeList();
638                    WFSFeatureType[] ft = ftl.getFeatureTypes();
639                    StringBuffer sb = new StringBuffer( 200 );
640                    for ( int i = 0; i < ft.length; i++ ) {
641                        SecuredObject secObj = null;
642                        try {
643                            // must be in try-catch block because an exception will be thrown
644                            // if no SecuredObject with the passed layer exists
645                            sb.delete( 0, sb.length() );
646                            sb.append( '{' ).append( ft[i].getName().getNamespace().toASCIIString() );
647                            sb.append( "}:" ).append( ft[i].getName().getLocalName() );
648                            secObj = access.getSecuredObjectByName( sb.toString(), "Featuretype" );
649                        } catch ( Exception e ) {
650                        }
651                        if ( secObj == null
652                             || user.getRights( access, secObj ).getRight( secObj, RightType.GETFEATURE ) == null ) {
653                            ftl.removeFeatureType( ft[i] );
654                        }
655                    }
656                } catch ( Exception e ) {
657                    LOG.logError( e.getMessage(), e );
658                    throw new UnauthorizedException( Messages.format( "GetCapabilitiesResponseValidator.INVALIDUSER", user ) );
659                }
660            } else {
661                // get list of valid wms layers
662                List<String> list = op.getValues();
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                    sb.delete( 0, sb.length() );
668                    sb.append( '{' ).append( ft[i].getName().getNamespace().toASCIIString() );
669                    sb.append( "}:" ).append( ft[i].getName().getLocalName() );
670                    if ( !list.contains( sb.toString() ) ) {
671                        ftl.removeFeatureType( ft[i] );
672                    }
673                }
674            }
675    
676            return capa;
677        }
678    }