mirror of
https://github.com/nextcloud/server.git
synced 2026-06-08 16:26:59 -04:00
feat: postpone receiving share validation after processing a certain number of users
Signed-off-by: Robin Appelman <robin@icewind.nl>
This commit is contained in:
parent
e3060179fc
commit
08bec7ef05
6 changed files with 105 additions and 7 deletions
|
|
@ -72,6 +72,7 @@ return array(
|
|||
'OCA\\Files_Sharing\\Listener\\ShareInteractionListener' => $baseDir . '/../lib/Listener/ShareInteractionListener.php',
|
||||
'OCA\\Files_Sharing\\Listener\\SharesUpdatedListener' => $baseDir . '/../lib/Listener/SharesUpdatedListener.php',
|
||||
'OCA\\Files_Sharing\\Listener\\UserAddedToGroupListener' => $baseDir . '/../lib/Listener/UserAddedToGroupListener.php',
|
||||
'OCA\\Files_Sharing\\Listener\\UserHomeSetupListener' => $baseDir . '/../lib/Listener/UserHomeSetupListener.php',
|
||||
'OCA\\Files_Sharing\\Listener\\UserShareAcceptanceListener' => $baseDir . '/../lib/Listener/UserShareAcceptanceListener.php',
|
||||
'OCA\\Files_Sharing\\Middleware\\OCSShareAPIMiddleware' => $baseDir . '/../lib/Middleware/OCSShareAPIMiddleware.php',
|
||||
'OCA\\Files_Sharing\\Middleware\\ShareInfoMiddleware' => $baseDir . '/../lib/Middleware/ShareInfoMiddleware.php',
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ class ComposerStaticInitFiles_Sharing
|
|||
'OCA\\Files_Sharing\\Listener\\ShareInteractionListener' => __DIR__ . '/..' . '/../lib/Listener/ShareInteractionListener.php',
|
||||
'OCA\\Files_Sharing\\Listener\\SharesUpdatedListener' => __DIR__ . '/..' . '/../lib/Listener/SharesUpdatedListener.php',
|
||||
'OCA\\Files_Sharing\\Listener\\UserAddedToGroupListener' => __DIR__ . '/..' . '/../lib/Listener/UserAddedToGroupListener.php',
|
||||
'OCA\\Files_Sharing\\Listener\\UserHomeSetupListener' => __DIR__ . '/..' . '/../lib/Listener/UserHomeSetupListener.php',
|
||||
'OCA\\Files_Sharing\\Listener\\UserShareAcceptanceListener' => __DIR__ . '/..' . '/../lib/Listener/UserShareAcceptanceListener.php',
|
||||
'OCA\\Files_Sharing\\Middleware\\OCSShareAPIMiddleware' => __DIR__ . '/..' . '/../lib/Middleware/OCSShareAPIMiddleware.php',
|
||||
'OCA\\Files_Sharing\\Middleware\\ShareInfoMiddleware' => __DIR__ . '/..' . '/../lib/Middleware/ShareInfoMiddleware.php',
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ use OCA\Files_Sharing\Listener\LoadSidebarListener;
|
|||
use OCA\Files_Sharing\Listener\ShareInteractionListener;
|
||||
use OCA\Files_Sharing\Listener\SharesUpdatedListener;
|
||||
use OCA\Files_Sharing\Listener\UserAddedToGroupListener;
|
||||
use OCA\Files_Sharing\Listener\UserHomeSetupListener;
|
||||
use OCA\Files_Sharing\Listener\UserShareAcceptanceListener;
|
||||
use OCA\Files_Sharing\Middleware\OCSShareAPIMiddleware;
|
||||
use OCA\Files_Sharing\Middleware\ShareInfoMiddleware;
|
||||
|
|
@ -48,6 +49,7 @@ use OCP\Files\Config\IMountProviderCollection;
|
|||
use OCP\Files\Events\BeforeDirectFileDownloadEvent;
|
||||
use OCP\Files\Events\BeforeZipCreatedEvent;
|
||||
use OCP\Files\Events\Node\BeforeNodeReadEvent;
|
||||
use OCP\Files\Events\UserHomeSetupEvent;
|
||||
use OCP\Group\Events\GroupChangedEvent;
|
||||
use OCP\Group\Events\GroupDeletedEvent;
|
||||
use OCP\Group\Events\UserAddedEvent;
|
||||
|
|
@ -123,6 +125,7 @@ class Application extends App implements IBootstrap {
|
|||
$context->registerEventListener(UserAddedEvent::class, SharesUpdatedListener::class);
|
||||
$context->registerEventListener(UserRemovedEvent::class, SharesUpdatedListener::class);
|
||||
$context->registerEventListener(UserShareAccessUpdatedEvent::class, SharesUpdatedListener::class);
|
||||
$context->registerEventListener(UserHomeSetupEvent::class, UserHomeSetupListener::class);
|
||||
|
||||
$context->registerConfigLexicon(ConfigLexicon::class);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ class ConfigLexicon implements ILexicon {
|
|||
public const SHOW_FEDERATED_AS_INTERNAL = 'show_federated_shares_as_internal';
|
||||
public const SHOW_FEDERATED_TO_TRUSTED_AS_INTERNAL = 'show_federated_shares_to_trusted_servers_as_internal';
|
||||
public const EXCLUDE_RESHARE_FROM_EDIT = 'shareapi_exclude_reshare_from_edit';
|
||||
public const UPDATE_SINGLE_CUTOFF = 'update_single_cutoff';
|
||||
public const UPDATE_ALL_CUTOFF = 'update_all_cutoff';
|
||||
public const USER_NEEDS_SHARE_REFRESH = 'user_needs_share_refresh';
|
||||
|
||||
public function getStrictness(): Strictness {
|
||||
return Strictness::IGNORE;
|
||||
|
|
@ -34,10 +37,15 @@ class ConfigLexicon implements ILexicon {
|
|||
new Entry(self::SHOW_FEDERATED_AS_INTERNAL, ValueType::BOOL, false, 'shows federated shares as internal shares', true),
|
||||
new Entry(self::SHOW_FEDERATED_TO_TRUSTED_AS_INTERNAL, ValueType::BOOL, false, 'shows federated shares to trusted servers as internal shares', true),
|
||||
new Entry(self::EXCLUDE_RESHARE_FROM_EDIT, ValueType::BOOL, false, 'Exclude reshare permission from "Allow editing" bundled permissions'),
|
||||
|
||||
new Entry(self::UPDATE_SINGLE_CUTOFF, ValueType::INT, 10, 'For how many users do we update the share data immediately for single-share updates'),
|
||||
new Entry(self::UPDATE_ALL_CUTOFF, ValueType::INT, 3, 'For how many users do we update the share data immediately for all-share updates'),
|
||||
];
|
||||
}
|
||||
|
||||
public function getUserConfigs(): array {
|
||||
return [];
|
||||
return [
|
||||
new Entry(self::USER_NEEDS_SHARE_REFRESH, ValueType::BOOL, false, 'whether a user needs to have the receiving share data refreshed for possible changes'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,12 +8,17 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Files_Sharing\Listener;
|
||||
|
||||
use OCA\Files_Sharing\AppInfo\Application;
|
||||
use OCA\Files_Sharing\Config\ConfigLexicon;
|
||||
use OCA\Files_Sharing\Event\UserShareAccessUpdatedEvent;
|
||||
use OCA\Files_Sharing\ShareRecipientUpdater;
|
||||
use OCP\Config\IUserConfig;
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\EventDispatcher\IEventListener;
|
||||
use OCP\Group\Events\UserAddedEvent;
|
||||
use OCP\Group\Events\UserRemovedEvent;
|
||||
use OCP\IAppConfig;
|
||||
use OCP\IUser;
|
||||
use OCP\Share\Events\BeforeShareDeletedEvent;
|
||||
use OCP\Share\Events\ShareCreatedEvent;
|
||||
use OCP\Share\Events\ShareTransferredEvent;
|
||||
|
|
@ -25,35 +30,71 @@ use OCP\Share\IManager;
|
|||
* @template-implements IEventListener<UserAddedEvent|UserRemovedEvent|ShareCreatedEvent|ShareTransferredEvent|BeforeShareDeletedEvent|UserShareAccessUpdatedEvent>
|
||||
*/
|
||||
class SharesUpdatedListener implements IEventListener {
|
||||
/**
|
||||
* for how many users do we update the share date immediately,
|
||||
* before just marking the other users when we know the relevant share
|
||||
*/
|
||||
private int $cutOffMarkAllSingleShare;
|
||||
/**
|
||||
* for how many users do we update the share date immediately,
|
||||
* before just marking the other users when the relevant shares are unknown
|
||||
*/
|
||||
private int $cutOffMarkAllShares ;
|
||||
|
||||
private int $updatedCount = 0;
|
||||
|
||||
public function __construct(
|
||||
private readonly IManager $shareManager,
|
||||
private readonly ShareRecipientUpdater $shareUpdater,
|
||||
private readonly IUserConfig $userConfig,
|
||||
IAppConfig $appConfig,
|
||||
) {
|
||||
$this->cutOffMarkAllSingleShare = $appConfig->getValueInt(Application::APP_ID, ConfigLexicon::UPDATE_SINGLE_CUTOFF, 10);
|
||||
$this->cutOffMarkAllShares = $appConfig->getValueInt(Application::APP_ID, ConfigLexicon::UPDATE_ALL_CUTOFF, 3);
|
||||
}
|
||||
|
||||
public function handle(Event $event): void {
|
||||
if ($event instanceof UserShareAccessUpdatedEvent) {
|
||||
foreach ($event->getUsers() as $user) {
|
||||
$this->shareUpdater->updateForUser($user, true);
|
||||
$this->updateOrMarkUser($user, true);
|
||||
}
|
||||
}
|
||||
if ($event instanceof UserAddedEvent || $event instanceof UserRemovedEvent) {
|
||||
$this->shareUpdater->updateForUser($event->getUser(), true);
|
||||
$this->updateOrMarkUser($event->getUser(), true);
|
||||
}
|
||||
if ($event instanceof ShareCreatedEvent || $event instanceof ShareTransferredEvent) {
|
||||
$share = $event->getShare();
|
||||
$shareTarget = $share->getTarget();
|
||||
foreach ($this->shareManager->getUsersForShare($share) as $user) {
|
||||
if ($share->getSharedBy() !== $user->getUID()) {
|
||||
$this->shareUpdater->updateForShare($user, $share);
|
||||
// Share target validation might have changed the target, restore it for the next user
|
||||
$share->setTarget($shareTarget);
|
||||
$this->updatedCount++;
|
||||
if ($this->updatedCount <= $this->cutOffMarkAllSingleShare) {
|
||||
$this->shareUpdater->updateForShare($user, $share);
|
||||
// Share target validation might have changed the target, restore it for the next user
|
||||
$share->setTarget($shareTarget);
|
||||
} else {
|
||||
$this->markUserForRefresh($user);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($event instanceof BeforeShareDeletedEvent) {
|
||||
foreach ($this->shareManager->getUsersForShare($event->getShare()) as $user) {
|
||||
$this->shareManager->updateForUser($user, false, [$event->getShare()]);
|
||||
$this->updateOrMarkUser($user, false, [$event->getShare()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function updateOrMarkUser(IUser $user, bool $verifyMountPoints, array $ignoreShares = []): void {
|
||||
$this->updatedCount++;
|
||||
if ($this->updatedCount <= $this->cutOffMarkAllShares) {
|
||||
$this->shareUpdater->updateForUser($user, $verifyMountPoints, $ignoreShares);
|
||||
} else {
|
||||
$this->markUserForRefresh($user);
|
||||
}
|
||||
}
|
||||
|
||||
private function markUserForRefresh(IUser $user): void {
|
||||
$this->userConfig->setValueBool($user->getUID(), Application::APP_ID, ConfigLexicon::USER_NEEDS_SHARE_REFRESH, true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
44
apps/files_sharing/lib/Listener/UserHomeSetupListener.php
Normal file
44
apps/files_sharing/lib/Listener/UserHomeSetupListener.php
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Files_Sharing\Listener;
|
||||
|
||||
use OCA\Files_Sharing\AppInfo\Application;
|
||||
use OCA\Files_Sharing\Config\ConfigLexicon;
|
||||
use OCA\Files_Sharing\ShareRecipientUpdater;
|
||||
use OCP\Config\IUserConfig;
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\EventDispatcher\IEventListener;
|
||||
use OCP\Files\Events\UserHomeSetupEvent;
|
||||
|
||||
/**
|
||||
* Listen to the users filesystem setup being started, to perform any receiving share
|
||||
* work that was postponed.
|
||||
*
|
||||
* @template-implements IEventListener<UserHomeSetupEvent>
|
||||
*/
|
||||
class UserHomeSetupListener implements IEventListener {
|
||||
public function __construct(
|
||||
private readonly ShareRecipientUpdater $updater,
|
||||
private readonly IUserConfig $userConfig,
|
||||
) {
|
||||
}
|
||||
|
||||
public function handle(Event $event): void {
|
||||
if (!$event instanceof UserHomeSetupEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user = $event->getUser();
|
||||
if ($this->userConfig->getValueBool($user->getUID(), Application::APP_ID, ConfigLexicon::USER_NEEDS_SHARE_REFRESH)) {
|
||||
$this->updater->updateForUser($user);
|
||||
$this->userConfig->setValueBool($user->getUID(), Application::APP_ID, ConfigLexicon::USER_NEEDS_SHARE_REFRESH, false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in a new issue