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 2, 2024
1 parent 1a51afd commit 87674f0
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 23 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
5 changes: 1 addition & 4 deletions apps/dav/lib/Connector/Sabre/FilesPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -347,11 +347,8 @@ public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node)

$propFind->handle(self::SHARE_NOTE, function () use ($node, $httpRequest): ?string {

Check failure on line 348 in apps/dav/lib/Connector/Sabre/FilesPlugin.php

View workflow job for this annotation

GitHub Actions / static-code-analysis

LessSpecificReturnType

apps/dav/lib/Connector/Sabre/FilesPlugin.php:348:79: LessSpecificReturnType: The inferred return type 'string' for /home/runner/actions-runner/_work/server/server/apps/dav/lib/connector/sabre/filesplugin.php:348:13182:-:closure is more specific than the declared return type 'null|string' (see https://psalm.dev/088)
$user = $this->userSession->getUser();
if ($user === null) {
return null;
}
return $node->getNoteFromShare(
$user->getUID()
$user?->getUID()

Check notice

Code scanning / Psalm

PossiblyNullArgument Note

Argument 1 of OCA\DAV\Connector\Sabre\Node::getNoteFromShare cannot be null, possibly null value provided
);
});

Expand Down
30 changes: 15 additions & 15 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 @@ -324,24 +324,24 @@ public function getShareAttributes(): array {
* @return string

Check failure on line 324 in apps/dav/lib/Connector/Sabre/Node.php

View workflow job for this annotation

GitHub Actions / static-code-analysis

InvalidReturnType

apps/dav/lib/Connector/Sabre/Node.php:324:13: InvalidReturnType: The declared return type 'string' for OCA\DAV\Connector\Sabre\Node::getNoteFromShare is incorrect, got 'array<never, never>|string' (see https://psalm.dev/011)
*/
public function getNoteFromShare($user) {
if ($user === null) {
return '';
try {
$storage = $this->node->getStorage();
} catch (NotFoundException $e) {
return [];

Check failure

Code scanning / Psalm

InvalidReturnStatement Error

The inferred type 'array<never, never>' does not match the declared return type 'string' for OCA\DAV\Connector\Sabre\Node::getNoteFromShare

Check failure on line 330 in apps/dav/lib/Connector/Sabre/Node.php

View workflow job for this annotation

GitHub Actions / static-code-analysis

InvalidReturnStatement

apps/dav/lib/Connector/Sabre/Node.php:330:11: InvalidReturnStatement: The inferred type 'array<never, never>' does not match the declared return type 'string' for OCA\DAV\Connector\Sabre\Node::getNoteFromShare (see https://psalm.dev/128)
}

// 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 {

Check notice

Code scanning / Psalm

DeprecatedInterface Note

OCP\Files\Storage is marked deprecated

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() {

Check notice

Code scanning / Psalm

MissingReturnType Note

Method OCA\DAV\Storage\PublicShareWrapper::getShare does not have a return type, expecting OCP\Share\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 87674f0

Please sign in to comment.