From 68a00206fe8741a069e4a16d50d196cacf2e8680 Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Thu, 29 Oct 2026 16:09:17 +0100 Subject: [PATCH] fix(dav): expose the share on storages of the legacy public endpoint Like on the new public endpoint, wrap storages accessed through `public.php/webdav` with `PublicShareWrapper`. Otherwise share restrictions and listeners that resolve the share from the storage (e.g. `ViewOnlyPlugin` or the download handling) are not applied there. Assisted-by: ClaudeCode:claude-opus-5-5 Signed-off-by: Ferdinand Thiessen --- apps/dav/appinfo/v1/publicwebdav.php | 5 ++++ .../integration/features/bootstrap/WebDav.php | 20 ++++++++++++++++ .../sharing_features/sharing-v1-part2.feature | 23 +++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/apps/dav/appinfo/v1/publicwebdav.php b/apps/dav/appinfo/v1/publicwebdav.php index ab68a40d2ab63..03ae57a23d05b 100644 --- a/apps/dav/appinfo/v1/publicwebdav.php +++ b/apps/dav/appinfo/v1/publicwebdav.php @@ -16,6 +16,7 @@ use OCA\DAV\Files\Sharing\FilesDropPlugin; use OCA\DAV\Files\Sharing\PublicLinkCheckPlugin; use OCA\DAV\Storage\PublicOwnerWrapper; +use OCA\DAV\Storage\PublicShareWrapper; use OCA\FederatedFileSharing\FederatedShareProvider; use OCP\App\IAppManager; use OCP\BeforeSabrePubliclyLoadedEvent; @@ -124,6 +125,10 @@ function (\Sabre\DAV\Server $server) use ( Filesystem::addStorageWrapper('shareOwner', function (string $mountPoint, IStorage $storage) use ($share) { return new PublicOwnerWrapper(['storage' => $storage, 'owner' => $share->getShareOwner()]); }); + // Ensure that also private shares have the `getShare` method + Filesystem::addStorageWrapper('getShare', function (string $mountPoint, IStorage $storage) use ($share) { + return new PublicShareWrapper(['storage' => $storage, 'share' => $share]); + }, 0); Filesystem::logWarningWhenAddingStorageWrapper($previousLog); $rootFolder = Server::get(IRootFolder::class); diff --git a/build/integration/features/bootstrap/WebDav.php b/build/integration/features/bootstrap/WebDav.php index f274782b64799..99ec1c859ff62 100644 --- a/build/integration/features/bootstrap/WebDav.php +++ b/build/integration/features/bootstrap/WebDav.php @@ -287,6 +287,26 @@ public function downloadingPublicFile(string $filename) { } } + #[When('Downloading public file :filename from legacy public webdav')] + public function downloadingPublicFileFromLegacyWebdav(string $filename) { + $token = $this->lastShareData->data->token; + $fullUrl = substr($this->baseUrl, 0, -4) . "public.php/webdav/$filename"; + + $client = new GClient(); + $options = [ + 'auth' => [$token, ''], + 'headers' => [ + 'X-Requested-With' => 'XMLHttpRequest', + ] + ]; + + try { + $this->response = $client->request('GET', $fullUrl, $options); + } catch (\GuzzleHttp\Exception\ClientException $e) { + $this->response = $e->getResponse(); + } + } + #[When('Downloading public file :filename without ajax header')] public function downloadingPublicFileWithoutHeader(string $filename) { $token = $this->lastShareData->data->token; diff --git a/build/integration/sharing_features/sharing-v1-part2.feature b/build/integration/sharing_features/sharing-v1-part2.feature index aa9a2390b6e39..20469d7b2ff49 100644 --- a/build/integration/sharing_features/sharing-v1-part2.feature +++ b/build/integration/sharing_features/sharing-v1-part2.feature @@ -1373,6 +1373,29 @@ Scenario: getting all shares of a file with a received share after revoking the And Downloading file "/sharedviewonly/document.odt" Then the HTTP status code should be "200" + Scenario: Cannot download a file from a view-only link share without shareapi_allow_view_without_download + Given As an "admin" + And parameter "shareapi_allow_view_without_download" of app "core" is set to "no" + Given user "user0" exists + And User "user0" created a folder "/sharedviewonly" + And User "user0" moves file "/textfile0.txt" to "/sharedviewonly/document.odt" + And As an "user0" + And creating a share with + | path | /sharedviewonly | + | shareType | 3 | + | permissions | 1 | + | attributes | [{"scope":"permissions","key":"download","value":false}] | + When Downloading public file "document.odt" + Then the HTTP status code should be "403" + When Downloading public file "document.odt" from legacy public webdav + Then the HTTP status code should be "403" + Then As an "admin" + And parameter "shareapi_allow_view_without_download" of app "core" is set to "yes" + When Downloading public file "document.odt" + Then the HTTP status code should be "200" + When Downloading public file "document.odt" from legacy public webdav + Then the HTTP status code should be "200" + Scenario: Cannot copy a file when it's shared view-only even with shareapi_allow_view_without_download enabled Given As an "admin" And parameter "shareapi_allow_view_without_download" of app "core" is set to "no"