Я пытаюсь обернуть голову вокруг безопасности на уровне строк в Postgres. К сожалению, документация не очень многословна по этому вопросу. Моя проблема заключается в следующем:
У меня есть две таблицы: locations
и locations_owners
. Для местоположений установлено значение TRIGGER
INSERT
, которое автоматически добавит новую строку в таблицу locations_owners
, включая переменную request.jwt.claim.sub
.
. Хорошо, однако, когда я хочу создать политику для DELETE
, например:
CREATE POLICY location_delete ON eventzimmer.locations FOR DELETE TO organizer USING(
(SELECT EXISTS (SELECT name FROM protected.locations_owners AS owners WHERE owners.name = name AND owners.sub = (SELECT current_setting('request.jwt.claim.sub', true))))
);
Она всегда будет иметь значение true, независимо от фактического содержимого. Я знаю, что я могу вызвать пользовательскую процедуру с SELECT
здесь, однако у меня возникли следующие вопросы:
- какова область действия
policy
? Могу ли я получить доступ к таблицам? Могу ли я получить доступ к процедурам? Документация гласит «Любое условное выражение SQL» , поэтому SELECT EXISTS
должно быть в порядке - как имена столбцов строк сопоставляются с политикой. В примерах просто волшебным образом используются имена столбцов (которые я принял, используя переменную
name
), однако я не нашел никакой документации о том, что это на самом деле делает - что такое магия
user_name
переменная. От куда это? Я полагаю, что текущий role
выполняет запрос, но как я могу узнать? - Почему для
DELETE
нет выражения WITH CHECK
? Если я правильно понимаю, WITH CHECK
будет fail
любой строкой с недопустимым ограничением, такое поведение я бы предпочел (потому что иначе PostgREST всегда будет возвращать 204
)
Я немногосбит с толку поразительно отсутствующим количеством информации в (иначе) очень хорошей документации PostgreSQL. Где эта информация? Как я могу его найти?
Ради полноты я также приложил следующие определения столбцов:
CREATE TABLE eventzimmer.locations (
name varchar PRIMARY KEY NOT NULL,
latitude float NOT NULL,
longitude float NOT NULL
);
CREATE TABLE IF NOT EXISTS protected.locations_owners (
name varchar NOT NULL REFERENCES eventzimmer.locations(name) ON DELETE CASCADE,
sub varchar NOT NULL
);