Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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 a46dca5
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/server/qgsaccesscontrol.cpp
Expand Up @@ -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 )
{
Expand Down
13 changes: 6 additions & 7 deletions src/server/qgsowsserver.cpp
Expand Up @@ -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() )
{
Expand All @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions src/server/qgsowsserver.h
Expand Up @@ -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
19 changes: 13 additions & 6 deletions src/server/qgswfsserver.cpp
Expand Up @@ -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();
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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 ) )
Expand All @@ -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 )
Expand Down Expand Up @@ -688,10 +695,6 @@ int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format
++featureCounter;
}
}

#ifdef HAVE_SERVER_PYTHON_PLUGINS
restoreLayerFilters( originalLayerFilters );
#endif
}
else
{
Expand All @@ -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();
Expand Down
31 changes: 20 additions & 11 deletions src/server/qgswmsserver.cpp
Expand Up @@ -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() )
{
Expand All @@ -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

Expand All @@ -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" );
}

Expand Down Expand Up @@ -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" );
}

Expand Down Expand Up @@ -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() )
{
Expand All @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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() )
{
Expand Down Expand Up @@ -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() )
{
Expand All @@ -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;
Expand All @@ -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 )
{
Expand Down
4 changes: 2 additions & 2 deletions src/server/qgswmsserver.h
Expand Up @@ -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*/
Expand Down

0 comments on commit a46dca5

Please sign in to comment.