Skip to content

Commit 867ef52

Browse files
authored
Merge pull request #57523 from nextcloud/authoritative-share-provider
Make share mount provider authoritative
2 parents e9bba6a + eb6f78e commit 867ef52

File tree

2 files changed

+32
-12
lines changed

2 files changed

+32
-12
lines changed

apps/files_sharing/lib/Listener/SharesUpdatedListener.php

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use OCP\EventDispatcher\IEventListener;
1616
use OCP\Files\Config\ICachedMountInfo;
1717
use OCP\Files\Config\IUserMountCache;
18+
use OCP\Files\Storage\IStorageFactory;
1819
use OCP\Group\Events\UserAddedEvent;
1920
use OCP\Group\Events\UserRemovedEvent;
2021
use OCP\IUser;
@@ -36,50 +37,64 @@ public function __construct(
3637
private readonly IUserMountCache $userMountCache,
3738
private readonly MountProvider $shareMountProvider,
3839
private readonly ShareTargetValidator $shareTargetValidator,
40+
private readonly IStorageFactory $storageFactory,
3941
) {
4042
}
4143
public function handle(Event $event): void {
4244
if ($event instanceof UserShareAccessUpdatedEvent) {
4345
foreach ($event->getUsers() as $user) {
44-
$this->updateForUser($user);
46+
$this->updateForUser($user, true);
4547
}
4648
}
4749
if ($event instanceof UserAddedEvent || $event instanceof UserRemovedEvent) {
48-
$this->updateForUser($event->getUser());
50+
$this->updateForUser($event->getUser(), true);
4951
}
5052
if (
5153
$event instanceof ShareCreatedEvent
52-
|| $event instanceof BeforeShareDeletedEvent
5354
|| $event instanceof ShareTransferredEvent
5455
) {
5556
foreach ($this->shareManager->getUsersForShare($event->getShare()) as $user) {
56-
$this->updateForUser($user);
57+
$this->updateForUser($user, true);
58+
}
59+
}
60+
if ($event instanceof BeforeShareDeletedEvent) {
61+
foreach ($this->shareManager->getUsersForShare($event->getShare()) as $user) {
62+
$this->updateForUser($user, false, [$event->getShare()]);
5763
}
5864
}
5965
}
6066

61-
private function updateForUser(IUser $user): void {
67+
private function updateForUser(IUser $user, bool $verifyMountPoints, array $ignoreShares = []): void {
6268
// prevent recursion
6369
if (isset($this->inUpdate[$user->getUID()])) {
6470
return;
6571
}
6672
$this->inUpdate[$user->getUID()] = true;
67-
6873
$cachedMounts = $this->userMountCache->getMountsForUser($user);
74+
$shareMounts = array_filter($cachedMounts, fn (ICachedMountInfo $mount) => $mount->getMountProvider() === MountProvider::class);
6975
$mountPoints = array_map(fn (ICachedMountInfo $mount) => $mount->getMountPoint(), $cachedMounts);
7076
$mountsByPath = array_combine($mountPoints, $cachedMounts);
7177

72-
$shares = $this->shareMountProvider->getSuperSharesForUser($user);
78+
$shares = $this->shareMountProvider->getSuperSharesForUser($user, $ignoreShares);
7379

80+
$mountsChanged = count($shares) !== count($shareMounts);
7481
foreach ($shares as &$share) {
7582
[$parentShare, $groupedShares] = $share;
7683
$mountPoint = '/' . $user->getUID() . '/files/' . trim($parentShare->getTarget(), '/') . '/';
7784
$mountKey = $parentShare->getNodeId() . '::' . $mountPoint;
7885
if (!isset($cachedMounts[$mountKey])) {
79-
$this->shareTargetValidator->verifyMountPoint($user, $parentShare, $mountsByPath, $groupedShares);
86+
$mountsChanged = true;
87+
if ($verifyMountPoints) {
88+
$this->shareTargetValidator->verifyMountPoint($user, $parentShare, $mountsByPath, $groupedShares);
89+
}
8090
}
8191
}
8292

93+
if ($mountsChanged) {
94+
$newMounts = $this->shareMountProvider->getMountsFromSuperShares($user, $shares, $this->storageFactory);
95+
$this->userMountCache->registerMounts($user, $newMounts, [MountProvider::class]);
96+
}
97+
8398
unset($this->inUpdate[$user->getUID()]);
8499
}
85100
}

apps/files_sharing/lib/MountProvider.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use OC\Files\View;
1313
use OCA\Files_Sharing\Event\ShareMountedEvent;
1414
use OCP\EventDispatcher\IEventDispatcher;
15+
use OCP\Files\Config\IAuthoritativeMountProvider;
1516
use OCP\Files\Config\IMountProvider;
1617
use OCP\Files\Config\IPartialMountProvider;
1718
use OCP\Files\Mount\IMountManager;
@@ -28,7 +29,7 @@
2829

2930
use function count;
3031

31-
class MountProvider implements IMountProvider, IPartialMountProvider {
32+
class MountProvider implements IMountProvider, IAuthoritativeMountProvider, IPartialMountProvider {
3233
public function __construct(
3334
protected readonly IConfig $config,
3435
protected readonly IManager $shareManager,
@@ -46,9 +47,10 @@ public function getMountsForUser(IUser $user, IStorageFactory $loader): array {
4647

4748
/**
4849
* @param IUser $user
50+
* @param list<IShare> $excludeShares
4951
* @return list<array{IShare, array<IShare>}> Tuple of [superShare, groupedShares]
5052
*/
51-
public function getSuperSharesForUser(IUser $user): array {
53+
public function getSuperSharesForUser(IUser $user, array $excludeShares = []): array {
5254
$userId = $user->getUID();
5355
$shares = $this->mergeIterables(
5456
$this->shareManager->getSharedWith($userId, IShare::TYPE_USER, null, -1),
@@ -58,7 +60,8 @@ public function getSuperSharesForUser(IUser $user): array {
5860
$this->shareManager->getSharedWith($userId, IShare::TYPE_DECK, null, -1),
5961
);
6062

61-
$shares = $this->filterShares($shares, $userId);
63+
$excludeShareIds = array_map(fn (IShare $share) => $share->getFullId(), $excludeShares);
64+
$shares = $this->filterShares($shares, $userId, $excludeShareIds);
6265
return $this->buildSuperShares($shares, $user);
6366
}
6467

@@ -318,14 +321,16 @@ public function getMountsFromSuperShares(
318321
* user has no permissions.
319322
*
320323
* @param iterable<IShare> $shares
324+
* @param list<string> $excludeShareIds
321325
* @return iterable<IShare>
322326
*/
323-
private function filterShares(iterable $shares, string $userId): iterable {
327+
private function filterShares(iterable $shares, string $userId, array $excludeShareIds = []): iterable {
324328
foreach ($shares as $share) {
325329
if (
326330
$share->getPermissions() > 0
327331
&& $share->getShareOwner() !== $userId
328332
&& $share->getSharedBy() !== $userId
333+
&& !in_array($share->getFullId(), $excludeShareIds)
329334
) {
330335
yield $share;
331336
}

0 commit comments

Comments
 (0)