From e7d45a0976b534d04007d1a24cbc7ef1e963092e Mon Sep 17 00:00:00 2001 From: rldhont Date: Fri, 26 May 2017 16:04:42 +0200 Subject: [PATCH 1/3] [Server] Add DescribeLayer test --- tests/src/python/test_qgsserver_wms.py | 6 ++++++ tests/testdata/qgis_server/describelayer.txt | 14 ++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 tests/testdata/qgis_server/describelayer.txt diff --git a/tests/src/python/test_qgsserver_wms.py b/tests/src/python/test_qgsserver_wms.py index 88823bf2fbd9..40b9f247c299 100644 --- a/tests/src/python/test_qgsserver_wms.py +++ b/tests/src/python/test_qgsserver_wms.py @@ -125,6 +125,12 @@ def test_project_wms(self): 'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\' OR "utf8nameè" = \'three èé↓\''), 'wms_getfeatureinfo_filter_or_utf8') + # Test DescribeLayer + self.wms_request_compare('DescribeLayer', + '&layers=testlayer%20%C3%A8%C3%A9&' + + 'SLD_VERSION=1.1.0', + 'describelayer') + def wms_inspire_request_compare(self, request): """WMS INSPIRE tests""" project = self.testdata_path + "test_project_inspire.qgs" diff --git a/tests/testdata/qgis_server/describelayer.txt b/tests/testdata/qgis_server/describelayer.txt new file mode 100644 index 000000000000..697594eefe33 --- /dev/null +++ b/tests/testdata/qgis_server/describelayer.txt @@ -0,0 +1,14 @@ +***** +Content-Type: text/xml; charset=utf-8 + + + + 1.1.0 + + wfs + + + testlayer èé + + + From 5b7829714949a44235b24a32f7a5dc699e8e5bc3 Mon Sep 17 00:00:00 2001 From: rldhont Date: Fri, 26 May 2017 16:35:16 +0200 Subject: [PATCH 2/3] [Server] Rename QgsServerProjectUtils::wcsLayers to QgsServerProjectUtils::wcsLayerIds --- python/server/qgsserverprojectutils.sip | 2 +- src/server/qgsserverprojectutils.cpp | 2 +- src/server/qgsserverprojectutils.h | 2 +- src/server/services/wcs/qgswcsdescribecoverage.cpp | 2 +- src/server/services/wcs/qgswcsgetcapabilities.cpp | 2 +- src/server/services/wcs/qgswcsgetcoverage.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/python/server/qgsserverprojectutils.sip b/python/server/qgsserverprojectutils.sip index 4855c1e69cbd..d0ac13f91b71 100644 --- a/python/server/qgsserverprojectutils.sip +++ b/python/server/qgsserverprojectutils.sip @@ -243,5 +243,5 @@ namespace QgsServerProjectUtils * @param project the QGIS project * @return the Layer ids list. */ - QStringList wcsLayers( const QgsProject &project ); + QStringList wcsLayerIds( const QgsProject &project ); }; diff --git a/src/server/qgsserverprojectutils.cpp b/src/server/qgsserverprojectutils.cpp index c85fc75ec776..12a6f5c4e3d3 100644 --- a/src/server/qgsserverprojectutils.cpp +++ b/src/server/qgsserverprojectutils.cpp @@ -263,7 +263,7 @@ QString QgsServerProjectUtils::wcsServiceUrl( const QgsProject &project ) return project.readEntry( QStringLiteral( "WCSUrl" ), QStringLiteral( "/" ), "" ); } -QStringList QgsServerProjectUtils::wcsLayers( const QgsProject &project ) +QStringList QgsServerProjectUtils::wcsLayerIds( const QgsProject &project ) { return project.readListEntry( QStringLiteral( "WCSLayers" ), QStringLiteral( "/" ) ); } diff --git a/src/server/qgsserverprojectutils.h b/src/server/qgsserverprojectutils.h index 79a988d6d993..1d0a0f763240 100644 --- a/src/server/qgsserverprojectutils.h +++ b/src/server/qgsserverprojectutils.h @@ -245,7 +245,7 @@ namespace QgsServerProjectUtils * \param project the QGIS project * \returns the Layer ids list. */ - SERVER_EXPORT QStringList wcsLayers( const QgsProject &project ); + SERVER_EXPORT QStringList wcsLayerIds( const QgsProject &project ); }; #endif diff --git a/src/server/services/wcs/qgswcsdescribecoverage.cpp b/src/server/services/wcs/qgswcsdescribecoverage.cpp index 08731d313e28..1d61709959e6 100644 --- a/src/server/services/wcs/qgswcsdescribecoverage.cpp +++ b/src/server/services/wcs/qgswcsdescribecoverage.cpp @@ -94,7 +94,7 @@ namespace QgsWcs } } - QStringList wcsLayersId = QgsServerProjectUtils::wcsLayers( *project ); + QStringList wcsLayersId = QgsServerProjectUtils::wcsLayerIds( *project ); for ( int i = 0; i < wcsLayersId.size(); ++i ) { QgsMapLayer *layer = project->mapLayer( wcsLayersId.at( i ) ); diff --git a/src/server/services/wcs/qgswcsgetcapabilities.cpp b/src/server/services/wcs/qgswcsgetcapabilities.cpp index 25e5449828dd..e48484f46a5c 100644 --- a/src/server/services/wcs/qgswcsgetcapabilities.cpp +++ b/src/server/services/wcs/qgswcsgetcapabilities.cpp @@ -260,7 +260,7 @@ namespace QgsWcs */ QDomElement contentMetadataElement = doc.createElement( QStringLiteral( "ContentMetadata" )/*wcs:ContentMetadata*/ ); - QStringList wcsLayersId = QgsServerProjectUtils::wcsLayers( *project ); + QStringList wcsLayersId = QgsServerProjectUtils::wcsLayerIds( *project ); for ( int i = 0; i < wcsLayersId.size(); ++i ) { QgsMapLayer *layer = project->mapLayer( wcsLayersId.at( i ) ); diff --git a/src/server/services/wcs/qgswcsgetcoverage.cpp b/src/server/services/wcs/qgswcsgetcoverage.cpp index 1c7855f0c733..7802c64da70b 100644 --- a/src/server/services/wcs/qgswcsgetcoverage.cpp +++ b/src/server/services/wcs/qgswcsgetcoverage.cpp @@ -73,7 +73,7 @@ namespace QgsWcs } //get the raster layer - QStringList wcsLayersId = QgsServerProjectUtils::wcsLayers( *project ); + QStringList wcsLayersId = QgsServerProjectUtils::wcsLayerIds( *project ); QgsRasterLayer *rLayer = nullptr; for ( int i = 0; i < wcsLayersId.size(); ++i ) From 8a0261c94e419a633b436cee4194bdd0739abb2f Mon Sep 17 00:00:00 2001 From: rldhont Date: Fri, 26 May 2017 16:56:35 +0200 Subject: [PATCH 3/3] [Server] WMS DescribeLayer refactoring --- .../services/wms/qgswmsdescribelayer.cpp | 100 +++++++++++++++++- 1 file changed, 98 insertions(+), 2 deletions(-) diff --git a/src/server/services/wms/qgswmsdescribelayer.cpp b/src/server/services/wms/qgswmsdescribelayer.cpp index ffb1f84b4125..f89a12d71912 100644 --- a/src/server/services/wms/qgswmsdescribelayer.cpp +++ b/src/server/services/wms/qgswmsdescribelayer.cpp @@ -40,7 +40,6 @@ namespace QgsWms Q_UNUSED( version ); QgsServerRequest::Parameters parameters = request.parameters(); - QgsWmsConfigParser *configParser = getConfigParser( serverIface ); if ( !parameters.contains( QStringLiteral( "SLD_VERSION" ) ) ) { @@ -64,6 +63,24 @@ namespace QgsWms { throw QgsServiceException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "Layers is empty" ), 400 ); } + QDomDocument myDocument = QDomDocument(); + + QDomNode header = myDocument.createProcessingInstruction( QStringLiteral( "xml" ), QStringLiteral( "version=\"1.0\" encoding=\"UTF-8\"" ) ); + myDocument.appendChild( header ); + + // Create the root element + QDomElement root = myDocument.createElementNS( QStringLiteral( "http://www.opengis.net/sld" ), QStringLiteral( "DescribeLayerResponse" ) ); + root.setAttribute( QStringLiteral( "xsi:schemaLocation" ), QStringLiteral( "http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/DescribeLayer.xsd" ) ); + root.setAttribute( QStringLiteral( "xmlns:ows" ), QStringLiteral( "http://www.opengis.net/ows" ) ); + root.setAttribute( QStringLiteral( "xmlns:se" ), QStringLiteral( "http://www.opengis.net/se" ) ); + root.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) ); + root.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) ); + myDocument.appendChild( root ); + + // store the Version element + QDomElement versionNode = myDocument.createElement( QStringLiteral( "Version" ) ); + versionNode.appendChild( myDocument.createTextNode( QStringLiteral( "1.1.0" ) ) ); + root.appendChild( versionNode ); // get the wms service url defined in project or keep the one from the // request url @@ -85,7 +102,86 @@ namespace QgsWms wcsHrefString = wmsHrefString; } - return configParser->describeLayer( layersList, wfsHrefString, wcsHrefString ); + // access control + QgsAccessControl *accessControl = serverIface->accessControls(); + // Use layer ids + bool useLayerIds = QgsServerProjectUtils::wmsUseLayerIds( *project ); + // WMS restricted layers + QStringList restrictedLayers = QgsServerProjectUtils::wmsRestrictedLayers( *project ); + // WFS layers + QStringList wfsLayerIds = QgsServerProjectUtils::wfsLayerIds( *project ); + // WCS layers + QStringList wcsLayerIds = QgsServerProjectUtils::wcsLayerIds( *project ); + + Q_FOREACH ( QgsMapLayer *layer, project->mapLayers() ) + { + QString name = layer->name(); + if ( useLayerIds ) + name = layer->id(); + else if ( !layer->shortName().isEmpty() ) + name = layer->shortName(); + + if ( !layersList.contains( name ) ) + { + continue; + } + + //unpublished layer + if ( restrictedLayers.contains( layer->name() ) ) + { + throw QgsSecurityException( QStringLiteral( "You are not allowed to access to this layer" ) ); + } + + if ( accessControl && !accessControl->layerReadPermission( layer ) ) + { + throw QgsSecurityException( QStringLiteral( "You are not allowed to access to this layer" ) ); + } + + // Create the NamedLayer element + QDomElement layerNode = myDocument.createElement( QStringLiteral( "LayerDescription" ) ); + root.appendChild( layerNode ); + + // store the owsType element + QDomElement typeNode = myDocument.createElement( QStringLiteral( "owsType" ) ); + // store the se:OnlineResource element + QDomElement oResNode = myDocument.createElement( QStringLiteral( "se:OnlineResource" ) ); + oResNode.setAttribute( QStringLiteral( "xlink:type" ), QStringLiteral( "simple" ) ); + // store the TypeName element + QDomElement nameNode = myDocument.createElement( QStringLiteral( "TypeName" ) ); + if ( layer->type() == QgsMapLayer::VectorLayer ) + { + typeNode.appendChild( myDocument.createTextNode( QStringLiteral( "wfs" ) ) ); + + if ( wfsLayerIds.indexOf( layer->id() ) != -1 ) + { + oResNode.setAttribute( QStringLiteral( "xlink:href" ), wfsHrefString ); + } + + // store the se:FeatureTypeName element + QDomElement typeNameNode = myDocument.createElement( QStringLiteral( "se:FeatureTypeName" ) ); + typeNameNode.appendChild( myDocument.createTextNode( name ) ); + nameNode.appendChild( typeNameNode ); + } + else if ( layer->type() == QgsMapLayer::RasterLayer ) + { + typeNode.appendChild( myDocument.createTextNode( QStringLiteral( "wcs" ) ) ); + + if ( wcsLayerIds.indexOf( layer->id() ) != -1 ) + { + oResNode.setAttribute( QStringLiteral( "xlink:href" ), wcsHrefString ); + } + + // store the se:CoverageTypeName element + QDomElement typeNameNode = myDocument.createElement( QStringLiteral( "se:CoverageTypeName" ) ); + typeNameNode.appendChild( myDocument.createTextNode( name ) ); + nameNode.appendChild( typeNameNode ); + } + layerNode.appendChild( typeNode ); + layerNode.appendChild( oResNode ); + layerNode.appendChild( nameNode ); + } + + return myDocument; } } // samespace QgsWms