Permission checking within SQL queries!!

This commit is contained in:
flash 2018-08-19 03:17:10 +02:00
parent 55d3979d2c
commit 0752577888
3 changed files with 61 additions and 29 deletions

View file

@ -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`),

View file

@ -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;
}

View file

@ -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;
}