enhancement
major
minor
major
minor
major
#30024
React-Oberfläche: NullPointerException in ModelAccessPolicy.isGrantable, wenn ein Zugriffs-Parent seine Parent-Typen nicht statisch kennt
Kontext
Seit #29856 entscheidet ModelAccessPolicy, ob ein Befehl oder eine Einheit der React-Oberfläche ausgeblendet wird: Ausgeblendet ist, was kein Benutzer je dürfen kann (isGrantable). Für einen Typ mit Zugriffs-Parent (Access Parent) prüft isGrantable die Operation rekursiv auf den Parent-Typen, die AccessParentFunction.getParentTypes(type) liefert.
Fehler
AccessParentFunction.getParentTypes darf laut Vertrag null liefern: Die Parent-Typen sind nicht statisch bekannt, der Typ zählt in einer Prüfung ohne konkretes Objekt als zugreifbar. ContainerRelation (der Standard-Zugriffs-Parent eines Kompositionsteils: sein Container) liefert null. ModelAccessPolicy.isGrantable iteriert ohne Prüfung über das Ergebnis:
Cannot invoke "java.util.Set.iterator()" because the return value of "com.top_logic.model.security.AccessParentFunction.getParentTypes(com.top_logic.model.TLClass)" is null
Betroffen ist jeder Benutzer ohne Administratorrechte, sobald eine Prüfung einen Typ mit Container als Zugriffs-Parent erreicht. Beispiel Steueranwendung (tl-factory): Workspace und AgentConversation sind Teile ihres Projekts. Für jedes Mitglied eines Mandanten endet die erste Seite nach der Anmeldung mit „Internal error“ (HTTP 500), und die Auswahl eines Projekts aktualisiert dessen Details nur teilweise. root ist nicht betroffen.
Verwandter Fehler im selben Mechanismus: Wird eine Operation am konkreten Objekt verweigert, entscheidet ModelAccessPolicy über „ausblenden oder deaktivieren“ nur anhand der Freigaben des Typs selbst. Ein Typ mit Zugriffs-Parent hat keine eigenen Freigaben. Daher wurde z.B. das Anlegen eines Kompositionsteils in einem Projekt ausgeblendet statt deaktiviert, wenn der Benutzer das Projekt nicht schreiben darf, obwohl andere Rollen es dürfen; ebenso Bearbeiten und Attribute solcher Teile.
Lösung
- Die möglichen Container eines Kompositionsteils kennt der SecurityConfigurationService statisch (er indiziert die Kompositionen, getAccessParentTypes). Diese Abfrage wird Teil der Schnittstelle ModelAccessRights (Default: die Parent-Typen der AccessParentFunction, leer ohne Zugriffs-Parent).
- ModelAccessPolicy.isGrantable fragt die Parent-Typen über ModelAccessRights.getAccessParentTypes ab: Für den Standard-Container-Parent werden die tatsächlichen Container-Typen geprüft. Sind die Parent-Typen unbekannt (null, z.B. ein per Skript berechneter Zugriffs-Parent), zählt der Typ wie vom Vertrag verlangt als zugreifbar; die Prüfung am konkreten Objekt entscheidet.
- Die Entscheidung „ausblenden statt deaktivieren“ nach einer Verweigerung am Objekt (Befehle auf Objekten, Anlegen in einem Container, Attribute) verwendet dieselbe Regel isGrantable und folgt damit ebenfalls dem Zugriffs-Parent.
- Die Abdeckungsanalyse (SecurityCoverageAnalysis) folgt ebenfalls den statisch bekannten Container-Typen, statt den Standard-Container-Parent als unentscheidbar zu übergehen. Sie kann dadurch Befunde für Kompositionsteile melden, die bisher unterdrückt waren.
- Test: Befehl, Einheit und Anlegen über einem Kompositionsteil (Standard-Zugriffs-Parent Container) für einen Benutzer ohne Administratorrechte; Zugriffs-Parent mit unbekannten Typen; Abdeckungsanalyse folgt dem Container.
Die benutzerbezogene Ausblend-Regel (ausblenden, was der angemeldete Benutzer auf keinem Objekt darf) ist #30025.