From f690679412e2347f96b3b73bd6c224fbf3b9cd6c Mon Sep 17 00:00:00 2001 From: flashwave Date: Sat, 3 Nov 2018 17:44:19 +0100 Subject: [PATCH] Added permissions override flag to table structure. --- ...03_145619_add_permission_override_flag.php | 102 ++++++++++++++++++ misuzu.php | 8 +- src/Forum/forum.php | 60 +++++------ 3 files changed, 137 insertions(+), 33 deletions(-) create mode 100644 database/2018_11_03_145619_add_permission_override_flag.php diff --git a/database/2018_11_03_145619_add_permission_override_flag.php b/database/2018_11_03_145619_add_permission_override_flag.php new file mode 100644 index 00000000..63025d1e --- /dev/null +++ b/database/2018_11_03_145619_add_permission_override_flag.php @@ -0,0 +1,102 @@ +exec(" + ALTER TABLE `msz_permissions` + ADD COLUMN `general_perms_override` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `general_perms_deny`, + ADD COLUMN `user_perms_override` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `user_perms_deny`, + ADD COLUMN `changelog_perms_override` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `changelog_perms_deny`, + ADD COLUMN `news_perms_override` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `news_perms_deny`, + ADD COLUMN `forum_perms_override` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `forum_perms_deny`, + ADD COLUMN `comments_perms_override` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `comments_perms_deny`; + "); + + $conn->exec(" + ALTER TABLE `msz_forum_permissions` + ADD COLUMN `forum_perms_override` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `forum_perms_deny`; + "); + + $conn->exec('DROP VIEW `msz_forum_permissions_view`'); + $conn->exec(" + CREATE VIEW `msz_forum_permissions_view` AS + WITH RECURSIVE permissions(user_id, role_id, forum_id, forum_perms_allow, forum_perms_deny) as ( + SELECT + pp.`user_id`, pp.`role_id`, + pc.`forum_id`, + IFNULL(pp.`forum_perms_allow`, 0), IFNULL(pp.`forum_perms_deny`, 0) + FROM `msz_forum_categories` as pc + LEFT JOIN `msz_forum_permissions` as pp + ON pp.`forum_id` = pc.`forum_id` + GROUP BY `user_id`, `role_id`, `forum_id` + UNION ALL + SELECT + permissions.`user_id`, permissions.`role_id`, + cc.`forum_id`, + IFNULL(cp.`forum_perms_allow`, 0) | (permissions.`forum_perms_allow` &~ IFNULL(cp.`forum_perms_override`, 0)), + IFNULL(cp.`forum_perms_deny`, 0) | (permissions.`forum_perms_deny` &~ IFNULL(cp.`forum_perms_override`, 0)) + FROM `msz_forum_categories` as cc + LEFT JOIN `msz_forum_permissions` as cp + ON cp.`forum_id` = cc.`forum_id` + INNER JOIN permissions + ON cc.`forum_parent` = permissions.`forum_id` + ) + SELECT + `user_id`, `role_id`, `forum_id`, + (BIT_OR(`forum_perms_allow`) &~ BIT_OR(`forum_perms_deny`)) as `forum_perms` + FROM permissions + GROUP BY `user_id`, `role_id`, `forum_id` + "); +} + +function migrate_down(PDO $conn): void +{ + $conn->exec('DROP VIEW `msz_forum_permissions_view`'); + $conn->exec(" + CREATE VIEW `msz_forum_permissions_view` AS + WITH RECURSIVE permissions(user_id, role_id, forum_id, forum_perms_allow, forum_perms_deny) as ( + SELECT + pp.`user_id`, pp.`role_id`, + pc.`forum_id`, + IFNULL(pp.`forum_perms_allow`, 0), IFNULL(pp.`forum_perms_deny`, 0) + FROM `msz_forum_categories` as pc + LEFT JOIN `msz_forum_permissions` as pp + ON pp.`forum_id` = pc.`forum_id` + GROUP BY `user_id`, `role_id`, `forum_id` + UNION ALL + SELECT + permissions.`user_id`, permissions.`role_id`, + cc.`forum_id`, + IFNULL(cp.`forum_perms_allow`, 0) | permissions.`forum_perms_allow`, + IFNULL(cp.`forum_perms_deny`, 0) | permissions.`forum_perms_deny` + FROM `msz_forum_categories` as cc + LEFT JOIN `msz_forum_permissions` as cp + ON cp.`forum_id` = cc.`forum_id` + INNER JOIN permissions + ON cc.`forum_parent` = permissions.`forum_id` + ) + SELECT + `user_id`, `role_id`, `forum_id`, + (BIT_OR(`forum_perms_allow`) &~ BIT_OR(`forum_perms_deny`)) as `forum_perms` + FROM permissions + GROUP BY `user_id`, `role_id`, `forum_id` + "); + + $conn->exec(" + ALTER TABLE `msz_forum_permissions` + DROP COLUMN `forum_perms_override`; + "); + + $conn->exec(" + ALTER TABLE `msz_permissions` + DROP COLUMN `general_perms_override`, + DROP COLUMN `user_perms_override`, + DROP COLUMN `changelog_perms_override`, + DROP COLUMN `news_perms_override`, + DROP COLUMN `forum_perms_override`, + DROP COLUMN `comments_perms_override`; + "); +} diff --git a/misuzu.php b/misuzu.php index 676c7847..0e0dd299 100644 --- a/misuzu.php +++ b/misuzu.php @@ -224,14 +224,16 @@ use PDO; function migrate_up(PDO \$conn): void { - \$conn->exec(' + \$conn->exec(" CREATE TABLE ... - '); + "); } function migrate_down(PDO \$conn): void { - \$conn->exec('DROP TABLE ...'); + \$conn->exec(" + DROP TABLE ... + "); } MIG; diff --git a/src/Forum/forum.php b/src/Forum/forum.php index 92f1b0d0..d0a6c2e0 100644 --- a/src/Forum/forum.php +++ b/src/Forum/forum.php @@ -81,44 +81,44 @@ function forum_fetch(int $forumId): array function forum_get_root_categories(int $userId): array { - $categoryPermSql = sprintf( - '(%s & %d)', + $getCategories = db_prepare(sprintf( + " + SELECT + f.`forum_id`, f.`forum_name`, f.`forum_type`, f.`forum_colour`, + ( + SELECT COUNT(`forum_id`) + FROM `msz_forum_categories` as sf + WHERE sf.`forum_parent` = f.`forum_id` + ) as `forum_children` + FROM `msz_forum_categories` as f + WHERE f.`forum_parent` = 0 + AND f.`forum_type` = %d + AND f.`forum_hidden` = 0 + AND (%s & %d) > 0 + ORDER BY f.`forum_order` + ", + MSZ_FORUM_TYPE_CATEGORY, forum_perms_get_user_sql('forum', 'f.`forum_id`'), MSZ_FORUM_PERM_CAN_LIST_FORUM - ); - - $getCategories = db_prepare(" - SELECT - f.`forum_id`, f.`forum_name`, f.`forum_type`, f.`forum_colour`, - ( - SELECT COUNT(`forum_id`) - FROM `msz_forum_categories` as sf - WHERE sf.`forum_parent` = f.`forum_id` - ) as `forum_children` - FROM `msz_forum_categories` as f - WHERE f.`forum_parent` = 0 - AND f.`forum_type` = 1 - AND f.`forum_hidden` = false - AND {$categoryPermSql} > 0 - ORDER BY f.`forum_order` - "); + )); $getCategories->bindValue('perm_user_id_user', $userId); $getCategories->bindValue('perm_user_id_role', $userId); $categories = $getCategories->execute() ? $getCategories->fetchAll(PDO::FETCH_ASSOC) : []; $categories = array_merge([MSZ_FORUM_ROOT_DATA], $categories); - $forumPermSql = sprintf( - '(%s & %d)', + $getRootForumCount = db_prepare(sprintf( + " + SELECT COUNT(`forum_id`) + FROM `msz_forum_categories` + WHERE `forum_parent` = %d + AND `forum_type` != %d + AND (%s & %d) > 0 + ", + MSZ_FORUM_ROOT, + MSZ_FORUM_TYPE_CATEGORY, forum_perms_get_user_sql('forum', '`forum_id`'), MSZ_FORUM_PERM_CAN_LIST_FORUM - ); - $getRootForumCount = db_prepare(sprintf(" - SELECT COUNT(`forum_id`) - FROM `msz_forum_categories` - WHERE `forum_parent` = %d - AND `forum_type` != 1 - AND {$forumPermSql} > 0 - ", MSZ_FORUM_ROOT)); + )); $getRootForumCount->bindValue('perm_user_id_user', $userId); $getRootForumCount->bindValue('perm_user_id_role', $userId); $getRootForumCount->execute(); @@ -307,7 +307,7 @@ define( LEFT JOIN `msz_roles` as r ON r.`role_id` = u.`display_role` WHERE f.`forum_parent` = :parent_id - AND f.`forum_hidden` = false + AND f.`forum_hidden` = 0 AND (%4$s & %5$d) > 0 AND ( (f.`forum_parent` = %2$d AND f.`forum_type` != %3$d)