mirror of
https://github.com/nextcloud/server.git
synced 2026-04-21 06:08:46 -04:00
Merge pull request #52987 from nextcloud/backport/50157/stable31
This commit is contained in:
commit
76d37a37f6
7 changed files with 179 additions and 24 deletions
|
|
@ -379,6 +379,9 @@ return array(
|
|||
'OCP\\Files\\Cache\\IScanner' => $baseDir . '/lib/public/Files/Cache/IScanner.php',
|
||||
'OCP\\Files\\Cache\\IUpdater' => $baseDir . '/lib/public/Files/Cache/IUpdater.php',
|
||||
'OCP\\Files\\Cache\\IWatcher' => $baseDir . '/lib/public/Files/Cache/IWatcher.php',
|
||||
'OCP\\Files\\Config\\Event\\UserMountAddedEvent' => $baseDir . '/lib/public/Files/Config/Event/UserMountAddedEvent.php',
|
||||
'OCP\\Files\\Config\\Event\\UserMountRemovedEvent' => $baseDir . '/lib/public/Files/Config/Event/UserMountRemovedEvent.php',
|
||||
'OCP\\Files\\Config\\Event\\UserMountUpdatedEvent' => $baseDir . '/lib/public/Files/Config/Event/UserMountUpdatedEvent.php',
|
||||
'OCP\\Files\\Config\\ICachedMountFileInfo' => $baseDir . '/lib/public/Files/Config/ICachedMountFileInfo.php',
|
||||
'OCP\\Files\\Config\\ICachedMountInfo' => $baseDir . '/lib/public/Files/Config/ICachedMountInfo.php',
|
||||
'OCP\\Files\\Config\\IHomeMountProvider' => $baseDir . '/lib/public/Files/Config/IHomeMountProvider.php',
|
||||
|
|
|
|||
|
|
@ -428,6 +428,9 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OCP\\Files\\Cache\\IScanner' => __DIR__ . '/../../..' . '/lib/public/Files/Cache/IScanner.php',
|
||||
'OCP\\Files\\Cache\\IUpdater' => __DIR__ . '/../../..' . '/lib/public/Files/Cache/IUpdater.php',
|
||||
'OCP\\Files\\Cache\\IWatcher' => __DIR__ . '/../../..' . '/lib/public/Files/Cache/IWatcher.php',
|
||||
'OCP\\Files\\Config\\Event\\UserMountAddedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Config/Event/UserMountAddedEvent.php',
|
||||
'OCP\\Files\\Config\\Event\\UserMountRemovedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Config/Event/UserMountRemovedEvent.php',
|
||||
'OCP\\Files\\Config\\Event\\UserMountUpdatedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Config/Event/UserMountUpdatedEvent.php',
|
||||
'OCP\\Files\\Config\\ICachedMountFileInfo' => __DIR__ . '/../../..' . '/lib/public/Files/Config/ICachedMountFileInfo.php',
|
||||
'OCP\\Files\\Config\\ICachedMountInfo' => __DIR__ . '/../../..' . '/lib/public/Files/Config/ICachedMountInfo.php',
|
||||
'OCP\\Files\\Config\\IHomeMountProvider' => __DIR__ . '/../../..' . '/lib/public/Files/Config/IHomeMountProvider.php',
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ use OC\User\LazyUser;
|
|||
use OCP\Cache\CappedMemoryCache;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\Diagnostics\IEventLogger;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Files\Config\Event\UserMountAddedEvent;
|
||||
use OCP\Files\Config\Event\UserMountRemovedEvent;
|
||||
use OCP\Files\Config\Event\UserMountUpdatedEvent;
|
||||
use OCP\Files\Config\ICachedMountFileInfo;
|
||||
use OCP\Files\Config\ICachedMountInfo;
|
||||
use OCP\Files\Config\IUserMountCache;
|
||||
|
|
@ -24,7 +28,6 @@ use Psr\Log\LoggerInterface;
|
|||
* Cache mounts points per user in the cache so we can easily look them up
|
||||
*/
|
||||
class UserMountCache implements IUserMountCache {
|
||||
|
||||
/**
|
||||
* Cached mount info.
|
||||
* @var CappedMemoryCache<ICachedMountInfo[]>
|
||||
|
|
@ -46,6 +49,7 @@ class UserMountCache implements IUserMountCache {
|
|||
private IUserManager $userManager,
|
||||
private LoggerInterface $logger,
|
||||
private IEventLogger $eventLogger,
|
||||
private IEventDispatcher $eventDispatcher,
|
||||
) {
|
||||
$this->cacheInfoCache = new CappedMemoryCache();
|
||||
$this->internalPathCache = new CappedMemoryCache();
|
||||
|
|
@ -106,16 +110,28 @@ class UserMountCache implements IUserMountCache {
|
|||
$this->removeFromCache($mount);
|
||||
unset($this->mountsForUsers[$userUID][$mount->getKey()]);
|
||||
}
|
||||
foreach ($changedMounts as $mount) {
|
||||
$this->updateCachedMount($mount);
|
||||
foreach ($changedMounts as $mountPair) {
|
||||
$newMount = $mountPair[1];
|
||||
$this->updateCachedMount($newMount);
|
||||
/** @psalm-suppress InvalidArgument */
|
||||
$this->mountsForUsers[$userUID][$mount->getKey()] = $mount;
|
||||
$this->mountsForUsers[$userUID][$newMount->getKey()] = $newMount;
|
||||
}
|
||||
$this->connection->commit();
|
||||
} catch (\Throwable $e) {
|
||||
$this->connection->rollBack();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
// Only fire events after all mounts have already been adjusted in the database.
|
||||
foreach ($addedMounts as $mount) {
|
||||
$this->eventDispatcher->dispatchTyped(new UserMountAddedEvent($mount));
|
||||
}
|
||||
foreach ($removedMounts as $mount) {
|
||||
$this->eventDispatcher->dispatchTyped(new UserMountRemovedEvent($mount));
|
||||
}
|
||||
foreach ($changedMounts as $mountPair) {
|
||||
$this->eventDispatcher->dispatchTyped(new UserMountUpdatedEvent($mountPair[0], $mountPair[1]));
|
||||
}
|
||||
}
|
||||
$this->eventLogger->end('fs:setup:user:register');
|
||||
}
|
||||
|
|
@ -123,9 +139,9 @@ class UserMountCache implements IUserMountCache {
|
|||
/**
|
||||
* @param array<string, ICachedMountInfo> $newMounts
|
||||
* @param array<string, ICachedMountInfo> $cachedMounts
|
||||
* @return ICachedMountInfo[]
|
||||
* @return list<list{0: ICachedMountInfo, 1: ICachedMountInfo}> Pairs of old and new mounts
|
||||
*/
|
||||
private function findChangedMounts(array $newMounts, array $cachedMounts) {
|
||||
private function findChangedMounts(array $newMounts, array $cachedMounts): array {
|
||||
$changed = [];
|
||||
foreach ($cachedMounts as $key => $cachedMount) {
|
||||
if (isset($newMounts[$key])) {
|
||||
|
|
@ -135,7 +151,7 @@ class UserMountCache implements IUserMountCache {
|
|||
$newMount->getMountId() !== $cachedMount->getMountId() ||
|
||||
$newMount->getMountProvider() !== $cachedMount->getMountProvider()
|
||||
) {
|
||||
$changed[] = $newMount;
|
||||
$changed[] = [$cachedMount, $newMount];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
27
lib/public/Files/Config/Event/UserMountAddedEvent.php
Normal file
27
lib/public/Files/Config/Event/UserMountAddedEvent.php
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCP\Files\Config\Event;
|
||||
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\Files\Config\ICachedMountInfo;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
|
||||
/**
|
||||
* Event emitted when a user mount was added.
|
||||
*
|
||||
* @since 30.0.12
|
||||
*/
|
||||
class UserMountAddedEvent extends Event {
|
||||
public function __construct(
|
||||
public readonly IMountPoint|ICachedMountInfo $mountPoint,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
}
|
||||
27
lib/public/Files/Config/Event/UserMountRemovedEvent.php
Normal file
27
lib/public/Files/Config/Event/UserMountRemovedEvent.php
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCP\Files\Config\Event;
|
||||
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\Files\Config\ICachedMountInfo;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
|
||||
/**
|
||||
* Event emitted when a user mount was removed.
|
||||
*
|
||||
* @since 30.0.12
|
||||
*/
|
||||
class UserMountRemovedEvent extends Event {
|
||||
public function __construct(
|
||||
public readonly IMountPoint|ICachedMountInfo $mountPoint,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
}
|
||||
28
lib/public/Files/Config/Event/UserMountUpdatedEvent.php
Normal file
28
lib/public/Files/Config/Event/UserMountUpdatedEvent.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCP\Files\Config\Event;
|
||||
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\Files\Config\ICachedMountInfo;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
|
||||
/**
|
||||
* Event emitted when a user mount was moved.
|
||||
*
|
||||
* @since 30.0.12
|
||||
*/
|
||||
class UserMountUpdatedEvent extends Event {
|
||||
public function __construct(
|
||||
public readonly IMountPoint|ICachedMountInfo $oldMountPoint,
|
||||
public readonly IMountPoint|ICachedMountInfo $newMountPoint,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ namespace Test\Files\Config;
|
|||
|
||||
use OC\DB\Exceptions\DbalException;
|
||||
use OC\DB\QueryBuilder\Literal;
|
||||
use OC\Files\Config\UserMountCache;
|
||||
use OC\Files\Mount\MountPoint;
|
||||
use OC\Files\Storage\Storage;
|
||||
use OC\User\Manager;
|
||||
|
|
@ -16,6 +17,9 @@ use OCP\Cache\CappedMemoryCache;
|
|||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\Diagnostics\IEventLogger;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Files\Config\Event\UserMountAddedEvent;
|
||||
use OCP\Files\Config\Event\UserMountRemovedEvent;
|
||||
use OCP\Files\Config\Event\UserMountUpdatedEvent;
|
||||
use OCP\Files\Config\ICachedMountInfo;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\IConfig;
|
||||
|
|
@ -29,28 +33,19 @@ use Test\Util\User\Dummy;
|
|||
* @group DB
|
||||
*/
|
||||
class UserMountCacheTest extends TestCase {
|
||||
/**
|
||||
* @var IDBConnection
|
||||
*/
|
||||
private $connection;
|
||||
|
||||
/**
|
||||
* @var IUserManager
|
||||
*/
|
||||
private $userManager;
|
||||
|
||||
/**
|
||||
* @var \OC\Files\Config\UserMountCache
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
private $fileIds = [];
|
||||
private IDBConnection $connection;
|
||||
private IUserManager $userManager;
|
||||
private IEventDispatcher $eventDispatcher;
|
||||
private UserMountCache $cache;
|
||||
private array $fileIds = [];
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->fileIds = [];
|
||||
|
||||
$this->connection = \OC::$server->getDatabaseConnection();
|
||||
|
||||
$config = $this->getMockBuilder(IConfig::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
|
@ -62,13 +57,22 @@ class UserMountCacheTest extends TestCase {
|
|||
->expects($this->any())
|
||||
->method('getAppValue')
|
||||
->willReturnArgument(2);
|
||||
|
||||
$this->userManager = new Manager($config, $this->createMock(ICacheFactory::class), $this->createMock(IEventDispatcher::class), $this->createMock(LoggerInterface::class));
|
||||
$userBackend = new Dummy();
|
||||
$userBackend->createUser('u1', '');
|
||||
$userBackend->createUser('u2', '');
|
||||
$userBackend->createUser('u3', '');
|
||||
$this->userManager->registerBackend($userBackend);
|
||||
$this->cache = new \OC\Files\Config\UserMountCache($this->connection, $this->userManager, $this->createMock(LoggerInterface::class), $this->createMock(IEventLogger::class));
|
||||
|
||||
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
|
||||
|
||||
$this->cache = new UserMountCache($this->connection,
|
||||
$this->userManager,
|
||||
$this->createMock(LoggerInterface::class),
|
||||
$this->createMock(IEventLogger::class),
|
||||
$this->eventDispatcher,
|
||||
);
|
||||
}
|
||||
|
||||
protected function tearDown(): void {
|
||||
|
|
@ -126,6 +130,11 @@ class UserMountCacheTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testNewMounts(): void {
|
||||
$this->eventDispatcher
|
||||
->expects($this->once())
|
||||
->method('dispatchTyped')
|
||||
->with($this->callback(fn (UserMountAddedEvent $event) => $event->mountPoint->getMountPoint() === '/asd/'));
|
||||
|
||||
$user = $this->userManager->get('u1');
|
||||
|
||||
[$storage] = $this->getStorage(10);
|
||||
|
|
@ -146,6 +155,11 @@ class UserMountCacheTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testSameMounts(): void {
|
||||
$this->eventDispatcher
|
||||
->expects($this->once())
|
||||
->method('dispatchTyped')
|
||||
->with($this->callback(fn (UserMountAddedEvent $event) => $event->mountPoint->getMountPoint() === '/asd/'));
|
||||
|
||||
$user = $this->userManager->get('u1');
|
||||
|
||||
[$storage] = $this->getStorage(10);
|
||||
|
|
@ -170,6 +184,18 @@ class UserMountCacheTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testRemoveMounts(): void {
|
||||
$operation = 0;
|
||||
$this->eventDispatcher
|
||||
->expects($this->exactly(2))
|
||||
->method('dispatchTyped')
|
||||
->with($this->callback(function (UserMountAddedEvent|UserMountRemovedEvent $event) use (&$operation) {
|
||||
return match(++$operation) {
|
||||
1 => $event instanceof UserMountAddedEvent && $event->mountPoint->getMountPoint() === '/asd/',
|
||||
2 => $event instanceof UserMountRemovedEvent && $event->mountPoint->getMountPoint() === '/asd/',
|
||||
default => false,
|
||||
};
|
||||
}));
|
||||
|
||||
$user = $this->userManager->get('u1');
|
||||
|
||||
[$storage] = $this->getStorage(10);
|
||||
|
|
@ -189,6 +215,19 @@ class UserMountCacheTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testChangeMounts(): void {
|
||||
$operation = 0;
|
||||
$this->eventDispatcher
|
||||
->expects($this->exactly(3))
|
||||
->method('dispatchTyped')
|
||||
->with($this->callback(function (UserMountAddedEvent|UserMountRemovedEvent $event) use (&$operation) {
|
||||
return match(++$operation) {
|
||||
1 => $event instanceof UserMountAddedEvent && $event->mountPoint->getMountPoint() === '/bar/',
|
||||
2 => $event instanceof UserMountAddedEvent && $event->mountPoint->getMountPoint() === '/foo/',
|
||||
3 => $event instanceof UserMountRemovedEvent && $event->mountPoint->getMountPoint() === '/bar/',
|
||||
default => false,
|
||||
};
|
||||
}));
|
||||
|
||||
$user = $this->userManager->get('u1');
|
||||
|
||||
[$storage] = $this->getStorage(10);
|
||||
|
|
@ -212,6 +251,18 @@ class UserMountCacheTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testChangeMountId(): void {
|
||||
$operation = 0;
|
||||
$this->eventDispatcher
|
||||
->expects($this->exactly(2))
|
||||
->method('dispatchTyped')
|
||||
->with($this->callback(function (UserMountAddedEvent|UserMountUpdatedEvent $event) use (&$operation) {
|
||||
return match(++$operation) {
|
||||
1 => $event instanceof UserMountAddedEvent && $event->mountPoint->getMountPoint() === '/foo/',
|
||||
2 => $event instanceof UserMountUpdatedEvent && $event->oldMountPoint->getMountId() === null && $event->newMountPoint->getMountId() === 1,
|
||||
default => false,
|
||||
};
|
||||
}));
|
||||
|
||||
$user = $this->userManager->get('u1');
|
||||
|
||||
[$storage] = $this->getStorage(10);
|
||||
|
|
|
|||
Loading…
Reference in a new issue