Skip to content
Permalink
Browse files

Correctly restore layer subsetStrings after wfs/wms requests...

by switching storage/restoration of subset strings to use
QgsMapLayer pointers instead of layer ids. It seems that the
majority of layers created by server are not registered in
the map layer registry, so retrieving layers by layer id
under server is not reliable.
  • Loading branch information
nyalldawson committed Feb 22, 2016
1 parent 90a4ae8 commit a46dca56f697da03dec0e182df2deaa9913b3a5c
@@ -51,7 +51,7 @@ QgsFeatureFilterProvider* QgsAccessControl::clone() const
/** Return an additional subset string (typically SQL) filter */
QString QgsAccessControl::extraSubsetString( const QgsVectorLayer* layer ) const
{
QStringList sqls = QStringList();
QStringList sqls;
QgsAccessControlFilterMap::const_iterator acIterator;
for ( acIterator = mPluginsAccessControls->constBegin(); acIterator != mPluginsAccessControls->constEnd(); ++acIterator )
{
@@ -21,19 +21,18 @@
#include "qgsvectorlayer.h"
#include "qgsvectordataprovider.h"


#ifdef HAVE_SERVER_PYTHON_PLUGINS
/** Apply filter from AccessControl */
void QgsOWSServer::applyAccessControlLayerFilters( QgsMapLayer* mapLayer, QMap<QString, QString>& originalLayerFilters ) const
void QgsOWSServer::applyAccessControlLayerFilters( QgsMapLayer* mapLayer, QHash<QgsMapLayer*, QString>& originalLayerFilters ) const
{
if ( QgsVectorLayer* layer = dynamic_cast<QgsVectorLayer*>( mapLayer ) )
{
QString sql = mAccessControl->extraSubsetString( layer );
if ( !sql.isEmpty() )
{
if ( !originalLayerFilters.contains( layer->id() ) )
if ( !originalLayerFilters.contains( layer ) )
{
originalLayerFilters.insert( layer->id(), layer->subsetString() );
originalLayerFilters.insert( layer, layer->subsetString() );
}
if ( !layer->subsetString().isEmpty() )
{
@@ -50,12 +49,12 @@ void QgsOWSServer::applyAccessControlLayerFilters( QgsMapLayer* mapLayer, QMap<Q
#endif

/** Restore layer filter as original */
void QgsOWSServer::restoreLayerFilters( const QMap<QString, QString>& filterMap ) const
void QgsOWSServer::restoreLayerFilters( const QHash<QgsMapLayer*, QString>& filterMap ) const
{
QMap<QString, QString>::const_iterator filterIt = filterMap.constBegin();
QHash<QgsMapLayer*, QString>::const_iterator filterIt = filterMap.constBegin();
for ( ; filterIt != filterMap.constEnd(); ++filterIt )
{
QgsVectorLayer* filteredLayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( filterIt.key() ) );
QgsVectorLayer* filteredLayer = dynamic_cast<QgsVectorLayer*>( filterIt.key() );
if ( filteredLayer )
{
QgsVectorDataProvider* dp = filteredLayer->dataProvider();
@@ -61,13 +61,13 @@ class QgsOWSServer
* @param originalLayerFilters the original layer filter
*
*/
void applyAccessControlLayerFilters( QgsMapLayer* layer, QMap<QString, QString>& originalLayerFilters ) const;
void applyAccessControlLayerFilters( QgsMapLayer* layer, QHash<QgsMapLayer*, QString>& originalLayerFilters ) const;
#endif

/** Restores the original layer filters
* @param filterMap the original layer filter
*/
void restoreLayerFilters( const QMap < QString, QString >& filterMap ) const;
void restoreLayerFilters( const QHash < QgsMapLayer*, QString >& filterMap ) const;
};

#endif // QGSOWSSERVER_H
@@ -422,6 +422,7 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format

QDomDocument doc;
QString errorMsg;
QHash<QgsMapLayer*, QString> originalLayerFilters;
if ( doc.setContent( mParameters.value( "REQUEST_BODY" ), true, &errorMsg ) )
{
QDomElement docElem = doc.documentElement();
@@ -465,10 +466,9 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
#ifdef HAVE_SERVER_PYTHON_PLUGINS
if ( !mAccessControl->layerReadPermission( currentLayer ) )
{
restoreLayerFilters( originalLayerFilters );
throw QgsMapServiceException( "Security", "Feature access permission denied" );
}

QMap<QString, QString> originalLayerFilters;
applyAccessControlLayerFilters( currentLayer, originalLayerFilters );
#endif

@@ -646,6 +646,9 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
{
if ( filter->hasParserError() )
{
#ifdef HAVE_SERVER_PYTHON_PLUGINS
restoreLayerFilters( originalLayerFilters );
#endif
throw QgsMapServiceException( "RequestNotWellFormed", filter->parserErrorString() );
}
while ( fit.nextFeature( feature ) && ( maxFeatures == -1 || featureCounter < maxFeat + startIndex ) )
@@ -655,6 +658,10 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
QVariant res = filter->evaluate( &expressionContext );
if ( filter->hasEvalError() )
{

#ifdef HAVE_SERVER_PYTHON_PLUGINS
restoreLayerFilters( originalLayerFilters );
#endif
throw QgsMapServiceException( "RequestNotWellFormed", filter->evalErrorString() );
}
if ( res.toInt() != 0 )
@@ -688,10 +695,6 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
++featureCounter;
}
}

#ifdef HAVE_SERVER_PYTHON_PLUGINS
restoreLayerFilters( originalLayerFilters );
#endif
}
else
{
@@ -700,6 +703,10 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format

}

#ifdef HAVE_SERVER_PYTHON_PLUGINS
restoreLayerFilters( originalLayerFilters );
#endif

QgsMessageLog::logMessage( mErrors.join( "\n" ) );

QgsMapLayerRegistry::instance()->removeAllMapLayers();
@@ -1247,8 +1247,6 @@ QByteArray* QgsWMSServer::getPrint( const QString& formatString )
}
delete theImage;

QMap<QString, QString> originalLayerFilters = applyRequestedLayerFilters( layersList );

#ifdef HAVE_SERVER_PYTHON_PLUGINS
Q_FOREACH ( QgsMapLayer *layer, QgsMapLayerRegistry::instance()->mapLayers() )
{
@@ -1257,7 +1255,11 @@ QByteArray* QgsWMSServer::getPrint( const QString& formatString )
throw QgsMapServiceException( "Security", "You are not allowed to access to the layer: " + layer->name() );
}
}
#endif

QHash<QgsMapLayer*, QString> originalLayerFilters = applyRequestedLayerFilters( layersList );

#ifdef HAVE_SERVER_PYTHON_PLUGINS
applyAccessControlLayersFilters( layersList, originalLayerFilters );
#endif

@@ -1266,6 +1268,8 @@ QByteArray* QgsWMSServer::getPrint( const QString& formatString )
//GetPrint request needs a template parameter
if ( !mParameters.contains( "TEMPLATE" ) )
{
restoreLayerFilters( originalLayerFilters );
clearFeatureSelections( selectedLayerIdList );
throw QgsMapServiceException( "ParameterMissing", "The TEMPLATE parameter is required for the GetPrint request" );
}

@@ -1340,6 +1344,8 @@ QByteArray* QgsWMSServer::getPrint( const QString& formatString )
}
else //unknown format
{
restoreLayerFilters( originalLayerFilters );
clearFeatureSelections( selectedLayerIdList );
throw QgsMapServiceException( "InvalidFormat", "Output format '" + formatString + "' is not supported in the GetPrint request" );
}

@@ -1381,8 +1387,6 @@ QImage* QgsWMSServer::getMap( HitTest* hitTest )
QPainter thePainter( theImage );
thePainter.setRenderHint( QPainter::Antialiasing ); //make it look nicer

QMap<QString, QString> originalLayerFilters = applyRequestedLayerFilters( layersList );

#ifdef HAVE_SERVER_PYTHON_PLUGINS
Q_FOREACH ( QgsMapLayer *layer, QgsMapLayerRegistry::instance()->mapLayers() )
{
@@ -1391,7 +1395,11 @@ QImage* QgsWMSServer::getMap( HitTest* hitTest )
throw QgsMapServiceException( "Security", "You are not allowed to access to the layer: " + layer->name() );
}
}
#endif

QHash<QgsMapLayer*, QString> originalLayerFilters = applyRequestedLayerFilters( layersList );

#ifdef HAVE_SERVER_PYTHON_PLUGINS
applyAccessControlLayersFilters( layersList, originalLayerFilters );
#endif

@@ -1618,7 +1626,7 @@ int QgsWMSServer::getFeatureInfo( QDomDocument& result, const QString& version )

//get the layer registered in QgsMapLayerRegistry and apply possible filters
QStringList layerIds = layerSet( layersList, stylesList, mMapRenderer->destinationCrs() );
QMap<QString, QString> originalLayerFilters = applyRequestedLayerFilters( layersList );
QHash<QgsMapLayer*, QString> originalLayerFilters = applyRequestedLayerFilters( layersList );
#ifdef HAVE_SERVER_PYTHON_PLUGINS
applyAccessControlLayersFilters( layersList, originalLayerFilters );
#endif
@@ -1702,6 +1710,7 @@ int QgsWMSServer::getFeatureInfo( QDomDocument& result, const QString& version )
#ifdef HAVE_SERVER_PYTHON_PLUGINS
if ( !mAccessControl->layerReadPermission( currentLayer ) )
{
restoreLayerFilters( originalLayerFilters );
throw QgsMapServiceException( "Security", "You are not allowed to access to the layer: " + currentLayer->name() );
}
#endif
@@ -2486,9 +2495,9 @@ QStringList QgsWMSServer::layerSet( const QStringList &layersList,
}


QMap<QString, QString> QgsWMSServer::applyRequestedLayerFilters( const QStringList& layerList ) const
QHash<QgsMapLayer*, QString> QgsWMSServer::applyRequestedLayerFilters( const QStringList& layerList ) const
{
QMap<QString, QString> filterMap;
QHash<QgsMapLayer*, QString> filterMap;

if ( layerList.isEmpty() )
{
@@ -2539,7 +2548,7 @@ QMap<QString, QString> QgsWMSServer::applyRequestedLayerFilters( const QStringLi
QgsVectorLayer* filteredLayer = dynamic_cast<QgsVectorLayer*>( filter );
if ( filteredLayer )
{
filterMap.insert( filteredLayer->id(), filteredLayer->subsetString() );
filterMap.insert( filteredLayer, filteredLayer->subsetString() );
QString newSubsetString = eqSplit.at( 1 );
if ( !filteredLayer->subsetString().isEmpty() )
{
@@ -2556,10 +2565,10 @@ QMap<QString, QString> QgsWMSServer::applyRequestedLayerFilters( const QStringLi
if ( mMapRenderer && mMapRenderer->extent().isEmpty() )
{
QgsRectangle filterExtent;
QMap<QString, QString>::const_iterator filterIt = filterMap.constBegin();
QHash<QgsMapLayer*, QString>::const_iterator filterIt = filterMap.constBegin();
for ( ; filterIt != filterMap.constEnd(); ++filterIt )
{
QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer( filterIt.key() );
QgsMapLayer* mapLayer = filterIt.key();
if ( !mapLayer )
{
continue;
@@ -2582,7 +2591,7 @@ QMap<QString, QString> QgsWMSServer::applyRequestedLayerFilters( const QStringLi
}

#ifdef HAVE_SERVER_PYTHON_PLUGINS
void QgsWMSServer::applyAccessControlLayersFilters( const QStringList& layerList, QMap<QString, QString>& originalLayerFilters ) const
void QgsWMSServer::applyAccessControlLayersFilters( const QStringList& layerList, QHash<QgsMapLayer*, QString>& originalLayerFilters ) const
{
Q_FOREACH ( const QString& layerName, layerList )
{
@@ -188,13 +188,13 @@ class QgsWMSServer: public QgsOWSServer

/** Apply filter (subset) strings from the request to the layers. Example: '&FILTER=<layer1>:"AND property > 100",<layer2>:"AND bla = 'hallo!'" '
@return a map with the original filters ( layer id / filter string )*/
QMap<QString, QString> applyRequestedLayerFilters( const QStringList& layerList ) const;
QHash<QgsMapLayer*, QString> applyRequestedLayerFilters( const QStringList& layerList ) const;
#ifdef HAVE_SERVER_PYTHON_PLUGINS
/** Apply filter strings from the access control to the layers.
* @param layerList layers to filter
* @param originalLayerFilters the original layers filter dictionary
*/
void applyAccessControlLayersFilters( const QStringList& layerList, QMap<QString, QString>& originalLayerFilters ) const;
void applyAccessControlLayersFilters( const QStringList& layerList, QHash<QgsMapLayer*, QString>& originalLayerFilters ) const;
#endif
/** Tests if a filter sql string is allowed (safe)
@return true in case of success, false if string seems unsafe*/

0 comments on commit a46dca5

Please sign in to comment.
You can’t perform that action at this time.