#sql #postgresql #row-level-security
Вопрос:
У меня есть следующие таблицы Postgres:
Пользователи
--------- --------------
| id (PK) | full_name |
--------- --------------
| uuid() | varchar |
--------- --------------
организации
--------- ---------
| id (PK) | name |
--------- ---------
| uuid() | varchar |
--------- ---------
организация_memberships
--------- ---------------------- --------------
| id (PK) | organization_id (FK) | user_id (FK) |
--------- ---------------------- --------------
| uuid() | uuid() | uuid() |
--------- ---------------------- --------------
Я пытаюсь написать политику безопасности на уровне строк Postgres (RLS).
Политика должна обеспечивать, чтобы пользователи могли SELECT
organizations
использовать таблицу только в том случае, если в таблице есть соответствующая запись organization_memberships
.
Это то, что у меня есть в настоящее время, но, похоже, работает не так, как я ожидал. Примечание.Этот uid()
метод предоставляется моим решением DBAAS для получения идентификатора аутентифицированного пользователя.
ALTER POLICY "User can only Select organizations where they are members" ON public.organizations USING (
(
EXISTS (
SELECT
orgmembs.user_id,
orgmembs.organization_id
FROM
organization_memberships orgmembs
WHERE
(
(orgmembs.organization_id = organizations.id)
AND (orgmembs.user_id = uid())
)
)
)
);
Я также пробовал эту немного другую версию, но я получаю сообщение об ошибке, Error updating policy: missing FROM-clause entry for table "organization"
:
ALTER POLICY "User can only Select organizations where they are member" ON public.organizations USING (
auth.uid() IN (
SELECT
user_id
FROM
organization_memberships
WHERE
organization_memberships.organization_id = organization.id
)
);
Комментарии:
1. Ваша политика выглядит нормально. Пожалуйста, опишите, как он себя ведет. Возможно, пользователь, выполняющий запрос, владеет таблицей или иным образом освобожден от RLS.
Ответ №1:
alter POLICY "User can only Select organizations where they are member"
ON organizations
USING (id IN (
SELECT organization_id
FROM organization_memberships om
JOIN users u ON om.user_id = u.id
)
)
Комментарии:
1. Спасибо за ответ. Похоже, это не работает как есть. Не могли бы вы подробнее рассказать?
2. Я не правильно понял ваш вопрос. Какой именно вы хотите, чтобы была политика?
3. Цель состоит в том, что пользователь может выбирать строки из
organizations
таблицы только в том случае, если есть соответствующая строка, вorganization_memberships
которой содержитсяuser.id
иorganization.id
.4. Правильный..
organization_memberships
Таблица соответствуетusers
organizations
. Я не хочу, чтобы пользователи моглиSELECT
создавать организации, к которым они не принадлежат. Неужели такое поведение невозможно? Это похоже на общую схему отношений5. Я отредактировал код. По запросу организации отображаются те, которые пользователь присоединяет к organization_memberships.