在 Postgraphile 中,对多对多关系使用权限

In Postgraphile, use permissions on many-to-many relationships

如何使用 Postgraphile 定义多对多关系的扩展权限和授权?

假设我有这种多对多关系(从 official docs 慷慨地借用并使用简化的权限进行调整):

create table post (
  id serial primary key,
  headline text,
  body text,
  summary text
);
create table author (
  id serial primary key,
  name text
);

create type post_permission as enum (
  'owner', -- assume owner can change `headline`, `summary` and `body` of a post
  'editor' -- assume editor can modify `summary` of a post
);
create table post_author (
  post_id integer references post,
  author_id integer references author,
  permission post_permission,
  primary key (post_id, author_id)
);

我可以制定行级安全策略,例如:

create policy update_post on post for update to app_user using (
  EXISTS(
    SELECT 1
    FROM post_author as pa
    WHERE pa.post_id = post.id 
      AND pa.author_id = app_hidden.current_user_id()
      AND pa.permission = 'owner'
  )
);

-- Assume `app_hidden.current_user_id()` returns a logged in user id

但是由于我是最近 MySQL 转换到 PostgreSQL 的人,所以我想看看我是否可以对上述尝试的更改进行策略检查 pa.permission 并且只允许 permission = owner 更新 post 的所有字段,而具有 permission = editor 的用户只能更新 summary.

我知道这通常是在应用程序层而不是数据库中处理的,但我想我会先看看有什么可能。

谢谢!

另见

根据调查和反复试验,这似乎是使用更新帖子的自定义函数来解决的最佳方法。

所有者可以通过 GraphQL/Postgraphile 使用此功能:

create function updatePost(
  headline text,
  body text,
  summary text
) returns post as $$
-- implement this function to check that the user found via 
-- app_hidden.current_user_id() exists in join table
-- with an `owner` permission
 -- then modify post
$$ language plpgsql strict security definer;

编辑器可以通过GraphQL/Postgraphile使用此功能:

create function updatePostMeta(
  summary text
) returns post as $$
-- implement this function to check that the user found via 
-- app_hidden.current_user_id() exists in join table 
-- with an `editor` or `owner` permission
-- then modify post
$$ language plpgsql strict security definer;

此外,使用 RLS,人们会希望阻止任何人直接通过 GraphQL/Postgraphile 更改 post,因此我们只允许来自 post 的用户 SELECT