CakePHP-Zugriffszuweisung für rollenbasierten spezifischen Datenzugriff
-
28-10-2019 - |
Frage
Meine Projektanforderung lautet ungefähr so:
Oben wird es einen Administrator geben, der auf der ersten Ebene Zugriff hat.
Unter Administrator gibt es Abteilungsleiter, die außer dem Erstellen von Abteilungsleitern Zugriff haben
Unter Abteilungsleiter befinden sich andere Mitglieder, die ihre zugewiesenen abteilungsweisen Daten verwalten.
Jetzt haben alle verschiedenen Abteilungsleiter ihre eigenen Informationen und Mitglieder, und alle Abteilungsleiter / Mitglieder haben Zugriff auf ihre eigenen spezifischen Datensätze, die sie eingeben / verwalten.
Mit der ACL-Komponente von CakePHP kann ich jetzt die Rollen und ihre Zugriffsebene aufteilen, aber alle Abteilungsleiter können die Informationen des anderen Abteilungsleiters sehen, da sie dieselbe Zugriffsebene haben, und alle anderen Mitglieder können die anderen Mitglieder sehen Informationen zu verschiedenen Abteilungen, ab denen sie denselben Zugriff haben.
Meine Projektkomplexität besteht darin, dass - sie nur ihre zugewiesenen oder erstellten Informationen / Daten sichtbar sein sollten, obwohl sie dieselben Ebenen- / Rollenzuweisungen wie andere haben.
Kann mir jemand die am besten geeignete Option vorschlagen, um all diese Dinge mit bereits verfügbaren Plug-Ins mit CakePHP zu verwalten.
Ich kann arbeiten, indem ich die Standard-ACL-Komponente anpasse, aber das dauert etwas länger als erwartet.
Bessere Ideen / Vorschläge wären willkommen!
Lösung
So wie ich das sehe, ist ACL nicht so magisch. Zum Beispiel: ACL könnte die Berechtigungen verwalten, um festzustellen, wer Zugriff zum Hinzufügen / Bearbeiten / Entfernen eines Produkts hat. Es kann jedoch keine Abfrage ändern, um die Produkte entsprechend den definierten Berechtigungen zu filtern (wie "Benutzer aus Abteilung A können dies nur" Siehe Produkte aus Abteilung A "). Nun, eigentlich ist das eine Lüge. ACL könnte das schaffen, aber es ist möglicherweise nicht praktikabel, da Sie jedes Mal, wenn Sie ein Produkt hinzufügen, einen ACO erstellen und die Berechtigung in der Tabelle AROS_ACOS festlegen müssen und da das AROS eine Baumstruktur ist, kann es leicht zu einem Nigthmare werden, wenn Sie vorhaben, Ihre Daten abzufragen
Ich würde eine Nur-Gruppen-ACL um den Zugriff auf bestimmte Seiten / Aktionen zu steuern und Regeln festzulegen wie:
- "Der Abteilungsleiter kann auf die Seite zugreifen 'Produktliste' und hinzufügen / löschen / ändern Produkte "
- "Administratoren können darauf zugreifen alle Seiten "
- "Andere Benutzer können darauf zugreifen
'Produktliste' und sie können hinzufügen
Produkte, aber nicht löschen "
und ich würde meine Abfragen entsprechend dem verbundenen Benutzer anpassen, also würde ich auf der Seite "Controller der Produktliste" Folgendes tun:
- Wenn der verbundene Benutzer zum Abteilungsleiter gehört, wählen Sie alle Produkte aus, bei denen
product.department_id=connected_user.department_id
- Wenn der verbundene Benutzer Administrator ist, wählen Sie alle Produkte aus.
Wenn Sie zu viele Abfragen haben und nicht Tausende von if-Sätzen ausführen möchten, können Sie eine Komponente, ein Verhalten oder möglicherweise Erweitern Sie die
find()
-Methode imapp_model
. Die Idee ist, alle Abfragen abzufangen und zu überprüfen, ob eines der in der Abfrage verwendeten Modelle das Feld "department_id" hat. Wenn dies der Fall ist, fügen Sie der Abfrage diemodel.department_id=connected_user.department_id
-Bedingung hinzu.Ich habe das für eine Website gemacht, die in mehreren Sprachen angezeigt wird und jede Sprache hat ihre eigenen Benutzer, Daten, Protokolle usw., und es gibt einen Administrator, der alle Informationen sehen kann. Und es funktioniert hervorragend für mich= )
Viel Glück!
BEARBEITET: Das Verhalten, das ich benutze, ist:
<?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; } } ?>
Es ist wirklich ganz einfach. Ich ändere die Abfrage, um eine Bedingung hinzuzufügen, die der aktuellen Sprache entspricht ($ _SESSION ['lang']). Im Controller muss ich nur das LocalizableBehavior anhängen und die find-Methode wie gewohnt verwenden:
$this->Products->find('all');
- Wenn der verbundene Benutzer zum Abteilungsleiter gehört, wählen Sie alle Produkte aus, bei denen