* * @copyright Copyright (c) 2016, ownCloud, Inc. * @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 * */ namespace OCA\DAV\Connector\Sabre; use \Sabre\DAV\PropFind; use \Sabre\DAV\PropPatch; use OCP\IUserSession; use OCP\Share\IShare; use OCA\DAV\Connector\Sabre\ShareTypeList; /** * Sabre Plugin to provide share-related properties */ class SharesPlugin extends \Sabre\DAV\ServerPlugin { const NS_OWNCLOUD = 'http://owncloud.org/ns'; const SHARETYPES_PROPERTYNAME = '{http://owncloud.org/ns}share-types'; /** * Reference to main server object * * @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; /** * @var IShare[] */ private $cachedShareTypes; /** * @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 ) { $this->tree = $tree; $this->shareManager = $shareManager; $this->userFolder = $userFolder; $this->userId = $userSession->getUser()->getUID(); $this->cachedShareTypes = []; } /** * This initializes the plugin. * * This function is called by \Sabre\DAV\Server, after * addPlugin is called. * * This method should set up the required event subscriptions. * * @param \Sabre\DAV\Server $server */ public function initialize(\Sabre\DAV\Server $server) { $server->xml->namespacesMap[self::NS_OWNCLOUD] = 'oc'; $server->xml->elementMap[self::SHARETYPES_PROPERTYNAME] = 'OCA\\DAV\\Connector\\Sabre\\ShareTypeList'; $server->protectedProperties[] = self::SHARETYPES_PROPERTYNAME; $this->server = $server; $this->server->on('propFind', array($this, 'handleGetProperties')); } /** * Return a list of share types for outgoing shares * * @param \OCP\Files\Node $node file node * * @return int[] array of share types */ private function getShareTypes(\OCP\Files\Node $node) { $shareTypes = []; $requestedShareTypes = [ \OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_LINK, \OCP\Share::SHARE_TYPE_REMOTE ]; foreach ($requestedShareTypes as $requestedShareType) { // one of each type is enough to find out about the types $shares = $this->shareManager->getSharesBy( $this->userId, $requestedShareType, $node, false, 1 ); if (!empty($shares)) { $shareTypes[] = $requestedShareType; } } return $shareTypes; } /** * Adds shares to propfind response * * @param PropFind $propFind propfind object * @param \Sabre\DAV\INode $sabreNode sabre node */ public function handleGetProperties( PropFind $propFind, \Sabre\DAV\INode $sabreNode ) { if (!($sabreNode instanceof \OCA\DAV\Connector\Sabre\Node)) { return; } // need prefetch ? if ($sabreNode instanceof \OCA\DAV\Connector\Sabre\Directory && $propFind->getDepth() !== 0 && !is_null($propFind->getStatus(self::SHARETYPES_PROPERTYNAME)) ) { $folderNode = $this->userFolder->get($propFind->getPath()); $children = $folderNode->getDirectoryListing(); $this->cachedShareTypes[$folderNode->getId()] = $this->getShareTypes($folderNode); foreach ($children as $childNode) { $this->cachedShareTypes[$childNode->getId()] = $this->getShareTypes($childNode); } } $propFind->handle(self::SHARETYPES_PROPERTYNAME, function() use ($sabreNode) { if (isset($this->cachedShareTypes[$sabreNode->getId()])) { $shareTypes = $this->cachedShareTypes[$sabreNode->getId()]; } else { $node = $this->userFolder->get($sabreNode->getPath()); $shareTypes = $this->getShareTypes($node); } return new ShareTypeList($shareTypes); }); } }