aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFerdinand Thiessen <opensource@fthiessen.de>2024-08-02 14:30:52 +0200
committerFerdinand Thiessen <opensource@fthiessen.de>2024-08-12 11:28:03 +0200
commitcb1b366baf75da4c578bc534884eefa7f6b4b3d2 (patch)
treebdb367d502a6990c39165960a76d3268270162ef
parent1a7acf061e26d938e2162f791afb262dc7c2b90d (diff)
downloadnextcloud-server-cb1b366baf75da4c578bc534884eefa7f6b4b3d2.tar.gz
nextcloud-server-cb1b366baf75da4c578bc534884eefa7f6b4b3d2.zip
fix(dav): Ensure share properties are also set on public remote endpoint
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
-rw-r--r--apps/dav/appinfo/v2/publicremote.php7
-rw-r--r--apps/dav/composer/composer/autoload_classmap.php1
-rw-r--r--apps/dav/composer/composer/autoload_static.php1
-rw-r--r--apps/dav/lib/Connector/Sabre/FilesPlugin.php7
-rw-r--r--apps/dav/lib/Connector/Sabre/Node.php34
-rw-r--r--apps/dav/lib/Storage/PublicShareWrapper.php38
-rw-r--r--build/integration/dav_features/dav-v2-public.feature22
-rw-r--r--build/integration/features/bootstrap/WebDav.php27
-rwxr-xr-xbuild/integration/run-docker.sh6
9 files changed, 115 insertions, 28 deletions
diff --git a/apps/dav/appinfo/v2/publicremote.php b/apps/dav/appinfo/v2/publicremote.php
index 44cf4214505..53e85d556eb 100644
--- a/apps/dav/appinfo/v2/publicremote.php
+++ b/apps/dav/appinfo/v2/publicremote.php
@@ -10,6 +10,7 @@ use OC\Files\Filesystem;
use OC\Files\Storage\Wrapper\PermissionsMask;
use OC\Files\View;
use OCA\DAV\Storage\PublicOwnerWrapper;
+use OCA\DAV\Storage\PublicShareWrapper;
use OCA\FederatedFileSharing\FederatedShareProvider;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Mount\IMountManager;
@@ -98,6 +99,12 @@ $server = $serverFactory->createServer($baseuri, $requestUri, $authPlugin, funct
return new PublicOwnerWrapper(['storage' => $storage, 'owner' => $share->getShareOwner()]);
});
+ // Ensure that also private shares have the `getShare` method
+ /** @psalm-suppress MissingClosureParamType */
+ Filesystem::addStorageWrapper('getShare', function ($mountPoint, $storage) use ($share) {
+ return new PublicShareWrapper(['storage' => $storage, 'share' => $share]);
+ }, 0);
+
/** @psalm-suppress InternalMethod */
Filesystem::logWarningWhenAddingStorageWrapper($previousLog);
diff --git a/apps/dav/composer/composer/autoload_classmap.php b/apps/dav/composer/composer/autoload_classmap.php
index 5081cc0ae97..adbf0a23d36 100644
--- a/apps/dav/composer/composer/autoload_classmap.php
+++ b/apps/dav/composer/composer/autoload_classmap.php
@@ -350,6 +350,7 @@ return array(
'OCA\\DAV\\SetupChecks\\NeedsSystemAddressBookSync' => $baseDir . '/../lib/SetupChecks/NeedsSystemAddressBookSync.php',
'OCA\\DAV\\SetupChecks\\WebdavEndpoint' => $baseDir . '/../lib/SetupChecks/WebdavEndpoint.php',
'OCA\\DAV\\Storage\\PublicOwnerWrapper' => $baseDir . '/../lib/Storage/PublicOwnerWrapper.php',
+ 'OCA\\DAV\\Storage\\PublicShareWrapper' => $baseDir . '/../lib/Storage/PublicShareWrapper.php',
'OCA\\DAV\\SystemTag\\SystemTagList' => $baseDir . '/../lib/SystemTag/SystemTagList.php',
'OCA\\DAV\\SystemTag\\SystemTagMappingNode' => $baseDir . '/../lib/SystemTag/SystemTagMappingNode.php',
'OCA\\DAV\\SystemTag\\SystemTagNode' => $baseDir . '/../lib/SystemTag/SystemTagNode.php',
diff --git a/apps/dav/composer/composer/autoload_static.php b/apps/dav/composer/composer/autoload_static.php
index 79bddfe8717..975af1af81f 100644
--- a/apps/dav/composer/composer/autoload_static.php
+++ b/apps/dav/composer/composer/autoload_static.php
@@ -365,6 +365,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\SetupChecks\\NeedsSystemAddressBookSync' => __DIR__ . '/..' . '/../lib/SetupChecks/NeedsSystemAddressBookSync.php',
'OCA\\DAV\\SetupChecks\\WebdavEndpoint' => __DIR__ . '/..' . '/../lib/SetupChecks/WebdavEndpoint.php',
'OCA\\DAV\\Storage\\PublicOwnerWrapper' => __DIR__ . '/..' . '/../lib/Storage/PublicOwnerWrapper.php',
+ 'OCA\\DAV\\Storage\\PublicShareWrapper' => __DIR__ . '/..' . '/../lib/Storage/PublicShareWrapper.php',
'OCA\\DAV\\SystemTag\\SystemTagList' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagList.php',
'OCA\\DAV\\SystemTag\\SystemTagMappingNode' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagMappingNode.php',
'OCA\\DAV\\SystemTag\\SystemTagNode' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagNode.php',
diff --git a/apps/dav/lib/Connector/Sabre/FilesPlugin.php b/apps/dav/lib/Connector/Sabre/FilesPlugin.php
index 3b96f67a82b..13244004993 100644
--- a/apps/dav/lib/Connector/Sabre/FilesPlugin.php
+++ b/apps/dav/lib/Connector/Sabre/FilesPlugin.php
@@ -345,13 +345,10 @@ class FilesPlugin extends ServerPlugin {
return $node->getNode()->getInternalPath() === '' ? 'true' : 'false';
});
- $propFind->handle(self::SHARE_NOTE, function () use ($node, $httpRequest): ?string {
+ $propFind->handle(self::SHARE_NOTE, function () use ($node, $httpRequest): string {
$user = $this->userSession->getUser();
- if ($user === null) {
- return null;
- }
return $node->getNoteFromShare(
- $user->getUID()
+ $user?->getUID()
);
});
diff --git a/apps/dav/lib/Connector/Sabre/Node.php b/apps/dav/lib/Connector/Sabre/Node.php
index 379574b30d6..075ea2dd65b 100644
--- a/apps/dav/lib/Connector/Sabre/Node.php
+++ b/apps/dav/lib/Connector/Sabre/Node.php
@@ -15,6 +15,7 @@ use OCA\DAV\Connector\Sabre\Exception\InvalidPath;
use OCP\Files\DavUtil;
use OCP\Files\FileInfo;
use OCP\Files\IRootFolder;
+use OCP\Files\NotFoundException;
use OCP\Files\StorageNotAvailableException;
use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\IManager;
@@ -298,15 +299,14 @@ abstract class Node implements \Sabre\DAV\INode {
* @return array
*/
public function getShareAttributes(): array {
- $attributes = [];
-
try {
- $storage = $this->info->getStorage();
- } catch (StorageNotAvailableException $e) {
- $storage = null;
+ $storage = $this->node->getStorage();
+ } catch (NotFoundException $e) {
+ return [];
}
- if ($storage && $storage->instanceOfStorage(\OCA\Files_Sharing\SharedStorage::class)) {
+ $attributes = [];
+ if (method_exists($storage, 'getShare')) {
/** @var \OCA\Files_Sharing\SharedStorage $storage */
$attributes = $storage->getShare()->getAttributes();
if ($attributes === null) {
@@ -319,29 +319,25 @@ abstract class Node implements \Sabre\DAV\INode {
return $attributes;
}
- /**
- * @param string $user
- * @return string
- */
- public function getNoteFromShare($user) {
- if ($user === null) {
+ public function getNoteFromShare(?string $user): string {
+ try {
+ $storage = $this->node->getStorage();
+ } catch (NotFoundException) {
return '';
}
- // Retrieve note from the share object already loaded into
- // memory, to avoid additional database queries.
- $storage = $this->getNode()->getStorage();
- if (!$storage->instanceOfStorage(\OCA\Files_Sharing\SharedStorage::class)) {
+ if (!method_exists($storage, 'getShare')) {
return '';
}
/** @var \OCA\Files_Sharing\SharedStorage $storage */
$share = $storage->getShare();
$note = $share->getNote();
- if ($share->getShareOwner() !== $user) {
- return $note;
+ if ($user === $share->getShareOwner()) {
+ // Note is only for recipient not the owner
+ return '';
}
- return '';
+ return $note;
}
/**
diff --git a/apps/dav/lib/Storage/PublicShareWrapper.php b/apps/dav/lib/Storage/PublicShareWrapper.php
new file mode 100644
index 00000000000..fb24abda9d0
--- /dev/null
+++ b/apps/dav/lib/Storage/PublicShareWrapper.php
@@ -0,0 +1,38 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\DAV\Storage;
+
+use OC\Files\Storage\Wrapper\Wrapper;
+use OCP\Share\IShare;
+
+class PublicShareWrapper extends Wrapper {
+
+ private IShare $share;
+
+ /**
+ * @param array $arguments ['storage' => $storage, 'share' => $share]
+ *
+ * $storage: The storage the permissions mask should be applied on
+ * $share: The share to use in case no share is found
+ */
+ public function __construct($arguments) {
+ parent::__construct($arguments);
+ $this->share = $arguments['share'];
+ }
+
+ public function getShare(): IShare {
+ $storage = parent::getWrapperStorage();
+ if (method_exists($storage, 'getShare')) {
+ /** @var \OCA\Files_Sharing\SharedStorage $storage */
+ return $storage->getShare();
+ }
+
+ return $this->share;
+ }
+}
diff --git a/build/integration/dav_features/dav-v2-public.feature b/build/integration/dav_features/dav-v2-public.feature
new file mode 100644
index 00000000000..773fc2c1d73
--- /dev/null
+++ b/build/integration/dav_features/dav-v2-public.feature
@@ -0,0 +1,22 @@
+# SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
+# SPDX-License-Identifier: AGPL-3.0-or-later
+Feature: dav-v2-public
+ Background:
+ Given using api version "1"
+
+ Scenario: See note to recipient in public shares
+ Given using new dav path
+ And As an "admin"
+ And user "user0" exists
+ And user "user1" exists
+ And As an "user1"
+ And user "user1" created a folder "/testshare"
+ And as "user1" creating a share with
+ | path | testshare |
+ | shareType | 3 |
+ | permissions | 1 |
+ | note | Hello |
+ And As an "user0"
+ Given using new public dav path
+ When Requesting share note on dav endpoint
+ Then the single response should contain a property "{http://nextcloud.org/ns}note" with value "Hello"
diff --git a/build/integration/features/bootstrap/WebDav.php b/build/integration/features/bootstrap/WebDav.php
index 852317f76a3..fff990fc141 100644
--- a/build/integration/features/bootstrap/WebDav.php
+++ b/build/integration/features/bootstrap/WebDav.php
@@ -52,6 +52,14 @@ trait WebDav {
$this->usingOldDavPath = false;
}
+ /**
+ * @Given /^using new public dav path$/
+ */
+ public function usingNewPublicDavPath() {
+ $this->davPath = "public.php/dav";
+ $this->usingOldDavPath = false;
+ }
+
public function getDavFilesPath($user) {
if ($this->usingOldDavPath === true) {
return $this->davPath;
@@ -75,7 +83,7 @@ trait WebDav {
];
if ($user === 'admin') {
$options['auth'] = $this->adminUser;
- } else {
+ } elseif ($user !== '') {
$options['auth'] = [$user, $this->regularUser];
}
return $client->request($method, $fullUrl, $options);
@@ -942,6 +950,23 @@ trait WebDav {
}
/**
+ * @When Requesting share note on dav endpoint
+ */
+ public function requestingShareNote() {
+ $propfind = '<d:propfind xmlns:d="DAV:" xmlns:nc="http://nextcloud.org/ns"><d:prop><nc:note /></d:prop></d:propfind>';
+ if (count($this->lastShareData->data->element) > 0) {
+ $token = $this->lastShareData->data[0]->token;
+ } else {
+ $token = $this->lastShareData->data->token;
+ }
+ try {
+ $this->response = $this->makeDavRequest('', 'PROPFIND', $token, [], $propfind);
+ } catch (\GuzzleHttp\Exception\ClientException $e) {
+ $this->response = $e->getResponse();
+ }
+ }
+
+ /**
* @Then there are no duplicate headers
*/
public function thereAreNoDuplicateHeaders() {
diff --git a/build/integration/run-docker.sh b/build/integration/run-docker.sh
index f49fd3ea650..11563c9aa21 100755
--- a/build/integration/run-docker.sh
+++ b/build/integration/run-docker.sh
@@ -201,7 +201,7 @@ cd "$(dirname $0)"
# "--image XXX" option can be provided to set the Docker image to use to run
# the integration tests (one of the "nextcloudci/phpX.Y:phpX.Y-Z" or
# "ghcr.io/nextcloud/continuous-integration-integration-phpX.Y:latest" images).
-NEXTCLOUD_LOCAL_IMAGE="ghcr.io/nextcloud/continuous-integration-integration-php8.0:latest"
+NEXTCLOUD_LOCAL_IMAGE="ghcr.io/nextcloud/continuous-integration-integration-php8.1:latest"
if [ "$1" = "--image" ]; then
NEXTCLOUD_LOCAL_IMAGE=$2
@@ -227,9 +227,9 @@ fi
# "--database-image XXX" option can be provided to set the Docker image to use
# for the database container (ignored when using "sqlite").
if [ "$DATABASE" = "mysql" ]; then
- DATABASE_IMAGE="mysql:5.7"
+ DATABASE_IMAGE="mysql:8.4"
elif [ "$DATABASE" = "pgsql" ]; then
- DATABASE_IMAGE="postgres:10"
+ DATABASE_IMAGE="postgres:15"
fi
if [ "$1" = "--database-image" ]; then
DATABASE_IMAGE=$2