Skip to content

Check delete permission on every page in a wiki subtree delete - #8105

Open
labkey-bpatel wants to merge 3 commits into
developfrom
fb_wiki_subtree_delete_1468
Open

labkey-bpatel wants to merge 3 commits into
developfrom
fb_wiki_subtree_delete_1468

Conversation

@labkey-bpatel

@labkey-bpatel labkey-bpatel commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Rationale

Deleting a wiki page with "Delete Entire Wiki Subtree" only checked delete permission on the root page. Because the creator of a page gets a contextual Owner role on it, an Author (Read + Insert, no Delete) could delete their own page's entire subtree, permanently removing child pages created by other users along with their version history and attachments. This change requires delete permission on every page in the subtree, so a subtree delete is allowed only when the user could delete each of those pages individually. Editors and Admins are unaffected, and a delete without the subtree option still moves children up a level. GH Issue 1468

Related Pull Requests

Changes

  • DeleteAction.handlePost walks the whole subtree before deleting anything and rejects the request with a 403 naming the first page the user can't delete, so the delete is all-or-nothing.
  • WikiManager.deleteWiki has a new overload that takes a per-page check, run on each descendant just before it's deleted, to catch a child added after the upfront check. The existing overload passes no check, so WikiService.deleteWiki and other callers are unchanged.
  • The delete confirmation page disables the subtree option and names the blocking page when the user can't delete the whole subtree.

<br/><labkey:checkbox id="isDeletingSubtree" name="isDeletingSubtree" value="true" checked="false"/> Delete Entire Wiki Subtree
<br/><labkey:checkbox id="isDeletingSubtree" name="isDeletingSubtree" value="true" checked="false" disabled="<%=null != undeletableDescendant%>"/> Delete Entire Wiki Subtree
<% if (null != undeletableDescendant) { %>
<br/><span class="labkey-error">You can't delete the entire subtree because you don't have permission to delete the child page '<%=h(undeletableDescendant.getName())%>'.</span>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine to just report the first child in practice, but there could be multiple children that you don't have permission to delete.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, correct. We stop at the first one since that’s enough to block the delete. I added a comment to make that clearer.

@labkey-jeckels

Copy link
Copy Markdown
Contributor

Looks like the new test isn't passing yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants