per prima cosa complimenti per la comunità che avete creato, è da poco che sto imparando Yii e lo trovo davvero stimolante anche grazie a voi e alle vostre risposte.
Ho una questione pratica relativa alla gestione dei ruoli per la quale ho bisogno di confrontarmi per capire il migliore approccio con Yii. Ho l’entità “Pratica” gestita dai seguenti attori:
cliente, vede solo la sua pratica
installatore, che gestisce più pratiche
commerciale, gestisce tutte le pratiche
supervisore, vede solo le pratiche dei sui installatori
La prima questione: nella index voglio far vedere solo le pratiche che assecondano le regole descritte in precedenza. Penso che utilizzare uno scope che differenzia il filtro a seconda del ruolo sia la soluzione giusta o sbaglio? Meglio ancora forse il defaultScope che verrebbe comodo per le altre viste.
Seconda questione: cliente, installatore e commerciale possono modificare diversi dati relativi alla stessa pratica.
Un approccio potrebbe essere utilizzare diversi scenari a seconda del ruolo per obbligare l’utente ad inserire determinati dati e differenziare la vista a seconda del ruolo per visualizzare solo i dati dello scenario.
Un altro approccio, ma che vedo più difficile da mantenere ed escluderei, consiste nel separare i dati della pratica in 3 diversi modelli tutti collegati alla pratica Pratica, e ciascuno di questi modificabile solo da un ruolo.
La soluzione più yii-style è di implementare l’autorizzazione utente basata su ruoli. [RBAC]. Ne sei completamente a digiuno?
Altrimenti, nel ‘loadModel’ potresti verificare, tramite la relation con ‘installatore_user_id’, ‘commerciale_user_id’, etc… se quella pratica gli può essere mostrata o meno.
In quel modo anche se l’utente cambia l’id a mano nell’url non lo freghi.
Per esempio:
ho la tabella utenti, e una pratiche
pratiche.cliente_id -> utenti.id [che è l’id utente del cliente]
pratiche.installatore_id -> utenti.id [che è l’id utente dell’installatore]
nel metodo ‘view’ userai di certo ‘loadModel’.
Modifichi questo in modo che…
if ($model->installatore_id != Yii::app()->user->id and
$model->cliente_id != Yii::app()->user->id) {
throw new CHttpException(501, "non sei autorizzato ...bla bla bla");
}
Ho installato yii-user e rights (da quanto capito la soluzione più solida per implementare RBAC).
Tramite rights posso definire se l’utente corrente è abilitato a compiere una certa azione ad esempio Pratica.update.
Ma per capire se l’utente è abilitato a modificare quel determinato oggetto devo farlo quando carico l’oggetto con loadModel, come giustamente mi hai indicato.
A questo punto questo check lo posso mettere come hai suggerito te in PraticaController e poi successivamente devo riusare la stessa condizione nella query per mostrare le Pratiche che può vedere.
In alternativa ribaltando il discorso potrei mettere il controllo nel model
public function defaultScope()
{
$roles=Rights::getAssignedRoles(Yii::app()->user->Id); // check for single role
foreach($roles as $role)
if($role->name == 'installatore')
{
return array(
'installatore_id' => Yii::app()->user->Id,
);
}
.........
}
In questo modo se l’installatore cambia l’id nella url per l’editing, la loadModel non dovrebbe caricare nessuna pratica. Nello stesso modo se nell’index cerco di caricare tutti i record verrebbero visualizzati solo quelli per cui ha diritto.
Ora non so se è una buona pratica spostare questa logia nel model anche se risulta comoda per motivi di sicurezza in quanto controllo sempre i diritti dell’utente per una determinata pratica.