PostgreSQL行级安全性,涉及视图或带连接的选择

brgchamk  于 2023-02-18  发布在  PostgreSQL
关注(0)|答案(1)|浏览(162)

(欢迎对更好或更具描述性的标题提出建议)。
我想知道在PostgreSQL中使用RLS是否可以实现以下功能(或任何其他机制)。我希望用户能够在其用户名与另一个表中的列匹配时更新表中的某些行。在下面的示例中,我希望用户nene(在表t0中显示为列u)为了能够更新表t2中的列ap,我想表达的是对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';
这可能吗?有什么建议吗?一个明显的解决方法是在表t2上复制用户名,但是这会在t2上添加额外的信息,并且需要强制执行额外的约束。
下面是我的三个表(在真实的情况中有更多的字段,表t1不能排除在问题之外;我将其留在示例中,因为需要两个连接可能会改变解决方案空间)。

  • 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)
  • 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)
  • 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)
lh80um4z

lh80um4z1#

试试看

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
  )

)

相关问题