我应该如何优化此行级安全策略以读取事件?

How should I go about optimizing this row level security policy for reading an event?

这是我用于此策略的表/实体的摘要(针对 SO 进行了简化)。

user
----
id (pk)

event
-----
uuid (pk)
host_id (fk -> user)
privacy: int

friendship
----------
user_id (pk, fk -> user)
friend_id (pk, fk -> user)

invitation
----------
user_id (pk, fk -> user)
event_uuid (pk, fk -> event)

ENUMS: 
- Privacy (Public, Friends, Private) = (0, 1, 2)

在我的例子中,我想确保的是,使用 PostgreSQL 中的行级安全性或其他一些方法(可能是什么条件?),用户只能在满足以下条件之一的情况下看到事件:

  1. 如果他们是活动的主持人
  2. 如果活动的隐私是 public
  3. 如果活动的隐私是朋友并且他们是活动主持人的朋友
  4. 如果他们受邀参加活动

我知道这些条件很多,但我不确定检查所有这些条件的最佳格式是什么。目前,这是我用来检查所有内容的 RLS 策略,但它看起来很冗长,我想知道是否缺少可以优化它的东西:

create policy read_event
    on event
    for select
    using (
        -- is host
        event.user_id = ?
        or
        -- is public
        event.privacy = 0
        or
        -- is invited
        exists (
            select *
            from invitation as i
            where i.user_id = ? and i.party_uuid = event.uuid
        )
        or
        -- is friends and party is friends-level privacy
        exists (
            select *
            from friendship as f
            where f.user_id = ? and f.friend_id = party.user_id
            or f.user_id = party.user_id and f.friend_id = ?
        )
        and 
        event.privacy = 1
    )

'?'可以替换为进行查询的当前用户的 ID(使用会话变量或其他替代方法)。总的来说,这是我正在尝试做的事情的简化版本,但我只是想看看我是否在正确的道路上,或者我是否遗漏了什么。

此外,这有点超出了这个 SO 问题的范围,但如果有人有洞察力的话仍然有用,从其他表加入时 RLS 策略是否级联(例如,如果我创建一个带有 fk 的事件邀请,它会检查 RLS 策略以在插入时读取事件吗?)

非常感谢您的帮助!

我没有检查条件是否符合您的要求,但策略定义看起来很正常。问题是

  • 如果 ? 与用户无关,如何获取?使用占位符参数将起作用,但可以随时使用 SET 语句更改参数。也许这足以满足您的安全要求。

  • USING 子句中的条件将作为过滤器添加到查询中。它包含 OR,因此它可能会严重影响查询性能。如果数据,您应该使用实际数量进行测试。

行级安全性按照 table 工作。因此,具有外键约束的行的可见性不受引用 table.

上的行级安全策略的影响