diff options
author | Kate <26026535+provokateurin@users.noreply.github.com> | 2024-11-25 14:41:40 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-25 14:41:40 +0100 |
commit | 235b7d7c26930367533f2e845bb2180ba9151608 (patch) | |
tree | 26c2c38d2a3a3fe687866fb617647983987d44f3 /lib | |
parent | 5088b910ec4a8c003ec22822741f1664eab90175 (diff) | |
parent | 7c3a78ad7695eeebe37ed0b15def92599bf43d2f (diff) | |
download | nextcloud-server-235b7d7c26930367533f2e845bb2180ba9151608.tar.gz nextcloud-server-235b7d7c26930367533f2e845bb2180ba9151608.zip |
Merge pull request #49073 from nextcloud/feat/files_sharing/co-owner
Diffstat (limited to 'lib')
-rw-r--r-- | lib/composer/composer/autoload_classmap.php | 1 | ||||
-rw-r--r-- | lib/composer/composer/autoload_static.php | 1 | ||||
-rw-r--r-- | lib/private/Share20/DefaultShareProvider.php | 4 | ||||
-rw-r--r-- | lib/private/Share20/Manager.php | 74 | ||||
-rw-r--r-- | lib/public/Files/Mount/IShareOwnerlessMount.php | 18 | ||||
-rw-r--r-- | lib/public/Share/IManager.php | 9 |
6 files changed, 82 insertions, 25 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index cc6b8be326c..5834bfd47b5 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -409,6 +409,7 @@ return array( 'OCP\\Files\\Mount\\IMountManager' => $baseDir . '/lib/public/Files/Mount/IMountManager.php', 'OCP\\Files\\Mount\\IMountPoint' => $baseDir . '/lib/public/Files/Mount/IMountPoint.php', 'OCP\\Files\\Mount\\IMovableMount' => $baseDir . '/lib/public/Files/Mount/IMovableMount.php', + 'OCP\\Files\\Mount\\IShareOwnerlessMount' => $baseDir . '/lib/public/Files/Mount/IShareOwnerlessMount.php', 'OCP\\Files\\Mount\\ISystemMountPoint' => $baseDir . '/lib/public/Files/Mount/ISystemMountPoint.php', 'OCP\\Files\\Node' => $baseDir . '/lib/public/Files/Node.php', 'OCP\\Files\\NotEnoughSpaceException' => $baseDir . '/lib/public/Files/NotEnoughSpaceException.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 54959bc6b91..e510e80d4c6 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -450,6 +450,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OCP\\Files\\Mount\\IMountManager' => __DIR__ . '/../../..' . '/lib/public/Files/Mount/IMountManager.php', 'OCP\\Files\\Mount\\IMountPoint' => __DIR__ . '/../../..' . '/lib/public/Files/Mount/IMountPoint.php', 'OCP\\Files\\Mount\\IMovableMount' => __DIR__ . '/../../..' . '/lib/public/Files/Mount/IMovableMount.php', + 'OCP\\Files\\Mount\\IShareOwnerlessMount' => __DIR__ . '/../../..' . '/lib/public/Files/Mount/IShareOwnerlessMount.php', 'OCP\\Files\\Mount\\ISystemMountPoint' => __DIR__ . '/../../..' . '/lib/public/Files/Mount/ISystemMountPoint.php', 'OCP\\Files\\Node' => __DIR__ . '/../../..' . '/lib/public/Files/Node.php', 'OCP\\Files\\NotEnoughSpaceException' => __DIR__ . '/../../..' . '/lib/public/Files/NotEnoughSpaceException.php', diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php index db2734190e4..40fbae541ce 100644 --- a/lib/private/Share20/DefaultShareProvider.php +++ b/lib/private/Share20/DefaultShareProvider.php @@ -798,13 +798,15 @@ class DefaultShareProvider implements IShareProviderWithNotification, IShareProv ->andWhere( $qb->expr()->orX( $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)), - $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)) + $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)), + $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_LINK)), ) ) ->andWhere($qb->expr()->orX( $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) )) + ->orderBy('id', 'ASC') ->executeQuery(); $shares = []; diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php index 4856c051307..4dadcdbfcd7 100644 --- a/lib/private/Share20/Manager.php +++ b/lib/private/Share20/Manager.php @@ -17,6 +17,7 @@ use OCP\Files\File; use OCP\Files\Folder; use OCP\Files\IRootFolder; use OCP\Files\Mount\IMountManager; +use OCP\Files\Mount\IShareOwnerlessMount; use OCP\Files\Node; use OCP\Files\NotFoundException; use OCP\HintException; @@ -785,13 +786,13 @@ class Manager implements IManager { * @throws \InvalidArgumentException * @throws GenericShareException */ - public function updateShare(IShare $share) { + public function updateShare(IShare $share, bool $onlyValid = true) { $expirationDateUpdated = false; $this->canShare($share); try { - $originalShare = $this->getShareById($share->getFullId()); + $originalShare = $this->getShareById($share->getFullId(), onlyValid: $onlyValid); } catch (\UnexpectedValueException $e) { throw new \InvalidArgumentException($this->l->t('Share does not have a full ID')); } @@ -1215,23 +1216,32 @@ class Manager implements IManager { throw new \Exception('non-shallow getSharesInFolder is no longer supported'); } - return array_reduce($providers, function ($shares, IShareProvider $provider) use ($userId, $node, $reshares) { - $newShares = $provider->getSharesInFolder($userId, $node, $reshares); - foreach ($newShares as $fid => $data) { - if (!isset($shares[$fid])) { - $shares[$fid] = []; - } + $isOwnerless = $node->getMountPoint() instanceof IShareOwnerlessMount; - $shares[$fid] = array_merge($shares[$fid], $data); + $shares = []; + foreach ($providers as $provider) { + if ($isOwnerless) { + foreach ($node->getDirectoryListing() as $childNode) { + $data = $provider->getSharesByPath($childNode); + $fid = $childNode->getId(); + $shares[$fid] ??= []; + $shares[$fid] = array_merge($shares[$fid], $data); + } + } else { + foreach ($provider->getSharesInFolder($userId, $node, $reshares) as $fid => $data) { + $shares[$fid] ??= []; + $shares[$fid] = array_merge($shares[$fid], $data); + } } - return $shares; - }, []); + } + + return $shares; } /** * @inheritdoc */ - public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0) { + public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0, bool $onlyValid = true) { if ($path !== null && !($path instanceof \OCP\Files\File) && !($path instanceof \OCP\Files\Folder)) { @@ -1244,7 +1254,11 @@ class Manager implements IManager { return []; } - $shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset); + if ($path?->getMountPoint() instanceof IShareOwnerlessMount) { + $shares = array_filter($provider->getSharesByPath($path), static fn (IShare $share) => $share->getShareType() === $shareType); + } else { + $shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset); + } /* * Work around so we don't return expired shares but still follow @@ -1256,11 +1270,13 @@ class Manager implements IManager { while (true) { $added = 0; foreach ($shares as $share) { - try { - $this->checkShare($share); - } catch (ShareNotFound $e) { - // Ignore since this basically means the share is deleted - continue; + if ($onlyValid) { + try { + $this->checkShare($share); + } catch (ShareNotFound $e) { + // Ignore since this basically means the share is deleted + continue; + } } $added++; @@ -1288,7 +1304,12 @@ class Manager implements IManager { $offset += $added; // Fetch again $limit shares - $shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset); + if ($path?->getMountPoint() instanceof IShareOwnerlessMount) { + // We already fetched all shares, so end here + $shares = []; + } else { + $shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset); + } // No more shares means we are done if (empty($shares)) { @@ -1347,7 +1368,7 @@ class Manager implements IManager { /** * @inheritdoc */ - public function getShareById($id, $recipient = null) { + public function getShareById($id, $recipient = null, bool $onlyValid = true) { if ($id === null) { throw new ShareNotFound(); } @@ -1362,7 +1383,9 @@ class Manager implements IManager { $share = $provider->getShareById($id, $recipient); - $this->checkShare($share); + if ($onlyValid) { + $this->checkShare($share); + } return $share; } @@ -1469,6 +1492,15 @@ class Manager implements IManager { $this->deleteShare($share); throw new ShareNotFound($this->l->t('The requested share does not exist anymore')); } + + try { + $share->getNode(); + // Ignore share, file is still accessible + } catch (NotFoundException) { + // Access lost, but maybe only temporarily, so don't delete the share right away + throw new ShareNotFound($this->l->t('The requested share does not exist anymore')); + } + if ($this->config->getAppValue('files_sharing', 'hide_disabled_user_shares', 'no') === 'yes') { $uids = array_unique([$share->getShareOwner(),$share->getSharedBy()]); foreach ($uids as $uid) { diff --git a/lib/public/Files/Mount/IShareOwnerlessMount.php b/lib/public/Files/Mount/IShareOwnerlessMount.php new file mode 100644 index 00000000000..b73ee620859 --- /dev/null +++ b/lib/public/Files/Mount/IShareOwnerlessMount.php @@ -0,0 +1,18 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\Files\Mount; + +/** + * Denotes that shares created under this mountpoint will be manageable by everyone with share permission. + * + * @since 31.0.0 + */ +interface IShareOwnerlessMount { +} diff --git a/lib/public/Share/IManager.php b/lib/public/Share/IManager.php index b07bc8f8051..c3a8494a5ac 100644 --- a/lib/public/Share/IManager.php +++ b/lib/public/Share/IManager.php @@ -41,11 +41,12 @@ interface IManager { * The state can't be changed this way: use acceptShare * * @param IShare $share + * @param bool $onlyValid Only updates valid shares, invalid shares will be deleted automatically and are not updated * @return IShare The share object * @throws \InvalidArgumentException * @since 9.0.0 */ - public function updateShare(IShare $share); + public function updateShare(IShare $share, bool $onlyValid = true); /** * Accept a share. @@ -127,10 +128,11 @@ interface IManager { * @param bool $reshares * @param int $limit The maximum number of returned results, -1 for all results * @param int $offset + * @param bool $onlyValid Only returns valid shares, invalid shares will be deleted automatically and are not returned * @return IShare[] * @since 9.0.0 */ - public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0); + public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0, bool $onlyValid = true); /** * Get shares shared with $user. @@ -168,11 +170,12 @@ interface IManager { * * @param string $id * @param string|null $recipient userID of the recipient + * @param bool $onlyValid Only returns valid shares, invalid shares will be deleted automatically and are not returned * @return IShare * @throws ShareNotFound * @since 9.0.0 */ - public function getShareById($id, $recipient = null); + public function getShareById($id, $recipient = null, bool $onlyValid = true); /** * Get the share by token possible with password |