From 07525778881eaab1aaa3f56f13bb99c0472d13bc Mon Sep 17 00:00:00 2001 From: flashwave Date: Sun, 19 Aug 2018 03:17:10 +0200 Subject: [PATCH] Permission checking within SQL queries!! --- ...018_08_18_014408_add_forum_permissions.php | 2 +- src/Forum/forum.php | 34 +++++++++--- src/Forum/perms.php | 54 +++++++++++-------- 3 files changed, 61 insertions(+), 29 deletions(-) diff --git a/database/2018_08_18_014408_add_forum_permissions.php b/database/2018_08_18_014408_add_forum_permissions.php index dbf02e43..328f7cf2 100644 --- a/database/2018_08_18_014408_add_forum_permissions.php +++ b/database/2018_08_18_014408_add_forum_permissions.php @@ -11,7 +11,7 @@ function migrate_up(PDO $conn): void CREATE TABLE `msz_forum_permissions` ( `user_id` INT(10) UNSIGNED NULL DEFAULT NULL, `role_id` INT(10) UNSIGNED NULL DEFAULT NULL, - `forum_id` INT(10) UNSIGNED NULL DEFAULT NULL, + `forum_id` INT(10) UNSIGNED NOT NULL, `forum_perms_allow` INT(10) UNSIGNED NOT NULL DEFAULT '0', `forum_perms_deny` INT(10) UNSIGNED NOT NULL DEFAULT '0', UNIQUE INDEX `forum_permissions_user_id_unique` (`user_id`), diff --git a/src/Forum/forum.php b/src/Forum/forum.php index 3d3e0f15..a2720ac1 100644 --- a/src/Forum/forum.php +++ b/src/Forum/forum.php @@ -6,6 +6,9 @@ define('MSZ_PERM_FORUM_MANAGE_FORUMS', 1); define('MSZ_FORUM_PERM_LIST_FORUM', 1); // can see stats, but will get error when trying to view define('MSZ_FORUM_PERM_VIEW_FORUM', 1 << 1); +// shorthand, never use this to SET!!!!!!! +define('MSZ_FORUM_PERM_CAN_LIST_FORUM', MSZ_FORUM_PERM_LIST_FORUM | MSZ_FORUM_PERM_VIEW_FORUM); + define('MSZ_FORUM_PERM_CREATE_TOPIC', 1 << 10); define('MSZ_FORUM_PERM_DELETE_TOPIC', 1 << 11); define('MSZ_FORUM_PERM_MOVE_TOPIC', 1 << 12); @@ -78,7 +81,12 @@ function forum_fetch(int $forumId): array function forum_get_root_categories(int $userId): array { - $categories = Database::query(' + $categoryPermSql = sprintf( + '(%s & %d)', + forum_perms_get_user_sql('forum', 'f.`forum_id`'), + MSZ_FORUM_PERM_CAN_LIST_FORUM + ); + $getCategories = Database::prepare(" SELECT f.`forum_id`, f.`forum_name`, f.`forum_type`, ( @@ -90,17 +98,31 @@ function forum_get_root_categories(int $userId): array WHERE f.`forum_parent` = 0 AND f.`forum_type` = 1 AND f.`forum_hidden` = false + AND {$categoryPermSql} > 0 ORDER BY f.`forum_order` - ')->fetchAll(); - + "); + $getCategories->bindValue('perm_user_id_1', $userId); + $getCategories->bindValue('perm_user_id_2', $userId); + $categories = $getCategories->execute() ? $getCategories->fetchAll(PDO::FETCH_ASSOC) : []; $categories = array_merge([MSZ_FORUM_ROOT_DATA], $categories); - $categories[0]['forum_children'] = (int)Database::query(' + $forumPermSql = sprintf( + '(%s & %d)', + forum_perms_get_user_sql('forum', '`forum_id`'), + MSZ_FORUM_PERM_CAN_LIST_FORUM + ); + $getRootForumCount = Database::prepare(sprintf(" SELECT COUNT(`forum_id`) FROM `msz_forum_categories` - WHERE `forum_parent` = ' . MSZ_FORUM_ROOT . ' + WHERE `forum_parent` = %d AND `forum_type` != 1 - ')->fetchColumn(); + AND {$forumPermSql} > 0 + ", MSZ_FORUM_ROOT)); + $getRootForumCount->bindValue('perm_user_id_1', $userId); + $getRootForumCount->bindValue('perm_user_id_2', $userId); + $getRootForumCount->execute(); + + $categories[0]['forum_children'] = (int)$getRootForumCount->fetchColumn(); return $categories; } diff --git a/src/Forum/perms.php b/src/Forum/perms.php index af70e809..265d1fdb 100644 --- a/src/Forum/perms.php +++ b/src/Forum/perms.php @@ -31,6 +31,34 @@ function forum_perms_create(): int return $perms; } +function forum_perms_get_user_sql( + string $prefix, + string $forum = ':perm_forum_id', + string $user_for_user = ':perm_user_id_1', + string $user_for_role = ':perm_user_id_2' +): string { + return " + SELECT BIT_OR(`{$prefix}_perms_allow`) &~ BIT_OR(`{$prefix}_perms_deny`) + FROM `msz_forum_permissions` + WHERE ( + `forum_id` = {$forum} + OR `forum_id` IS NULL + ) + AND ( + (`user_id` IS NULL AND `role_id` IS NULL) + OR (`user_id` = {$user_for_user} AND `role_id` IS NULL) + OR ( + `user_id` IS NULL + AND `role_id` IN ( + SELECT `role_id` + FROM `msz_user_roles` + WHERE `user_id` = {$user_for_role} + ) + ) + ) + "; +} + function forum_perms_get_user(string $prefix, int $forum, int $user): int { if (!in_array($prefix, MSZ_FORUM_PERM_MODES) || $user < 1) { @@ -39,28 +67,10 @@ function forum_perms_get_user(string $prefix, int $forum, int $user): int //return 0x7FFFFFFF; } - $getPerms = Database::prepare(" - SELECT BIT_OR(`{$prefix}_perms_allow`) &~ BIT_OR(`{$prefix}_perms_deny`) - FROM `msz_forum_permissions` - WHERE ( - `forum_id` = :forum_id - OR `forum_id` IS NULL - ) - AND ( - (`user_id` = :user_id_1 AND `role_id` IS NULL) - OR ( - `user_id` IS NULL - AND `role_id` IN ( - SELECT `role_id` - FROM `msz_user_roles` - WHERE `user_id` = :user_id_2 - ) - ) - ) - "); - $getPerms->bindValue('forum_id', $forum); - $getPerms->bindValue('user_id_1', $user); - $getPerms->bindValue('user_id_2', $user); + $getPerms = Database::prepare(forum_perms_get_user_sql($prefix)); + $getPerms->bindValue('perm_forum_id', $forum); + $getPerms->bindValue('perm_user_id_1', $user); + $getPerms->bindValue('perm_user_id_2', $user); return $getPerms->execute() ? (int)$getPerms->fetchColumn() : 0; }