aboutsummaryrefslogtreecommitdiffstats
path: root/apps/dav/lib/Connector/Sabre/SharesPlugin.php
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dav/lib/Connector/Sabre/SharesPlugin.php')
-rw-r--r--apps/dav/lib/Connector/Sabre/SharesPlugin.php147
1 files changed, 63 insertions, 84 deletions
diff --git a/apps/dav/lib/Connector/Sabre/SharesPlugin.php b/apps/dav/lib/Connector/Sabre/SharesPlugin.php
index 57c91e05a8c..f49e85333f3 100644
--- a/apps/dav/lib/Connector/Sabre/SharesPlugin.php
+++ b/apps/dav/lib/Connector/Sabre/SharesPlugin.php
@@ -1,39 +1,23 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Julius Härtl <jus@bitgrid.net>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Tobias Kaminsky <tobias@kaminsky.me>
- * @author Vincent Petry <vincent@nextcloud.com>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\DAV\Connector\Sabre;
+use OC\Share20\Exception\BackendError;
use OCA\DAV\Connector\Sabre\Node as DavNode;
use OCP\Files\Folder;
+use OCP\Files\Node;
use OCP\Files\NotFoundException;
use OCP\IUserSession;
+use OCP\Share\IManager;
use OCP\Share\IShare;
use Sabre\DAV\PropFind;
+use Sabre\DAV\Server;
+use Sabre\DAV\Tree;
/**
* Sabre Plugin to provide share-related properties
@@ -50,40 +34,19 @@ class SharesPlugin extends \Sabre\DAV\ServerPlugin {
* @var \Sabre\DAV\Server
*/
private $server;
-
- /** @var \OCP\Share\IManager */
- private $shareManager;
-
- /** @var \Sabre\DAV\Tree */
- private $tree;
-
- /** @var string */
- private $userId;
-
- /** @var \OCP\Files\Folder */
- private $userFolder;
+ private string $userId;
/** @var IShare[][] */
- private $cachedShares = [];
-
+ private array $cachedShares = [];
/** @var string[] */
- private $cachedFolders = [];
+ private array $cachedFolders = [];
- /**
- * @param \Sabre\DAV\Tree $tree tree
- * @param IUserSession $userSession user session
- * @param \OCP\Files\Folder $userFolder user home folder
- * @param \OCP\Share\IManager $shareManager share manager
- */
public function __construct(
- \Sabre\DAV\Tree $tree,
- IUserSession $userSession,
- \OCP\Files\Folder $userFolder,
- \OCP\Share\IManager $shareManager
+ private Tree $tree,
+ private IUserSession $userSession,
+ private Folder $userFolder,
+ private IManager $shareManager,
) {
- $this->tree = $tree;
- $this->shareManager = $shareManager;
- $this->userFolder = $userFolder;
$this->userId = $userSession->getUser()->getUID();
}
@@ -95,9 +58,9 @@ class SharesPlugin extends \Sabre\DAV\ServerPlugin {
*
* This method should set up the required event subscriptions.
*
- * @param \Sabre\DAV\Server $server
+ * @return void
*/
- public function initialize(\Sabre\DAV\Server $server) {
+ public function initialize(Server $server) {
$server->xml->namespaceMap[self::NS_OWNCLOUD] = 'oc';
$server->xml->elementMap[self::SHARETYPES_PROPERTYNAME] = ShareTypeList::class;
$server->protectedProperties[] = self::SHARETYPES_PROPERTYNAME;
@@ -108,10 +71,10 @@ class SharesPlugin extends \Sabre\DAV\ServerPlugin {
}
/**
- * @param \OCP\Files\Node $node
+ * @param Node $node
* @return IShare[]
*/
- private function getShare(\OCP\Files\Node $node): array {
+ private function getShare(Node $node): array {
$result = [];
$requestedShareTypes = [
IShare::TYPE_USER,
@@ -122,19 +85,31 @@ class SharesPlugin extends \Sabre\DAV\ServerPlugin {
IShare::TYPE_ROOM,
IShare::TYPE_CIRCLE,
IShare::TYPE_DECK,
+ IShare::TYPE_SCIENCEMESH,
];
+
foreach ($requestedShareTypes as $requestedShareType) {
- $shares = $this->shareManager->getSharesBy(
+ $result = array_merge($result, $this->shareManager->getSharesBy(
$this->userId,
$requestedShareType,
$node,
false,
-1
- );
- foreach ($shares as $share) {
- $result[] = $share;
+ ));
+
+ // Also check for shares where the user is the recipient
+ try {
+ $result = array_merge($result, $this->shareManager->getSharedWith(
+ $this->userId,
+ $requestedShareType,
+ $node,
+ -1
+ ));
+ } catch (BackendError $e) {
+ // ignore
}
}
+
return $result;
}
@@ -156,27 +131,29 @@ class SharesPlugin extends \Sabre\DAV\ServerPlugin {
*/
private function getShares(DavNode $sabreNode): array {
if (isset($this->cachedShares[$sabreNode->getId()])) {
- $shares = $this->cachedShares[$sabreNode->getId()];
- } else {
- [$parentPath,] = \Sabre\Uri\split($sabreNode->getPath());
- if ($parentPath === '') {
- $parentPath = '/';
- }
- // if we already cached the folder this file is in we know there are no shares for this file
- if (array_search($parentPath, $this->cachedFolders) === false) {
- try {
- $node = $sabreNode->getNode();
- } catch (NotFoundException $e) {
- return [];
- }
- $shares = $this->getShare($node);
- $this->cachedShares[$sabreNode->getId()] = $shares;
- } else {
+ return $this->cachedShares[$sabreNode->getId()];
+ }
+
+ [$parentPath,] = \Sabre\Uri\split($sabreNode->getPath());
+ if ($parentPath === '') {
+ $parentPath = '/';
+ }
+
+ // if we already cached the folder containing this file
+ // then we already know there are no shares here.
+ if (array_search($parentPath, $this->cachedFolders) === false) {
+ try {
+ $node = $sabreNode->getNode();
+ } catch (NotFoundException $e) {
return [];
}
+
+ $shares = $this->getShare($node);
+ $this->cachedShares[$sabreNode->getId()] = $shares;
+ return $shares;
}
- return $shares;
+ return [];
}
/**
@@ -187,18 +164,20 @@ class SharesPlugin extends \Sabre\DAV\ServerPlugin {
*/
public function handleGetProperties(
PropFind $propFind,
- \Sabre\DAV\INode $sabreNode
+ \Sabre\DAV\INode $sabreNode,
) {
if (!($sabreNode instanceof DavNode)) {
return;
}
- // need prefetch ?
+ // If the node is a directory and we are requesting share types or sharees
+ // then we get all the shares in the folder and cache them.
+ // This is more performant than iterating each files afterwards.
if ($sabreNode instanceof Directory
&& $propFind->getDepth() !== 0
&& (
- !is_null($propFind->getStatus(self::SHARETYPES_PROPERTYNAME)) ||
- !is_null($propFind->getStatus(self::SHAREES_PROPERTYNAME))
+ !is_null($propFind->getStatus(self::SHARETYPES_PROPERTYNAME))
+ || !is_null($propFind->getStatus(self::SHAREES_PROPERTYNAME))
)
) {
$folderNode = $sabreNode->getNode();
@@ -209,7 +188,7 @@ class SharesPlugin extends \Sabre\DAV\ServerPlugin {
}
}
- $propFind->handle(self::SHARETYPES_PROPERTYNAME, function () use ($sabreNode) {
+ $propFind->handle(self::SHARETYPES_PROPERTYNAME, function () use ($sabreNode): ShareTypeList {
$shares = $this->getShares($sabreNode);
$shareTypes = array_unique(array_map(function (IShare $share) {
@@ -219,7 +198,7 @@ class SharesPlugin extends \Sabre\DAV\ServerPlugin {
return new ShareTypeList($shareTypes);
});
- $propFind->handle(self::SHAREES_PROPERTYNAME, function () use ($sabreNode) {
+ $propFind->handle(self::SHAREES_PROPERTYNAME, function () use ($sabreNode): ShareeList {
$shares = $this->getShares($sabreNode);
return new ShareeList($shares);