Joomla – Noix ACL: Bug im Media Manager

Folgendes Problem tat sich mir jüngst bei einem Joomla-Projekt auf, bei dem ich für die Rechte-Verwaltung NoixACL verwende. Ich habe die Version 2.0.6 beta installiert u.a. mit dem Adapter „access“ in der Version 1.5.4. Soweit ich es in der Version 1.5.5 sehen konnte, ist dieses Problem dort nicht behoben worden. Eventuell ist dieses Verhalten auch Absicht, aber das kann ich mir eigentlich nicht vorstellen, da ich schon an vielen Stellen im Internet diese Schilderung gefunden habe, aber leider immer ohne Erklärung oder Workaround. Deswegen tu ich hier meine Erkenntnisse kund und hoffe damit, dem ein oder anderen zu helfen.

Problem

Alle Nutzer, die keine Superadministratoren waren, konnten keine Dateien im Media Manager bzw. Bilder beim Bild-Upload in einem Artikel hochladen, obwohl unter „Manage Groups“ > „Access“ > „General“ > „Manage Media“ der Zugriff erlaubt wurde. Es fehlte schlicht das Formularfeld für den Datei-Upload, wie man auf dem Bild-Vergleich sehen kann. Die Ansicht, die Auswahl und das Löschen von Dateien funktionierte problemlos.

Links, wie es sein soll und rechts die verbuggte Variante unter noixACL

 

Das Problem betrifft also die Zugriffsrechte auf die Komponente „com_media“.

Lösung

Jetzt muss ich gleich vornweg sagen, dass mir die Struktur von Joomla-Komponenten und dem Joomla-Framework selbst noch nicht so geläufig ist. Es kann also durchaus sein, dass es eine elegantere Lösung gibt, aber ich meine zumindest, das Problem an der richtigen Stelle mit den richtigen Maßnahmen angegriffen zu haben. So oder so will ich hier kurz meinen „Trial & Error“-Weg skizzieren als Anhalt, wie man bei der Problemsuche vorgehen kann.

Wo liegt der Hund begraben

Also. Ein Blick in die Komponente „com_media“, genauer gesagt, die Datei, die das Upload-Formular anzeigt1, hat mir verraten, dass das Formularfeld nur angezeigt wird, wenn der Nutzer Upload-Rechte hat, was ja logisch ist.

<?php $canUpload= ($this->user->authorize('com_media', 'upload')); ?>

Da noixACL nicht in den Joomla-Kern selber eingreift, konnte das Problem also nicht hier liegen.
Der nächste Blick wanderte daher auf die Datenbank und hier auf die Tabelle „jos_noixacl_rules“. Dort habe ich nach aco_section=’com_media‘ gefiltert und für jede Benutzergruppe, die Schreibrechte haben sollte, zwei Einträge gefunden. Einen Eintrag mit aco_value=’manage‘ und einen mit aco_value=’popup‘.

SQL-Datenbank manipulieren

Ein kleiner Test (Datensatz löschen) ergab, dass der Wert „manage“ den Zugriff auf den Media Manager erlaubt und „popup“ auf den Bild-Upload innerhalb eines Artikels. Diese Zeilen mussten also bestehen bleiben. Anhand der Überprüfung innerhalb der „com_media“-Komponente (s.o.) hab ich nun einen neuen Datensatz mit dem Wert „upload“ im Feld „aco_value“ angelegt (siehe Bild).

Neuen Datensatz unter PHPMyAdmin anlegen

Dabei muss das Feld „id“ leer bleiben, da es automatisch inkrementiert wird. Im Feld „aro_value“ wird der Gruppenname so angegeben, wie er auch in der Gruppenliste angezeigt wird (also bsp. ‚Administrator‘). Alternativ kann man auch eine SQL-Anweisung schreiben statt der bequemen PHPMyAdmin-Variante:

INSERT INTO jos_noixacl_rules VALUES (NULL,'com_media','upload','users','Gruppenname','','')

Und siehe da, das Upload-Formular ist sichtbar und funktioniert sowohl im Media Manager als auch im Bild-Upload innerhalb eines Artikels.

Quelltext des Adapters anpassen

Dieser manuelle Eingriff in die Datenbank ist natürlich unschön. Schöner ist es, wenn beim Anlegen/Bearbeiten einer Gruppe die richtigen Datenbankeinträge gesetzt werden.

Dazu muss man in den Adapter „access“ gehen, der den Zugriff auf Komponenten steuert. Die gesuchte php-Datei ist

../administrator/components/com_noixacl/adapters/access/aeccess.php

In der Methode „save“ werden systematisch die Zugriffsregeln vorbereitet, welche dann als Datensatz in die Datenbank geschrieben werden. Da man für den Zugriff auf den Media Manager aber nur ein Haken gesetzt wird, aber mindestens 2 Regeln benötigt werden (für die zusätzlichen Bild-Upload innerhalb eines Artikels) wird ab der Zeile 48 in einer switch-Anweisung die zusätzliche Regel mit dem Wert „popup“ erzeugt.

switch($aco_section) {
  case 'com_media':                            
    if ($aco_value='manage') {
      $arrRule = array(
        "aco_section" => $aco_section,
        "aco_value" => 'popup',
        "aro_section" => "users",
        "aro_value" => $groupName,
        "axo_section" => $axo_section,
        "axo_value" => $axo_value
      );
      $this->insertRule($arrRule);
    }
}

Hier muss man innerhalb der if-Anweisung nun noch eine Regel ergänzen, die statt dem Wert ‚popup‘ den Wert ‚upload‘ enthält.

switch($aco_section) {
  case 'com_media':                            
    if ($aco_value='manage') {
      $arrRule = array(
        "aco_section" => $aco_section,
        "aco_value" => 'popup',
        "aro_section" => "users",
        "aro_value" => $groupName,
        "axo_section" => $axo_section,
        "axo_value" => $axo_value
      );
      $this->insertRule($arrRule);
      $arrRule = array(
        "aco_section" => $aco_section,
        "aco_value" => 'upload',
        "aro_section" => "users",
        "aro_value" => $groupName,
        "axo_section" => $axo_section,
        "axo_value" => $axo_value
      );
      $this->insertRule($arrRule);
    }
}

Also nochmal zusammenfassend, wofür welche Regel da ist:

manage – Zugriff auf den Media Manager
popup   – Zugriff auf den Bild-Upload innerhalb eines Beitrags
upload   – Anzeige der Formular-Felder für den Datei-Upload

Alle diese drei Regeln müssen für eine Gruppe in der Datenbank vorhanden sein.

Wie eingangs erwähnt, habe ich „noch“ die Version 1.5.4 des Access-Adapters für noixACL installiert. Mittlerweile gibt es die Version 1.5.5, in welcher – wenn ich mich nicht verguckt habe – dieses Problem aber nicht behoben wurde. Wenn man nach diesem Eingriff in den Quellcode also eine neue Version installiert, muss man den Quellcode erneut bearbeiten.

Für bestehende Gruppen kann man die Rechte nachträglich ändern, indem man entweder jede Gruppe im Backend betrachtet und den Haken bei „Manage Media“ einmal entfernt und wieder setzt oder man erzeugt mit einem Schlag für jede Gruppe einen neuen Datensatz mit einem SQL-Statement (wie oben).

Die Sache abrunden (delete-Methode)

Um Datenbankleichen und ggf. Fehlfunktionen aus dem Weg zu gehen, wenn man eine Gruppe löscht, muss in derselben Datei in der Methode „delete“ ca. bei Zeile 95 der Befehl

$this->deleteRules("com_media","upload",$groupName);

ergänzt werden.

 

1) Genau handelt es sich um die Datei ../administrator/components/com_media/views/media/tmpl/default.php