为什么PostgreSQL权限在Triggers和Check约束之间表现不同?

问题描述 投票:0回答:1

我当前有一个具有两个架构app_privateapp_public(除了默认的公共架构)的数据库。我还有一个角色,该角色已被授予app_public模式的使用权限,但未被授予[[app_private模式的使用权限。我还在桌上使用了两个函数(一个触发函数和一个检查约束函数)。

请参见下面的代码:

((1)创建模式(和授权)

CREATE SCHEMA app_public; CREATE SCHEMA app_private; grant usage on schema public, app_public to "grant_test_role";

((2)撤消来自PUBLIC用户的授权]

然后我有这个特殊的DDL语句。对于公共用户角色(所有其他角色都继承自)的任何新添加的功能,应该具有

REVOKE

权限。alter default privileges revoke all on functions from public;
((3)函数定义(触发器和约束)]

-- Trigger Function create OR replace function app_private.tg__timestamps() returns trigger as $$ begin NEW.created_at = (case when TG_OP = 'INSERT' then NOW() else OLD.created_at end); NEW.updated_at = (case when TG_OP = 'UPDATE' and OLD.updated_at >= NOW() then OLD.updated_at + interval '1 millisecond' else NOW() end); return NEW; end; $$ language plpgsql volatile set search_path to pg_catalog, app_private, public, pg_temp; -- Constraint Function CREATE OR REPLACE FUNCTION app_private.constraint_max_length( value text, maxLength integer, error_message text default 'The value "$1" is too long. It must be maximum $2 characters long.', error_code text default 'MXLEN' ) RETURNS boolean AS $$ begin if length(value) > maxLength then error_text = replace(replace(error_message, '$1', value), '$2', maxLength); raise exception '%', error_text using errcode = error_code; end if; return true; end; $$ LANGUAGE plpgsql set search_path to pg_catalog, app_private, public, pg_temp;

((4)表定义(使用上面的触发器和约束函数)]

create table app_public.test_tab ( id INT not null primary key, name text not null, created_at timestamptz not null default now(), updated_at timestamptz not null default now(), constraint name_length_check check (app_private.constraint_max_length(name, 5)); ); create trigger _100_timestamps before insert or update on app_public.test_tab for each row execute procedure app_private.tg__timestamps(); -- Setting some restrictions on the test_tab for the "grant_test_role" REVOKE ALL ON TABLE app_public.test_tab FROM "grant_test_role"; GRANT SELECT, DELETE ON app_public.test_tab TO "grant_test_role"; GRANT INSERT(id, name), UPDATE(id, name) ON app_public.test_tab TO "grant_test_role";

(5)代码(以

grant_test_role

运行)begin; set local role to grant_test_role; insert into app_public.test_tab (id, name) values (1, 'Very Long Name'); commit;
我每次都试图在一个新的数据库中执行此操作,以了解PostgreSQL权限如何在不同的调用上下文中工作(例如,触发函数,自动检查函数的约束检查等)

[当我没有从PUBLIC用户撤消功能许可的代码块(2)时,代码块(5)的执行没有任何错误。尽管用户角色没有授予存在触发器功能和约束功能的

app_private

模式的事件,但该事件。但是在存在代码块(2)的情况下,代码可以很好地执行触发器,但为我提供了"permission denied for function constraint_max_length"作为检查约束。所以我想了解,

    在用户角色没有使用授权的模式中存在的触发器函数如何始终成功执行?
  1. 如果执行了触发功能,为什么CHECK约束功能会给我上面的权限被拒绝的错误?
  2. 代码块(2)实际做什么?
  • 我在努力寻找有关如何在这种“自动执行”方案(触发/约束)中应用权限的文档,因为用户不是“明确”调用这些函数,而是由数据库自动调用它们。因此,我不确定哪个角色在执行它们。
  • postgresql triggers permissions constraints roles
    1个回答
    0
    投票
    我将此问题发布到PostgreSQL邮件列表中,并最终得到答案。

    到目前为止,这就是PostgreSQL的工作方式(无论它是否符合SQL规范:)

    原始邮件线程-https://www.postgresql.org/message-id/CANYEAx8vZnN9eeFQfsiLGMi9NdCP0wUdriHTCGU-7jP0VmNKPA%40mail.gmail.com


    触发功能

      触发功能特权在创建时会与创建它们的角色进行检查。
    • 在运行时,根本不会根据执行角色来检查触发器功能的特权,而只是可以解析的能力。
    • 触发器函数内部的语句将对执行角色进行常规特权检查


  • 检查约束功能

      检查约束功能特权是在“创建”时针对创建特权的角色进行检查的。

  • 在运行时,仅检查约束函数的架构是否具有“解析能力”。就像存在这样的架构,但如果可以访问则不存在。
  • 然而,在运行时,将检查函数本身(无论存在于其架构中的模式)是否具有针对执行角色的特权。

  • 所以这解释了我在PostgreSQL中遇到的行为
  • © www.soinside.com 2019 - 2024. All rights reserved.