Skip to content
Permalink
Browse files

The plugin define the following methods:

* layerFilterExpression
  Return an additional filter, used in
  WMS/GetMap, WMS/GetFeatureInfo, WFS/GetFeature to filter the features
* layerFilterSubsetString
  Return an additional the subset string (typically SQL) filter.
  Faster than the layerFilterExpression but not supported on all the
  type of layer
* layerPermissions
  Change the rights on the layer per user (known by the plugin)
  Concern rights: publish, insert, update, delete.
  Mostly used in WFS/Transaction, and the publish in all requests.
* authorizedLayerAttributes
  Be able to show some attributes only for a subset of user
  Used in: WMS/GetFeatureInfo, WFS/GetFeature
* allowToEdit
  Be able to don't allow to edit a particular feature, in our case base
  on the Geometry
  Used in: WFS/Transaction
* cacheKey
  Cache key to used to create the capabilities cache, "" for no cache,
  shouldn't contains any "-", default to ""
  • Loading branch information
sbrunner committed May 19, 2015
1 parent b1743dc commit c9f0d83aaf4e2fddfed4c287b8dd61df003852a4
Showing with 5,676 additions and 103 deletions.
  1. +1 −0 ci/travis/linux/before_install.sh
  2. +0 −1 ci/travis/linux/before_script.sh
  3. +0 −1 ci/travis/linux/script.sh
  4. +1 −0 cmake_templates/Doxyfile.in
  5. +1 −0 python/core/core.sip
  6. +24 −0 python/core/qgsfeaturefilterprovider.sip
  7. +4 −0 python/core/qgsmaprenderer.sip
  8. +33 −0 python/server/qgsaccesscontrol.sip
  9. +77 −0 python/server/qgsaccesscontrolfilter.sip
  10. +4 −3 python/server/qgsconfigcache.sip
  11. +1 −1 python/server/qgsrequesthandler.sip
  12. +2 −0 python/server/qgsserverinterface.sip
  13. +1 −1 python/server/qgswcserver.sip
  14. +1 −1 python/server/qgswcsprojectparser.sip
  15. +1 −1 python/server/qgswfserver.sip
  16. +1 −1 python/server/qgswfsprojectparser.sip
  17. +1 −1 python/server/qgswmserver.sip
  18. +1 −1 python/server/qgswmsprojectparser.sip
  19. +2 −0 python/server/server.sip
  20. +55 −0 src/core/qgsfeaturefilterprovider.h
  21. +7 −0 src/core/qgsmaprenderer.h
  22. +19 −0 src/core/qgsrendercontext.cpp
  23. +19 −0 src/core/qgsrendercontext.h
  24. +16 −2 src/core/qgsvectorlayerrenderer.cpp
  25. +3 −0 src/core/qgsvectorlayerrenderer.h
  26. +3 −0 src/server/CMakeLists.txt
  27. +169 −0 src/server/qgsaccesscontrol.cpp
  28. +125 −0 src/server/qgsaccesscontrol.h
  29. +87 −0 src/server/qgsaccesscontrolfilter.cpp
  30. +115 −0 src/server/qgsaccesscontrolfilter.h
  31. +5 −5 src/server/qgscapabilitiescache.cpp
  32. +12 −4 src/server/qgscapabilitiescache.h
  33. +38 −6 src/server/qgsconfigcache.cpp
  34. +22 −3 src/server/qgsconfigcache.h
  35. +4 −0 src/server/qgshttprequesthandler.cpp
  36. +72 −0 src/server/qgsowsserver.cpp
  37. +34 −2 src/server/qgsowsserver.h
  38. +54 −6 src/server/qgsserver.cpp
  39. +2 −0 src/server/qgsserverinterface.cpp
  40. +10 −0 src/server/qgsserverinterface.h
  41. +9 −0 src/server/qgsserverinterfaceimpl.cpp
  42. +7 −0 src/server/qgsserverinterfaceimpl.h
  43. +2 −0 src/server/qgsserverprojectparser.h
  44. +30 −2 src/server/qgswcsprojectparser.cpp
  45. +13 −1 src/server/qgswcsprojectparser.h
  46. +36 −5 src/server/qgswcsserver.cpp
  47. +9 −2 src/server/qgswcsserver.h
  48. +25 −2 src/server/qgswfsprojectparser.cpp
  49. +15 −1 src/server/qgswfsprojectparser.h
  50. +133 −8 src/server/qgswfsserver.cpp
  51. +9 −2 src/server/qgswfsserver.h
  52. +49 −5 src/server/qgswmsprojectparser.cpp
  53. +13 −1 src/server/qgswmsprojectparser.h
  54. +155 −23 src/server/qgswmsserver.cpp
  55. +29 −11 src/server/qgswmsserver.h
  56. +1 −0 tests/src/python/CMakeLists.txt
  57. +1,056 −0 tests/src/python/test_qgsserver_accesscontrol.py
  58. BIN ...testdata/control_images/qgis_server_accesscontrol/Restricted_WMS_GetMap/Restricted_WMS_GetMap.png
  59. BIN ...ol_images/qgis_server_accesscontrol/WMS_GetLegendGraphic_Country/WMS_GetLegendGraphic_Country.png
  60. BIN ...ontrol_images/qgis_server_accesscontrol/WMS_GetLegendGraphic_Hello/WMS_GetLegendGraphic_Hello.png
  61. BIN tests/testdata/control_images/qgis_server_accesscontrol/WMS_GetMap/WMS_GetMap.png
  62. +58 −0 tests/testdata/qgis_server_accesscontrol/Country.qml
  63. +59 −0 tests/testdata/qgis_server_accesscontrol/Hello.qml
  64. BIN tests/testdata/qgis_server_accesscontrol/dem.tif
  65. +20 −0 tests/testdata/qgis_server_accesscontrol/dem.tif.aux.xml
  66. BIN tests/testdata/qgis_server_accesscontrol/dem.tif.ovr
  67. BIN tests/testdata/qgis_server_accesscontrol/helloworld.db
  68. +2,842 −0 tests/testdata/qgis_server_accesscontrol/project.qgs
  69. +79 −0 tests/testdata/qgis_server_accesscontrol/project.qgs.cfg
  70. BIN tests/testdata/qgis_server_accesscontrol/results/WCS_GetCoverage.geotiff
@@ -44,6 +44,7 @@ sudo apt-get install --force-yes --no-install-recommends --no-install-suggests \
python-qt4-sql \
python-sip \
python-sip-dev \
python-gdal \
spawn-fcgi \
txt2tags \
xauth \
@@ -1,4 +1,3 @@
printf "[qgis_test]\nhost=localhost\ndbname=qgis_test\nuser=postgres" > ~/.pg_service.conf
psql -c 'CREATE DATABASE qgis_test;' -U postgres
psql -f $TRAVIS_BUILD_DIR/tests/testdata/provider/testdata.sql -U postgres -d qgis_test

@@ -1,2 +1 @@
xvfb-run ctest -V -E 'qgis_openstreetmaptest|qgis_wcsprovidertest' -S ./qgis-test-travis.ctest --output-on-failure

@@ -604,6 +604,7 @@ INPUT = @CMAKE_SOURCE_DIR@/doc \
@CMAKE_SOURCE_DIR@/src/server/qgsmapserviceexception.h \
@CMAKE_SOURCE_DIR@/src/server/qgsrequesthandler.h \
@CMAKE_SOURCE_DIR@/src/server/qgsserverfilter.h \
@CMAKE_SOURCE_DIR@/src/server/qgsaccesscontrolfilter.h \
@CMAKE_SOURCE_DIR@/src/server/qgsserverinterface.h

# This tag can be used to specify the character encoding of the source files
@@ -47,6 +47,7 @@
%Include qgsfeature.sip
%Include qgsfeatureiterator.sip
%Include qgsfeaturerequest.sip
%Include qgsfeaturefilterprovider.sip
%Include qgsfield.sip
%Include qgsgeometryvalidator.sip
%Include qgsgeometrysimplifier.sip
@@ -0,0 +1,24 @@
/**
* Interface used by class that will filter the features of a layer.
* The only method `filterFeatures` fill the `QgsFeatureRequest` to get only the
* wanted features.
**/
class QgsFeatureFilterProvider
{
%TypeHeaderCode
#include <qgsfeaturefilterprovider.h>
%End

public:
/** Add some filter to the feature request to don't have the unauthorized (unauthorised) features
* @param layer the layer to filter
* @param featureRequest the feature request to update
* @note not available in Python bindings
*/
virtual void filterFeatures( const QgsVectorLayer* layer, QgsFeatureRequest& featureRequest ) const = 0;

/** Create a clone of the feature filter provider
* @return a new clone
*/
virtual QgsFeatureFilterProvider* clone() const = 0;
};
@@ -288,6 +288,10 @@ class QgsMapRenderer : QObject
*/
bool splitLayersExtent( QgsMapLayer* layer, QgsRectangle& extent /In,Out/, QgsRectangle& r2 /Out/ );

/** Set a feature filter provider to filter the features
* @param ffp the feature filter provider
*/
void setFeatureFilterProvider( const QgsFeatureFilterProvider* ffp );
signals:

//! @deprecated in 2.4 - not emitted anymore
@@ -0,0 +1,33 @@
/***************************************************************************
qgsaccesscontrol.sip
--------------------
Access control helper for Qgis Server plugins

begin : 2015-05-19
copyright : (C) 2015 by Stéphane Brunner
email : stephane dot brunner at camptocamp dot org
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

/**
* \class QgsAccessControl
* \brief Class defining access control helper for QGIS Server.
*/
class QgsAccessControl : QgsFeatureFilterProvider
{
%TypeHeaderCode
#include "qgsaccesscontrol.h"
#include "qgsaccesscontrolfilter.h"

#include <QMultiMap>
%End

};
@@ -0,0 +1,77 @@
/***************************************************************************
qgsaccesscontrolfilter.sip
--------------------------
Access control interface for Qgis Server plugins

begin : 2015-05-19
copyright : (C) 2015 by Stéphane Brunner
email : stephane dot brunner at camptocamp dot org
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

/**
* \class QgsAccessControlFilter
* \brief Class defining access control interface for QGIS Server.
*
* Security can define any (or none) of the following method:
* * layerFilterExpression()
* * layerFilterSubsetString()
* * layerPermissions()
* * authorizedLayerAttributes()
* * allowToEdit()
* * cacheKey()
*/

class QgsAccessControlFilter
{
%TypeHeaderCode
#include "qgsaccesscontrolfilter.h"
#include "qgsserverinterface.h"
#include "qgsfeature.h"
#include "qgsmaplayer.h"
%End

public:
/** Constructor
* QgsServerInterface passed to plugins constructors
* and must be passed to QgsAccessControlPlugin instances.
*/
QgsAccessControlFilter( const QgsServerInterface* serverInterface );
/** Destructor */
virtual ~QgsAccessControlFilter();

/** Describe the layer permission */
struct LayerPermissions
{
bool canRead;
bool canUpdate;
bool canInsert;
bool canDelete;
};

/** Return the QgsServerInterface instance*/
const QgsServerInterface* serverInterface() const;
/** Return an additional expression filter */
virtual const QString layerFilterExpression( const QgsVectorLayer* layer /Transfer/ ) const;
/** Return an additional the subset string (typically SQL) filter.
Faster than the layerFilterExpression but not supported on all the type of layer */
virtual const QString layerFilterSubsetString( const QgsVectorLayer* layer /Transfer/ ) const;
/** Return the layer permissions */
virtual const LayerPermissions layerPermissions( const QgsMapLayer* layer /Transfer/ ) const;
/** Return the authorized layer attributes */
virtual const QStringList* authorizedLayerAttributes( const QgsVectorLayer* layer /Transfer/, const QStringList& attributes ) const;
/** Are we authorize to modify the following geometry */
virtual bool allowToEdit( const QgsVectorLayer* layer /Transfer/, const QgsFeature& feature /Transfer/ ) const;
/** Cache key to used to create the capabilities cache, "" for no cache, shouldn't any contains "-", default to "" */
virtual const QString cacheKey() const;
};

typedef QMultiMap<int, QgsAccessControlFilter*> QgsAccessControlFilterMap;
@@ -25,15 +25,16 @@ class QgsConfigCache: QObject
{
%TypeHeaderCode
#include "qgsconfigcache.h"
#include "qgsaccesscontrolfilter.h"
%End
public:
static QgsConfigCache* instance();
~QgsConfigCache();

QgsServerProjectParser* serverConfiguration( const QString& filePath );
QgsWCSProjectParser* wcsConfiguration( const QString& filePath );
QgsWFSProjectParser* wfsConfiguration( const QString& filePath );
QgsWMSConfigParser* wmsConfiguration( const QString& filePath, const QMap<QString, QString>& parameterMap = QMap< QString, QString >() );
QgsWCSProjectParser* wcsConfiguration( const QString& filePath, const QgsAccessControl* accessControl );
QgsWFSProjectParser* wfsConfiguration( const QString& filePath, const QgsAccessControl* accessControl );
QgsWMSConfigParser* wmsConfiguration( const QString& filePath, const QgsAccessControl* accessControl, const QMap<QString, QString>& parameterMap = QMap< QString, QString >() );

private:
QgsConfigCache();
@@ -61,7 +61,7 @@ class QgsRequestHandler
/** Remove a request parameter*/
virtual int removeParameter( const QString &key ) = 0;
/** Return a request parameter*/
virtual QString parameter( const QString &key) const = 0;
virtual QString parameter( const QString &key ) const = 0;
/** Return the requested format string*/
QString format() const;
/** Return the mime type for the response*/
@@ -50,6 +50,8 @@ class QgsServerInterface
virtual void registerFilter( QgsServerFilter* filter /Transfer/, int priority = 0 ) = 0;
/** Set the filters map */
virtual void setFilters( QgsServerFiltersMap* filters /Transfer/) = 0;
/** Register a security module with the given priority.*/
virtual void registerAccessControl( QgsAccessControlFilter* accessControl /Transfer/, int priority = 0 ) = 0;
/** Return an environment variable set by FCGI*/
virtual QString getEnv(const QString& name ) const = 0;
// Commented because of problems with typedef QgsServerFiltersMap, provided
@@ -37,7 +37,7 @@ class QgsWCSServer: public QgsOWSServer
public:
/** Constructor. Takes parameter map and a pointer to a renderer object (does not take ownership)*/
QgsWCSServer( const QString& configFilePath, QMap<QString, QString>& parameters, QgsWCSProjectParser* pp,
QgsRequestHandler* rh );
QgsRequestHandler* rh, const QgsAccessControl* accessControl );
~QgsWCSServer();

void executeRequest() override;
@@ -23,7 +23,7 @@ class QgsWCSProjectParser

%End
public:
QgsWCSProjectParser( const QString& filePath );
QgsWCSProjectParser( const QString& filePath, const QgsAccessControl* ac );
~QgsWCSProjectParser();

void serviceCapabilities( QDomElement& parentElement, QDomDocument& doc ) const;
@@ -61,7 +61,7 @@ class QgsWFSServer: public QgsOWSServer
public:
/** Constructor. Takes parameter map and a pointer to a renderer object (does not take ownership)*/
QgsWFSServer( const QString& configFilePath, QMap<QString, QString>& parameters, QgsWFSProjectParser* cp,
QgsRequestHandler* rh );
QgsRequestHandler* rh, const QgsAccessControl* accessControl );
~QgsWFSServer();

void executeRequest() override;
@@ -24,7 +24,7 @@ class QgsWFSProjectParser
%End

public:
QgsWFSProjectParser( const QString& filePath );
QgsWFSProjectParser( const QString& filePath, const QgsAccessControl* ac );
~QgsWFSProjectParser();

void serviceCapabilities( QDomElement& parentElement, QDomDocument& doc ) const;
@@ -59,7 +59,7 @@ class QgsWMSServer: public QgsOWSServer
/** Constructor. Does _NOT_ take ownership of
QgsConfigParser, QgsCapabilitiesCache and QgsMapRenderer*/
QgsWMSServer( const QString& configFilePath, QMap<QString, QString> &parameters, QgsWMSConfigParser* cp, QgsRequestHandler* rh,
QgsMapRenderer* renderer, QgsCapabilitiesCache* capCache );
QgsMapRenderer* renderer, QgsCapabilitiesCache* capCache, const QgsAccessControl* accessControl );
~QgsWMSServer();

void executeRequest() override;
@@ -23,7 +23,7 @@ class QgsWMSProjectParser : public QgsWMSConfigParser

%End
public:
QgsWMSProjectParser( const QString& filePath );
QgsWMSProjectParser( const QString& filePath, const QgsAccessControl* ac );
virtual ~QgsWMSProjectParser();

/** Adds layer and style specific capabilities elements to the parent node. This includes the individual layers and styles, their description, native CRS, bounding boxes, etc.
@@ -14,6 +14,8 @@
%If (HAVE_SERVER_PYTHON_PLUGINS)
%Include qgsserverfilter.sip
%Include qgsserverinterface.sip
%Include qgsaccesscontrolfilter.sip
%Include qgsaccesscontrol.sip
%End

%Include qgsmapserviceexception.sip
@@ -0,0 +1,55 @@
/***************************************************************************
qgsfeaturefilterprovider.h
--------------------------
begin : 22-05-2015
copyright : (C) 2008 by Stéphane Brunner
email : stephane dot brunner at camptocamp dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSFEATUREFILTERPROVIDER_H
#define QGSFEATUREFILTERPROVIDER_H

#include <QtGlobal>

class QString;
class QgsVectorLayer;
class QgsFeatureRequest;


/** \ingroup core
* Interface used by class that will filter the features of a layer.
* The only method `filterFeatures` fill the `QgsFeatureRequest` to get only the
* wanted features.
**/
class CORE_EXPORT QgsFeatureFilterProvider
{
public:

/** Constructor */
QgsFeatureFilterProvider() {};

/** Destructor */
virtual ~QgsFeatureFilterProvider() {};

/** Add some filter to the feature request to don't have the unauthorized (unauthorised) features
* @param layer the layer to filter
* @param featureRequest the feature request to update
*/
virtual void filterFeatures( const QgsVectorLayer* layer, QgsFeatureRequest& featureRequest ) const = 0;

/** Create a clone of the feature filter provider
* @return a new clone
*/
virtual QgsFeatureFilterProvider* clone() const = 0;
};

#endif
@@ -335,6 +335,13 @@ class CORE_EXPORT QgsMapRenderer : public QObject
*/
bool splitLayersExtent( QgsMapLayer* layer, QgsRectangle& extent, QgsRectangle& r2 );

/** Set a feature filter provider to filter the features
* @param ffp the feature filter provider
*/
void setFeatureFilterProvider( const QgsFeatureFilterProvider* ffp ) {
mRenderContext.setFeatureFilterProvider( ffp );
}

signals:

//! @deprecated in 2.4 - not emitted anymore
@@ -19,6 +19,8 @@
#include "qgsrendercontext.h"

#include "qgsmapsettings.h"
#include "qgsexpression.h"
#include "qgsvectorlayer.h"

QgsRenderContext::QgsRenderContext()
: mFlags( DrawEditingInfo | UseAdvancedEffects | DrawSelection | UseRenderingOptimization )
@@ -31,12 +33,17 @@ QgsRenderContext::QgsRenderContext()
, mLabelingEngine( NULL )
, mLabelingEngine2( 0 )
, mGeometry( 0 )
, mFeatureFilterProvider( NULL )
{
mVectorSimplifyMethod.setSimplifyHints( QgsVectorSimplifyMethod::NoSimplification );
}

QgsRenderContext::~QgsRenderContext()
{
if ( mFeatureFilterProvider != NULL ) {
delete mFeatureFilterProvider;
mFeatureFilterProvider = NULL;
}
}

void QgsRenderContext::setFlags( const QgsRenderContext::Flags& flags )
@@ -140,3 +147,15 @@ void QgsRenderContext::setUseRenderingOptimization( bool enabled )
{
setFlag( UseRenderingOptimization, enabled );
}

void QgsRenderContext::setFeatureFilterProvider( const QgsFeatureFilterProvider* ffp )
{
if ( mFeatureFilterProvider != NULL ) {
delete mFeatureFilterProvider;
mFeatureFilterProvider = NULL;
}
if ( ffp != NULL )
{
mFeatureFilterProvider = ffp->clone();
}
}

0 comments on commit c9f0d83

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