|
| Description: |
We need to check the spaceId field in addition to the space field when importing space permissions to adapt to this breaking change and keep importing space permissions them from Confluence Cloud.
Original, verbose, LLM generated report: ---- h3. {color:#172b4d}*Expected*{color}
{color:#172b4d}Space permissions (for example {{VIEWSPACE}} for a group) are migrated to {{XWiki.XWikiGlobalRights}} objects on the {{WebPreferences}} page of each space.{color} h3. {color:#172b4d}*Actual*{color}
{color:#172b4d}Not a single space permission is migrated, and nothing is logged — no warning, no error. The backup contains 5,038 {{SpacePermission}} objects across 41 spaces; after the import there is no {{XWikiGlobalRights}} object on any space-level {{{}WebPreferences{}}}. Spaces that were restricted to individual groups in Confluence are readable by every logged-in user in XWiki.{color} h3. {color:#172b4d}*Cause*{color}
{color:#172b4d}In this backup format, {{SpacePermission}} references its space through {{{}<property name="spaceId">…</property>{}}}. {{ConfluenceXMLPackage#readSpacePermissionObject}} reads {{properties.getLong(KEY_PAGE_SPACE, null)}} with {{{}KEY_PAGE_SPACE = "space"{}}}, receives {{null}} and skips the record:{color}
{code:java} Long permissionId = asLong(r.readRecord(properties)); Long spaceId = properties.getLong(KEY_PAGE_SPACE, null); if (permissionId != null && spaceId != null && !shouldIgnoreSpace(spaceId) && properties.getBoolean(KEY_ACTIVE, true) ) { saveSpacePermissionProperties(properties, spaceId, permissionId); } {code}
{{{color:#172b4d}ConfluenceXMLStreamReader{color}}}{color:#172b4d} stores property names verbatim, so {{spaceId}} is never mapped to {{{}space{}}}. Still the same on {{master}} as of 2026-09-28.{color} h4. {color:#172b4d}*Second consequence: home page restrictions are lost as well*{color}
{color:#172b4d}{{ConfluenceInputFilterStream#sendSpaceRights}} returns early when the space permission list is empty. The loop that sends the home page's inherited rights comes after that return:{color} {code:java} Collection<Object> spacePermissions = spaceProperties.getList(ConfluenceXMLPackage.KEY_SPACE_PERMISSIONS); if (spacePermissions.isEmpty()) { return; } … if (inheritedRights != null) { for (ConfluenceRight confluenceRight : inheritedRights) { sendInheritedPageRight(homePageProperties, proxyFilter, confluenceRight); } }{code} {color:#172b4d}In our import this affected 18 space home pages whose view restrictions were dropped. Because Confluence inherits page restrictions downwards, this exposes the whole page tree below those home pages.{color}{{{{}}{}}} h3. *{color:#172b4d}Suggested fix{color}* # {color:#172b4d}Fall back to {{spaceId}} when {{space}} is absent.{color} # {color:#172b4d}Send the home page's inherited rights independently of whether the space permission list is empty.{color}
{color:#172b4d}{*}Sample record from{*}{{{}entities.xml{}}}{*}{{}}{*}{color} {code:java} <object class="SpacePermission" package="com.atlassian.confluence.security"> <id name="id">4174308</id> <property name="spaceId">4161554</property> <property name="type">EDITBLOG</property> <property name="group" /> <property name="userSubject" class="ConfluenceUserImpl" package="com.atlassian.confluence.user"><id name="key">…</id></property> <property name="allUsersSubject" /> <property name="active">true</property> </object> {code} h4. {color:#172b4d}{*}{{*}}{*}{{{{}}{}}}How it was verified{*}{color} ||{color:#172b4d}Observation{color}||{color:#172b4d}Source{color}|| |{color:#172b4d}5,038 {{SpacePermission}} objects with a {{spaceId}} property and no {{space}} property; {{Space}} objects have no {{permissions}} collection{color}|{color:#172b4d}{{entities.xml}} of the backup{color}| |{color:#172b4d}The filter reads {{space}}{color}|{color:#172b4d}{{{}ConfluenceXMLPackage.java{}}}, tag {{confluence-9.96.3}} and {{master}}{color}| |{color:#172b4d}Property names are stored verbatim{color}|{color:#172b4d}{{ConfluenceXMLStreamReader.java}}{color}| |{color:#172b4d}0 space-level rights in the wiki after the import, while 254 page-level view restrictions were migrated correctly{color}|{color:#172b4d}database query{color}| |{color:#172b4d}18 space home pages without the view restriction they had in Confluence{color}|{color:#172b4d}own verification script{color}| |
| Assignee: |
Raphaël Jakse |
|