Benutzerverwaltung in der Oberfläche, Mediathek als eigene Seite
Konten gab es bisher nur über die Konsole. Unter "Benutzer" legt ein Administrator jetzt Konten an, ändert Rollen, setzt Passwörter und löscht Konten; unter "Mein Konto" ändert jeder sein eigenes Passwort, aber nur mit dem aktuellen in der Hand. Eine Rolle je Konto: Administrator, Veröffentlicher, Redakteur. Ein Passwort oder eine Rolle zu ändern meldet jede offene Sitzung dieses Kontos ab - dafür war nichts zu bauen, CmsUser::isEqualTo vergleicht Hash und Rollen mit der Datenbank. Genau eine Sitzung überlebt: die, die ihr eigenes Passwort geändert hat. "Jemanden sofort aussperren" ist damit dasselbe wie "Passwort setzen". Es bleibt immer ein Administrator übrig, nicht über eine Zählung, sondern weil niemand sein eigenes Konto löschen oder herabstufen kann und jede Änderung die Administratorrolle voraussetzt. Die zusätzliche Prüfung auf einen zweiten Administrator war damit unerreichbar und ist wieder heraus. Mediathek (Umut: "das sollte direkt laden in pagination"): /admin/media zeigt die Bilder jetzt selbst, 24 je Seite, neueste zuerst, mit Blättern und einem Schalter für archivierte. Hochladen und Bildangaben laufen über gewöhnliche Formulare ohne JavaScript; der Dialog bleibt der Weg, beim Bearbeiten ein Bild auszuwählen. Die Bild-ID steht in jeder Karte, weil Beitragsbild und Teilen-Vorschau genau diese ID erwarten. Die Migrationsliste der Testfixtures stand dreimal da und steht jetzt einmal in tests/TestSchema.php. 217 PHP-Tests / 845 Assertions unter PHP 8.2.12 und 8.4.22. axe deckt jetzt elf Bildschirme ab statt drei - alle Verwaltungsseiten, nicht nur Anmeldung, Seitenliste und Editor -, null Verstöße. Nicht geprüft: kein Screenreader; Blättern und Upload sind mit zwei Bildern geprüft, nicht mit einer großen Bibliothek. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4841bf65bc
commit
14031a5880
23 files changed
+1281
-101
No files matched your search
@@ -373,3 +373,23 @@ Umuts Auftrag war „backend komplett neugestalten, einfacher schöner Bedienbar
|
||||
Beim Zerlegen ist mir ein Fehler unterlaufen, den erst der Browsertest gefunden hat: mein Skript schnitt am Ende jedes `@media`-Blocks **alle** schließenden Klammern ab statt nur einer. Die Datei war damit ab dem ersten Medienblock ungültig, der Browser behielt 29 von 202 Regeln. Symptom war eine Vorschaubreite von 1236 statt 1240 Pixeln, weil der Standardrahmen des iframe nicht mehr entfernt wurde – vier Pixel als einziges Anzeichen dafür, dass dreiviertel des Editor-Stylesheets fehlte.
|
||||
|
||||
**Systemschrift statt Arial**, und eine dunkle Seitenleiste als ruhiger Anker. Für die Verwaltung wird nichts nachgeladen; Google Fonts bleiben der Website vorbehalten, wo Umut sie auswählt.
|
||||
|
||||
## ADR 030 – Benutzerverwaltung: eine Rolle je Konto, und Sperren heißt Abmelden (12.09.2026)
|
||||
|
||||
Konten gab es bisher nur über die Konsole. Jetzt gibt es sie in der Verwaltung, mit drei Entscheidungen.
|
||||
|
||||
**Eine Rolle je Konto.** Gespeichert ist weiter eine Liste, weil die Sitzung sie so vergleicht, aber die Oberfläche kennt genau eine: Administrator, Veröffentlicher, Redakteur. Mehrere Rollen gleichzeitig hätte niemand erklären können, und die Rollenhierarchie in `security.yaml` leistet dasselbe.
|
||||
|
||||
**Wer gesperrt wird, wird abgemeldet.** Ein Passwort oder eine Rolle zu ändern beendet jede offene Sitzung dieses Kontos. Dafür war nichts zu bauen: `CmsUser::isEqualTo` vergleicht Passworthash und Rollen mit der Datenbank, und eine Sitzung, deren gespeicherter Stand abweicht, ist bei der nächsten Anfrage nicht mehr angemeldet. Genau eine Sitzung überlebt, nämlich die, die ihr eigenes Passwort geändert hat – der Controller legt ihr den frischen Benutzer in die Sitzung. Damit ist „jemanden sofort aussperren“ dasselbe wie „Passwort setzen“, und das steht auch so in der Oberfläche.
|
||||
|
||||
**Es bleibt immer ein Administrator übrig.** Nicht über eine Zählung, sondern über eine einfachere Regel: niemand kann sein eigenes Konto löschen oder herabstufen. Weil jede Änderung an einem Konto die Administratorrolle voraussetzt, braucht das Entfernen eines Administrators einen zweiten, der danach noch da ist. Ich hatte zuerst zusätzlich geprüft, ob noch ein anderer Administrator existiert – mit dieser Regel ist das unerreichbarer Code und wieder heraus.
|
||||
|
||||
Das eigene Passwort darf jeder ändern, aber nur mit dem aktuellen in der Hand: eine offen stehengelassene Sitzung soll nicht genügen, um ein Konto zu übernehmen. Untere Grenze 14 Zeichen, obere 72 Bytes, weil bcrypt alles darüber stillschweigend ignoriert. `cms:user:create` bleibt der Weg zurück, wenn kein Konto mehr funktioniert; das steht auch auf dem Bildschirm, samt Hinweis, dass es Dateizugriff auf den Server braucht.
|
||||
|
||||
## ADR 031 – Die Mediathek ist eine Seite, kein Knopf (12.09.2026)
|
||||
|
||||
Umut: „Ich finde mediathek komisch das sollte direkt laden in pagination“. Er hatte recht: der Bildschirm zeigte einen Knopf, der denselben Dialog öffnete, den der Editor zum Auswählen benutzt. Um zu sehen, was in der Mediathek liegt, musste man erst etwas anklicken.
|
||||
|
||||
Jetzt rendert `/admin/media` die Bilder selbst, 24 je Seite, neueste zuerst, mit Blättern über `?seite=` und einem Schalter für archivierte. Hochladen und Bildangaben laufen über gewöhnliche Formulare statt über `fetch`, also ohne JavaScript; dieser Bildschirm lädt weder `media.js` noch `editor.css`. Die Bild-ID steht in jeder Karte, weil die Felder für Beitragsbild und Teilen-Vorschau genau diese ID erwarten.
|
||||
|
||||
Der Dialog bleibt, was er ist: der Weg, beim Bearbeiten ein Bild auszuwählen. Zwei Wege zum gleichen Bestand mit verschiedenen Aufgaben – `MediaLibrary::list()` bleibt für den Dialog neben `page()` bestehen, weil der Dialog seinen eigenen Filter mitbringt.
|
||||
Reference in new issue
Block a user