diff options
Diffstat (limited to 'apps/files_sharing/lib/SharedMount.php')
-rw-r--r-- | apps/files_sharing/lib/SharedMount.php | 149 |
1 files changed, 75 insertions, 74 deletions
diff --git a/apps/files_sharing/lib/SharedMount.php b/apps/files_sharing/lib/SharedMount.php index be600caef4c..692a6c8979b 100644 --- a/apps/files_sharing/lib/SharedMount.php +++ b/apps/files_sharing/lib/SharedMount.php @@ -1,116 +1,102 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Björn Schießle <bjoern@schiessle.org> - * @author Daniel Kesselberg <mail@danielkesselberg.de> - * @author Frédéric Fortier <frederic.fortier@oronospolytechnique.com> - * @author Joas Schilling <coding@schilljs.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @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\Files_Sharing; -use OC\Cache\CappedMemoryCache; use OC\Files\Filesystem; use OC\Files\Mount\MountPoint; use OC\Files\Mount\MoveableMount; use OC\Files\View; +use OCA\Files_Sharing\Exceptions\BrokenPath; +use OCP\Cache\CappedMemoryCache; use OCP\EventDispatcher\IEventDispatcher; +use OCP\Files\Events\InvalidateMountCacheEvent; use OCP\Files\Storage\IStorageFactory; +use OCP\IDBConnection; +use OCP\IUser; +use OCP\Server; use OCP\Share\Events\VerifyMountPointEvent; +use OCP\Share\IShare; +use Psr\Log\LoggerInterface; /** * Shared mount points can be moved by the user */ -class SharedMount extends MountPoint implements MoveableMount { +class SharedMount extends MountPoint implements MoveableMount, ISharedMountPoint { /** - * @var \OCA\Files_Sharing\SharedStorage $storage + * @var SharedStorage $storage */ protected $storage = null; - /** - * @var \OC\Files\View - */ - private $recipientView; - - /** - * @var string - */ - private $user; - - /** @var \OCP\Share\IShare */ + /** @var IShare */ private $superShare; - /** @var \OCP\Share\IShare[] */ + /** @var IShare[] */ private $groupedShares; - /** - * @param string $storage - * @param SharedMount[] $mountpoints - * @param array $arguments - * @param IStorageFactory $loader - * @param View $recipientView - */ - public function __construct($storage, array $mountpoints, $arguments, IStorageFactory $loader, View $recipientView, CappedMemoryCache $folderExistCache) { - $this->user = $arguments['user']; - $this->recipientView = $recipientView; - + public function __construct( + $storage, + array $mountpoints, + $arguments, + IStorageFactory $loader, + private View $recipientView, + CappedMemoryCache $folderExistCache, + private IEventDispatcher $eventDispatcher, + private IUser $user, + bool $alreadyVerified, + ) { $this->superShare = $arguments['superShare']; $this->groupedShares = $arguments['groupedShares']; - $newMountPoint = $this->verifyMountPoint($this->superShare, $mountpoints, $folderExistCache); - $absMountPoint = '/' . $this->user . '/files' . $newMountPoint; - parent::__construct($storage, $absMountPoint, $arguments, $loader); + $absMountPoint = '/' . $user->getUID() . '/files/' . trim($this->superShare->getTarget(), '/') . '/'; + + // after the mountpoint is verified for the first time, only new mountpoints (e.g. groupfolders can overwrite the target) + if (!$alreadyVerified || isset($mountpoints[$absMountPoint])) { + $newMountPoint = $this->verifyMountPoint($this->superShare, $mountpoints, $folderExistCache); + $absMountPoint = '/' . $user->getUID() . '/files/' . trim($newMountPoint, '/') . '/'; + } + + parent::__construct($storage, $absMountPoint, $arguments, $loader, null, null, MountProvider::class); } /** * check if the parent folder exists otherwise move the mount point up * - * @param \OCP\Share\IShare $share + * @param IShare $share * @param SharedMount[] $mountpoints + * @param CappedMemoryCache<bool> $folderExistCache * @return string */ - private function verifyMountPoint(\OCP\Share\IShare $share, array $mountpoints, CappedMemoryCache $folderExistCache) { + private function verifyMountPoint( + IShare $share, + array $mountpoints, + CappedMemoryCache $folderExistCache, + ) { $mountPoint = basename($share->getTarget()); $parent = dirname($share->getTarget()); $event = new VerifyMountPointEvent($share, $this->recipientView, $parent); - /** @var IEventDispatcher $dispatcher */ - $dispatcher = \OC::$server->query(IEventDispatcher::class); - $dispatcher->dispatchTyped($event); + $this->eventDispatcher->dispatchTyped($event); $parent = $event->getParent(); - if ($folderExistCache->hasKey($parent)) { - $parentExists = $folderExistCache->get($parent); + $cached = $folderExistCache->get($parent); + if ($cached) { + $parentExists = $cached; } else { $parentExists = $this->recipientView->is_dir($parent); $folderExistCache->set($parent, $parentExists); } if (!$parentExists) { - $parent = Helper::getShareFolder($this->recipientView); + $parent = Helper::getShareFolder($this->recipientView, $this->user->getUID()); } $newMountPoint = $this->generateUniqueTarget( - \OC\Files\Filesystem::normalizePath($parent . '/' . $mountPoint), + Filesystem::normalizePath($parent . '/' . $mountPoint), $this->recipientView, $mountpoints ); @@ -126,7 +112,7 @@ class SharedMount extends MountPoint implements MoveableMount { * update fileTarget in the database if the mount point changed * * @param string $newPath - * @param \OCP\Share\IShare $share + * @param IShare $share * @return bool */ private function updateFileTarget($newPath, &$share) { @@ -134,8 +120,10 @@ class SharedMount extends MountPoint implements MoveableMount { foreach ($this->groupedShares as $tmpShare) { $tmpShare->setTarget($newPath); - \OC::$server->getShareManager()->moveShare($tmpShare, $this->user); + Server::get(\OCP\Share\IManager::class)->moveShare($tmpShare, $this->user->getUID()); } + + $this->eventDispatcher->dispatchTyped(new InvalidateMountCacheEvent($this->user)); } @@ -167,7 +155,7 @@ class SharedMount extends MountPoint implements MoveableMount { * * @param string $path the absolute path * @return string e.g. turns '/admin/files/test.txt' into '/test.txt' - * @throws \OCA\Files_Sharing\Exceptions\BrokenPath + * @throws BrokenPath */ protected function stripUserFilesPath($path) { $trimmed = ltrim($path, '/'); @@ -175,8 +163,8 @@ class SharedMount extends MountPoint implements MoveableMount { // it is not a file relative to data/user/files if (count($split) < 3 || $split[1] !== 'files') { - \OC::$server->getLogger()->error('Can not strip userid and "files/" from path: ' . $path, ['app' => 'files_sharing']); - throw new \OCA\Files_Sharing\Exceptions\BrokenPath('Path does not start with /user/files', 10); + Server::get(LoggerInterface::class)->error('Can not strip userid and "files/" from path: ' . $path, ['app' => 'files_sharing']); + throw new BrokenPath('Path does not start with /user/files', 10); } // skip 'user' and 'files' @@ -203,7 +191,13 @@ class SharedMount extends MountPoint implements MoveableMount { $this->setMountPoint($target); $this->storage->setMountPoint($relTargetPath); } catch (\Exception $e) { - \OC::$server->getLogger()->logException($e, ['app' => 'files_sharing', 'message' => 'Could not rename mount point for shared folder "' . $this->getMountPoint() . '" to "' . $target . '"']); + Server::get(LoggerInterface::class)->error( + 'Could not rename mount point for shared folder "' . $this->getMountPoint() . '" to "' . $target . '"', + [ + 'app' => 'files_sharing', + 'exception' => $e, + ] + ); } return $result; @@ -215,8 +209,8 @@ class SharedMount extends MountPoint implements MoveableMount { * @return bool */ public function removeMount() { - $mountManager = \OC\Files\Filesystem::getMountManager(); - /** @var \OCA\Files_Sharing\SharedStorage $storage */ + $mountManager = Filesystem::getMountManager(); + /** @var SharedStorage $storage */ $storage = $this->getStorage(); $result = $storage->unshareStorage(); $mountManager->removeMount($this->mountPoint); @@ -225,13 +219,20 @@ class SharedMount extends MountPoint implements MoveableMount { } /** - * @return \OCP\Share\IShare + * @return IShare */ public function getShare() { return $this->superShare; } /** + * @return IShare[] + */ + public function getGroupedShares(): array { + return $this->groupedShares; + } + + /** * Get the file id of the root of the storage * * @return int @@ -247,13 +248,13 @@ class SharedMount extends MountPoint implements MoveableMount { if (!is_null($this->getShare()->getNodeCacheEntry())) { return $this->getShare()->getNodeCacheEntry()->getStorageId(); } else { - $builder = \OC::$server->getDatabaseConnection()->getQueryBuilder(); + $builder = Server::get(IDBConnection::class)->getQueryBuilder(); $query = $builder->select('storage') ->from('filecache') ->where($builder->expr()->eq('fileid', $builder->createNamedParameter($this->getStorageRootId()))); - $result = $query->execute(); + $result = $query->executeQuery(); $row = $result->fetch(); $result->closeCursor(); if ($row) { |