Skip to content

Honor dirId when creating files through a folder share - #58

Draft
kubrickfr wants to merge 1 commit into
arnowelzel:mainfrom
kubrickfr:fix-create-dirid-in-share
Draft

Honor dirId when creating files through a folder share#58
kubrickfr wants to merge 1 commit into
arnowelzel:mainfrom
kubrickfr:fix-create-dirid-in-share

Conversation

@kubrickfr

@kubrickfr kubrickfr commented Aug 18, 2026

Copy link
Copy Markdown

What happens today

getDir() only reads dirId on the logged-in branch. As soon as a share token is present, getNodeByToken() returns the share root and dirId is never looked at again. POST /ajax/new therefore always creates the file in the share root — and reports the share root as parentId, so the client is told the wrong location too.

Before the security fix in 4.3.6 the logged-in-with-token case crashed with a 500; since 4.3.6 it returns HTTP 200 with the file silently placed in the wrong folder. (The 4.3.6 reordering of getDir() was done for parity with getFile(), but getFile()'s descend-into-the-share step was not ported along with it.)

Two smaller pre-existing issues sit next to it:

  • Passing a file-share token to /ajax/new reached getNonExistingName() on a File and died with a fatal error (500).
  • create() never caught anything getDir() throws, so its "The required folder was not found" error branch was dead code — every failure surfaced as a 500 instead of the endpoint's documented JSON error shape.

The fix

  • getDir() now resolves dirId inside the share with Folder::getFirstNodeById(), exactly the way getFile() resolves a file inside a shared folder (so an id outside the share subtree yields not-found, and a dirId equal to the share root id keeps working).
  • A final guard requires the resolved node to be a Folder, which also fixes the file-share-token fatal.
  • create() maps NotFoundException/ForbiddenException from getDir() to its JSON error responses, making the previously dead error branch meaningful.

Tests

  • 6 new unit tests covering the share-token create path: subfolder honored, share root with empty/root dirId, dirId outside the share, file-share token, and a token without create permission.
  • 2 new end-to-end tests: an anonymous visitor on an editable public folder share creates a file in a subfolder via dirId (asserting both the reported parentId and the file's physical location over WebDAV), and a dirId pointing outside the share is rejected without creating anything. Supporting this, E2ETestCase gains a davMkcol() helper and createLinkShare() accepts share permissions.

Full suite results: unit 112/112 green (19 pre-existing skips untouched here), e2e 25/25 green against Nextcloud 33.0.8.

Note: #59 re-enables the 19 skipped unit tests; the two branches touch neighbouring test code, so whichever merges second may need a trivial rebase.

🤖 Generated with Claude Code

getDir() only looked at dirId on the logged-in branch. With a share
token, getNodeByToken() returns the share root and dirId was silently
ignored, so /ajax/new created the file in the share root and reported
the share root as parentId regardless of the requested target folder.

Resolve dirId inside the share with getFirstNodeById(), the same way
getFile() resolves a file inside a shared folder, and refuse ids that
do not resolve to a folder within the share. The guard that the
resolved node is a folder also replaces the fatal error that a
file-share token used to cause in getNonExistingName().

create() now maps NotFoundException and ForbiddenException from
getDir() to its documented JSON error responses instead of letting
them escape as a 500, which makes the previously dead
"folder was not found" branch meaningful.

Covered by new unit tests for the share-token create path and by two
end-to-end tests that exercise an anonymous visitor creating a file in
a subfolder of an editable folder share.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant