Postgres 策略的范围是什么?

Foh*_*len 2 postgresql policies

我试图围绕 Postgres 中的行级安全性进行思考。不幸的是,文档在这个问题上不是很详细。我的问题如下:

我有两个表:locationslocations_owners。有一TRIGGERINSERT用于位置,它将自动向locations_owners表中添加一个新行,包括request.jwt.claim.sub 变量

这一切正常,但是当我想创建这样的策略时DELETE

CREATE POLICY location_delete ON eventzimmer.locations FOR DELETE TO organizer USING(
    (SELECT EXISTS (SELECT name FROM protected.locations_owners AS owners WHERE owners.name = name AND owners.sub = (SELECT current_setting('request.jwt.claim.sub', true))))
);
Run Code Online (Sandbox Code Playgroud)

无论实际内容如何,​​它都将始终评估为真。我知道我可以SELECT在这里调用自定义程序,但是我最终遇到了以下问题:

  • a 的范围是policy什么?我可以访问表吗?我可以访问程序吗?文档说“任何 SQL 条件表达式”所以SELECT EXISTS应该没问题
  • 行的列名如何映射到策略。这些示例只是神奇地使用了列名(我通过使用name变量采用了它),但是我没有找到任何关于它实际作用的文档
  • 什么是魔法user_name变量。它从何而来?我相信是当前role正在执行查询,但我怎么知道?
  • 为什么没有WITH CHECK可用的表达式DELETE?如果我理解正确的话,WITH CHECKfail与无效的约束,这是我希望的行为(因为否则PostgREST总是会返回任何行204

我对 PostgreSQL 的(否则)非常好的文档中惊人地丢失的信息量感到有点困惑。这些信息在哪里?我怎样才能找到它?

为了完整起见,我还附上了下面的列定义:

CREATE TABLE eventzimmer.locations (
  name varchar PRIMARY KEY NOT NULL,
  latitude float NOT NULL,
  longitude float NOT NULL
);

CREATE TABLE IF NOT EXISTS protected.locations_owners (
    name varchar NOT NULL REFERENCES eventzimmer.locations(name) ON DELETE CASCADE,
    sub varchar NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

Lau*_*lbe 5

Many of the questions will become clear once you understand how row level security is implemented: the conditions in the policies will automatically be added to the query, just as if you added another WHERE condition.

Use EXPLAIN to see the query plan, and you will see the policy's conditions in there.

  • So you can use any columns from the table on which the policy is defined.

    Essentially, you can use anything in a policy definition that you could use in a WHERE conditions: Function calls, subqueries and so on.

    如果需要消除歧义,您还可以使用表名限定列名。这可以在您的示例中的策略中使用:不合格name被解释为owners.name,因此测试总是成功。要修复该策略,请使用locations.name代替name

  • 没有魔法user_name变量,我不知道你从哪里得到它。但是,该current_user功能始终可用,当然也可以用于策略定义。

  • WITH CHECK是新行添加INSERTUPDATE必须满足的条件。由于DELETE不添加任何数据,WITH CHECK因此不适用于它。