0

I'll explain my case:

The problem

I've got the following database table:

+----+----------+---------+------------+---------+---------------+-----------+---------+------+
| id | owner_id | user_id | group_mode | item_id | capability_id | from_date | to_date | deny |
+----+----------+---------+------------+---------+---------------+-----------+---------+------+

The id and owner_id field are not relevant for this question.

The group_mode can have 3 modes: 0 for a single user, 1 if the item is being shared for a group of users, or 2 if it's being shared in a team way.

The deny field can have 0 or 1. In case it's 1, the user won't be able to do anything that needs this permission. If it has a 0, the user will be able to do so. The "default" value means that no permission has been assigned to this user and object, and it's if the user is not found in the table with that item_id assigned.

I've managed to receive what I want from this query, but it's an extremely large query and with code repeated, since every comparison is made to every "user mode".

What I'd like to get

I'd like to make a query in order to receive the most restrictive permission of an object. If a user has permission 1 (edit) to an object, but a group to which he belongs is denied this permission (1), the result should be denied, and viceversa. If a group has the permission but the user has it denied, the permission is denied.

Also, if the user is the owner of the item all permissions are granted, even if they are not listed in the table (I explain this in order for you to understand the query I'll write).

All these must be if NOW() - today - is inside the date range. So, a denied permission from X to Y, if we are out from this range, is not denied anymore: is set to default (like it didn't exist).

When it complicates is when, if the user has not any permission set but a group or a team he belongs to has it, the permission is applied. I mean: it might be possible that the user won't have any permission granted, but a group to which he belongs yes, so he has this permission granted (herency).

What I've thought: The query explained

It's very simple, but very long at the end. What I do is to check:

IF the user has THIS PERMISSION to THIS OBJECT in THIS RANGE of dates, ONLY WHEN any group from which he belongs has not THIS PERMISSION denied NOR ANY TEAM in THIS RANGE of dates OR if ANY GROUP to which THIS USER belongs has set THIS PERMISSION in THIS RANGE for THIS OBJECT, ONLY WHEN the user itself has not THIS PERMISSION denied NOR ANY TEAM to which he belongs OR the same for the teams.

What I've thought: The query written

SELECT ITEM_SELECT_TABLE_FIELDS 
        FROM ITEM_ORIGINAL_TABLE
        WHERE deleted IS NULL  
            AND (user_id = 'USER_ID'  
                OR unique_id IN 
                    (SELECT sh.item_id 
                    FROM SHARED_ITEMS_TABLE sh 
                    WHERE (sh.user_id = 'USER_ID' 
                        AND sh.deny = 0 
                        AND sh.capability_id != 0 

                        AND sh.from_date < NOW() 
                        AND (sh.to_date > NOW() 
                            OR sh.to_date IS NULL) 
                        AND sh.user_id NOT IN 
                            (SELECT gr.user_id 
                            FROM GROUPS_TABLE gr 
                            WHERE group_id IN 
                                (SELECT sh2.user_id 
                                FROM SHARED_ITEMS_TABLE sh2 
                                WHERE sh2.group_mode = 1 
                                    AND sh2.deny = 1 
                                    AND sh2.from_date < NOW() 
                                    AND (sh2.to_date > NOW() 
                                        OR sh2.to_date IS NULL) 
                                    AND sh2.capability_id = sh.capability_id 
                                )
                            )
                        AND sh.user_id NOT IN 
                            (SELECT tm1.user_id 
                            FROM TEAMS_TABLE tm1 
                            WHERE tm1.team_id IN (
                                SELECT sh8.user_id 
                                FROM SHARED_ITEMS_TABLE sh8 
                                WHERE sh8.group_mode = 1 
                                    AND sh8.deny = 1 
                                    AND sh8.from_date < NOW() 
                                    AND (sh8.to_date > NOW() 
                                        OR sh8.to_date IS NULL) 
                                    AND sh8.capability_id = sh.capability_id 
                                )
                            )
                        ) 

                        OR 

                        (sh.user_id IN 
                            (SELECT grus2.group_id 
                            FROM GROUPS_TABLE grus2 
                            WHERE grus2.user_id = 'USER_ID' 
                            AND grus2.user_id NOT IN
                                (SELECT sh3.user_id 
                                FROM SHARED_ITEMS_TABLE sh3 
                                WHERE sh3.group_mode = 0 
                                AND sh3.deny = 1 
                                AND sh3.from_date < NOW() 
                                AND (sh3.to_date > NOW() 
                                    OR sh3.to_date IS NULL) 
                                AND sh3.capability_id = sh.capability_id 
                                AND sh3.user_id NOT IN 
                                    (SELECT grus3.group_id 
                                    FROM GROUPS_TABLE grus3 
                                    WHERE grus3.user_id IN 
                                        (SELECT sh5.user_id 
                                        FROM SHARED_ITEMS_TABLE sh5 
                                        WHERE sh5.group_mode = 0 
                                            AND sh5.deny = 1 
                                            AND sh5.from_date < NOW() 
                                            AND (sh5.to_date > NOW() 
                                                OR sh5.to_date IS NULL) 
                                            AND sh5.capability_id = sh.capability_id 
                                        )
                                    )
                                )
                            AND grus2.user_id NOT IN 
                                (SELECT tm3.user_id 
                                FROM TEAMS_TABLE tm3
                                WHERE tm3.team_id IN (
                                    SELECT sh9.user_id 
                                    FROM SHARED_ITEMS_TABLE sh9 
                                    WHERE sh9.group_mode = 2 
                                        AND sh9.deny = 1 
                                        AND sh9.from_date < NOW() 
                                        AND (sh9.to_date > NOW() 
                                            OR sh9.to_date IS NULL) 
                                        AND sh9.capability_id = sh.capability_id 
                                    )
                                )
                            ) 
                            AND sh.deny = 0 
                            AND group_mode = 1 
                            AND sh.from_date < NOW() 
                            AND (sh.to_date > NOW() 
                                OR sh.to_date IS NULL)
                        )

                        OR

                        (sh.user_id IN 
                            (SELECT tm4.team_id 
                            FROM TEAMS_TABLE tm4 
                            WHERE tm4.user_id = 'USER_ID' 
                                AND sh.deny = 0 
                                AND group_mode = 2 
                                AND sh.from_date < NOW() 
                                AND (sh.to_date > NOW() 
                                    OR sh.to_date IS NULL) 
                                AND sh.user_id NOT IN 
                                    (SELECT gr2.user_id 
                                    FROM GROUPS_TABLE gr2
                                    WHERE gr2.group_id IN 
                                        (SELECT sh10.user_id 
                                        FROM SHARED_ITEMS_TABLE sh10 
                                        WHERE sh10.group_mode = 1 
                                            AND sh10.deny = 1 
                                            AND sh10.from_date < NOW() 
                                            AND (sh10.to_date > NOW() 
                                                OR sh10.to_date IS NULL) 
                                            AND sh10.capability_id = sh.capability_id 
                                        )
                                    )
                                AND sh.user_id NOT IN 
                                    (SELECT grus7.group_id 
                                    FROM GROUPS_TABLE grus7
                                    WHERE grus7.user_id IN 
                                        (SELECT sh11.user_id 
                                        FROM SHARED_ITEMS_TABLE sh11 
                                        WHERE sh11.group_mode = 0 
                                            AND sh11.deny = 1 
                                            AND sh11.from_date < NOW() 
                                            AND (sh11.to_date > NOW() 
                                                OR sh11.to_date IS NULL) 
                                            AND sh11.capability_id = sh.capability_id 
                                        )
                                    )
                                )

                        )
                    )
                )  ORDER BY created_timestamp DESC

What I see

It's an extremely large query and if I add another group_mode (for example, maybe I want to add a group of groups to the permissions), I have to rewrite every WHERE condition to add the new one, in every case. It's a problem.

I know it must be some way to simplify all this, because the code in every WHERE condition is the same: just make sure that any correlatives of the user (group, team or the user itself) have not THIS PERMISSION denied.

Conclusion

I don't need you to write me the query. If you could explain me how to make somehow something recursive (without using procedures if it's possible) to check what I told before would be great.

Sorry for the large question and for my bad "MySQL language".

Thank you very much for your time and your answers!

4

1 回答 1

0

我认为,如果您对每种请求进行一个查询并使用 PHP 单独验证,它可能会更简单。

例如,您有一个 $item 对象 ( $item->deny) 的拒绝项目之类的属性。

如果$item->deny=1用户想对这个项目做点什么,他会发现:

if($item->deny==1)
{
   $message = "You are not allowed";
   echo $message;
} 
else 
{
   //do whatever
}

只是一个示例,但您可以对各种请求执行此操作。

于 2013-10-25T14:36:21.933 回答