Я пытаюсь создать систему контроля доступа.
Вот урезанный пример того, как выглядит таблица, к которой я пытаюсь контролировать доступ:
things table:
id group_id name
1 1 thing 1
2 1 thing 2
3 1 thing 3
4 1 thing 4
5 2 thing 5
А таблица контроля доступа выглядит так:
access table:
user_id type object_id access
1 group 1 50
1 thing 1 10
1 thing 2 100
Доступ может быть предоставлен либо указанием идентификатора «вещи» напрямую, либо предоставлением всей группы вещей путем указания идентификатора группы. В приведенном выше примере пользователю 1 был предоставлен уровень доступа 50 к группе 1, который должен применяться, если не существует каких-либо других правил, предоставляющих более конкретный доступ к отдельной вещи.
Мне нужен запрос, который возвращает список вещей (только идентификаторы в порядке) вместе с уровнем доступа для конкретного пользователя. Поэтому, используя приведенный выше пример, я бы хотел что-то подобное для идентификатора пользователя 1:
desired result:
thing_id access
1 10
2 100
3 50 (things 3 and 4 have no specific access rule,
4 50 so this '50' is from the group rule)
5 (thing 5 has no rules at all, so although I
still want it in the output, there's no access
level for it)
Самое близкое, что я могу придумать, это:
SELECT *
FROM things
LEFT JOIN access ON
user_id = 1
AND (
(access.type = 'group' AND access.object_id = things.group_id)
OR (access.type = 'thing' AND access.object_id = things.id)
)
Но это возвращает несколько строк, когда мне нужна только одна строка для каждой строки в таблице «вещей». Я не уверен, как перейти к одной строке для каждой «вещи» или как расставить приоритеты для «вещей» по сравнению с «групповыми» правилами.
Если это поможет, я использую базу данных PostgreSQL.
Пожалуйста, не стесняйтесь оставлять комментарии, если есть какая-то информация, которую я пропустил.
Заранее спасибо!