Newsgroup: it.comp.www.php
Titolo: [Farsi del male] RBAC basata su ruoli ma con eccezzioni

Dovrei implementare un semplice rbac, cioè ogni ruolo ha un flag true/
false su ogni permesso all'interno dell'applicazione, tipo:
 
$ruolo_a = array(
    'edit own posts' => true,
    'edit all posts' => true,
    'create users' => false
);
$ruolo_b = array(
    'edit own posts' => true,
    'edit all posts' => false
    'create users' => false
);
 
Ogni utente può avere più ruoli, che vengono poi uniti tramite 'and',
se nell'esempio precedente un utente ha sia il ruolo a che b, i suoi
permessi finali sono:
 
array(
    'edit own posts' => true,
    'edit all posts' => true,
    'create users' => false
)
 
 
Fin qui tutto ok, per giocare d'anticipo sul cliente con una funzione
che (conoscendolo bene) mi chiederà di sicuro, ovvero il famoso "si ma
no" o più tecnicamente definito "assolutamente sempre _tranne se_...",
volevo vedere come strutturare il tutto per poter aggiungere delle
regole del tipo:
 
ruolo_a può modificare tutti i posts CHE hanno come categoria X
ruolo_b può modificare tutti i propri post CHE non hanno il valore Y
nel campo Z.
 
La struttura ad array non và più bene, almeno di non stravolgerla
così:
$ruolo_a = array(
    'edit own posts' => array('allowed' => true, 'rules' => [...]),
    'edit all posts' => array('allowed' => true, 'rules' => [...]),
    'create users' => array('allowed' => false),
);
$ruolo_b = array(
    'edit own posts' => array('allowed' => true, 'rules' => [...]),
    'edit all posts' => array('allowed' => false),
    'create users' => array('allowed' => false),
);
 
non sono immaginare google groups come formetterà questa roba.
 
 
Comunque, anche mantenendo questa struttura il mio problema nasce dal
come gestire le 'rules' (dimenticavo, i campi dei posts sono
dinamici.. non fissi), se da un lato mi piacerebbe inserire
direttamente l'sql (che poi sotto prepared necesiterebbe anche di un
callback per recuperare i valori dei placeholders), dall'altro mi
piacerebbe trovare una formula che sia _interpretabile_ facilmente da
codice, tant'è che se un domani cambio (ad esempio) database da db sql
a non-sql devo solo cambiare l'interprete e non riscrivere tutte le
regole dei permessi.
 
Idee/Suggerimenti?

nel campo Z.
 
Il modo piu' crudele e' di usare, al posto di true/false, degli array di
regole:
 
array(
	'edit posts' => array(
			'i tuoi post' => '$post[\'author\']==$SELF',
	);
 
oppure "($post['author']==$SELF)&&($post['category']!='power')"
 
...e poi andare di eval. Tanto, le regole le inserisci tu, mica lui, per
cui il rischio di code injection non c'e'.
 
O anche fare puntare le regole a delle callback.
 
Definito un "ambiente" in cui vivono quelle regole, il resto segue.
 
Certo, non ci puoi fare una SELECT del tipo "dammi tutti i post che sono
in grado di modificare" (dovresti fare una SELECT ALL e poi nascondere i
post che falliscono il test).
 
Leonardo
 
-- 
Tell us whether you spy, in the light of the morn,
what saluted was fiercely at the fall of the past day:
whose pips and whose bands in the very heart of the fray
bravely floated from the bulwarks to which we were sworn?


OMG eval no!
Ok che la tabella con tutti i checkbox dei permessi li creo io, ma non
posso basarmi su dei campi fissi.. mi spiego, oggi i post hanno il
campo utente 'autore', quindi normalmente il proprietario del post è
colui che è impostato nel campo 'autore'.
 
Domani mi aggiungono ai post il campo 'follower', e vogliono impostare
le regole in modo che gli utenti che sono messi nel campo "follower"
possano anche essi modificare il post (esempio del menga)
 
La mia idea era di impostare il valore della regola in modo
'interpretabile', tramite placeolder, una roba del tipo:
 
regola 1: "[posts].[author] == [current_user_id]"
OR
regola 2: "[posts].[follower] == [current_user_id]"
 
Ovviamente quell'OR deve poter diventare anche un AND, NOR e NAND
quando il cliente ne ha bisogno (ma questo è un'altro discorso e ma la
spoccio io), e io nel database mi salvo solo la stringa  "[posts].
[follower] == [current_user_id]", dove avrò una lista di possibili
placeholder da utilizzare... e nulla mi vieta di mettere poi in cache
la query generata, qualora il calcolo di queste robe diventa
problematico.
 
Altro problema che sorge è che usando queste 'regole' posso usare le
rappresentazioni binarie solo per il primo livello (visualizza post si/
no), ma perdono significato al giungere delle regole (danno comunque
una bella sgrossata).