首页 > 解决方案 > 在 Postgraphile 中,对多对多关系使用权限

问题描述

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

想象一下我有这种多对多的关系(从官方文档中借用并用简化的权限进行了调整):

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更新帖子的所有字段,而用户permission = editor只能更新summary.

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

谢谢!

另请参阅此处的相关主题

标签: postgresqlpostgraphile

解决方案


根据调查和反复试验,这似乎是最好使用自定义功能来更新帖子来解决的问题。

所有者可以通过 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,我们希望阻止任何人post直接通过 GraphQL/Postgraphile 更改 a,因此我们只允许用户SELECTpost


推荐阅读