major
#29760
Improve the React UI of the model-based security configuration; let a TL-Script function determine the access parent of a type
The coverage view of the model-based access definition (Administration > Access control > Coverage, React view admin/access-control/coverage.view.xml) and the configuration editor it uses are improved, and the access parent of a type can be computed by a TL-Script function.
Access parent
- The access parent of a type is configured as one polymorphic element <access-parent> of the <class> entry of the SecurityConfigurationService, holding exactly one definition: <container/>, <target reference="..."/>, <self/> or <script expr="..."/>.
- <script expr="..."/> (ScriptAccessParent): a TL-Script function computes the access parent of an object. It is evaluated without security. A result of several objects, a non-object result, an object without access control of its own (e.g. a transient object) or a failure denies access and is logged; an empty result means no access parent.
- A delegating access parent together with grants or marks of the same entry is rejected with a message naming the conflicting property by its label.
- Dropping an access parent an underlying configuration layer sets (by a mark, or by removing it in the access rights dialog) stores <self/> as override.
Coverage view
- The coverage table is a tree table: the modules of the analyzed types are its nodes, their types the children. A module is selected like any row; "Module access rights…" is offered only while a module is selected.
- A mark (internal, without access control) inherited from a module or a generalization is reported with its origin (the type itself, then a marked generalization, then the module); dropping a mark is offered only for a mark of the type's own.
- The access rights dialog shows the marks and the access parent in effect, also those an underlying configuration layer sets.
- Rule creation ("Role parent…", "Role rule…") moved to the "Rules in effect" panel, next to editing and deleting; a script step of a rule is shown as written.
- The dialogs check their form before saving (check-config-form) and disable Save while errors are shown (config-form-valid); the individual violations are listed below the refusal.
- Table header stays aligned with the body when scrolled fully right; dialog forms are inset; icons of options are shown.
Configuration editor (React)
- An optional non-polymorphic item property is edited as a list of at most one entry; an item that may not be null offers no removal.
- A TL-Script valued property is edited in the TL-Script editor of the script console; parse and compile errors are reported when the editor is left.
- An unset mandatory item written as text, and an unset mandatory polymorphic item, are reported as missing.
- The type selector is labelled in the user's language and marked mandatory.
- Errors of a field whose control does not display them are shown in the field chrome.
Table (React)
- TreeRowSource.refresh() recomputes the displayed rows after the tree changed, keeping the expansion state.
- A tree table offers no grouping: neither the column header menu nor the column selection offers to group by a column.
- In a cell showing several values as one line, the name of a value keeps its gap to the icon.
Migration
The access parent of a type is no longer configured by the attributes access-parent and access-reference of the <class> entry of the SecurityConfigurationService, but by an element <access-parent> holding exactly one definition. The old attributes are rejected as configuration error at startup.
| = old = | = new = |
| access-parent="container" | <access-parent><container/></access-parent> |
| access-parent="container" access-reference="X" | <access-parent><container reference="X"/></access-parent> |
| access-parent="target" access-reference="X" | <access-parent><target reference="X"/></access-parent> |
| access-parent="self" | <access-parent><self/></access-parent> |
| access-parent="auto" | remove the attribute |
Also check WEB-INF/autoconf/com.top_logic.model.security.SecurityConfigurationService.config.xml: the "Access rights…" dialog of the coverage view writes to it.
The record TypeCoverage holds the origin of the marks (withoutSecurityOrigin, internalOrigin, a TLModelPart) instead of the booleans withoutSecurity and internal; the accessors withoutSecurity() and internal() remain.