Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
fix(dav): Ensure share properties are also set on public remote endpoint
Signed-off-by: Ferdinand Thiessen <[email protected]>
  • Loading branch information
susnux committed Aug 12, 2024
commit cb1b366baf75da4c578bc534884eefa7f6b4b3d2
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