1

(les suggestions pour un titre meilleur ou plus descriptif sont les bienvenues).Sécurité de niveau ligne PostgreSQL impliquant une vue ou un select avec jointure

Je me demande si ce qui suit est possible dans PostgreSQL en utilisant RLS (ou tout autre mécanisme). Je souhaite qu'un utilisateur puisse mettre à jour certaines lignes d'une table si son nom d'utilisateur correspond à une colonne d'une autre table. Dans l'exemple qui suit, je veux l'utilisateur nene, qui apparaît comme colonne u dans le tableau t0, pour pouvoir mettre à jour les colonnes a et p dans le tableau t2. Ce que je veux exprimer est d'appliquer une politique aux lignes dans t2 qui serait assortie par l'instruction de sélection suivante: 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';

Est-ce possible? Des suggestions sur la façon de procéder? Une solution de contournement évidente serait de dupliquer le nom d'utilisateur sur la table t2, mais cela ajoute des informations superflues sur t2 et nécessite des contraintes supplémentaires à appliquer.

Voici mes trois tables (dans la situation réelle il y a beaucoup plus de champs, et la table t1 ne peut pas être factorisée, je l'ai laissé dans l'exemple car deux jointures peuvent changer l'espace de solution).

  • Tableau t0 a été créé avec CREATE TABLE t0 (id TEXT PRIMARY KEY, u TEXT UNIQUE, pn TEXT); et contient maintenant:

    => SELECT * FROM t0; 
        id | u | pn 
    ------+------+------ 
    b321 | toto | fifi 
    a421 | nene | xuxu 
    (2 rows) 
    
  • Tableau t1 a été créé avec CREATE TABLE t1 (id TEXT PRIMARY KEY, t0id TEXT REFERENCES t0(id), pn TEXT); et contient maintenant:

    => SELECT * FROM t1; 
    id | t0id | pn 
    ------+------+------ 
    x99 | a421 | lala 
    zy49 | a421 | popo 
    l2l | b321 | nipa 
    (3 rows) 
    
  • Tableau t2 a été créé avec CREATE TABLE t2 (id TEXT, t1id TEXT REFERENCES t1(id), a INET, p INT); et contient maintenant

    => 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) 
    

Répondre

2

Essayez

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)) 
+0

Merci. Il a fallu ajouter les privilèges correspondants sur t0 et t1, mais c'était exactement le genre d'indice dont j'avais besoin pour comprendre comment cela fonctionne. – JayEye