2015-06-20 3 views
1

Возможно ли настроить базу данных Postgres таким образом, чтобы конкретный столбец мог обновляться только триггером, но при этом позволял запускать сам запуск в ответ на обновление с помощью роли без разрешения обновить этот столбец? Если да, то как?Предотвращение обновления столбца за исключением триггера

Например, данные таблицы и триггер, как это:

CREATE TABLE a(
    id serial PRIMARY KEY, 
    flag boolean NOT NULL DEFAULT TRUE, 
    data text NOT NULL 
); 

CREATE TABLE b(
    id serial PRIMARY KEY, 
    updated_on DATE NOT NULL DEFAULT CURRENT_DATE, 
    a_id INTEGER NOT NULL, 
    FOREIGN KEY (a_id) references a(id) 
); 

CREATE FUNCTION update_aflag() RETURNS trigger AS $update_aflag$ 
    BEGIN 
    UPDATE a 
    SET flag = FALSE 
    WHERE id = NEW.a_id; 
    RETURN NEW; 
    END; 
$update_aflag$ LANGUAGE plpgsql; 

CREATE TRIGGER update_aflag_trigger 
    AFTER INSERT ON b 
    FOR EACH ROW 
    EXECUTE PROCEDURE update_aflag() 
; 

Я хотел бы, чтобы определить роль, которую делает не разрешения на обновление a.flag непосредственно используя UPDATE заявление, но который может обновление flag косвенно через спусковой крючок.

ответ

3

Да, это возможно с помощью функции триггера SECURITY DEFINER. Функция триггера запускается как роль, которая имеет право изменять столбец flag, но вы не используете GRANT, что право на обычных пользователей. Вы должны создать триггерную функцию как роль, которой вы предоставите требуемые права.

Это требует, чтобы приложение не запускалось как пользователь, которому принадлежат таблицы, и, конечно, не как суперпользователь.

Вы можете GRANT права на обновление столбца для других столбцов пользователю, просто оставьте поле flag. Обратите внимание, что GRANT ing UPDATE на всех столбцах, то REVOKE На нем flag будет не Работайте, это не то же самое.

+0

Вау, спасибо за подробный ответ Крейг. Теперь прочитайте документацию и попытайтесь создать соответствующую функцию триггера 'SECURITY DEFINER' :) – bsa

Смежные вопросы