major
#29692
TL Views: Formularfelder, Tabellenzellen und das Bearbeiten eines Formulars richten sich nach den Modell-Zugriffsrechten
Kontext
Ticket #29675 bildet die Modell-Zugriffsrechte (SecurityConfigurationService, abgefragt über ModelAccessRights) auf die Befehle der View-Schicht ab (Anlegen, Löschen, eigene Operationen) und setzt das Schreibrecht beim Speichern durch. Formulare und Tabellen zeigen und bearbeiten Attribute aber weiterhin ohne Rücksicht auf die Rechte: ein Benutzer sieht Werte, die er nicht lesen darf, und kann Felder bearbeiten, deren Änderung beim Speichern abgelehnt wird. Auch in Anlege-Dialogen sind alle Felder bearbeitbar, unabhängig davon, ob der Benutzer das Attribut am angelegten Objekt belegen darf.
Gewünschtes Verhalten
Wo ein Element Objekt und Attribut kennt, leitet es die Rechte selbst ab, ohne Konfiguration in der View:
- Formularfeld und Tabellenspalte: ohne Leserecht auf dem Attribut wird das Feld ausgeblendet bzw. die Zelle leer dargestellt.
- Formularfeld und Zellbearbeitung: ohne Schreibrecht auf dem Attribut ist das Feld schreibgeschützt.
- Bearbeiten eines Formulars (Bearbeiten-Befehl, initial-edit-mode, Bearbeiten-Kanal): ohne Schreibrecht auf dem Objekt wird das Bearbeiten nicht angeboten, das Formular bleibt schreibgeschützt.
- Anlege-Dialog: der Dialog öffnet sich nur, wenn der Benutzer das Objekt anlegen und dem aktuellen Kontext zuordnen darf; im Dialog sind nur die Felder bearbeitbar, die der Benutzer beim Anlegen belegen darf.
Darstellung nach der zentralen Regel aus #29675: Recht auf dem Typ fehlt → ausblenden; Recht nur auf diesem Objekt fehlt → deaktivieren mit Begründung.
Lösung
- Rechte eines Entwurfs (ModelAccessRights.isAllowedInitial(person, draft, attribute, operation)): Ein noch nicht angelegtes (transientes) Objekt hat noch keine Rollen.
- Ohne eigene Attribut-Freigabe für die Operation ist das Attribut nicht weiter eingeschränkt: das Anlegerecht deckt das Belegen der Anfangswerte ab. Transiente Hilfsobjekte (z.B. Eingabemasken, auch ohne angemeldeten Benutzer) bleiben uneingeschränkt. Eine Freigabe ohne Rollen verweigert die Operation überall.
- Typ mit Access-Parent (delegiert Freigaben und Rollen an ein anderes Objekt, z.B. einen Container): Die Kette der Access-Parents wird vom Entwurf aus verfolgt (Container bzw. Referenzwert des Entwurfs, auch über weitere Entwürfe hinweg) bis zum ersten gespeicherten Objekt; dort werden die Attribut-Freigaben gegen die Rollen des Benutzers am Ende der Kette geprüft – genau wie nach dem Speichern.
- Lücke: Typ, der über eigene Rollen entscheidet (eigene Freigaben, Rollen aus Rollenregeln, Rollen-Eltern oder direkten Zuweisungen): Die Rollen, die das Objekt haben wird, entstehen erst mit dem Objekt. Attribut-Freigaben eines solchen Typs schränken einen Entwurf deshalb nicht ein; wer das Objekt anlegen darf, belegt im Anlege-Dialog alle Attribute. Die Rechte greifen ab dem gespeicherten Objekt. Eine exakte Prüfung müsste die Rollenregeln auf dem Entwurf auswerten (nicht umgesetzt).
- Speichern eines Entwurfs: Beim Persistieren (<persist-transient>, copy(transient: false)) wird wie bisher das Anlegerecht geprüft, aber kein Schreibrecht je Attribut: Die Werte eines Entwurfs setzt die Anwendung (z.B. Vorbelegungen) und der Benutzer über Formularfelder, die den Schreibrechten folgen; ein gesperrtes Feld nimmt serverseitig keinen Wert an.
- Formularfeld: Die Rechte begrenzen den Modus des Feldes; es gilt der strengere aus Rechten und Modell (Anzeige-Annotationen, dynamische Sichtbarkeit). Geprüft wird stets das gespeicherte Objekt (nicht der Bearbeitungsstand), bei einem Entwurf der Entwurf wie oben.
- Ohne Leserecht wird das Feld ausgeblendet, und der Wert wird nicht an den Browser übertragen.
- Ohne Schreibrecht ist das Feld schreibgeschützt. Fehlt das Recht nur auf diesem Objekt, erscheint das Feld beim Bearbeiten deaktiviert, mit der Begründung im Tooltip.
- Die Rechte werden bei jedem Wechsel des Objekts und beim Betreten/Verlassen des Bearbeitungsmodus neu ausgewertet.
- Zentrale Regel für Attribute: Ein Attribut, dessen Freigabe für eine Operation keine Rolle nennt, ist unabhängig vom Objekt verweigert und wird daher ausgeblendet – auch bei Befehlen mit <model-access attribute="…"/> (bisher deaktiviert).
- Bearbeiten eines Formulars: Das Bearbeiten-Recht des Formulars kombiniert die konfigurierte edit-executability mit dem Schreibrecht auf dem Objekt (die stärkere Ablehnung gewinnt). Bearbeiten-Befehl, initial-edit-mode und Bearbeiten-Kanal gehen alle über diese Prüfung; ein abgelehnter Wechsel über den Kanal setzt den Kanal zurück. Ein Entwurf darf bearbeitet werden (das Öffnen des Anlege-Dialogs ist bereits durch das Anlegerecht geprüft).
- Öffnen eines Anlege-Dialogs: <create-transient> bringt seit #29675 die Anlege-Prüfung mit (Anlegerecht im Kontext und Schreibrecht auf der Kompositionsreferenz des Containers); der öffnende Befehl wird ohne diese Rechte nicht angeboten.
- Tabellen: Eine Attributspalte (<column attribute>, auch über <embedded-columns>) zeigt eine leere Zelle, wenn das Leserecht auf der Zeile fehlt; Sortieren, Filtern, Suchen und Export sehen denselben leeren Wert. Geprüft wird je Zeile nur ein Attribut mit eigener Lese-Freigabe; die Zeilen selbst stammen aus lesegeprüften Quellen. Darf der Benutzer das Attribut auf keiner Zeile lesen, wird die Spalte nicht angeboten; ein vordefinierter Filter auf einer solchen Spalte entfällt ohne Fehlermeldung. Die Zellbearbeitung (row-edit, <composition-table>) wird nur mit Lese- und Schreibrecht auf dem Zeilenobjekt angeboten. Berechnete Spalten werten TL-Script aus und unterliegen dessen Prüfungen.
- Demo (tl-demo-react, Projektverwaltung):
- Das Budget eines Projekts lesen und ändern nur dessen Administratoren; ein Mitglied sieht es weder im Formular noch in der Übersichtstabelle.
- Ein Meilenstein wird nur von den Administratoren des Projekts freigegeben, auch beim Anlegen (Meilensteine haben das Projekt als Access-Parent): für ein Mitglied ist „Freigegeben“ im Anlege-Dialog und beim Bearbeiten deaktiviert.
- Projekte legen die Mitglieder der Gruppe DemoProjectManagers an (globale Rolle demo.react.ProjectManager auf der Sicherheitswurzel); der Anlege-Dialog setzt den Anlegenden als Administrator des Projekts.