Skip to content

Commit

Permalink
fix(dav): Ensure share properties are also set on public remote endpoint
Browse files Browse the repository at this point in the history
Signed-off-by: Ferdinand Thiessen <[email protected]>
  • Loading branch information
susnux committed Aug 11, 2024
1 parent 722a74e commit 66950c0
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 28 deletions.
7 changes: 7 additions & 0 deletions apps/dav/appinfo/v2/publicremote.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
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;
Expand Down Expand Up @@ -98,6 +99,12 @@
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);

Expand Down
1 change: 1 addition & 0 deletions apps/dav/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@
'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',
Expand Down
1 change: 1 addition & 0 deletions apps/dav/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
7 changes: 2 additions & 5 deletions apps/dav/lib/Connector/Sabre/FilesPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -345,13 +345,10 @@ public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node)
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()
);
});

Expand Down
34 changes: 15 additions & 19 deletions apps/dav/lib/Connector/Sabre/Node.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
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;
Expand Down Expand Up @@ -298,15 +299,14 @@ public function getSharePermissions($user) {
* @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) {
Expand All @@ -319,29 +319,25 @@ public function getShareAttributes(): array {
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;
}

/**
Expand Down
38 changes: 38 additions & 0 deletions apps/dav/lib/Storage/PublicShareWrapper.php
Original file line number Diff line number Diff line change
@@ -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;
}
}
22 changes: 22 additions & 0 deletions build/integration/dav_features/dav-v2-public.feature
Original file line number Diff line number Diff line change
@@ -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"
27 changes: 26 additions & 1 deletion build/integration/features/bootstrap/WebDav.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ public function usingNewDavPath() {
$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;
Expand All @@ -75,7 +83,7 @@ public function makeDavRequest($user, $method, $path, $headers, $body = null, $t
];
if ($user === 'admin') {
$options['auth'] = $this->adminUser;
} else {
} elseif ($user !== '') {
$options['auth'] = [$user, $this->regularUser];
}
return $client->request($method, $fullUrl, $options);
Expand Down Expand Up @@ -941,6 +949,23 @@ public function connectingToDavEndpoint() {
}
}

/**
* @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
*/
Expand Down
6 changes: 3 additions & 3 deletions build/integration/run-docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand Down

0 comments on commit 66950c0

Please sign in to comment.