【发布时间】:2022-01-24 17:26:24
【问题描述】:
鉴于我的架构中的以下 sn-p:
create table users (
id serial primary key,
name text not null
);
create table user_groups (
id serial primary key,
name text not null
);
create table user_user_group (
user_id integer not null references users(id),
user_group_id integer not null references user_groups(id)
);
grant all on users to staff;
grant all on user_groups to staff;
grant all on user_user_group to staff;
create function can_access_user_group(id integer) returns boolean as $$
select exists(
select 1
from user_user_group
where user_group_id = id
and user_id = current_user_id()
);
$$ language sql stable security invoker;
create function can_access_user(id integer) returns boolean as $$
select exists(
select 1
from user_user_group
where user_id = id
and can_access_user_group(user_group_id)
);
$$ language sql stable security invoker;
alter table users enable row level security;
create policy staff_users_policy
on users
to staff
using (
can_access_user(id)
);
请假设staff 角色和current_user_id() 功能已经过测试并且工作正常。我希望允许“员工”角色通过user_user_group 表在他们可以访问的用户组中创建用户。以下语句使staff_users_policy 失败:
begin;
set local role staff;
with new_user as (
insert into users (
name
) values (
'Some name'
)
returning id
)
insert into user_user_group (
user_id,
user_group_id
)
select
new_user.id,
1 as user_group_id
from new_user;
commit;
我可以像这样添加staff_insert_users_policy:
create policy staff_insert_users_policy
on users
for insert
to staff
with check (
true
);
这允许我插入用户,但在 returning id 上失败,我需要新的用户 ID 才能将行添加到 user_user_group 表中。
我明白它为什么会失败,但从概念上讲,我该如何避免这个问题?我可以为此创建一个“定义者”函数,或者一个具有自己策略的新角色,但我希望有一个更直接的方法。
【问题讨论】:
-
您找到解决此问题的方法了吗?我也有。
-
不,抱歉。我最终使用了定义函数和手动检查。
-
好的。我最终做了同样的事情。
-
@AtaiasReis 你能举个例子吗?
-
@Akrambek 我更改了项目,但我没有示例了。但是,您可以查看 PostGraphile 的文档:graphile.org/postgraphile/postgresql-schema-design/…。寻找“定义者”,他们根据我的记忆很好地解释了它。
标签: postgresql row-level-security