If an account is deleted and a new account is subsequently created that reuses the old contact (see #28461), the new user will have no permissions. A full security rebuild is required for the user to regain their permissions.
**Example:**
- A contact is listed in the "responsible" attribute.
- There is a rule that assigns a role to people listed in this attribute.
- If this contact’s account is deleted, all roles are removed from the SecurityStorage.
- If the account is recreated and linked to this contact, the security for this contact is not recalculated incrementally (ElementSecurityUpdateManager).
Code Migration
AccessManager role rules (e.g., InitialRoleRule.xml) must be updated. Security now functions exclusively through the model, meaning a rule must include an “attribute” and, if necessary, a “meta-element.”
- Search and replace <step association=: Instead of navigating generally through the association table, you must identify the MetaAttribute that stores values in this table and navigate through it. For example, {{{
<step association="hasStructureChild" inverse="false" /> }}} must be changed to {{{ <step attribute="children" inverse="false" /> }}}
- Searching and replacing <rule meta-object=: Instead of specifying the table type, the TLModel type must now be specified. For example, {{{
<rule meta-object="StoredQuery" ... }}} becomes {{{ <rule meta-element="tl.search:StoredQuery" ... }}}
Data Migration
The migrations Ticket_28710_Removed_legacy_types, Ticket_28710_Update_application_types, and Ticket_28710_RoleAssignment_TLSearch ( tl-element module) run automatically on first launch. Please note:
- Directly assigned global roles will be lost. The hasGlobalRole table will be deleted without replacement; its data will not be transferred. This affects only applications that have programmatically assigned roles using Person#addGlobalRole(...) (the engine did not provide a user interface for this). Such assignments must be mapped as group membership plus role rules before the update.
- The application must delete its own legacy table types. The modules `tl.legacy.tabletypes ` and ` tl .tables ` no longer exist; the engine migration deletes only the engine’s types (`tl.legacy.tabletypes`:`PersonTable`, `tl.tables`:`PersonTableInterface`, ...). If the application’s database still contains its own types from these modules (from the update from TL 6 to TL 7 or from TableInterface-based models), the application must delete them in a separate migration (template: com.top_logic.demo/src/main/webapp/WEB-INF/kbase/migration/tl-demo/Ticket_28710_Removed_legacy_types.migration.xml) and re-types attributes that reference such types (change-part-type ... target="tl.accounts:Person"). Configuration references such as IndexedObjectNaming <type name="tl.legacy.tabletypes:..."> or defaultFor="tl.legacy.tabletypes:..." must be removed.
- hasRole is no longer a KnowledgeAssociation, but rather a MOKnowledgeObject of the model type tl.accounts:RoleAssignment (references source, dest, owner); definesRole and hasGlobalRole have been removed. Any custom *Meta.xml files that reference these tables must be updated.
Code Migration (Java)
- BoundedRole.HAS_ROLE_ASSOCIATION and DEFINES_ROLE_ASSOCIATION are deprecated. Role assignments are written using ` BoundedRole.assignRole(context, person|group, role)` and read using ` getLocalAndGlobalRoles(context, person) ` as well as the queries ` roleAssignmentsForContext(...)` and `roleAssignmentsForRole(...)` (which return a CloseableIterator that must be closed). Code that navigates via getOutgoingAssociations(HAS_ROLE_ASSOCIATION) must be refactored. Person#getGlobalRoles(), addGlobalRole(...), and removeGlobalRole(...) are deprecated.
- LegacyFlexWrapper and StoredFlexWrapper have been removed: Wrapper classes that inherit from them (such as StoredQuery and StoredReport in the engine) now inherit from com.top_logic.element.meta.kbbased.AttributedWrapper; MapBasedPersistancySupport.getObjects(KnowledgeItem) and setObjects(Collection, KnowledgeItem) replace the FlexData variants.
- The extension points ExternalRoleProvider (<role-provider>) and SecurityStorageCommitObserver (<commit-observer>) on ElementAccessManager and FallbackAccessManager have been removed without replacement; programmatic role assignment must be expressed as a configured role rule.
- AccessManager#handleSecurityUpdate(KnowledgeBase, Map, Map, Map, CommitHandler) is now called handleSecurityUpdate(TLObjectChangeSet, CommitHandler); the same applies to LogHandler#logSecurityUpdate(TLObjectChangeSet, Map, Set). An override with the old signature will no longer be silently called if it lacks the @Override annotation.
- `RoleRule` is abstract (implementations: `DefaultRoleRule`, `SingletonRule`); `PathElement` is an interface (implementation: `PathNavigation`); `RoleRule#matches(...)` takes a `TLObject`; `ElementAccessManager#getRules()` returns a `Map<TLClass, Collection<RoleProvider>>`.