From 96685d2bedc25008ebb0430064b937c70cc2f210 Mon Sep 17 00:00:00 2001 From: Josef Rokos Date: Fri, 11 Mar 2016 14:13:40 +0100 Subject: [PATCH] Implementation of basic permission checks. --- core/autoform.h | 4 ++++ core/autotablemodel.h | 2 ++ core/core.pro | 6 +++-- core/imetadataplugin.cpp | 5 +++++ core/iservice.cpp | 5 ++++- core/iservice.h | 6 +++++ core/permissionevaluator.cpp | 43 ++++++++++++++++++++++++++++++++++++ core/permissionevaluator.h | 23 +++++++++++++++++++ core/service.h | 43 ++++++++++++++++++++++++++++++------ 9 files changed, 127 insertions(+), 10 deletions(-) create mode 100644 core/permissionevaluator.cpp create mode 100644 core/permissionevaluator.h diff --git a/core/autoform.h b/core/autoform.h index 02e944b..34d063a 100644 --- a/core/autoform.h +++ b/core/autoform.h @@ -41,6 +41,10 @@ public slots: QMessageBox::critical(this, "Database error", msg.toStdString().c_str()); m_saved = false; }); + this->connect(service(), &IService::permissionDenied, [this](QString permission) { + QMessageBox::critical(this, "Permission denied", permission.toStdString().c_str()); + m_saved = false; + }); this->connect(service(), &IService::dataChanged, [this]() { m_saved = true; }); diff --git a/core/autotablemodel.h b/core/autotablemodel.h index 0866a87..ca210bc 100644 --- a/core/autotablemodel.h +++ b/core/autotablemodel.h @@ -155,7 +155,9 @@ public: void setData(QList > list) { + beginResetModel(); m_list = list; + endResetModel(); } protected: diff --git a/core/core.pro b/core/core.pro index 313c498..02834c2 100644 --- a/core/core.pro +++ b/core/core.pro @@ -50,7 +50,8 @@ SOURCES += \ data/system.cpp \ settings/globalsettings.cpp \ settingsform.cpp \ - settings/globalsettingsform.cpp + settings/globalsettingsform.cpp \ + permissionevaluator.cpp HEADERS += core.h\ core_global.h \ @@ -100,7 +101,8 @@ HEADERS += core.h\ settings/globalsettings.h \ settingsform.h \ settings/globalsettingsform.h \ - formbinder.h + formbinder.h \ + permissionevaluator.h unix { target.path = /usr/lib diff --git a/core/imetadataplugin.cpp b/core/imetadataplugin.cpp index 438ca92..44b72a8 100644 --- a/core/imetadataplugin.cpp +++ b/core/imetadataplugin.cpp @@ -60,6 +60,11 @@ void IMetaDataPlugin::init(const QJsonObject &metaData) { pluginUi->setPluginId(pluginId()); } + + if (m_service != NULL) + { + m_service->setPluginId(pluginId()); + } } void IMetaDataPlugin::parseMetaData(const QJsonObject &metaData) diff --git a/core/iservice.cpp b/core/iservice.cpp index 281d46b..7e95dda 100644 --- a/core/iservice.cpp +++ b/core/iservice.cpp @@ -2,11 +2,14 @@ IService::IService(QObject *parent) : QObject(parent) { - } IService::~IService() { +} +void IService::setPluginId(const QString &pluginId) +{ + m_pluginId = pluginId; } diff --git a/core/iservice.h b/core/iservice.h index e7fde5d..21a1697 100644 --- a/core/iservice.h +++ b/core/iservice.h @@ -14,6 +14,8 @@ public: explicit IService(QObject *parent = 0); virtual ~IService(); + void setPluginId(const QString &pluginId); + signals: void dbError(QString errMsg); void dbErrorRead(QString errMsg); @@ -23,8 +25,12 @@ signals: void dataChanged(); void updateDenied(); void readDenied(); + void permissionDenied(QString permission); public slots: + +protected: + QString m_pluginId; }; #endif // ISERVICE_H diff --git a/core/permissionevaluator.cpp b/core/permissionevaluator.cpp new file mode 100644 index 0000000..510fd31 --- /dev/null +++ b/core/permissionevaluator.cpp @@ -0,0 +1,43 @@ +#include "permissionevaluator.h" + +#include + +#include "data/core-data.h" +#include "context.h" + +PermissionEvaluator::PermissionEvaluator(QObject *parent) + :QObject(parent) +{ +} + +PermissionEvaluator::~PermissionEvaluator() +{ +} + +bool PermissionEvaluator::hasPermission(const QString &pluginId, const QString &permission) +{ + if (Context::instance().currentUser()->isAdmin()) + { + return true; + } + + bool ret; + QList > roles = Context::instance().currentUser()->listRoles(); + + ret = std::find_if(ALL(roles), [&pluginId, &permission](QSharedPointer role) -> bool { + foreach (QSharedPointer perm, role->listPermissions()) { + if (perm->pluginId() == pluginId && perm->permissionName() == permission) { + return true; + } + } + return false; + }) != roles.end(); + + if (!ret) + { + emit permissionDenied(permission); + } + + return ret; +} + diff --git a/core/permissionevaluator.h b/core/permissionevaluator.h new file mode 100644 index 0000000..f475301 --- /dev/null +++ b/core/permissionevaluator.h @@ -0,0 +1,23 @@ +#ifndef PERMISSIONEVALUATOR_H +#define PERMISSIONEVALUATOR_H + +#include +#include + +#include "core_global.h" + +class CORESHARED_EXPORT PermissionEvaluator : public QObject +{ + Q_OBJECT + +public: + explicit PermissionEvaluator(QObject *parent = NULL); + ~PermissionEvaluator(); + + bool hasPermission(const QString &pluginId, const QString &permission); + +signals: + void permissionDenied(QString permission); +}; + +#endif // PERMISSIONEVALUATOR_H diff --git a/core/service.h b/core/service.h index 3476890..e3267db 100644 --- a/core/service.h +++ b/core/service.h @@ -13,6 +13,7 @@ #include "core_global.h" #include "context.h" #include "iservice.h" +#include "permissionevaluator.h" #include "transaction.h" @@ -27,12 +28,17 @@ public: } QList > all(const QString &where = "") { + QList > ret; + + if (!checkPermission(PERM_READ)) { + return ret; + } + odb::database *db = Context::instance().db(); Q_ASSERT(db); Transaction tx; - QList > ret; try { @@ -62,6 +68,10 @@ public: } void save(QSharedPointer entity) { + if (!checkPermission(PERM_ADD)) { + return; + } + odb::database *db = Context::instance().db(); Q_ASSERT(db); @@ -84,6 +94,10 @@ public: } void update(QSharedPointer entity) { + if (!checkPermission(PERM_EDIT)) { + return; + } + odb::database *db = Context::instance().db(); Q_ASSERT(db); @@ -106,12 +120,17 @@ public: } QSharedPointer loadById(int id) { + QSharedPointer entity; + + if (!checkPermission(PERM_READ)) { + return entity; + } + odb::database *db = Context::instance().db(); Q_ASSERT(db); Transaction tx; - QSharedPointer entity; try { @@ -137,6 +156,10 @@ public: } void erase(QSharedPointer entity) { + if (!checkPermission(PERM_DELETE)) { + return; + } + odb::database *db = Context::instance().db(); Q_ASSERT(db); @@ -155,12 +178,18 @@ public: } } - void setPluginId(const QString &pluginId) { - m_pluginId = pluginId; - } +protected: + bool checkPermission(const QString &permission) { + if (!m_pluginId.isEmpty()) { + PermissionEvaluator ev; + if (!ev.hasPermission(m_pluginId, permission)) { + emit permissionDenied(permission); + return false; + } + } -private: - QString m_pluginId; + return true; + } }; #endif // SERVICE_H