涉及视图的 PostgreSQL row-level 安全性或具有连接的 select
PostgreSQL row-level security involving a view or a select with join
(欢迎提出更好或 more-descriptive 标题的建议)。
我想知道在使用 RLS(或任何其他机制)的 PostgreSQL 中是否可以实现以下功能。如果用户的用户名与另一个 table 中的列匹配,我希望用户能够更新 table 的某些行。在下面的示例中,我希望在 table t0
中显示为列 u
的用户 nene
能够更新列 a
和 p
在 table t2
中。我想表达的是将策略应用于 t2 中的行,这些行将与以下 select 语句匹配:SELECT a, p FROM t2 INNER JOIN t1 ON (t2.t1id = t1.id) INNER JOIN t0 ON (t1.t0id = t0.id) WHERE t0.u = 'nene';
这可能吗?关于如何进行的任何建议?一个明显的解决方法是在 table t2 上复制用户名,但这会在 t2 上添加无关信息并且需要执行额外的约束。
这是我的三个table(实际情况下还有更多的字段,table t1不能排除问题;我把它留在例子中,因为需要两个加入可能会改变解决方案 space).
Table t0
是用 CREATE TABLE t0 (id TEXT PRIMARY KEY, u TEXT UNIQUE, pn TEXT);
创建的,现在包含:
=> SELECT * FROM t0;
id | u | pn
------+------+------
b321 | toto | fifi
a421 | nene | xuxu
(2 rows)
Table t1
是用 CREATE TABLE t1 (id TEXT PRIMARY KEY, t0id TEXT REFERENCES t0(id), pn TEXT);
创建的,现在包含:
=> SELECT * FROM t1;
id | t0id | pn
------+------+------
x99 | a421 | lala
zy49 | a421 | popo
l2l | b321 | nipa
(3 rows)
Table t2
是用 CREATE TABLE t2 (id TEXT, t1id TEXT REFERENCES t1(id), a INET, p INT);
创建的,现在包含
=> SELECT * FROM t2;
id | t1id | a | p
------+------+-------------+-------
1264 | x99 | |
1267 | zy49 | |
1842 | l2l | 192.0.200.3 | 31337
1234 | x99 | 10.0.0.89 | 23
(4 rows)
尝试
CREATE POLICY t2_policy_update ON t2 FOR UPDATE
USING (EXISTS (SELECT * FROM t1 INNER JOIN t0 ON (t1.t0id = t0.id) WHERE t0.u = session_user AND t1id = t1.id))
(欢迎提出更好或 more-descriptive 标题的建议)。
我想知道在使用 RLS(或任何其他机制)的 PostgreSQL 中是否可以实现以下功能。如果用户的用户名与另一个 table 中的列匹配,我希望用户能够更新 table 的某些行。在下面的示例中,我希望在 table t0
中显示为列 u
的用户 nene
能够更新列 a
和 p
在 table t2
中。我想表达的是将策略应用于 t2 中的行,这些行将与以下 select 语句匹配:SELECT a, p FROM t2 INNER JOIN t1 ON (t2.t1id = t1.id) INNER JOIN t0 ON (t1.t0id = t0.id) WHERE t0.u = 'nene';
这可能吗?关于如何进行的任何建议?一个明显的解决方法是在 table t2 上复制用户名,但这会在 t2 上添加无关信息并且需要执行额外的约束。
这是我的三个table(实际情况下还有更多的字段,table t1不能排除问题;我把它留在例子中,因为需要两个加入可能会改变解决方案 space).
Table
t0
是用CREATE TABLE t0 (id TEXT PRIMARY KEY, u TEXT UNIQUE, pn TEXT);
创建的,现在包含:=> SELECT * FROM t0; id | u | pn ------+------+------ b321 | toto | fifi a421 | nene | xuxu (2 rows)
Table
t1
是用CREATE TABLE t1 (id TEXT PRIMARY KEY, t0id TEXT REFERENCES t0(id), pn TEXT);
创建的,现在包含:=> SELECT * FROM t1; id | t0id | pn ------+------+------ x99 | a421 | lala zy49 | a421 | popo l2l | b321 | nipa (3 rows)
Table
t2
是用CREATE TABLE t2 (id TEXT, t1id TEXT REFERENCES t1(id), a INET, p INT);
创建的,现在包含=> SELECT * FROM t2; id | t1id | a | p ------+------+-------------+------- 1264 | x99 | | 1267 | zy49 | | 1842 | l2l | 192.0.200.3 | 31337 1234 | x99 | 10.0.0.89 | 23 (4 rows)
尝试
CREATE POLICY t2_policy_update ON t2 FOR UPDATE
USING (EXISTS (SELECT * FROM t1 INNER JOIN t0 ON (t1.t0id = t0.id) WHERE t0.u = session_user AND t1id = t1.id))