Angenommen, die folgende Datenbankstruktur (kann bei Bedarf geändert werden) ...
Ich suche nach einer guten Möglichkeit, die "effektiven Berechtigungen" für einen bestimmten Benutzer auf einer bestimmten Seite so zu ermitteln, dass ich eine Zeile mit der Seite und den effektiven Berechtigungen zurückgeben kann.
Ich denke, dass die ideale Lösung eine Funktion enthalten kann, die einen CTE verwendet, um die Rekursion durchzuführen, die erforderlich ist, um die "effektiven Berechtigungen" für eine bestimmte Seitenzeile für den aktuellen Benutzer zu bewerten.
Hintergrund und Implementierungsdetails
Das obige Schema stellt einen Startpunkt für ein Content-Management-System dar, in dem Benutzern Berechtigungen erteilt werden können, indem sie Rollen hinzugefügt und daraus entfernt werden.
Ressourcen im System (z. B. Seiten) sind Rollen zugeordnet, um der mit dieser Rolle verknüpften Benutzergruppe die von ihr gewährten Berechtigungen zu erteilen.
Die Idee ist, einen Benutzer einfach sperren zu können, indem einfach alle Rollen verweigert werden und die Stammebene im Baum zu dieser Rolle hinzugefügt wird und der Benutzer dann zu dieser Rolle hinzugefügt wird.
Dies würde es ermöglichen, dass die Berechtigungsstruktur erhalten bleibt, wenn (zum Beispiel) ein Auftragnehmer, der für das Unternehmen arbeitet, für längere Zeit nicht verfügbar ist. Dies ermöglicht dann auch die gleiche Erteilung seiner ursprünglichen Berechtigungen, indem der Benutzer einfach aus dieser einen Rolle entfernt wird .
Berechtigungen basieren auf typischen ACL-Regeln, die möglicherweise für das Dateisystem gelten, indem diese Regeln befolgt werden.
Die CRUD-Berechtigungen müssen nullfähige Bits sein, damit die verfügbaren Werte wahr, falsch und nicht definiert sind, wenn Folgendes wahr ist:
- falsch + irgendetwas = falsch
- wahr + nicht definiert = wahr
- wahr + wahr = wahr
- nicht definiert + nicht definiert = nicht definiert
Wenn eine der Berechtigungen falsch ist -> falsch Sonst, wenn einer wahr ist -> wahr Sonst (alle nicht definiert) -> false
Mit anderen Worten, Sie erhalten keine Berechtigungen für irgendetwas, es sei denn, Sie erhalten sie durch Rollenmitgliedschaft und eine Verweigerungsregel überschreibt eine Zulassungsregel.
Der "Satz" von Berechtigungen, für den dies gilt, sind alle Berechtigungen, die auf den Baum bis einschließlich der aktuellen Seite angewendet werden, mit anderen Worten: Wenn ein Falsch in einer Rolle auf eine Seite im Baum dieser Seite angewendet wird, ist das Ergebnis falsch Wenn jedoch der gesamte Baum bis hierher nicht definiert ist, enthält die aktuelle Seite eine wahre Regel. Das Ergebnis ist hier wahr, für das übergeordnete Element jedoch falsch.
Ich möchte die Datenbankstruktur möglichst locker beibehalten und auch bedenken, dass mein Ziel hier darin besteht, in der Lage zu sein, Folgendes zu tun: select * from pages where effective permissions (read = true) and user = ?
Jede Lösung sollte es mir ermöglichen, einen abfragbaren Satz mit den darin enthaltenen effektiven Berechtigungen zu haben auf irgendeine Weise (die Rückgabe ist optional, solange die Kriterien angegeben werden können).
Angenommen, es gibt 2 Seiten, auf denen 1 ein untergeordnetes Element der anderen ist und 2 Rollen vorhanden sind, eine für Administratorbenutzer und eine für schreibgeschützte Benutzer. Beide sind nur mit der Seite auf Stammebene verknüpft, von der ich erwarten würde, dass so etwas als erwartete Ausgabe angezeigt wird:
Admin user:
Id, Parent, Name, Create, Read, Update, Delete
1, null, Root, True , True, True , True
2, 1, Child,True , True, True , True
Read only user:
Id, Parent, Name, Create, Read, Update, Delete
1, null, Root, False , True, False , False
2, 1, Child,False , True, False , False
Weitere Diskussionen zu dieser Frage finden Sie ab hier im Chatroom der Hauptseite .