Skip to content

Commit

Permalink
Merge pull request qgis#31673 from elpaso/server-api-wfs3-acl
Browse files Browse the repository at this point in the history
Server api wfs3 acl
  • Loading branch information
elpaso authored Sep 12, 2019
2 parents 8c4bc20 + dabc380 commit 9b7a2cd
Show file tree
Hide file tree
Showing 25 changed files with 3,122 additions and 226 deletions.
10 changes: 1 addition & 9 deletions python/server/auto_generated/qgsserverapiutils.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@




class QgsServerApiUtils
{
%Docstring
Expand All @@ -38,14 +39,6 @@ Parses a comma separated ``bbox`` into a (possibily empty) :py:class:`QgsRectang
static QgsCoordinateReferenceSystem parseCrs( const QString &bboxCrs );
%Docstring
Parses the CRS URI ``bboxCrs`` (example: "http://www.opengis.net/def/crs/OGC/1.3/CRS84") into a QGIS CRS object
%End

static const QgsFields publishedFields( const QgsVectorLayer *layer );
%Docstring
Returns the list of fields accessible to the service for a given ``layer``.

This method takes into account the ACL restrictions provided by QGIS Server Access Control plugins.
TODO: implement ACL
%End

static const QVector<QgsMapLayer *> publishedWfsLayers( const QgsProject *project );
Expand All @@ -57,7 +50,6 @@ This method takes into account the ACL restrictions provided by QGIS Server Acce
.. note::

project must not be NULL
TODO: implement ACL
%End


Expand Down
6 changes: 4 additions & 2 deletions python/server/auto_generated/qgsserverogcapihandler.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,11 @@ Fallback to the default content type of the handler if none of the above matches
Returns a link to the parent page up to ``levels`` in the HTML hierarchy from the given ``url``, MAP query argument is preserved
%End

static QgsVectorLayer *layerFromCollection( const QgsServerApiContext &context, const QString &collectionId );
static QgsVectorLayer *layerFromCollectionId( const QgsServerApiContext &context, const QString &collectionId );
%Docstring
Returns a vector layer from the ``collectionId`` in the given ``context``
Returns a vector layer from the ``collectionId`` in the given ``context``.

:raises QgsServerApiNotFoundError: if the layer could not be found.
%End


Expand Down
6 changes: 0 additions & 6 deletions src/server/qgsserverapiutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,6 @@ QgsCoordinateReferenceSystem QgsServerApiUtils::parseCrs( const QString &bboxCrs
}
}

const QgsFields QgsServerApiUtils::publishedFields( const QgsVectorLayer *layer )
{
// TODO: implement plugin's ACL filtering
return layer->fields();
}

const QVector<QgsMapLayer *> QgsServerApiUtils::publishedWfsLayers( const QgsProject *project )
{
const QStringList wfsLayerIds = QgsServerProjectUtils::wfsLayerIds( *project );
Expand Down
49 changes: 26 additions & 23 deletions src/server/qgsserverapiutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
#include <QString>
#include "qgsproject.h"
#include "qgsserverprojectutils.h"
#include "qgsserverapicontext.h"

#ifdef HAVE_SERVER_PYTHON_PLUGINS
#include "qgsaccesscontrol.h"
#include "qgsserverinterface.h"
#endif

class QgsRectangle;
class QgsCoordinateReferenceSystem;
Expand Down Expand Up @@ -65,21 +71,12 @@ class SERVER_EXPORT QgsServerApiUtils
*/
static QgsCoordinateReferenceSystem parseCrs( const QString &bboxCrs );

/**
* Returns the list of fields accessible to the service for a given \a layer.
*
* This method takes into account the ACL restrictions provided by QGIS Server Access Control plugins.
* TODO: implement ACL
*/
static const QgsFields publishedFields( const QgsVectorLayer *layer );

/**
* Returns the list of layers accessible to the service for a given \a project.
*
* This method takes into account the ACL restrictions provided by QGIS Server Access Control plugins.
*
* \note project must not be NULL
* TODO: implement ACL
*/
static const QVector<QgsMapLayer *> publishedWfsLayers( const QgsProject *project );

Expand All @@ -92,28 +89,34 @@ class SERVER_EXPORT QgsServerApiUtils
*
* QVector<QgsVectorLayer*> vectorLayers = publishedLayers<QgsVectorLayer>();
*
* TODO: implement ACL
* \note not available in Python bindings
* \see publishedWfsLayers()
*/
template <typename T>
static const QVector<T *> publishedWfsLayers( const QgsProject *project )
static const QVector<const T *> publishedWfsLayers( const QgsServerApiContext &context )
{
const QStringList wfsLayerIds = QgsServerProjectUtils::wfsLayerIds( *project );
const QStringList wfstUpdateLayersId = QgsServerProjectUtils::wfstUpdateLayerIds( *project );
const QStringList wfstInsertLayersId = QgsServerProjectUtils::wfstInsertLayerIds( *project );
const QStringList wfstDeleteLayersId = QgsServerProjectUtils::wfstDeleteLayerIds( *project );
QVector<T *> result;
const auto constLayers { project->layers<T *>() };
for ( const auto &layer : constLayers )
#ifdef HAVE_SERVER_PYTHON_PLUGINS
QgsAccessControl *accessControl = context.serverInterface()->accessControls();
#endif
const QgsProject *project = context.project();
QVector<const T *> result;
if ( project )
{
if ( wfstUpdateLayersId.contains( layer->id() ) ||
wfstInsertLayersId.contains( layer->id() ) ||
wfstDeleteLayersId.contains( layer->id() ) )
const QStringList wfsLayerIds = QgsServerProjectUtils::wfsLayerIds( *project );
const auto constLayers { project->layers<T *>() };
for ( const auto &layer : constLayers )
{
if ( ! wfsLayerIds.contains( layer->id() ) )
{
continue;
}
#ifdef HAVE_SERVER_PYTHON_PLUGINS
if ( accessControl && !accessControl->layerReadPermission( layer ) )
{
continue;
}
#endif
result.push_back( layer );
}

}
return result;
}
Expand Down
7 changes: 4 additions & 3 deletions src/server/qgsserverogcapihandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ void QgsServerOgcApiHandler::jsonDump( json &data, const QgsServerApiContext &co
QDateTime time { QDateTime::currentDateTime() };
time.setTimeSpec( Qt::TimeSpec::UTC );
data["timeStamp"] = time.toString( Qt::DateFormat::ISODate ).toStdString() ;
context.response()->setStatusCode( 200 );
context.response()->setHeader( QStringLiteral( "Content-Type" ), contentType );
#ifdef QGISDEBUG
context.response()->write( data.dump( 2 ) );
Expand Down Expand Up @@ -230,7 +231,7 @@ QgsVectorLayer *QgsServerOgcApiHandler::layerFromContext( const QgsServerApiCont
}
const QString collectionId { match.captured( QStringLiteral( "collectionId" ) ) };
// May throw if not found
return layerFromCollection( context, collectionId );
return layerFromCollectionId( context, collectionId );

}

Expand Down Expand Up @@ -463,12 +464,12 @@ QString QgsServerOgcApiHandler::parentLink( const QUrl &url, int levels )
return result.toString();
}

QgsVectorLayer *QgsServerOgcApiHandler::layerFromCollection( const QgsServerApiContext &context, const QString &collectionId )
QgsVectorLayer *QgsServerOgcApiHandler::layerFromCollectionId( const QgsServerApiContext &context, const QString &collectionId )
{
const auto mapLayers { context.project()->mapLayersByShortName<QgsVectorLayer *>( collectionId ) };
if ( mapLayers.count() != 1 )
{
throw QgsServerApiImproperlyConfiguredException( QStringLiteral( "Collection with given id (%1) was not found or multiple matches were found" ).arg( collectionId ) );
throw QgsServerApiNotFoundError( QStringLiteral( "Collection with given id (%1) was not found or multiple matches were found" ).arg( collectionId ) );
}
return mapLayers.first();
}
Expand Down
5 changes: 3 additions & 2 deletions src/server/qgsserverogcapihandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,9 +314,10 @@ class SERVER_EXPORT QgsServerOgcApiHandler
static QString parentLink( const QUrl &url, int levels = 1 );

/**
* Returns a vector layer from the \a collectionId in the given \a context
* Returns a vector layer from the \a collectionId in the given \a context.
* \throws QgsServerApiNotFoundError if the layer could not be found.
*/
static QgsVectorLayer *layerFromCollection( const QgsServerApiContext &context, const QString &collectionId );
static QgsVectorLayer *layerFromCollectionId( const QgsServerApiContext &context, const QString &collectionId );

/**
* Returns the defaultResponse as JSON
Expand Down
Loading

0 comments on commit 9b7a2cd

Please sign in to comment.