1

我一直试图自己找到这个答案,但我太糟糕了,所以我来到这里希望你能帮助我。

我有以下数据库表:

user(
    int unsigned id,
    varchar      login
)
group(
    int unsigned id,
    varchar      label
)
right(
    int unsigned id,
    varchar      label
)
user_group(
    int unsigned userId,
    int unsigned groupId
)
user_right(
    int unsigned userId,
    int unsigned rightId,
    boolean      granted
)
group_right(
    int unsigned groupId,
    int unsigned rightId,
    boolean      granted
)

和 3 个配置参数(PHP 定义):

  • GRANTED_BY_DEFAULT可以是TRUEFALSE。它指示,当没有为组或用户指定权限时(即不在关联表中),是否授予权限。

  • RESULTING_RIGHTS可以是MIN_RIGHTSMAX_RIGHTS。它指示在确定结果权限时是使用“AND”还是“OR”运算符。例如,如果对于右“r1”,组“g1”为 TRUE,组“g2”和“g3”为 FALSE,“MIN_RIGHTS”为 FALSE,“MAX_RIGHTS”为 TRUE。

  • RIGHTS_PRIORITY可以是USER_OVER_GROUPGROUP_OVER_USER。它指示用户自己的权限是否优先于他的组的权限,或者组的权限是否会优先于用户自己的权限。

考虑到这 3 个参数和他的组,我想提出一个可以找到用户有效拥有的权限的查询,但我真的不知道该怎么做。我还可以进行多个查询并在 PHP 端完成部分工作,但我想避免进行很多查询,因为我希望我的应用程序足够快,可以处理 AJAX 自动完成和其他类似的事情。

如果没有人愿意或有时间帮助我,我会理解 :p 感谢您的阅读。

编辑:一些示例数据:

user (id, login) :
1 "Admin"

group (id, label) :
1 "g1"
2 "g2"
3 "g3"

right (id, label) :
1 "r1"
2 "r2"
3 "r3"

user_group (userId, groupId) :
1 1
1 2

user_right (userId, rightId) :
1 1 true
1 2 false

group_rights (groupId, rightId) :
1 1 true
1 2 false
2 1 false
2 3 true

并且输出将是 (right_id, right_label) 行的列表,具体取决于参数和其他表的行。

在检索权限时,用户 ID 和/或登录名被认为是已知的。

4

1 回答 1

2
DECLARE @USERID INT = 1,
        @GRANTED_BY_DEFAULT INT = 0,
        @RESULTING_RIGHTS VARCHAR(20) = 'MIN_RIGHTS',
        @RIGHTS_PRIORITY VARCHAR(20) = 'USER_OVER_GROUP'

SELECT 
    R.ID,
    R.NAME,
    CASE
        WHEN MAX(UR.Value) IS NULL AND MAX(GR.Value) IS NULL THEN
            @GRANTED_BY_DEFAULT
        WHEN MAX(UR.Value) IS NOT NULL AND MAX(GR.Value) IS NOT NULL THEN
            CASE
                WHEN @RIGHTS_PRIORITY = 'USER_OVER_GROUP' THEN
                    MAX(UR.Value)
                ELSE
                    CASE 
                        WHEN @RESULTING_RIGHTS = 'MIN_RIGHTS' THEN
                            MIN(GR.Value)
                        ELSE
                            MAX(GR.Value)
                    END
            END
        WHEN MAX(GR.Value) IS NULL THEN
            MAX(UR.Value)
        ELSE
            CASE
                WHEN @RESULTING_RIGHTS = 'MIN_RIGHTS' THEN
                    MIN(GR.Value)
                ELSE
                    MAX(GR.Value)
            END
    END VALUE
FROM
    [Right] R
    CROSS JOIN [User] U
    LEFT JOIN [User_Right] UR
        ON R.ID = UR.RightID
        AND UR.UserID = U.ID
    LEFT JOIN [User_Group] UG
        ON UG.UserID = U.ID
    LEFT JOIN [Group_Right] GR
        ON UG.GroupID = GR.GroupID 
        AND GR.RightID = R.ID
WHERE
    U.ID = @USERID
GROUP BY 
    R.ID,
    R.NAME

这是一个 SQL 小提琴示例SQL Fiddle

于 2012-11-13T16:21:27.670 回答