Skip to content

Commit d80a3a7

Browse files
authored
Merge pull request #57760 from nextcloud/share-update-check-single
Active share validation/authoritative mount improvements
2 parents 8f9b11e + e548d71 commit d80a3a7

42 files changed

Lines changed: 1768 additions & 157 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/files/lib/Command/Mount/ListMounts.php

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,18 @@
88

99
namespace OCA\Files\Command\Mount;
1010

11+
use OC\Core\Command\Base;
1112
use OCP\Files\Config\ICachedMountInfo;
1213
use OCP\Files\Config\IMountProviderCollection;
1314
use OCP\Files\Config\IUserMountCache;
1415
use OCP\Files\Mount\IMountPoint;
1516
use OCP\IUserManager;
16-
use Symfony\Component\Console\Command\Command;
1717
use Symfony\Component\Console\Input\InputArgument;
1818
use Symfony\Component\Console\Input\InputInterface;
19+
use Symfony\Component\Console\Input\InputOption;
1920
use Symfony\Component\Console\Output\OutputInterface;
2021

21-
class ListMounts extends Command {
22+
class ListMounts extends Base {
2223
public function __construct(
2324
private readonly IUserManager $userManager,
2425
private readonly IUserMountCache $userMountCache,
@@ -28,52 +29,81 @@ public function __construct(
2829
}
2930

3031
protected function configure(): void {
32+
parent::configure();
3133
$this
3234
->setName('files:mount:list')
3335
->setDescription('List of mounts for a user')
34-
->addArgument('user', InputArgument::REQUIRED, 'User to list mounts for');
36+
->addArgument('user', InputArgument::REQUIRED, 'User to list mounts for')
37+
->addOption('cached-only', null, InputOption::VALUE_NONE, 'Only return cached mounts, prevents filesystem setup');
3538
}
3639

3740
public function execute(InputInterface $input, OutputInterface $output): int {
3841
$userId = $input->getArgument('user');
42+
$cachedOnly = $input->getOption('cached-only');
3943
$user = $this->userManager->get($userId);
4044
if (!$user) {
4145
$output->writeln("<error>User $userId not found</error>");
4246
return 1;
4347
}
4448

45-
$mounts = $this->mountProviderCollection->getMountsForUser($user);
46-
$mounts[] = $this->mountProviderCollection->getHomeMountForUser($user);
47-
/** @var array<string, IMountPoint> $cachedByMountpoint */
48-
$mountsByMountpoint = array_combine(array_map(fn (IMountPoint $mount) => $mount->getMountPoint(), $mounts), $mounts);
49+
if ($cachedOnly) {
50+
$mounts = [];
51+
} else {
52+
$mounts = $this->mountProviderCollection->getMountsForUser($user);
53+
$mounts[] = $this->mountProviderCollection->getHomeMountForUser($user);
54+
}
55+
/** @var array<string, IMountPoint> $cachedByMountPoint */
56+
$mountsByMountPoint = array_combine(array_map(fn (IMountPoint $mount) => $mount->getMountPoint(), $mounts), $mounts);
4957
usort($mounts, fn (IMountPoint $a, IMountPoint $b) => $a->getMountPoint() <=> $b->getMountPoint());
5058

5159
$cachedMounts = $this->userMountCache->getMountsForUser($user);
5260
usort($cachedMounts, fn (ICachedMountInfo $a, ICachedMountInfo $b) => $a->getMountPoint() <=> $b->getMountPoint());
5361
/** @var array<string, ICachedMountInfo> $cachedByMountpoint */
54-
$cachedByMountpoint = array_combine(array_map(fn (ICachedMountInfo $mount) => $mount->getMountPoint(), $cachedMounts), $cachedMounts);
62+
$cachedByMountPoint = array_combine(array_map(fn (ICachedMountInfo $mount) => $mount->getMountPoint(), $cachedMounts), $cachedMounts);
63+
64+
$format = $input->getOption('output');
5565

56-
foreach ($mounts as $mount) {
57-
$output->writeln('<info>' . $mount->getMountPoint() . '</info>: ' . $mount->getStorageId());
58-
if (isset($cachedByMountpoint[$mount->getMountPoint()])) {
59-
$cached = $cachedByMountpoint[$mount->getMountPoint()];
60-
$output->writeln("\t- provider: " . $cached->getMountProvider());
61-
$output->writeln("\t- storage id: " . $cached->getStorageId());
62-
$output->writeln("\t- root id: " . $cached->getRootId());
63-
} else {
64-
$output->writeln("\t<error>not registered</error>");
66+
if ($format === self::OUTPUT_FORMAT_PLAIN) {
67+
foreach ($mounts as $mount) {
68+
$output->writeln('<info>' . $mount->getMountPoint() . '</info>: ' . $mount->getStorageId());
69+
if (isset($cachedByMountPoint[$mount->getMountPoint()])) {
70+
$cached = $cachedByMountPoint[$mount->getMountPoint()];
71+
$output->writeln("\t- provider: " . $cached->getMountProvider());
72+
$output->writeln("\t- storage id: " . $cached->getStorageId());
73+
$output->writeln("\t- root id: " . $cached->getRootId());
74+
} else {
75+
$output->writeln("\t<error>not registered</error>");
76+
}
6577
}
66-
}
67-
foreach ($cachedMounts as $cachedMount) {
68-
if (!isset($mountsByMountpoint[$cachedMount->getMountPoint()])) {
69-
$output->writeln('<info>' . $cachedMount->getMountPoint() . '</info>:');
70-
$output->writeln("\t<error>registered but no longer provided</error>");
71-
$output->writeln("\t- provider: " . $cachedMount->getMountProvider());
72-
$output->writeln("\t- storage id: " . $cachedMount->getStorageId());
73-
$output->writeln("\t- root id: " . $cachedMount->getRootId());
78+
foreach ($cachedMounts as $cachedMount) {
79+
if ($cachedOnly || !isset($mountsByMountPoint[$cachedMount->getMountPoint()])) {
80+
$output->writeln('<info>' . $cachedMount->getMountPoint() . '</info>:');
81+
if (!$cachedOnly) {
82+
$output->writeln("\t<error>registered but no longer provided</error>");
83+
}
84+
$output->writeln("\t- provider: " . $cachedMount->getMountProvider());
85+
$output->writeln("\t- storage id: " . $cachedMount->getStorageId());
86+
$output->writeln("\t- root id: " . $cachedMount->getRootId());
87+
}
7488
}
89+
} else {
90+
$cached = array_map(fn (ICachedMountInfo $cachedMountInfo) => [
91+
'mountpoint' => $cachedMountInfo->getMountPoint(),
92+
'provider' => $cachedMountInfo->getMountProvider(),
93+
'storage_id' => $cachedMountInfo->getStorageId(),
94+
'root_id' => $cachedMountInfo->getRootId(),
95+
], $cachedMounts);
96+
$provided = array_map(fn (IMountPoint $cachedMountInfo) => [
97+
'mountpoint' => $cachedMountInfo->getMountPoint(),
98+
'provider' => $cachedMountInfo->getMountProvider(),
99+
'storage_id' => $cachedMountInfo->getStorageId(),
100+
'root_id' => $cachedMountInfo->getStorageRootId(),
101+
], $mounts);
102+
$this->writeArrayInOutputFormat($input, $output, array_filter([
103+
'cached' => $cached,
104+
'provided' => $cachedOnly ? null : $provided,
105+
]));
75106
}
76-
77107
return 0;
78108
}
79109

apps/files/lib/Service/OwnershipTransferService.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -577,14 +577,16 @@ private function restoreShares(
577577
$output->writeln('');
578578
}
579579

580-
private function transferIncomingShares(string $sourceUid,
580+
private function transferIncomingShares(
581+
string $sourceUid,
581582
string $destinationUid,
582583
array $sourceShares,
583584
array $destinationShares,
584585
OutputInterface $output,
585586
string $path,
586587
string $finalTarget,
587-
bool $move): void {
588+
bool $move,
589+
): void {
588590
$output->writeln('Restoring incoming shares ...');
589591
$progress = new ProgressBar($output, count($sourceShares));
590592
$prefix = "$destinationUid/files";
@@ -623,8 +625,11 @@ private function transferIncomingShares(string $sourceUid,
623625
if ($move) {
624626
continue;
625627
}
628+
$oldMountPoint = $this->getShareMountPoint($destinationUid, $share->getTarget());
629+
$newMountPoint = $this->getShareMountPoint($destinationUid, $shareTarget);
626630
$share->setTarget($shareTarget);
627631
$this->shareManager->moveShare($share, $destinationUid);
632+
$this->mountManager->moveMount($oldMountPoint, $newMountPoint);
628633
continue;
629634
}
630635
$this->shareManager->deleteShare($share);
@@ -642,8 +647,11 @@ private function transferIncomingShares(string $sourceUid,
642647
if ($move) {
643648
continue;
644649
}
650+
$oldMountPoint = $this->getShareMountPoint($destinationUid, $share->getTarget());
651+
$newMountPoint = $this->getShareMountPoint($destinationUid, $shareTarget);
645652
$share->setTarget($shareTarget);
646653
$this->shareManager->moveShare($share, $destinationUid);
654+
$this->mountManager->moveMount($oldMountPoint, $newMountPoint);
647655
continue;
648656
}
649657
} catch (NotFoundException $e) {
@@ -656,4 +664,8 @@ private function transferIncomingShares(string $sourceUid,
656664
$progress->finish();
657665
$output->writeln('');
658666
}
667+
668+
private function getShareMountPoint(string $uid, string $target): string {
669+
return '/' . $uid . '/files/' . trim($target, '/') . '/';
670+
}
659671
}

apps/files_external/lib/Service/MountCacheService.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public function handle(Event $event): void {
7575

7676
public function handleDeletedStorage(StorageConfig $storage): void {
7777
foreach ($this->applicableHelper->getUsersForStorage($storage) as $user) {
78-
$this->userMountCache->removeMount($storage->getMountPointForUser($user));
78+
$this->userMountCache->removeMount($storage->getMountPointForUser($user), $user);
7979
}
8080
}
8181

@@ -87,7 +87,7 @@ public function handleAddedStorage(StorageConfig $storage): void {
8787

8888
public function handleUpdatedStorage(StorageConfig $oldStorage, StorageConfig $newStorage): void {
8989
foreach ($this->applicableHelper->diffApplicable($oldStorage, $newStorage) as $user) {
90-
$this->userMountCache->removeMount($oldStorage->getMountPointForUser($user));
90+
$this->userMountCache->removeMount($oldStorage->getMountPointForUser($user), $user);
9191
}
9292
foreach ($this->applicableHelper->diffApplicable($newStorage, $oldStorage) as $user) {
9393
$this->registerForUser($user, $newStorage);
@@ -156,7 +156,7 @@ private function handleUserRemoved(IGroup $group, IUser $user): void {
156156
$storages = $this->storagesService->getAllStoragesForGroup($group);
157157
foreach ($storages as $storage) {
158158
if (!$this->applicableHelper->isApplicableForUser($storage, $user)) {
159-
$this->userMountCache->removeMount($storage->getMountPointForUser($user));
159+
$this->userMountCache->removeMount($storage->getMountPointForUser($user), $user);
160160
}
161161
}
162162
}
@@ -181,7 +181,7 @@ private function handleGroupDeleted(IGroup $group): void {
181181
private function removeGroupFromStorage(StorageConfig $storage, IGroup $group): void {
182182
foreach ($group->searchUsers('') as $user) {
183183
if (!$this->applicableHelper->isApplicableForUser($storage, $user)) {
184-
$this->userMountCache->removeMount($storage->getMountPointForUser($user));
184+
$this->userMountCache->removeMount($storage->getMountPointForUser($user), $user);
185185
}
186186
}
187187
}

apps/files_sharing/composer/composer/autoload_classmap.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
'OCA\\Files_Sharing\\Listener\\ShareInteractionListener' => $baseDir . '/../lib/Listener/ShareInteractionListener.php',
7373
'OCA\\Files_Sharing\\Listener\\SharesUpdatedListener' => $baseDir . '/../lib/Listener/SharesUpdatedListener.php',
7474
'OCA\\Files_Sharing\\Listener\\UserAddedToGroupListener' => $baseDir . '/../lib/Listener/UserAddedToGroupListener.php',
75+
'OCA\\Files_Sharing\\Listener\\UserHomeSetupListener' => $baseDir . '/../lib/Listener/UserHomeSetupListener.php',
7576
'OCA\\Files_Sharing\\Listener\\UserShareAcceptanceListener' => $baseDir . '/../lib/Listener/UserShareAcceptanceListener.php',
7677
'OCA\\Files_Sharing\\Middleware\\OCSShareAPIMiddleware' => $baseDir . '/../lib/Middleware/OCSShareAPIMiddleware.php',
7778
'OCA\\Files_Sharing\\Middleware\\ShareInfoMiddleware' => $baseDir . '/../lib/Middleware/ShareInfoMiddleware.php',
@@ -96,6 +97,7 @@
9697
'OCA\\Files_Sharing\\ResponseDefinitions' => $baseDir . '/../lib/ResponseDefinitions.php',
9798
'OCA\\Files_Sharing\\Scanner' => $baseDir . '/../lib/Scanner.php',
9899
'OCA\\Files_Sharing\\Settings\\Personal' => $baseDir . '/../lib/Settings/Personal.php',
100+
'OCA\\Files_Sharing\\ShareRecipientUpdater' => $baseDir . '/../lib/ShareRecipientUpdater.php',
99101
'OCA\\Files_Sharing\\ShareTargetValidator' => $baseDir . '/../lib/ShareTargetValidator.php',
100102
'OCA\\Files_Sharing\\SharedMount' => $baseDir . '/../lib/SharedMount.php',
101103
'OCA\\Files_Sharing\\SharedStorage' => $baseDir . '/../lib/SharedStorage.php',

apps/files_sharing/composer/composer/autoload_static.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ class ComposerStaticInitFiles_Sharing
8787
'OCA\\Files_Sharing\\Listener\\ShareInteractionListener' => __DIR__ . '/..' . '/../lib/Listener/ShareInteractionListener.php',
8888
'OCA\\Files_Sharing\\Listener\\SharesUpdatedListener' => __DIR__ . '/..' . '/../lib/Listener/SharesUpdatedListener.php',
8989
'OCA\\Files_Sharing\\Listener\\UserAddedToGroupListener' => __DIR__ . '/..' . '/../lib/Listener/UserAddedToGroupListener.php',
90+
'OCA\\Files_Sharing\\Listener\\UserHomeSetupListener' => __DIR__ . '/..' . '/../lib/Listener/UserHomeSetupListener.php',
9091
'OCA\\Files_Sharing\\Listener\\UserShareAcceptanceListener' => __DIR__ . '/..' . '/../lib/Listener/UserShareAcceptanceListener.php',
9192
'OCA\\Files_Sharing\\Middleware\\OCSShareAPIMiddleware' => __DIR__ . '/..' . '/../lib/Middleware/OCSShareAPIMiddleware.php',
9293
'OCA\\Files_Sharing\\Middleware\\ShareInfoMiddleware' => __DIR__ . '/..' . '/../lib/Middleware/ShareInfoMiddleware.php',
@@ -111,6 +112,7 @@ class ComposerStaticInitFiles_Sharing
111112
'OCA\\Files_Sharing\\ResponseDefinitions' => __DIR__ . '/..' . '/../lib/ResponseDefinitions.php',
112113
'OCA\\Files_Sharing\\Scanner' => __DIR__ . '/..' . '/../lib/Scanner.php',
113114
'OCA\\Files_Sharing\\Settings\\Personal' => __DIR__ . '/..' . '/../lib/Settings/Personal.php',
115+
'OCA\\Files_Sharing\\ShareRecipientUpdater' => __DIR__ . '/..' . '/../lib/ShareRecipientUpdater.php',
114116
'OCA\\Files_Sharing\\ShareTargetValidator' => __DIR__ . '/..' . '/../lib/ShareTargetValidator.php',
115117
'OCA\\Files_Sharing\\SharedMount' => __DIR__ . '/..' . '/../lib/SharedMount.php',
116118
'OCA\\Files_Sharing\\SharedStorage' => __DIR__ . '/..' . '/../lib/SharedStorage.php',

apps/files_sharing/lib/AppInfo/Application.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
use OCA\Files_Sharing\Listener\ShareInteractionListener;
2727
use OCA\Files_Sharing\Listener\SharesUpdatedListener;
2828
use OCA\Files_Sharing\Listener\UserAddedToGroupListener;
29+
use OCA\Files_Sharing\Listener\UserHomeSetupListener;
2930
use OCA\Files_Sharing\Listener\UserShareAcceptanceListener;
3031
use OCA\Files_Sharing\Middleware\OCSShareAPIMiddleware;
3132
use OCA\Files_Sharing\Middleware\ShareInfoMiddleware;
@@ -45,6 +46,8 @@
4546
use OCP\Files\Events\BeforeDirectFileDownloadEvent;
4647
use OCP\Files\Events\BeforeZipCreatedEvent;
4748
use OCP\Files\Events\Node\BeforeNodeReadEvent;
49+
use OCP\Files\Events\UserHomeSetupEvent;
50+
use OCP\Group\Events\BeforeGroupDeletedEvent;
4851
use OCP\Group\Events\GroupChangedEvent;
4952
use OCP\Group\Events\GroupDeletedEvent;
5053
use OCP\Group\Events\UserAddedEvent;
@@ -54,6 +57,7 @@
5457
use OCP\IGroup;
5558
use OCP\Share\Events\BeforeShareDeletedEvent;
5659
use OCP\Share\Events\ShareCreatedEvent;
60+
use OCP\Share\Events\ShareMovedEvent;
5761
use OCP\Share\Events\ShareTransferredEvent;
5862
use OCP\User\Events\UserChangedEvent;
5963
use OCP\User\Events\UserDeletedEvent;
@@ -119,7 +123,11 @@ function () use ($c) {
119123
$context->registerEventListener(ShareTransferredEvent::class, SharesUpdatedListener::class);
120124
$context->registerEventListener(UserAddedEvent::class, SharesUpdatedListener::class);
121125
$context->registerEventListener(UserRemovedEvent::class, SharesUpdatedListener::class);
126+
$context->registerEventListener(BeforeGroupDeletedEvent::class, SharesUpdatedListener::class);
127+
$context->registerEventListener(GroupDeletedEvent::class, SharesUpdatedListener::class);
122128
$context->registerEventListener(UserShareAccessUpdatedEvent::class, SharesUpdatedListener::class);
129+
$context->registerEventListener(ShareMovedEvent::class, SharesUpdatedListener::class);
130+
$context->registerEventListener(UserHomeSetupEvent::class, UserHomeSetupListener::class);
123131

124132
$context->registerConfigLexicon(ConfigLexicon::class);
125133
}

apps/files_sharing/lib/Config/ConfigLexicon.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ class ConfigLexicon implements ILexicon {
2424
public const SHOW_FEDERATED_AS_INTERNAL = 'show_federated_shares_as_internal';
2525
public const SHOW_FEDERATED_TO_TRUSTED_AS_INTERNAL = 'show_federated_shares_to_trusted_servers_as_internal';
2626
public const EXCLUDE_RESHARE_FROM_EDIT = 'shareapi_exclude_reshare_from_edit';
27+
public const UPDATE_CUTOFF_TIME = 'update_cutoff_time';
28+
public const USER_NEEDS_SHARE_REFRESH = 'user_needs_share_refresh';
2729

2830
public function getStrictness(): Strictness {
2931
return Strictness::IGNORE;
@@ -34,10 +36,14 @@ public function getAppConfigs(): array {
3436
new Entry(self::SHOW_FEDERATED_AS_INTERNAL, ValueType::BOOL, false, 'shows federated shares as internal shares', true),
3537
new Entry(self::SHOW_FEDERATED_TO_TRUSTED_AS_INTERNAL, ValueType::BOOL, false, 'shows federated shares to trusted servers as internal shares', true),
3638
new Entry(self::EXCLUDE_RESHARE_FROM_EDIT, ValueType::BOOL, false, 'Exclude reshare permission from "Allow editing" bundled permissions'),
39+
40+
new Entry(self::UPDATE_CUTOFF_TIME, ValueType::FLOAT, 3.0, 'Maximum time in second during which we update the share data immediately before switching to only marking the user'),
3741
];
3842
}
3943

4044
public function getUserConfigs(): array {
41-
return [];
45+
return [
46+
new Entry(self::USER_NEEDS_SHARE_REFRESH, ValueType::BOOL, true, 'whether a user needs to have the receiving share data refreshed for possible changes'),
47+
];
4248
}
4349
}

0 commit comments

Comments
 (0)