2016-05-27 1 views
2

Скажем, у нас есть две функции. Сначала нужно проверить разрешения, и если все идет правильно, обновите таблицу. Вот он:Функция вызова, которая не имеет разрешения от другой функции

CREATE OR REPLACE FUNCTION public.clients_test(
_clientid int 
,_comments varchar 
) 
    RETURNS void AS 
$BODY$ 
declare _result varchar; 
BEGIN 

if now()::time>'17:00'::time then 
    select public.clients_check_17_00() into _result; 
end if; 

update clients set comments=_comments where clientid=_clientid; 

END 
$BODY$ 
    LANGUAGE plpgsql VOLATILE SECURITY DEFINER 
    COST 1; 
ALTER FUNCTION public.clients_test(int, varchar) OWNER TO postgres; 
GRANT EXECUTE ON FUNCTION public.clients_test(int, varchar) TO postgres; 
GRANT EXECUTE ON FUNCTION public.clients_test(int, varchar) TO "RestrictedAccess"; 
REVOKE ALL ON FUNCTION public.clients_test(int, varchar) FROM public; 

Вторая функция ничего не делает с базой данных и существует только по соображениям безопасности. Я собирался назвать это из кулака. Вот он:

CREATE OR REPLACE FUNCTION public.clients_check_17_00() 
    RETURNS void AS 
$BODY$ 
BEGIN 

END 
$BODY$ 
    LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER 
    COST 1; 
ALTER FUNCTION public.clients_check_17_00()OWNER TO postgres; 
GRANT EXECUTE ON FUNCTION public.clients_check_17_00() TO postgres; 
GRANT EXECUTE ON FUNCTION public.clients_check_17_00() TO "FullAccess"; 
REVOKE ALL ON FUNCTION public.clients_check_17_00() FROM public; 

Некоторые пользователи должны обновлять комментарии только до 17:00. Таким образом, у них есть разрешения на

public.clients_test 

и не имеют права на

public.clients_check_17_00 

Я хотел бы иметь ошибку «У вас нет разрешения для выполнения public.clients_check_17_00», но это не сработало ,

ответ

0

Это интересная проблема, но ваш подход ошибочен.

Вместо того, чтобы проверить в течение времени внутри функции, вы должны управлять разрешениями вне функции. В вашем подходе время проверяется при каждом вызове, также в 08:02, 14:23, 16:34 и т. Д., Что является очень неэффективным по очевидным причинам. Вместо этого создайте два простых файла сценария SQL, один для отключения разрешений на выполнение функции, а другой - для повторного разрешения этих прав и запланированного задания запустите эти сценарии в 17:00, а затем, предположительно, в 08:00 или около того, чтобы снова включить выполнение разрешение. Это может быть так же просто:

psql -h localhost -d your_db -U postgres \ 
    -c 'REVOKE EXECUTE ON FUNCTION clients_test(int, varchar) FROM "RestrictedAccess"' 

И наоборот, чтобы снова разрешить разрешение. Но см. documentation для параметров, специфичных для доступа к вашему серверу.

Как именно это работает, зависит от вашей ОС; в Linux вы должны использовать задание cron, в Windows вы используете Task Scheduler.

Кстати, возврат сообщения от функции к сеансу осуществляется с помощью RAISE NOTICE.

Еще один важный момент в вашем коде: НИКОГДА НЕ ИСПОЛЬЗУЙТЕ postgres РОЛЬ КАК ВЛАДЕЛЬЦУ ОБЪЕКТОВ ИЛИ ПРОДОЛЖИТЬ КОД. Извините, номер: EMPHASIS, но этот момент не может быть достаточно подчеркнут. Вместо этого вы должны сделать привилегированную роль, предпочтительно без login привилегии, как владельца всех объектов (таблиц и функций и т. Д.), А затем явно установить привилегии для определенных ролей пользователей.

+0

Привет, Патрик. Благодарим за ваше предложение. Для меня было глупо упрощать оригинальную проблему. На самом деле у меня есть записи в таблице, которую я пытался разделить по возрасту. Например, записи старше 24 часов не могут быть отредактированы группой «RestrictedAccess». Поэтому, когда кто-то пытался отредактировать запись, я проверял, прошло ли 24 часа, и если да, то попытался выполнить функцию. – QuickJoe

+0

Я использую postgres как владелец объектов, потому что я использую функцию с флагом определения безопасности. Таким образом, пользователи не имеют прав на прямое изменение таблиц или выбор данных из них. Пользователи могут выполнять только функции и функции, делая очень ограниченные изменения. Около одной функции в поле. Поэтому я могу точно настроить разрешения. Я понимаю, что вы правы, что даже сейчас мне приходится заменять постгресы чем-то другим? – QuickJoe

+0

Таблицы по умолчанию доступны только для их владельца (и суперпользователей), и у владельца есть полные разрешения.Таким образом, даже если у владеющей роли нет значительных других разрешений или даже привилегий входа в систему, она полностью контролирует таблицы. Для этого вам не нужна роль супервизора. – Patrick

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