假设我们有两个功能。首先应检查权限,如果一切顺利更新表。这是:
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 :(得分: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上使用任务计划程序。
顺便说一句,将函数中的消息返回到会话是使用RAISE NOTICE
完成的。
您的代码中的另一个要点:永远不要使用postgres作为对象或运行代码的角色。为 EMPHASIS 道歉,但这一点不够强调。您应该将非特权角色(最好没有login
权限)作为所有对象(表和函数等)的所有者,然后为特定用户角色显式设置权限。