ich habe hier eine nette Rails 1.2.6 Anwendung (nicht restful-designed)
in die
ich gerne ACLs einführen möchte.
Dabei würde ich diese Logik ungern im Controller unterbringen, da sich die
ACLs fachseitig zum einen auf die Objekte beziehen und zum anderen
verschiedene Controller die gleichen Operationen auf den Objekten ausführen
(da in n:m Beziehungen referenzierte Objekte mitbearbeitet werden können).
Die View gerade zu ziehen ist erstmal nicht das Problem…
Also:
-Von der Benutzerverwaltung her gesehen gibt es Benutzer und Gruppen.
Ein
Benutzer ist Mitglied in mehreren Gruppen.
Jedes Objekt besitzt genau einen Eigentümer-User.
Ein Benutzer kann das Recht haben eine Operation (save, destroy,
update_attributes, etc.) auf einem Objekt auszuführen, wenn
a) ihm das Objekt
gehörtb) er Mitglied einer bestimmten Gruppe ist.
Das Recht kann eingeschränkt werde, wenn:
a) Sich das Objekt in einem bestimmten Zustand befindet. (D.h. flag,
eine
Eigenschaft, etc. am Objekt gesetzt ist).
Nun muss ich diese ganzen ACLs irgendwie in Ruby-Code notieren. Dabei
sollen
sie einfach lesbar und wartbar sein (Was insb. viele und / oder
verschachtelte if-Anweisung ausschließt) und von ActiveRecord angewendet
werden.
Aus leidvoller Erfahrung empfehle ich, Rechte für einzelne Operationen
feinkörnig zu vergeben. Diese Rechte können natürlich in Rollen
zusammengefasst und Benutzer diesen Rollen zugeordnet werden.
Ich habe in einem Projekt das authorization-Plugin verwendet, mit dem
man quasi-deklarativ Sachen schreiben kann wie
permit?(“owner of :object”)
Sieht schön aus, nicht wahr? Führt aber (mich jedenfalls) dazu,
Entscheidungen über Rechte in den Code zu verlegen, wo sie nicht
hingehören: “Ach, der Benutzer ist Admin oder hat Rolle xyz – dann
darf er das.” Teufelszeug. Führt zu Wiederholungen und ist schlecht zu
warten. Im Anwendungscode sollte nur stehen “Darf Benutzer B Aktion A
ausführen?”. Die Zuordnung gehört an eine andere Stelle.
Es gibt ein oder mehrere ACL/RBAC-Plugins, mit denen Benutzer, Rollen
und Rechte einigermaßen komfortabel verwaltet werden können. Ich kenne
keine vorgefertigte Lösung, die mit “dynamischen Rollen” umgehen
können, etwa einer besonderen Beziehung des Benutzers zu einem Objekt
(“Besitzer”) oder Eigenschaften des Objekts. Das geht auch ohnehin
fließend in die allgemeine Geschäftslogik
über.
Was ich auch nicht in einer aktuellen Form kenne, ist ein Ansatz, der
Rechte implizit in Views anwendet, also so, dass etwa f.text_field
inaktiven Text oder gar nichts zeigt, wenn der Benutzer das Attribut
nicht ändern bzw. sehen darf. Es gab vor Jahren Model Security von
Bruce P., ich nehme aber an, das ist nicht mehr aktuell.