From 94fba56dab1f17dc8f1e0260af9a0d817765d800 Mon Sep 17 00:00:00 2001 From: Josef Rokos Date: Tue, 22 Dec 2015 16:08:47 +0100 Subject: [PATCH] Implemented permission settings for Roles. --- core/autoform.h | 7 ++- core/autotablemodel.h | 3 +- core/context.cpp | 66 +++++++++++++++++-------- core/context.h | 4 ++ core/core.pro | 6 ++- core/data/permission.cpp | 5 ++ core/data/permission.h | 5 +- core/data/role.cpp | 10 ++++ core/data/role.h | 11 +++-- core/define.h | 6 +++ core/metaData.json | 99 +++++++++++++++++++------------------- core/permissionservice.cpp | 38 +++++++++++++++ core/permissionservice.h | 30 ++++++++++++ core/roles/rolesform.cpp | 54 +++++++++++++++++++++ core/roles/rolesform.h | 5 ++ core/roles/rolesform.ui | 26 +++++++++- 16 files changed, 295 insertions(+), 80 deletions(-) create mode 100644 core/permissionservice.cpp create mode 100644 core/permissionservice.h diff --git a/core/autoform.h b/core/autoform.h index 5d6be9b..0936ac1 100644 --- a/core/autoform.h +++ b/core/autoform.h @@ -52,6 +52,10 @@ public: m_validators.append(validator); } +protected: + virtual void bindOtherToUi() {} + virtual bool bindOtherToData() { return true; } + private: QSharedPointer m_entity; QList m_bindWidgets; @@ -63,6 +67,7 @@ private: const char* prop = widget->metaObject()->userProperty().name(); widget->setProperty(prop, ((QObject*)m_entity.data())->property(widget->objectName().toStdString().c_str())); } + bindOtherToUi(); } bool bindToData() { @@ -78,7 +83,7 @@ private: ((QObject*)m_entity.data())->setProperty(widget->objectName().toStdString().c_str(), widget->property(prop)); } - return true; + return bindOtherToData(); } public slots: diff --git a/core/autotablemodel.h b/core/autotablemodel.h index b70f3c3..af977d5 100644 --- a/core/autotablemodel.h +++ b/core/autotablemodel.h @@ -119,7 +119,8 @@ public: void addRow(QSharedPointer data) { - beginInsertRows(QModelIndex(), rowCount() - 1, rowCount() - 1); + int index = rowCount() == 0 ? 0 : rowCount() - 1; + beginInsertRows(QModelIndex(), index, index); insertRow(rowCount()); m_list.append(data); endInsertRows(); diff --git a/core/context.cpp b/core/context.cpp index 1a760b4..c5d80af 100644 --- a/core/context.cpp +++ b/core/context.cpp @@ -13,6 +13,7 @@ #include "coreplugin.h" #include "users/users.h" #include "roles/roles.h" +#include "permissionservice.h" Context &Context::instance() { @@ -76,6 +77,8 @@ void Context::openDb(const QString &path) m_db = new odb::sqlite::database(path.toStdString()); m_settings->setValue("db/path", path); m_dbOpened = true; + + checkPermissions(); } void Context::destroy() @@ -96,6 +99,11 @@ void Context::destroy() m_plugins.clear(); } +QStringList Context::defaultPerms() +{ + return QStringList() << PERM_READ << PERM_ADD << PERM_EDIT << PERM_DELETE; +} + Context::Context() { m_db = NULL; @@ -105,29 +113,32 @@ Context::Context() void Context::checkDb(const QString &path) { - QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); - db.setDatabaseName(path); - db.open(); - QSqlQuery q(db); - QString verSql = "SELECT pluginId, schemaVersion FROM system"; - QString createSysSql = "CREATE TABLE \"system\" (\"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \"pluginId\" TEXT NULL, \"schemaVersion\" TEXT NULL)"; - - if (q.exec(verSql)) { - QMap schemas; - while (q.next()) + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "check"); + db.setDatabaseName(path); + db.open(); + QSqlQuery q(db); + QString verSql = "SELECT pluginId, schemaVersion FROM system"; + QString createSysSql = "CREATE TABLE \"system\" (\"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \"pluginId\" TEXT NULL, \"schemaVersion\" TEXT NULL)"; + + if (q.exec(verSql)) { - schemas[q.value("pluginId").toString()] = q.value("schemaVersion").toInt(); + QMap schemas; + while (q.next()) + { + schemas[q.value("pluginId").toString()] = q.value("schemaVersion").toInt(); + } + checkSchema(db, schemas); + } + else + { + q.exec(createSysSql); + checkSchema(db, QMap()); } - checkSchema(db, schemas); - } - else - { - q.exec(createSysSql); - checkSchema(db, QMap()); - } - db.close(); + db.close(); + } + QSqlDatabase::removeDatabase("check"); } void Context::checkSchema(const QSqlDatabase &db, const QMap &schemaMap) @@ -197,3 +208,20 @@ void Context::createSchema(IPlugin *plugin, const QSqlDatabase &db, const QMap p = permService.forNameAndPlugin(perm, plugin->pluginId()); + if (p.isNull()) + { + QSharedPointer nPerm(new Permission); + nPerm->setPermissionName(perm); + nPerm->setPluginId(plugin->pluginId()); + permService.save(nPerm); + } + } + } +} diff --git a/core/context.h b/core/context.h index 993af5f..4ef2cfb 100644 --- a/core/context.h +++ b/core/context.h @@ -13,6 +13,7 @@ #include "transaction.h" #include +#include class IPlugin; @@ -28,6 +29,7 @@ public: QSettings *settings() { return m_settings; } bool dbOpened() { return m_dbOpened; } void destroy(); + QStringList defaultPerms(); private: Context(); @@ -35,6 +37,7 @@ private: odb::database *m_db; QSettings *m_settings; bool m_dbOpened; + odb::session m_session; QStringList m_solved; @@ -42,6 +45,7 @@ private: void checkSchema(const QSqlDatabase &db, const QMap &schemaMap); void solveDep(IPlugin *plugin, const QSqlDatabase &db, const QMap &schemaMap); void createSchema(IPlugin *plugin, const QSqlDatabase &db, const QMap &schemaMap); + void checkPermissions(); }; #endif // CONTEXT_H diff --git a/core/core.pro b/core/core.pro index fdea287..6369b4e 100644 --- a/core/core.pro +++ b/core/core.pro @@ -32,7 +32,8 @@ SOURCES += \ roles/rolestablemodel.cpp \ roles/roles.cpp \ roles/rolesui.cpp \ - roles/rolesform.cpp + roles/rolesform.cpp \ + permissionservice.cpp HEADERS += core.h\ core_global.h \ @@ -64,7 +65,8 @@ HEADERS += core.h\ roles/rolestablemodel.h \ roles/roles.h \ roles/rolesui.h \ - roles/rolesform.h + roles/rolesform.h \ + permissionservice.h unix { target.path = /usr/lib diff --git a/core/data/permission.cpp b/core/data/permission.cpp index e00ec7b..7657cad 100644 --- a/core/data/permission.cpp +++ b/core/data/permission.cpp @@ -68,6 +68,11 @@ void Permission::setListRoles(const QList > &listRoles) m_listRoles = listRoles; } +void Permission::addRole(QSharedPointer role) +{ + m_listRoles.append(role); +} + diff --git a/core/data/permission.h b/core/data/permission.h index a469599..c6dcfca 100644 --- a/core/data/permission.h +++ b/core/data/permission.h @@ -9,6 +9,7 @@ #include #include #include +#include #pragma db object class Permission : public QObject @@ -43,6 +44,8 @@ public: QList > listRoles() const; void setListRoles(const QList > &listRoles); + void addRole(QSharedPointer role); + private: friend class odb::access; @@ -54,7 +57,7 @@ private: QDateTime m_createDate; bool m_active; #pragma db value_not_null inverse(m_listPermissions) - QList > m_listRoles; + QOdbList > m_listRoles; }; diff --git a/core/data/role.cpp b/core/data/role.cpp index 44c725e..15d4511 100644 --- a/core/data/role.cpp +++ b/core/data/role.cpp @@ -68,6 +68,16 @@ void Role::setListPermissions(const QList > &listPerm m_listPermissions = listPermissions; } +void Role::addPermission(QSharedPointer perm) +{ + m_listPermissions.append(perm); +} + +void Role::clearPermissions() +{ + m_listPermissions.clear(); +} + diff --git a/core/data/role.h b/core/data/role.h index 43d2074..3d4dbb4 100644 --- a/core/data/role.h +++ b/core/data/role.h @@ -9,6 +9,7 @@ #include #include #include +#include #pragma db object class Role : public QObject @@ -42,6 +43,9 @@ public: QList > listPermissions() const; void setListPermissions(const QList > &listPermissions); + void addPermission(QSharedPointer perm); + void clearPermissions(); + private: friend class odb::access; @@ -53,11 +57,8 @@ private: bool m_active; #pragma db value_not_null inverse(m_listRoles) QList > m_listUsers; -#pragma db value_not_null unordered - QList > m_listPermissions; - - - +#pragma db value_not_null + QOdbList > m_listPermissions; }; #endif // ROLE_H diff --git a/core/define.h b/core/define.h index 683daf4..42ac1a7 100644 --- a/core/define.h +++ b/core/define.h @@ -3,5 +3,11 @@ #define ALL(arr) arr.begin(), arr.end() +// default rights +#define PERM_READ "READ" +#define PERM_ADD "ADD" +#define PERM_EDIT "EDIT" +#define PERM_DELETE "DELETE" + #endif // DEFINE_H diff --git a/core/metaData.json b/core/metaData.json index 57d6737..f9339ab 100644 --- a/core/metaData.json +++ b/core/metaData.json @@ -12,62 +12,63 @@ "schemaVersion" : 1, "sql" : [ "CREATE TABLE \"User\" ( - \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - \"login\" TEXT NULL, - \"password\" TEXT NULL, - \"name\" TEXT NULL, - \"lastModDate\" TEXT NULL, - \"createDate\" TEXT NULL, - \"active\" INTEGER NOT NULL, - \"isAdmin\" INTEGER NOT NULL); + \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + \"login\" TEXT NULL, + \"password\" TEXT NULL, + \"name\" TEXT NULL, + \"lastModDate\" TEXT NULL, + \"createDate\" TEXT NULL, + \"active\" INTEGER NOT NULL, + \"isAdmin\" INTEGER NOT NULL); - CREATE TABLE \"User_listRoles\" ( - \"object_id\" INTEGER NOT NULL, - \"value\" INTEGER NOT NULL, - CONSTRAINT \"object_id_fk\" - FOREIGN KEY (\"object_id\") - REFERENCES \"User\" (\"id\") - ON DELETE CASCADE, - CONSTRAINT \"value_fk\" - FOREIGN KEY (\"value\") - REFERENCES \"Role\" (\"id\") - DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE \"User_listRoles\" ( + \"object_id\" INTEGER NOT NULL, + \"value\" INTEGER NOT NULL, + CONSTRAINT \"object_id_fk\" + FOREIGN KEY (\"object_id\") + REFERENCES \"User\" (\"id\") + ON DELETE CASCADE, + CONSTRAINT \"value_fk\" + FOREIGN KEY (\"value\") + REFERENCES \"Role\" (\"id\") + DEFERRABLE INITIALLY DEFERRED); - CREATE INDEX \"User_listRoles_object_id_i\" - ON \"User_listRoles\" (\"object_id\"); +CREATE INDEX \"User_listRoles_object_id_i\" + ON \"User_listRoles\" (\"object_id\"); - CREATE TABLE \"Role\" ( - \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - \"name\" TEXT NULL, - \"lastModDate\" TEXT NULL, - \"createDate\" TEXT NULL, - \"active\" INTEGER NOT NULL); +CREATE TABLE \"Role\" ( + \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + \"name\" TEXT NULL, + \"lastModDate\" TEXT NULL, + \"createDate\" TEXT NULL, + \"active\" INTEGER NOT NULL); - CREATE TABLE \"Role_listPermissions\" ( - \"object_id\" INTEGER NOT NULL, - \"value\" INTEGER NOT NULL, - CONSTRAINT \"object_id_fk\" - FOREIGN KEY (\"object_id\") - REFERENCES \"Role\" (\"id\") - ON DELETE CASCADE, - CONSTRAINT \"value_fk\" - FOREIGN KEY (\"value\") - REFERENCES \"Permission\" (\"id\") - DEFERRABLE INITIALLY DEFERRED); +CREATE TABLE \"Role_listPermissions\" ( + \"object_id\" INTEGER NOT NULL, + \"index\" INTEGER NOT NULL, + \"value\" INTEGER NOT NULL, + CONSTRAINT \"object_id_fk\" + FOREIGN KEY (\"object_id\") + REFERENCES \"Role\" (\"id\") + ON DELETE CASCADE, + CONSTRAINT \"value_fk\" + FOREIGN KEY (\"value\") + REFERENCES \"Permission\" (\"id\") + DEFERRABLE INITIALLY DEFERRED); - CREATE INDEX \"Role_listPermissions_object_id_i\" - ON \"Role_listPermissions\" (\"object_id\"); +CREATE INDEX \"Role_listPermissions_object_id_i\" + ON \"Role_listPermissions\" (\"object_id\"); - CREATE TABLE \"Permission\" ( - \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - \"pluginId\" TEXT NULL, - \"permissionName\" TEXT NULL, - \"lastModDate\" TEXT NULL, - \"createDate\" TEXT NULL, - \"active\" INTEGER NOT NULL);" +CREATE INDEX \"Role_listPermissions_index_i\" + ON \"Role_listPermissions\" (\"index\"); - - ], +CREATE TABLE \"Permission\" ( + \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + \"pluginId\" TEXT NULL, + \"permissionName\" TEXT NULL, + \"lastModDate\" TEXT NULL, + \"createDate\" TEXT NULL, + \"active\" INTEGER NOT NULL);" ], "dependencies" : [] } } diff --git a/core/permissionservice.cpp b/core/permissionservice.cpp new file mode 100644 index 0000000..f3a0b60 --- /dev/null +++ b/core/permissionservice.cpp @@ -0,0 +1,38 @@ +#include "permissionservice.h" + +PermissionService::PermissionService() +{ +} + +PermissionService::~PermissionService() +{ +} + +QList > PermissionService::forPlugin(const QString &pluginId) +{ + Transaction tr; + odb::database *db = Context::instance().db(); + permQuery q(permQuery::pluginId == pluginId); + permResult result = db->query(q); + + QList > ret; + for (permResult::iterator it = result.begin(); it != result.end(); it++) + { + ret.append(it.load()); + } + + tr.commit(); + return ret; +} + +QSharedPointer PermissionService::forNameAndPlugin(const QString &name, const QString &pluginId) +{ + Transaction tr; + odb::database *db = Context::instance().db(); + permQuery q(permQuery::pluginId == pluginId && permQuery::permissionName == name); + QSharedPointer p = db->query_one(q); + + tr.commit(); + return p; +} + diff --git a/core/permissionservice.h b/core/permissionservice.h new file mode 100644 index 0000000..f48af7f --- /dev/null +++ b/core/permissionservice.h @@ -0,0 +1,30 @@ +#ifndef PERMISSIONSERVICE_H +#define PERMISSIONSERVICE_H + +#include "service.h" +#include "permission.h" +#include "core-odb.hxx" +#include "core_global.h" +#include +#include +#include +#include + +#include +#include +#include + +typedef odb::query permQuery; +typedef odb::result permResult; + +class CORESHARED_EXPORT PermissionService : public Service +{ +public: + PermissionService(); + ~PermissionService(); + + QList > forPlugin(const QString &pluginId); + QSharedPointer forNameAndPlugin(const QString &name, const QString &pluginId); +}; + +#endif // PERMISSIONSERVICE_H diff --git a/core/roles/rolesform.cpp b/core/roles/rolesform.cpp index 7d6cfb7..7ab8890 100644 --- a/core/roles/rolesform.cpp +++ b/core/roles/rolesform.cpp @@ -1,5 +1,9 @@ #include "rolesform.h" #include "ui_rolesform.h" +#include "iplugin.h" +#include "permissionservice.h" + +#include RolesForm::RolesForm(QWidget *parent) : AutoForm(parent), @@ -15,3 +19,53 @@ RolesForm::~RolesForm() { delete ui; } + +void RolesForm::bindOtherToUi() +{ + ui->treePerms->clear(); + QList > perms = entity()->listPermissions(); + + foreach (IPlugin *plugin, Context::instance().plugins()) { + if (plugin->pluginId() != "CORE") + { + QTreeWidgetItem *item = new QTreeWidgetItem(); + item->setText(0, plugin->pluginName()); + item->setData(0, Qt::UserRole, plugin->pluginId()); + + foreach (QString perm, Context::instance().defaultPerms()) { + QTreeWidgetItem *permItem = new QTreeWidgetItem(); + permItem->setText(0, tr(perm.toStdString().c_str())); + permItem->setData(0, Qt::UserRole, perm); + QList >::iterator it = std::find_if(ALL(perms), [&perm, plugin](QSharedPointer p){ return p->permissionName() == perm + && p->pluginId() == plugin->pluginId(); }); + permItem->setCheckState(0, it != perms.end() ? Qt::Checked : Qt::Unchecked); + item->addChild(permItem); + } + ui->treePerms->addTopLevelItem(item); + } + } +} + +bool RolesForm::bindOtherToData() +{ + PermissionService permService; + + entity()->clearPermissions(); + for (int i = 0; i < ui->treePerms->topLevelItemCount(); i++) + { + QTreeWidgetItem *item = ui->treePerms->topLevelItem(i); + + for (int j = 0; j < item->childCount(); j++) + { + QTreeWidgetItem *permItem = item->child(j); + if (permItem->checkState(0) == Qt::Checked) + { + QSharedPointer perm = permService.forNameAndPlugin(permItem->data(0, Qt::UserRole).toString(), item->data(0, Qt::UserRole).toString()); + perm->addRole(entity()); + entity()->addPermission(perm); + } + } + } + + return true; +} diff --git a/core/roles/rolesform.h b/core/roles/rolesform.h index c8d6811..b711ba8 100644 --- a/core/roles/rolesform.h +++ b/core/roles/rolesform.h @@ -20,6 +20,11 @@ public: private: Ui::RolesForm *ui; + + // AutoForm interface +protected: + virtual void bindOtherToUi() override; + virtual bool bindOtherToData() override; }; #endif // ROLESFORM_H diff --git a/core/roles/rolesform.ui b/core/roles/rolesform.ui index ea50558..07afc5f 100644 --- a/core/roles/rolesform.ui +++ b/core/roles/rolesform.ui @@ -7,13 +7,16 @@ 0 0 542 - 388 + 270 Form + + QFormLayout::AllNonFixedFieldsGrow + @@ -24,13 +27,32 @@ - + Active + + + + false + + + + 1 + + + + + + + + Permissions: + + +