Jump to content
Sign in to follow this  
k00ni

Kleines Rechtesystem über eine ACL mit Hilfe von Gruppen

Recommended Posts

Hi,


ich hab bei meinem Fork ein kleines Rechtesystem implementiert, welches über Gruppen funktioniert. Da ich denke, dass das recht hilfreich sein kann und hier immer mal über soetwas philosophiert wurde, möchte ich dass mal kurz vorstellen.



Einstieg


Im pSys ist es möglich jeden User in verschiedene Gruppen zu stecken. Damit könnte man nun so weit gehen, dass man gewissen Gruppen gewisse "Rechte" gibt. Aber was genau ist nun ein Recht?


Ein Recht ist für mich entweder 1 oder ein bzw. mehrere Buchstaben aus CRUD . CRUD steht hier für Create, Read, Update und Delete. Die 1 bedeutet, dass man komplett alle Rechte hat. Dies macht z.B. bei Rechten ähnlich wie "system_access_during_maintenance" Sinn. (Man hat hier Zugriff während das System im Wartungsmodus ist, oder eben nicht). Hat man aber zum Beispiel die Rechte C, R. Dann kann man nur etwas erstellen (Create) und lesen (Read).



Ein Beispiel


Man hat eine Gruppe namens Redakteure und einen Users namens fancy. Dieser User ist in der Gruppe Redakteure. Nun gibt man dieser Gruppe das Recht "administrate_news_content" mit dem Wert "c,r,u". Damit können nun alle Mitglieder Newseinträge anlegen, lesen und ändern, aber nicht löschen. (ihnen fehlt dazu das d).



Die Umsetzung



Neue Tabellen


Man bräuchte neben der bestehenden Gruppentabelle 2 weitere:


+ rights (Speichert die Rechte)

+ groups_rights (Speichert die Verknüpfung zwischen einem Recht, einer Gruppe sowie den Wert (CRUD))


Strukturell:


+ rights: ( id, name )

+ groups_rights ( id, groupid, rightid, value )



Die Implementierung


Ich möchte hier nicht zu konkret werden, da das nur eine Skizze sein soll. Daher beschränke ich mich auf das Wesentlichste. Ich habe mir eine Funktion geschrieben welche folgendermaßen aussieht:

 

check_right ( $S_right , $S_value )

 

Sie bekommt das konkrete Recht und den zu erwartenden Wert übergeben und liefert true oder false zurück. Ein Beispiel-Aufruf könnte dann so aussehen:

 

check_right ( 'system_administrate_users', 'c,r,u' ) )
						{
							$Bo_authentificated = true;
						}

						break;	
}
?>

 

Man prüft, ob der aktuell zugreifende User das Recht (system_administrate_users) besitzt vorhandene User zu erstellen, anzuschauen und zu ändern. Hat er es, so wird Bo_authentificated auf true gesetzt, was man später noch gebrauchen könnte.


Wie man sieht greife ich über eine Instanz namens In_user auf den aktuellen User zu. Das liegt hier daran, dass ich eine Klasse user geschrieben habe, welche mir verschiedene Dinge bereitstellt.





So, soweit die Skizze. Was haltet ihr davon?

Share this post


Link to post
Share on other sites

Ich würd eine Tabelle für die Rechte machen und fertig :-D

=>


id | bereich | gruppe | rechte


und auch nicht nach Filenamen gehen ...

eher nach Modulen/Bereiche ...


if ( true == ...

na wenn schon dann === oder einfach gleich weglassen :-D

oder aber gleich den Wert den dir $In_user->check_right() retour gibt in die Variable werfen ;-)

Zumal du das alles sicher überhaupt gleich in $In_user->check_right() abfahren könntest ^^


Ich hab @work sowas ähnliches nur auf Accounts und nicht auf Gruppen

da hab ich in einer Tabelle => account | section | right

und fang alles per $User->right(); ab :-)

Die Section ist bei mir immer in einer Konstanten, Account kommt per NTLM

Share this post


Link to post
Share on other sites
id | bereich | gruppe | rechte


und auch nicht nach Filenamen gehen ...

eher nach Modulen/Bereiche ...



Und wie stellst du dir das mit den Teilbereichen im Modul geschweige denn in einem Bereich vor? (Ich nehme an du meinst die Bereiche vom pSys, die area's). Stelle mir das gerade etwas grob vor, da ein Bereich ja verschiedene Seitenbereiche umfassen kann.

Bei einem Modul hast du dann aber auch wieder das Problem, dass du das hier und da einzeln prüfen musst.


An sich reden wir doch vom Gleiche, oder? Nur das ich das hier für Gruppen beschreibe und du stattdessen User nimmst.


oder aber gleich den Wert den dir $In_user->check_right() retour gibt in die Variable werfen [Zwinkern]

Zumal du das alles sicher überhaupt gleich in $In_user->check_right() abfahren könntest ^^



Die Funktion gibt mir nur true oder false zurück und anhand daran entscheide ich, ob ich eine/weitere Funktion/en ausführe oder nicht. Das Beispiel hier oben ist für das Backend gedacht. Man hat eine zentrale Stelle wo die Rechte aller admin-Dateien geprüft werden. Und wenn diese Variable Bo_authentificated nicht auf true steht, blockt er einfach den User.


Man kanns ja aber auch so nutzen:

 

if ( true == $In_user->check_right ( ..., 'c' ) )
{
     // Lasse Erstellen zu
}
else
{
    // Gib eine Erstellen-Verboten-Fehlermeldung aus. 
}

 

Anbei, da ich eh nur true oder false bekomme ist es unerheblich ob ich == oder === nutze.



Grüße

Share this post


Link to post
Share on other sites

Naja, ich hab die Rechte nach einer Hierachie und nicht nach Create, Update, usw. ;-)

und da kann ich von 0-999 gehn, wobei 999 nur ich hab :-D

Die erstrecken sich übers ganze System, hinuntergebrochen auf die Bereiche/Module und im Modul wenn notwendig noch weiter, wobei zB 500 in dem einen Modul nicht gleichzusetzen mit 500 im anderen ist.


Ich kann dir nur eine alte Version (glaub Frühjahr/Sommer 2008) von der Funktion zeigen, die bricht aber noch nicht ab.

Bei der die abbricht wird einfach kein false zurück gegeben sondern aus Datenschutzgründen nur gelogt und weitergeleitet, abgesehn davon gibts noch ein paar andere Features mehr ... ;-)

user_rights[$sectionid]) && $this->user_rights[1] != 999) {
           $query = "SELECT `permission` FROM `{$mysql->table('rights')}`
                     WHERE `account`='{$this->usercache['account']}'
                     AND (`section`='$sectionid' OR `section`='1') ORDER BY `section` DESC;";
           $right = $mysql->fetch($query);
           if ($right['permission'] === null) {
               $this->user_rights[$sectionid] = 0;
           } else {
               $this->user_rights[$sectionid] = $right['permission'];
           }
           $perm = $this->user_rights[$sectionid];
       } elseif ($this->user_rights[1] == 999) {
           $perm = 999;
       } else {
           $perm = $this->user_rights[$sectionid];
       }

       if ($minlevel === false || $perm >= $minlevel) {
           return $perm;
       } else {
           return false;
       }
   }
?>

Share this post


Link to post
Share on other sites

Hi,


soweit ich das sehe, unterscheidest du zwischen verschiedenen Sections? Damit kann ich dann wahrscheinlich auf verschiedene Kategorien z.b. der Galerie auch verschiedene Rechte geben, oder?


Das fehlt bei mir oben nämlich noch. Deshalb hab ich noch die Spalte section hinzugefügt, welche z.b. eine Kategorie ID speichert. Oder "all", was für beliebig steht.


Gibts bei dir eigentlich eine Unterteilung in User, Admin oder Gäste? Ich versuche gerade das insgesamt so umzustellen, dass man nur noch Benutzer hat aber diese in verschiedene Gruppen eintragen kann. Über die einzelnen Rechte kann man dann entscheiden, was sie dürfen.



Grüße

Share this post


Link to post
Share on other sites

Gäste => 0

User => 1 (nur gucken und da nur eigene Sachen)

Admin => 950 (für eine Sektion, kann aber keinen User zum Admin machen!)

BOFH => 999 (nur ICH ICH ICH!!! :-D)


Dazwischen gibt es je nach Modul die unterschiedlichsten Rechte.

Das musste ich so machen da die Anforderungen immer andere sind.


Brauche ich in einzelnen Bereichen eines Moduls auch noch unterschiedliche Rechte so regelt sich das jedes Modul eigentlich selbst (aufgrund der Anforderungen).

Diese Rechte stehen dann auch in einer eigenen Tabelle, wobei der User aber auch ein Recht in der "Haupttabelle" eingetragen braucht, sonst kommt er erst garnicht hin :-)


Ich habe aber eine ähnliche Funktion wie die die ich gepostet habe die mir das Recht des Users für diesen Unterbereich ausliest ;-)

Share this post


Link to post
Share on other sites
Guest
You are commenting as a guest. If you have an account, please sign in.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×