Hinweis: Sie sind auf den Seiten der Moodle 1.9 Dokumentation. Die Dokumentation der aktuellsten Moodle-Version finden Sie hier: Wie Rechte berechnet werden.

Wie Rechte berechnet werden

Aus MoodleDocs
Wechseln zu:Navigation, Suche

Eine der am häufigsten gestellten Fragen lautet: "Was sind meine Rechte in diesem Kontext?" In diesem Artikel wird die Funktion beschrieben, die Moodle verwendet, um diese Frage zu beantworten. Der Artikel ist sowohl für Nicht-Programmierer als auch Programmierer geschrieben, denn er beschreibt, was diese Funktion tut, nicht wie sie es tut. Das Wie ist kompliziert, das Was dagegen ist relativ einfach zu verstehen. Wenn Sie Programmierer sind und den entsprechenden Code lesen möchten, suchen Sie die Funktion has_capability() im PHP-Skript lib/accesslib.php.

Zu einem gegebenen Nutzer, einer gegebenen Fähigkeit und einem gegebenen Kontext liefert die Funktion has_capability() ein true (wahr), wenn der Nutzer im gegebenen Kontext das Recht hat, die Aktion, die durch die gegebene Fähigkeit gesteuert wird, durchzuführen, und andernfalls liefert sie false (falsch). Bei der Berechnung des Ergebnisses berücksichtigt die Funktion alle relevanten Rechte-Daten, inklusive Rollendefinitionen, Rollenzuweisungen und Rollenänderungen.

Moodle berechnet nie den "Gesamtsatz" aller Rechte eines Nutzers. Das wäre sehr teuer, zeitaufwändig und unnütz, weil die meisten Rechte in einer gegebenen Situation nicht relevant sind. Stattdessen berechnet Moodle Rechte nur dann, wenn es nötig ist. Diese Rechte werden auch nicht gespeichert, sondern bei Bedarf jedes Mal neu berechnet. Daher gibt es auch keine "Verzögerungseffekte" mehr (etwa wenn Sie Rollen ändern), wie das in Moodle 1.7, 1.8 der Fall ist.

Übrigens können Sie mit Hilfe des PHP-Skripts rolesdebug.php Rechte-Tabellen, wie sie in diesem Artikel weiter unten vorkommen, generieren.

Der Berechnungsalgorithmus

Wenn ein Nutzer versucht, eine Aktion auszuführen, die durch eine Fähigkeit kontrolliert wird, ruft Moodle die Funktion has_capability() auf, um zu prüfen, ob der Nutzer das Recht dazu hat. Der Funktionsaufruf lautet:

 has_capability(CAP,CONTEXT,USER);

wobei

  • CAP die Fähigkeit ist, die die Aktion steuert (z.B. mod/quiz:attempt),
  • CONTEXT der Kontext ist, in dem die Fähigkeit geprüft wird, und
  • USER der Nutzer ist, der versucht, die Aktion auszuführen.

Die Funktion liefert als Ergebnis ein true (wahr) oder false (falsch):

  • true bedeutet, dass der Nutzer die Aktion ausführen darf,
  • false bedeutet, dass der Nutzer die Aktion nicht ausführen darf.

Daten, die die Funktion verwendet

Nehmen wir an, ein Nutzer USER versucht, einen Test durchzuführen, d.h. CAP = mod/quiz:attempt, und zwar in einem Modul-Kontext, der über vier Ebenen im System-Kontext verschachtelt ist:

     System
        |
    Kursbereich A
        |					      
   Unterkursbereich B
        |
      Kurs
        |
      Test <--- der Nutzer ist hier

Das Test-Modul ruft die Funktion has_capability(), um zu prüfen, ob der Nutzer den Testversuch durchführen darf.

Die Funktion has_capability() prüft nun folgende Rechte-Daten:

Die Funktion has_capability() ignoriert alle anderen Fähigkeiten und prüft nur die Fähigkeit CAP. Aufgrund dieser Vereinfachung können wir jede Rollenzuweisung oder -änderung als mit einem "einfachen Recht" belegt betrachten, wobei dieses Recht einen der folgenden Werte annehmen kann:

   N - Not set (nicht gesetzt)
   A - Allow (erlaubt)
   P - Prevent (unterbunden)
   X - Prohibit (untersagt)

Im weiteren nutzen wir die folgende Notation: Für eine Rolle R1 mit einem Recht P schreiben wir R1(P).

Beispiel

Nehmen wir im obigen Beispiel mit dem Testversuch durchführen an, der Nutzer hat vier Rollen, die wie folgt in den verschiedenen Kontexten zugewiesen oder geändert sind:

   0     System           <---- Rollendefinitionen: R1(A), R2(N), R3(N), R4(P)
           |                    Rollenzuweisungen: R1
           |
   1   Kursbereich A      <---- Rollenänderungen:  R1(N) und R4(N)
           |                          
           |                          
   2  Unterkursbereich B  <---- Rollenzuweisungen: R2 und R3
           |
           |
   3     Kurs             <---- Rollenänderungen: R2(X) und R3(A)
           |
           |
   4     Test             <---- Rollenzuweisungen: R4 und R1

Beachten Sie, dass die Rolle R1 in zwei verschiedenen Kontexten (System und Test) zugewiesen wurde. Das entspricht eigentlich nicht der gängigen Praxis (und wurde vermutlich von jemandem falsch gemacht). Da es aber in Moodle trotzdem, erlaubt ist, müssen wir es als Möglichkeit mit in Betracht ziehen. Tatsächlich wurde dieses Beispiel extra gewählt, um den Algorithmus auch für Grenzfälle zu testen. In der Praxis ist die Berechnung von Rechten trivial, und der Algorithmus berechnet das Ergebnis so, wie es der gesunde Menschenverstand erwartet und einfache logische Analyse ergibt (siehe auch den Abschnitt Anmerkung zum Algorithmus weiter unten).

Darstellung der Daten in Tabellenform

Wir werden die Rechte-Daten in Tabellenform darstellen. Die Tabelle hat

  • eine Spalte für jeden Kontext, beginnend mit dem obersten Kontext (System-Kontext) und endend mit dem untersten Kontext (dort, wo das Recht letztendlich berechnet werden soll) und
  • eine Zeile für jeden Kontext, wieder beginnend mit dem obersten und endend mit dem untersten.

Die leere Tabelle sieht wie folgt aus:

                System     Kursbereich A     Kursbereich B     Kurs     Test
               +--------+-----------------+-----------------+--------+---------
               |        |                 |                 |        |    
 System        |        |                 |                 |        | 
               |        |                 |                 |        |
 Kursbereich A |        |                 |                 |        |
               |        |                 |                 |        | 
 Kursbereich B |        |                 |                 |        | 
               |        |                 |                 |        | 
 Kurs          |        |                 |                 |        |
               |        |                 |                 |        | 
 Test          |        |                 |                 |        |
               |        |                 |                 |        |

Die Rollendefinitionen kommen in die erste Zeile. Jede Definition kommt in die Spalte, die zu dem Kontext gehört, in dem die Rollen zugewiesen wurde.

Die Tabelle mit eingetragenen Rollenzuweisungen sieht dann so aus:

                System     Kursbereich A     Kursbereich B     Kurs     Test
               +--------+-----------------+-----------------+--------+-------------
               |        |                 |                 |        |    
 System        | R1(A)  |                 |  R2(N)  R3(N)   |        | R1(A)  R4(P)
               |        |                 |                 |        |
 Kursbereich A |        |                 |                 |        |
               |        |                 |                 |        | 
 Kursbereich B |        |                 |                 |        | 
               |        |                 |                 |        | 
 Kurs          |        |                 |                 |        |
               |        |                 |                 |        | 
 Test          |        |                 |                 |        |
               |        |                 |                 |        |

Die Rollenänderungen werden in den verbleibenden Zeilen eingetragen. Jede Rollenänderung kommt

  • in dieselbe Spalte, wie die Rolle, die geändert wird,
  • in die Zeile, die zu dem Kontext gehört, in dem die Rolle geändert wurde.

Zur Verdeutlichung lassen Sie uns die Rollenänderung R2(X) im Kurs-Kontext eintragen:

                System     Kursbereich A     Kursbereich B     Kurs     Test
               +--------+-----------------+-----------------+--------+-------------
               |        |                 |                 |        |    
 System        | R1(A)  |                 |  R2(N)  R3(N)   |        | R1(A)  R4(P)
               |        |                 |                 |        |
 Kursbereich A |        |                 |                 |        |
               |        |                 |                 |        | 
 Kursbereich B |        |                 |                 |        | 
               |        |                 |                 |        | 
 Kurs          |        |                 |  R2(X)          |        |
               |        |                 |                 |        | 
 Test          |        |                 |                 |        |
               |        |                 |                 |        |


R2(X) steht für die Rollenänderung von Rolle R2 im Kurs-Kontext. Wenn alle weiteren Rollenänderungen eingetragen sind, ergibt sich folgende Tabelle:

                System     Kursbereich A     Kursbereich B     Kurs     Test
               +--------+-----------------+-----------------+--------+-------------
               |        |                 |                 |        |    
 System        | R1(A)  |                 |  R2(N)  R3(N)   |        | R1(A)  R4(P)
               |        |                 |                 |        |
 Kursbereich A | R1(N)  |                 |                 |        | R1(N)  R4(N)
               |        |                 |                 |        | 
 Kursbereich B |        |                 |                 |        | 
               |        |                 |                 |        | 
 Kurs          |        |                 |  R2(X)  R3(A)   |        |
               |        |                 |                 |        | 
 Test          |        |                 |                 |        |
               |        |                 |                 |        |

Jetzt ist die Tabelle vollständig, und wir können mit Hilfe des Algorithmus das Recht berechnen.

Der Algorithmus

Der Algorithmus durchläuft die Tabelle entlang des Pfads, wie in der untenstehenden Abbildung mit Pfeilen und Konten markiert ist, und bricht ab, sobald ein Ergebnis berechnet ist.

tabelle1.jpg

  1. Wenn irgendwo in der Tabelle ein X steht, wird abgebrochen. Das berechnete Recht ist X (untersagt).
  2. Geh zum Startknoten.
  3. Wenn es keinen Folgeknoten gibt, wird abgebrochen. Das berechnete Recht ist P (unterbunden).
  4. Andernfalls folge dem Pfad zum nächsten Knoten.
  5. Addiere die Rechte im Knoten gemäß den Regeln: N = 0, A = +1, P = -1.
    • Ist die Summe größer Null, wird abgebrochen. Das berechnete Recht ist A (erlaubt).
    • Ist die Summe kleiner Null, wird abgebrochen. Das berechnete Recht ist P (unterbunden).
    • Ist die Summe gleich Null, gehe zu Schritt 3.

Beachten Sie, dass der Algorithmus abbricht, wenn entweder ein Ergebnis berechnet ist oder der Algorithmus den letzten Knoten erreicht, ohne ein Ergebnis berechnet zu haben.

Anwendung des Algorithmus auf unser Beispiel

Wenn wir den Algorithmus auf unser obiges Beispiel (Testversuch durchführen), wird in Schritt 1 abgebrochen, und das berechnete Recht ist X (untersagt). Dieses Beispiel ist nicht interessant, ersetzen wir also das X durch ein P und sehen, was dann passiert:

tabelle2.jpg

Der Algorithmus arbeitet dann wie folgt:

  • Es gibt kein X in der Tabelle.
  • Geh zum Startknoten.
  • Geh zum nächsten Knoten.
  • N+N=0
  • Die Summe ist gleich Null, geh zum nächsten Knoten.
  • A + P = 0
  • Die Summe ist gleich Null, geh zum nächsten Knoten.
  • P+A=0
  • Die Summe ist gleich Null, geh zum nächsten Knoten.
  • N+N=0
  • Die Summe ist gleich Null, geh zum nächsten Knoten.
  • N=0
  • Die Summe ist gleich Null, geh zum nächsten Knoten
  • A=+1
  • Die Summe ist größer Null, es wird abgebrochen. Das berechnete Recht ist A (erlaubt).

Wenn das berechnete Recht A ist, liefert die Funktion has_capabilty() ein true (wahr), und der Nutzer darf die Aktion ausführen (Testversuch durchführen).

Wäre das berechnete Recht P oder X gewesen, würde die Funktion has_capabilty() nicht sofort ein false zurückgeben. Vielmehr würde sie testen, ob der Nutzer das Recht moodle/site:doanything = erlaubt hat (weil dieses Recht alle anderen sticht. Der Test erfolgt dadurch, dass die Funktion sich selbst aufruft:

   final result = has_capability(moodle/site:doanything,CONTEXT, USER);

Anmerkung zum Algorithmus

Weiter oben hatten wir gesagt, dass der Algorithmus das Ergebnis berechnet, das der gesunde Menschenverstand erwartet. Aber was erwarten wir eigentlich? Die Intuition sagt, dass Rechte, die "näher am Nutzer dran sind" ein stärkeres Gewicht haben sollten als weiter entfernte Rechte. Das ist der Grund, weshalb die Tabelle so wie beschrieben angelegt wird und der Algorithmus die Tabelle genau so durchläuft. Die letzte Spalte der Tabelle repräsentiert die Rechte, die "am nächsten am Nutzer dran sind", die vorletzte Spalte repräsentiert die nächst entfernten Rechte usw. Daher durchläuft der Algorithmus "von hinten nach vorn". Innerhalb einer Spalte durchläuft der Algorithmus diue Tabelle "von unten nach oben", damit Rollenänderungen, die "näher am Nutzer dran sind", größeres Gewicht erhalten als weiter entfernte. Wenn es in einer Spalte keine Rollenänderungen gibt, dann wird das Recht aus der Rollendefinition verwendet (erste Zeile = Systemkontext).

Wie Sie sicherstellen, dass der Algorithmus das erwartete Ergebnis liefert

Damit der Algorithmus auch tatsächlich das Ergebnis liefert, das Sie vom gesunden Menschenverstand her erwarten, sollten Sie Ihre Rollendefinitionen und -änderungen so einfach wie möglich halten. Wir empfehlen daher einige "Regeln" für Rollendefinitionen und -änderungen. Wenn Sie verstanden haben, wie der Algorithmus funktionieren, dann verstehen Sie auch den Sinn dieser Regeln.

Rollendefinitionen

Wenn Sie Rollen definieren, nutzen Sie Erlauben, wenn die Rolle die entsprechende Aktion tatsächlich ausführen dürfen soll. Verwenden Sie Nicht gesetzt für Fähigkeiten, die Ihnen (in der gegebenen Situation) egal sind.

Rollenänderungen

Lassen Sie die Einstellung Vererben für alle Fähigkeiten, außer für die, die Sie tatsächlich ändern möchten. Setzen Sie die letzteren auf Erlauben, wenn Sie die entsprechende Aktion erlauben wollen bzw. auf Unterbinden, wenn Sie die entsprechende Aktion unterbinden möchten.

Untersagen nur in Spezialfällen

Die Einstellung Untersagen für Rechte wurde nur für extreme Situationen eingerichtet, wie z.B.:Angenommen Sie haben einen frechen Nutzer, der wiederholt unangemessene Forumsbeiträge schreibt. Dann müssen Sie in der Lage sein, einem solchen Nutzer die Möglichkeit zu entziehen, zu öffentlichen Diskussionen beizutragen, bis er Besserung gelobt. Allerdings können Sie ihn in diesem Zeitraum nicht komplett vom Zugriff auf Arbeitsmaterialien und Lernaktivitäten ausschließen, weil der Nutzer ja weiterhin lernen und arbeiten soll. Deshalb bietet Moodle die Möglichkeit, das Recht für spezielle Fähigkeiten (wie z.B. mod/forum:replypost) auf Untersagen zu setzen, so dass dieses Fähigkeit nicht mehr geändert werden kann. Sie können das erreichen, indem Sie eine spezielle Rolle "Frecher Teilnehmer" anlegen, das Recht für die entsprechenden Fähigkeiten auf untersagen setzen und dem problematischen Nutzer für eine gewisse Zeit diese Rolle im Site- oder Kurs-Kontext zuweisen.

Ein praktisches Beispiel

Angenommen, ein Nutzer, der im Kontext des Kursbereichs B die Kursverwalter-Rolle hat, legt in diesem Kursbereich einen neuen Kurs an (und hat damit im Kontext dieses Kurses automatisch die Trainer-Rolle) und fügt dann eine Lektion zu diesem Kurs hinzu. Jetzt möchte dieser Nutzer die Lektion bearbeiten (diese Aktion wird durch die Fähigkeit mod/lesson:edit gesteuert). Hier sind die zugehörigen Rechte-Daten:

   0     System           <---- Rollendefinitionen: Authentifizierter Nutzer(N), Kursverwalter(N), Trainer(A)
           |                    Rollenzuweisungen: Authentifizierter Nutzer
           |
   1   Kursbereich A      
           |                          
           |                          
   2  Unterkursbereich B  <---- Rollenzuweisung: Kursverwalter
           |
           |
   3     Kurs             <---- Rollenzuweisung: Trainer
           |
           |
   4     Lektion          <---- Nutzer versucht, die Lektion zu bearbeiten

Die entsprechte Rechte-Tabelle sieht wie folgt aus:

                System                          Kursbereich A     Kursbereich B      Kurs         Lektion
               +-----------------------------+-----------------+------------------+------------+-------------
               |                             |                 |                  |            |    
 System        | Authentifizierter Nutzer(N) |                 | Kursverwalter(N) | Trainer(A) | 
               |                             |                 |                  |            |
 Kursbereich A |                             |                 |                  |            | 
               |                             |                 |                  |            | 
 Kursbereich B |                             |                 |                  |            | 
               |                             |                 |                  |            | 
 Kurs          |                             |                 |                  |            |
               |                             |                 |                  |            | 
 Lektion       |                             |                 |                  |            |
               |                             |                 |                  |            |

Da es keine Rollenänderungen gibt, enthält die Tabelle nur in der ersten Zeile Daten. Der Algorithmus berechnet schnell das Recht A (erlaubt), liefert ein true (wahr zurück, und der Nutzer darf die Lektion bearbeiten.

Nehmen wir jetzt an, die Trainer-Rolle wurde im Kontext der Lektion geändert: mod/lesson:edit = P.

Die Tabelle sieht dann so aus:

                System                          Kursbereich A     Kursbereich B      Kurs         Lektion
               +-----------------------------+-----------------+------------------+------------+-------------
               |                             |                 |                  |            |    
 System        | Authentifizierter Nutzer(N) |                 | Kursverwalter(N) | Trainer(A) | 
               |                             |                 |                  |            |
 Kursbereich A |                             |                 |                  |            | 
               |                             |                 |                  |            | 
 Kursbereich B |                             |                 |                  |            | 
               |                             |                 |                  |            | 
 Kurs          |                             |                 |                  |            |
               |                             |                 |                  |            | 
 Lektion       |                             |                 |                  | Trainer(P) |
               |                             |                 |                  |            |

Logischerweise darf der Nutzer die Lektion jetzt nicht mehr bearbeiten.

Nehmen wir aber nun an, der Moodle-Administrator (oder jemand anderes, der Rollen ändern darf) überschreibt nun die Kursverwalter-Rolle im Kontext des Kursbereichs B: mod/lesson:edit = P.

Dann ergibt sich folgende Tabelle:

                System                          Kursbereich A     Kursbereich B      Kurs         Lektion
               +-----------------------------+-----------------+------------------+------------+-------------
               |                             |                 |                  |            |    
 System        | Authentifizierter Nutzer(N) |                 | Kursverwalter(N) | Trainer(A) | 
               |                             |                 |                  |            |
 Kursbereich A |                             |                 |                  |            | 
               |                             |                 |                  |            | 
 Kursbereich B |                             |                 | Kursverwalter(P) |            | 
               |                             |                 |                  |            | 
 Kurs          |                             |                 |                  |            |
               |                             |                 |                  |            | 
 Lektion       |                             |                 |                  |            |
               |                             |                 |                  |            |

Zu unserer Überraschung darf der Nutzer in diesem Fall nach wie vor die Lektion bearbeiten! Wenn Sie den Artikel verstanden haben, sollten Sie allerdings nicht mehr überrascht sein, sondern sollten in der Lage sein zu erklären, warum das so ist.

Siehe auch

Diskussionsbeiträge im Kurs Using Moodle auf moodle.org:

Skript zum Testen von Rollen: