Neo*_*Neo 3 postgresql permissions triggers roles constraints
我目前有一个具有两个模式app_private和app_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";
Run Code Online (Sandbox Code Playgroud)
(2) 撤销PUBLIC用户的授权
然后我就有了这个特殊的 DDL 语句。它应该从公共用户角色(所有其他角色继承自)中撤销任何新添加的功能的权限。
alter default privileges revoke all on functions from public;
Run Code Online (Sandbox Code Playgroud)
(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;
Run Code Online (Sandbox Code Playgroud)
(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";
Run Code Online (Sandbox Code Playgroud)
(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;
Run Code Online (Sandbox Code Playgroud)
我每次都尝试在新的数据库中执行此操作,以便了解 PostgreSQL 权限如何在不同的调用上下文中工作(即触发函数、自动调用函数的约束检查等)
当我没有撤销 PUBLIC 用户的函数权限的代码块 (2) 时,代码块 (5) 执行时不会出现任何错误。尽管用户角色没有对存在触发器函数和约束函数的app_private架构的授权,但仍发生事件。但是,有了代码块 (2),代码就可以很好地执行触发器,同时还给了我一个"permission denied for function constraint_max_length"检查约束。
所以我试图理解,
我正在努力寻找有关如何在这种“自动执行”场景(触发器/约束)中应用权限的文档,因为用户不是“显式”调用这些函数,而是由数据库自动调用它们。所以我不确定哪个角色正在执行它们。
我把这个问题发布到 PostgreSQL 邮件列表,终于得到了答案。
到目前为止,这就是 PostgreSQL 的工作方式(无论是否符合 SQL 规范:)
这解释了我在 PostgreSQL 中遇到的行为
| 归档时间: |
|
| 查看次数: |
1788 次 |
| 最近记录: |