Skip to content

Commit

Permalink
The plugin define the following methods:
Browse files Browse the repository at this point in the history
* 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 Nov 18, 2015
1 parent b1743dc commit c9f0d83
Show file tree
Hide file tree
Showing 70 changed files with 5,676 additions and 103 deletions.
1 change: 1 addition & 0 deletions ci/travis/linux/before_install.sh
Expand Up @@ -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 \
Expand Down
1 change: 0 additions & 1 deletion ci/travis/linux/before_script.sh
@@ -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 change: 0 additions & 1 deletion ci/travis/linux/script.sh
@@ -1,2 +1 @@
xvfb-run ctest -V -E 'qgis_openstreetmaptest|qgis_wcsprovidertest' -S ./qgis-test-travis.ctest --output-on-failure

1 change: 1 addition & 0 deletions cmake_templates/Doxyfile.in
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions python/core/core.sip
Expand Up @@ -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
Expand Down
24 changes: 24 additions & 0 deletions python/core/qgsfeaturefilterprovider.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;
};
4 changes: 4 additions & 0 deletions python/core/qgsmaprenderer.sip
Expand Up @@ -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
Expand Down
33 changes: 33 additions & 0 deletions python/server/qgsaccesscontrol.sip
@@ -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

};
77 changes: 77 additions & 0 deletions python/server/qgsaccesscontrolfilter.sip
@@ -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;
7 changes: 4 additions & 3 deletions python/server/qgsconfigcache.sip
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion python/server/qgsrequesthandler.sip
Expand Up @@ -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*/
Expand Down
2 changes: 2 additions & 0 deletions python/server/qgsserverinterface.sip
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion python/server/qgswcserver.sip
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion python/server/qgswcsprojectparser.sip
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion python/server/qgswfserver.sip
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion python/server/qgswfsprojectparser.sip
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion python/server/qgswmserver.sip
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion python/server/qgswmsprojectparser.sip
Expand Up @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions python/server/server.sip
Expand Up @@ -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
Expand Down
55 changes: 55 additions & 0 deletions src/core/qgsfeaturefilterprovider.h
@@ -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
7 changes: 7 additions & 0 deletions src/core/qgsmaprenderer.h
Expand Up @@ -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
Expand Down
19 changes: 19 additions & 0 deletions src/core/qgsrendercontext.cpp
Expand Up @@ -19,6 +19,8 @@
#include "qgsrendercontext.h"

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

QgsRenderContext::QgsRenderContext()
: mFlags( DrawEditingInfo | UseAdvancedEffects | DrawSelection | UseRenderingOptimization )
Expand All @@ -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 )
Expand Down Expand Up @@ -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.