好的。我将删除所有角色权限,然后再次添加。
是否可以将所有4个查询合并为一个?
我正在创建权限系统。
假设:
每个用户可以拥有多个角色
每个角色可以拥有多个权限
权限也可以直接分配给用户(它们的优先级高于角色的权限)
权限的优先级是:
角色权限
拒绝角色
用户权限
拒绝用户
拒绝用户具有最高优先级
PHP的问题很简单:
我创建具有所有权限的数组
我正在获得角色的权限(按访问权限排序)
我分配访问权限,如果被拒绝,我将使用拒绝访问覆盖访问权限
我对用户权限也是如此
我分配访问权限,如果被拒绝,我将使用拒绝访问覆盖访问权限
这样,我拥有整个阵列,并具有特定用户的权限,例如$ user ['permission'] ['delete_post'] //输出:false ||是
我现在需要进行权限检查。这意味着哪个用户可以访问例如'delete_post'
我有这个数据库结构: 这里摆弄数据库:DB fiddle
我对第一个查询有疑问
**Query #1**
=============================================
List of all roles related to permission with id 3 */
SELECT DISTINCT role_id, access, permission_id FROM role_permissions WHERE permission_id=3 ORDER BY role_id, access DESC;
| role_id | access | permission_id |
| ------- | ------ | ------------- |
| 5 | 0 | 3 |
| 8 | 1 | 3 |
| 10 | 1 | 3 |
| 10 | 0 | 3 |
我应该得到
| role_id | access | permission_id |
| ------- | ------ | ------------- |
| 8 | 1 | 3 |
我无法添加WHERE permission_id=3 AND access=1
,因为我得到的结果是:role_id = 8和role_id = 10,但是role_id = 10确实没有访问权限。
答案 0 :(得分:1)
一种方法是根据各个表之间的关系进行所有适当的联接,然后使用带有GROUP BY
子句的HAVING
进行基于聚集的过滤。
以下查询将为您提供所有具有给定权限ID允许访问权限的用户(以下查询中的注释中有更多解释-可能需要对逻辑有更多了解;如果需要,请进行检查和注释):>
SELECT
u.user_id,
u.name
FROM users AS u
-- Left Join to get access (if defined for input permission id)
LEFT JOIN user_permissions AS up
ON up.user_id = u.user_id
AND up.permission_id = 3
-- Join to Roles; assuming every user has atleast one role
-- Change this to LEFT JOIN if it is possible that user can have NO role
JOIN user_roles AS ur
ON ur.user_id = u.user_id
-- Left Join to get access defined for input permission id for roles
LEFT JOIN role_permissions AS rp
ON rp.role_id = ur.role_id
AND rp.permission_id = 3
GROUP BY u.user_id, u.name
HAVING
-- first priority if user specific access allowed
-- if data is sane then up.access will have same value
-- across all rows in a group for user
MAX(up.access) = 1
OR
-- second priority is not have a single role with
-- denied permission AND
-- atleast one role exists with allowed permission
( NOT SUM(rp.access = 0)
AND
SUM(rp.access = 1)
);
结果
| user_id | name |
| ------- | ---------------- |
| 4 | Cyrus Gomez |
| 7 | MacKensie Morton |
| 13 | Nadine Taylor |
| 15 | Ezekiel Bonner |
| 17 | Ciaran Turner |
| 35 | Olga Dominguez |
| 38 | Lucas Pierce |
答案 1 :(得分:0)
您可以如下添加WHERE条件-
SELECT DISTINCT role_id, access, permission_id
FROM role_permissions
WHERE permission_id=3
AND role_id NOT IN (
SELECT DISTINCT role_id
FROM role_permissions
WHERE access = 0
AND permission_id=3 -- New condition added
)
ORDER BY role_id, access DESC;