Allocazione di accesso CakePHP su accesso ai dati specifico basato sul ruolo
-
28-10-2019 - |
Domanda
Il requisito del mio progetto è qualcosa del genere:
In alto, ci sarà l'Amministratore, che avrà tutti gli accessi d, di primo livello
Sotto Amministratore, ci saranno capi dipartimento, che avranno tutti i d accesso, a parte la creazione di capi dipartimento
Sotto il capo del dipartimento, ci saranno altri membri, che gestiranno i dati di dipartimento assegnati.
Ora, tutti i diversi capi dipartimento avranno le proprie informazioni e membri e tutti i capi dipartimento / membri avranno accesso ai propri record specifici, che stanno inserendo / gestendo.
Ora, con il componente ACL di CakePHP, posso dividere i ruoli e il loro livello di accesso, ma tutti i capi dipartimento possono vedere le informazioni dell'altro capo dipartimento, poiché avranno lo stesso livello di accesso e tutti gli altri membri possono vedere gli altri membri informazioni sui dipartimenti diff, dal momento che avranno lo stesso livello di accesso.
La complessità del mio progetto è che: dovrebbero essere visibili solo le informazioni / dati assegnati o creati, sebbene abbiano le stesse assegnazioni di ruolo / livello degli altri.
Qualcuno può suggerirmi l'opzione più adatta, per gestire tutte queste cose con plug-in già disponibili con CakePHP.
Posso lavorare personalizzando il componente ACL predefinito, ma ci vorrà un po 'più di tempo rispetto a quanto previsto.
Eventuali idee / suggerimenti migliori sarebbero apprezzati!
Soluzione
per come la vedo io, ACL non è così magico. Ad esempio: ACL potrebbe gestire le autorizzazioni per dire a chi ha accesso per aggiungere / modificare / rimuovere un prodotto .. ma non sarà in grado di modificare una query per filtrare i prodotti in base alle autorizzazioni definite (come "gli utenti del reparto A possono solo vedi prodotti dal reparto A ") .. beh, in realtà è una bugia, ACL potrebbe gestirlo ma potrebbe non essere pratico, perché ogni volta che aggiungi un prodotto dovresti creare un'ACO e impostare l'autorizzazione nella tabella AROS_ACOS e poiché AROS è una struttura ad albero, quindi potrebbe facilmente diventare un incubo, se hai intenzione di interrogare i tuoi dati
Userei un ACL di solo gruppo per controllare l'accesso a determinate pagine / azioni e creare regole come:
- "Il capo dipartimento può accedere alla pagina 'elenco prodotti' e aggiungi / elimina / modifica prodotti "
- "Gli amministratori possono accedere tutte le pagine "
- "Altri utenti possono accedere 'elenco prodotti' e possono aggiungere prodotti ma non eliminarli "
e adattare le mie query in base all'utente connesso, quindi nel controller della pagina "elenco prodotti", farei qualcosa come:
- Se l'utente connesso effettua la connessione al responsabile del dipartimento, seleziona tutti i prodotti in cui
product.department_id=connected_user.department_id
- Se l'utente connesso è un amministratore, seleziona tutti i prodotti
se hai troppe domande e non vuoi fare migliaia di frasi if, potresti creare un componente, un comportamento o forse estendi il metodo find()
nel app_model
. L'idea è di catturare tutte le query e controllare se uno dei modelli utilizzati nella query ha un campo chiamato "department_id", in caso affermativo aggiungere la condizione model.department_id=connected_user.department_id
alla query.
L'ho fatto per un sito web che può essere visto in più lingue e ogni lingua ha i propri utenti, dati, log e così via, e c'è un amministratore che può vedere tutte le informazioni .. e funziona benissimo per me= )
Buona fortuna!
MODIFICATO: il comportamento che uso è:
<?php
class LocalizableBehavior extends ModelBehavior {
/**
* Filter query conditions with the correct `type' field condition.
*/
function beforeFind(&$model, $query)
{
/**
* Condition for the paginators that uses joins
*/
if(isset($query['joins']) && !empty($query['joins'])){
foreach($query['joins'] as $key => $joinTable){
if(ClassRegistry::init($joinTable['alias'])->hasField('lang')){
$query['joins'][$key]['conditions'][] = $joinTable['alias'].".lang = '".$_SESSION['lang']."'";
}
}
}
/**
* condition for the normal find queries
*/
if($model->hasField('lang') && $model->name != "User"){
$query['conditions'][$model->name.'.lang'] = $_SESSION['lang'];
}
return $query;
}
}
?>
in realtà è abbastanza semplice, cambio la query per aggiungere una condizione da abbinare alla lingua corrente ($ _SESSION ['lang']). Nel controller tutto ciò che devo fare è collegare LocalizableBehavior e utilizzare il metodo find come al solito:
$this->Products->find('all');