diff options
author | Robin Appelman <robin@icewind.nl> | 2022-03-08 14:50:25 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-08 14:50:25 +0000 |
commit | e8872f01ae850bcbf66220beba44463f68e3d673 (patch) | |
tree | 9b2b1d01992d26368ff456af0440d0a2965308a6 | |
parent | 23e8ae15aaea30359a927492155de13c97b311ce (diff) | |
parent | 917c74e214094e321ff96e1aa067ae60d22e2c58 (diff) | |
download | nextcloud-server-e8872f01ae850bcbf66220beba44463f68e3d673.tar.gz nextcloud-server-e8872f01ae850bcbf66220beba44463f68e3d673.zip |
Merge pull request #31431 from nextcloud/fs-setup-manager
Unify/cleanup filesystem setup
42 files changed, 767 insertions, 525 deletions
diff --git a/apps/dav/tests/unit/Connector/Sabre/ObjectTreeTest.php b/apps/dav/tests/unit/Connector/Sabre/ObjectTreeTest.php index d77f65b33f5..7416cf7a3f7 100644 --- a/apps/dav/tests/unit/Connector/Sabre/ObjectTreeTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/ObjectTreeTest.php @@ -34,6 +34,7 @@ use OC\Files\Storage\Temporary; use OC\Files\View; use OCA\DAV\Connector\Sabre\Directory; use OCA\DAV\Connector\Sabre\ObjectTree; +use OCP\Files\Mount\IMountManager; /** * Class ObjectTreeTest @@ -266,7 +267,7 @@ class ObjectTreeTest extends \Test\TestCase { ]; } - + public function testGetNodeForPathInvalidPath() { $this->expectException(\OCA\DAV\Connector\Sabre\Exception\InvalidPath::class); @@ -287,8 +288,7 @@ class ObjectTreeTest extends \Test\TestCase { $rootNode = $this->getMockBuilder(Directory::class) ->disableOriginalConstructor() ->getMock(); - $mountManager = $this->getMockBuilder(Manager::class) - ->getMock(); + $mountManager = $this->createMock(IMountManager::class); $tree = new \OCA\DAV\Connector\Sabre\ObjectTree(); $tree->init($rootNode, $view, $mountManager); @@ -314,8 +314,7 @@ class ObjectTreeTest extends \Test\TestCase { $rootNode = $this->getMockBuilder(Directory::class) ->disableOriginalConstructor() ->getMock(); - $mountManager = $this->getMockBuilder(Manager::class) - ->getMock(); + $mountManager = $this->createMock(IMountManager::class); $tree = new \OCA\DAV\Connector\Sabre\ObjectTree(); $tree->init($rootNode, $view, $mountManager); diff --git a/apps/files_external/tests/PersonalMountTest.php b/apps/files_external/tests/PersonalMountTest.php index b8a57657f9d..024695b0188 100644 --- a/apps/files_external/tests/PersonalMountTest.php +++ b/apps/files_external/tests/PersonalMountTest.php @@ -25,8 +25,13 @@ namespace OCA\Files_External\Tests; use OC\Files\Mount\Manager; +use OC\Files\SetupManagerFactory; use OCA\Files_External\Lib\PersonalMount; use OCA\Files_External\Lib\StorageConfig; +use OCP\Diagnostics\IEventLogger; +use OCP\EventDispatcher\IEventDispatcher; +use OCP\Files\Config\IMountProviderCollection; +use OCP\IUserManager; use Test\TestCase; class PersonalMountTest extends TestCase { @@ -47,7 +52,7 @@ class PersonalMountTest extends TestCase { $mount = new PersonalMount($storageService, $storageConfig, 10, $storage, '/foo'); - $mountManager = new Manager(); + $mountManager = new Manager($this->createMock(SetupManagerFactory::class)); $mountManager->addMount($mount); $this->assertEquals([$mount], $mountManager->findByStorageId('dummy')); diff --git a/apps/files_sharing/lib/External/Manager.php b/apps/files_sharing/lib/External/Manager.php index a48e2a63ae4..a8510321a5a 100644 --- a/apps/files_sharing/lib/External/Manager.php +++ b/apps/files_sharing/lib/External/Manager.php @@ -43,6 +43,7 @@ use OCP\EventDispatcher\IEventDispatcher; use OCP\Federation\ICloudFederationFactory; use OCP\Federation\ICloudFederationProviderManager; use OCP\Files; +use OCP\Files\NotFoundException; use OCP\Files\Storage\IStorageFactory; use OCP\Http\Client\IClientService; use OCP\IDBConnection; @@ -599,8 +600,9 @@ class Manager { } public function removeShare($mountPoint): bool { - $mountPointObj = $this->mountManager->find($mountPoint); - if ($mountPointObj === null) { + try { + $mountPointObj = $this->mountManager->find($mountPoint); + } catch (NotFoundException $e) { $this->logger->error('Mount point to remove share not found', ['mountPoint' => $mountPoint]); return false; } diff --git a/apps/files_sharing/lib/Updater.php b/apps/files_sharing/lib/Updater.php index 9ce114f495d..ad194dde016 100644 --- a/apps/files_sharing/lib/Updater.php +++ b/apps/files_sharing/lib/Updater.php @@ -26,6 +26,7 @@ */ namespace OCA\Files_Sharing; +use OC\Files\Mount\MountPoint; use OCP\Constants; use OCP\Share\IShare; @@ -105,6 +106,7 @@ class Updater { $mountManager = \OC\Files\Filesystem::getMountManager(); $mountedShares = $mountManager->findIn('/' . \OC_User::getUser() . '/files/' . $oldPath); foreach ($mountedShares as $mount) { + /** @var MountPoint $mount */ if ($mount->getStorage()->instanceOfStorage(ISharedStorage::class)) { $mountPoint = $mount->getMountPoint(); $target = str_replace($absOldPath, $absNewPath, $mountPoint); diff --git a/apps/files_sharing/tests/External/ManagerTest.php b/apps/files_sharing/tests/External/ManagerTest.php index ab7c682c3a6..307b630970f 100644 --- a/apps/files_sharing/tests/External/ManagerTest.php +++ b/apps/files_sharing/tests/External/ManagerTest.php @@ -31,14 +31,19 @@ namespace OCA\Files_Sharing\Tests\External; use OC\Federation\CloudIdManager; +use OC\Files\SetupManager; +use OC\Files\SetupManagerFactory; use OC\Files\Storage\StorageFactory; use OCA\Files_Sharing\External\Manager; use OCA\Files_Sharing\External\MountProvider; use OCA\Files_Sharing\Tests\TestCase; use OCP\Contacts\IManager; +use OCP\Diagnostics\IEventLogger; use OCP\EventDispatcher\IEventDispatcher; use OCP\Federation\ICloudFederationFactory; use OCP\Federation\ICloudFederationProviderManager; +use OCP\Files\Config\IMountProviderCollection; +use OCP\Files\NotFoundException; use OCP\Http\Client\IClientService; use OCP\Http\Client\IResponse; use OCP\IGroup; @@ -102,9 +107,8 @@ class ManagerTest extends TestCase { parent::setUp(); $this->uid = $this->getUniqueID('user'); - $this->createUser($this->uid, ''); - $this->user = \OC::$server->getUserManager()->get($this->uid); - $this->mountManager = new \OC\Files\Mount\Manager(); + $this->user = $this->createUser($this->uid, ''); + $this->mountManager = new \OC\Files\Mount\Manager($this->createMock(SetupManagerFactory::class)); $this->clientService = $this->getMockBuilder(IClientService::class) ->disableOriginalConstructor()->getMock(); $this->cloudFederationProviderManager = $this->createMock(ICloudFederationProviderManager::class); @@ -740,12 +744,12 @@ class ManagerTest extends TestCase { private function assertNotMount($mountPoint) { $mountPoint = rtrim($mountPoint, '/'); - $mount = $this->mountManager->find($this->getFullPath($mountPoint)); - if ($mount) { + try { + $mount = $this->mountManager->find($this->getFullPath($mountPoint)); $this->assertInstanceOf('\OCP\Files\Mount\IMountPoint', $mount); $this->assertNotEquals($this->getFullPath($mountPoint), rtrim($mount->getMountPoint(), '/')); - } else { - $this->assertNull($mount); + } catch (NotFoundException $e) { + } } diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 6fd3d9207db..86efab3ad52 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -271,6 +271,7 @@ return array( 'OCP\\Files\\Events\\Node\\BeforeNodeRenamedEvent' => $baseDir . '/lib/public/Files/Events/Node/BeforeNodeRenamedEvent.php', 'OCP\\Files\\Events\\Node\\BeforeNodeTouchedEvent' => $baseDir . '/lib/public/Files/Events/Node/BeforeNodeTouchedEvent.php', 'OCP\\Files\\Events\\Node\\BeforeNodeWrittenEvent' => $baseDir . '/lib/public/Files/Events/Node/BeforeNodeWrittenEvent.php', + 'OCP\\Files\\Events\\Node\\FilesystemTornDownEvent' => $baseDir . '/lib/public/Files/Events/Node/FilesystemTornDownEvent.php', 'OCP\\Files\\Events\\Node\\NodeCopiedEvent' => $baseDir . '/lib/public/Files/Events/Node/NodeCopiedEvent.php', 'OCP\\Files\\Events\\Node\\NodeCreatedEvent' => $baseDir . '/lib/public/Files/Events/Node/NodeCreatedEvent.php', 'OCP\\Files\\Events\\Node\\NodeDeletedEvent' => $baseDir . '/lib/public/Files/Events/Node/NodeDeletedEvent.php', @@ -1162,6 +1163,8 @@ return array( 'OC\\Files\\Search\\SearchComparison' => $baseDir . '/lib/private/Files/Search/SearchComparison.php', 'OC\\Files\\Search\\SearchOrder' => $baseDir . '/lib/private/Files/Search/SearchOrder.php', 'OC\\Files\\Search\\SearchQuery' => $baseDir . '/lib/private/Files/Search/SearchQuery.php', + 'OC\\Files\\SetupManager' => $baseDir . '/lib/private/Files/SetupManager.php', + 'OC\\Files\\SetupManagerFactory' => $baseDir . '/lib/private/Files/SetupManagerFactory.php', 'OC\\Files\\SimpleFS\\NewSimpleFile' => $baseDir . '/lib/private/Files/SimpleFS/NewSimpleFile.php', 'OC\\Files\\SimpleFS\\SimpleFile' => $baseDir . '/lib/private/Files/SimpleFS/SimpleFile.php', 'OC\\Files\\SimpleFS\\SimpleFolder' => $baseDir . '/lib/private/Files/SimpleFS/SimpleFolder.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index c8c0e7df381..ea37771d63c 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -300,6 +300,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OCP\\Files\\Events\\Node\\BeforeNodeRenamedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/BeforeNodeRenamedEvent.php', 'OCP\\Files\\Events\\Node\\BeforeNodeTouchedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/BeforeNodeTouchedEvent.php', 'OCP\\Files\\Events\\Node\\BeforeNodeWrittenEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/BeforeNodeWrittenEvent.php', + 'OCP\\Files\\Events\\Node\\FilesystemTornDownEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/FilesystemTornDownEvent.php', 'OCP\\Files\\Events\\Node\\NodeCopiedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/NodeCopiedEvent.php', 'OCP\\Files\\Events\\Node\\NodeCreatedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/NodeCreatedEvent.php', 'OCP\\Files\\Events\\Node\\NodeDeletedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/Node/NodeDeletedEvent.php', @@ -1191,6 +1192,8 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Files\\Search\\SearchComparison' => __DIR__ . '/../../..' . '/lib/private/Files/Search/SearchComparison.php', 'OC\\Files\\Search\\SearchOrder' => __DIR__ . '/../../..' . '/lib/private/Files/Search/SearchOrder.php', 'OC\\Files\\Search\\SearchQuery' => __DIR__ . '/../../..' . '/lib/private/Files/Search/SearchQuery.php', + 'OC\\Files\\SetupManager' => __DIR__ . '/../../..' . '/lib/private/Files/SetupManager.php', + 'OC\\Files\\SetupManagerFactory' => __DIR__ . '/../../..' . '/lib/private/Files/SetupManagerFactory.php', 'OC\\Files\\SimpleFS\\NewSimpleFile' => __DIR__ . '/../../..' . '/lib/private/Files/SimpleFS/NewSimpleFile.php', 'OC\\Files\\SimpleFS\\SimpleFile' => __DIR__ . '/../../..' . '/lib/private/Files/SimpleFS/SimpleFile.php', 'OC\\Files\\SimpleFS\\SimpleFolder' => __DIR__ . '/../../..' . '/lib/private/Files/SimpleFS/SimpleFolder.php', diff --git a/lib/private/Cache/CappedMemoryCache.php b/lib/private/Cache/CappedMemoryCache.php index 584a53f0ff2..9260bf1f6b3 100644 --- a/lib/private/Cache/CappedMemoryCache.php +++ b/lib/private/Cache/CappedMemoryCache.php @@ -27,30 +27,42 @@ use OCP\ICache; * In-memory cache with a capacity limit to keep memory usage in check * * Uses a simple FIFO expiry mechanism + * @template T */ class CappedMemoryCache implements ICache, \ArrayAccess { private $capacity; + /** @var T[] */ private $cache = []; public function __construct($capacity = 512) { $this->capacity = $capacity; } - public function hasKey($key) { + public function hasKey($key): bool { return isset($this->cache[$key]); } + /** + * @return ?T + */ public function get($key) { - return isset($this->cache[$key]) ? $this->cache[$key] : null; + return $this->cache[$key] ?? null; } - public function set($key, $value, $ttl = 0) { + /** + * @param string $key + * @param T $value + * @param int $ttl + * @return bool + */ + public function set($key, $value, $ttl = 0): bool { if (is_null($key)) { $this->cache[] = $value; } else { $this->cache[$key] = $value; } $this->garbageCollect(); + return true; } public function remove($key) { @@ -68,13 +80,18 @@ class CappedMemoryCache implements ICache, \ArrayAccess { } /** - * @return mixed + * @return T */ #[\ReturnTypeWillChange] public function &offsetGet($offset) { return $this->cache[$offset]; } + /** + * @param string $key + * @param T $value + * @return void + */ public function offsetSet($offset, $value): void { $this->set($offset, $value); } @@ -83,6 +100,9 @@ class CappedMemoryCache implements ICache, \ArrayAccess { $this->remove($offset); } + /** + * @return T[] + */ public function getData() { return $this->cache; } diff --git a/lib/private/Files/Config/CachedMountFileInfo.php b/lib/private/Files/Config/CachedMountFileInfo.php index 71a6ddb9ea9..11a9a505808 100644 --- a/lib/private/Files/Config/CachedMountFileInfo.php +++ b/lib/private/Files/Config/CachedMountFileInfo.php @@ -27,8 +27,7 @@ use OCP\Files\Config\ICachedMountFileInfo; use OCP\IUser; class CachedMountFileInfo extends CachedMountInfo implements ICachedMountFileInfo { - /** @var string */ - private $internalPath; + private string $internalPath; public function __construct( IUser $user, diff --git a/lib/private/Files/Config/CachedMountInfo.php b/lib/private/Files/Config/CachedMountInfo.php index c70dba100a4..43c9fae63ec 100644 --- a/lib/private/Files/Config/CachedMountInfo.php +++ b/lib/private/Files/Config/CachedMountInfo.php @@ -28,38 +28,13 @@ use OCP\Files\Node; use OCP\IUser; class CachedMountInfo implements ICachedMountInfo { - /** - * @var IUser - */ - protected $user; - - /** - * @var int - */ - protected $storageId; - - /** - * @var int - */ - protected $rootId; - - /** - * @var string - */ - protected $mountPoint; - - /** - * @var int|null - */ - protected $mountId; - - /** - * @var string - */ - protected $rootInternalPath; - - /** @var string */ - protected $mountProvider; + protected IUser $user; + protected int $storageId; + protected int $rootId; + protected string $mountPoint; + protected ?int $mountId; + protected string $rootInternalPath; + protected string $mountProvider; /** * CachedMountInfo constructor. @@ -95,28 +70,28 @@ class CachedMountInfo implements ICachedMountInfo { /** * @return IUser */ - public function getUser() { + public function getUser(): IUser { return $this->user; } /** * @return int the numeric storage id of the mount */ - public function getStorageId() { + public function getStorageId(): int { return $this->storageId; } /** * @return int the fileid of the root of the mount */ - public function getRootId() { + public function getRootId(): int { return $this->rootId; } /** - * @return Node the root node of the mount + * @return Node|null the root node of the mount */ - public function getMountPointNode() { + public function getMountPointNode(): ?Node { // TODO injection etc Filesystem::initMountPoints($this->getUser()->getUID()); $userNode = \OC::$server->getUserFolder($this->getUser()->getUID()); @@ -131,7 +106,7 @@ class CachedMountInfo implements ICachedMountInfo { /** * @return string the mount point of the mount for the user */ - public function getMountPoint() { + public function getMountPoint(): string { return $this->mountPoint; } @@ -141,7 +116,7 @@ class CachedMountInfo implements ICachedMountInfo { * @return int|null mount id or null if not applicable * @since 9.1.0 */ - public function getMountId() { + public function getMountId(): ?int { return $this->mountId; } @@ -150,7 +125,7 @@ class CachedMountInfo implements ICachedMountInfo { * * @return string */ - public function getRootInternalPath() { + public function getRootInternalPath(): string { return $this->rootInternalPath; } diff --git a/lib/private/Files/Config/LazyStorageMountInfo.php b/lib/private/Files/Config/LazyStorageMountInfo.php index fd3bbcbe0fb..78055a2cdb8 100644 --- a/lib/private/Files/Config/LazyStorageMountInfo.php +++ b/lib/private/Files/Config/LazyStorageMountInfo.php @@ -25,8 +25,7 @@ use OCP\Files\Mount\IMountPoint; use OCP\IUser; class LazyStorageMountInfo extends CachedMountInfo { - /** @var IMountPoint */ - private $mount; + private IMountPoint $mount; /** * CachedMountInfo constructor. @@ -37,12 +36,15 @@ class LazyStorageMountInfo extends CachedMountInfo { public function __construct(IUser $user, IMountPoint $mount) { $this->user = $user; $this->mount = $mount; + $this->rootId = 0; + $this->storageId = 0; + $this->mountPoint = ''; } /** * @return int the numeric storage id of the mount */ - public function getStorageId() { + public function getStorageId(): int { if (!$this->storageId) { $this->storageId = $this->mount->getNumericStorageId(); } @@ -52,7 +54,7 @@ class LazyStorageMountInfo extends CachedMountInfo { /** * @return int the fileid of the root of the mount */ - public function getRootId() { + public function getRootId(): int { if (!$this->rootId) { $this->rootId = $this->mount->getStorageRootId(); } @@ -62,14 +64,14 @@ class LazyStorageMountInfo extends CachedMountInfo { /** * @return string the mount point of the mount for the user */ - public function getMountPoint() { + public function getMountPoint(): string { if (!$this->mountPoint) { $this->mountPoint = $this->mount->getMountPoint(); } return parent::getMountPoint(); } - public function getMountId() { + public function getMountId(): ?int { return $this->mount->getMountId(); } @@ -78,7 +80,7 @@ class LazyStorageMountInfo extends CachedMountInfo { * * @return string */ - public function getRootInternalPath() { + public function getRootInternalPath(): string { return $this->mount->getInternalPath($this->mount->getMountPoint()); } diff --git a/lib/private/Files/Config/MountProviderCollection.php b/lib/private/Files/Config/MountProviderCollection.php index ba70e29ab8d..cd8a2a2e29f 100644 --- a/lib/private/Files/Config/MountProviderCollection.php +++ b/lib/private/Files/Config/MountProviderCollection.php @@ -184,16 +184,6 @@ class MountProviderCollection implements IMountProviderCollection, Emitter { } /** - * Cache mounts for user - * - * @param IUser $user - * @param IMountPoint[] $mountPoints - */ - public function registerMounts(IUser $user, array $mountPoints) { - $this->mountCache->registerMounts($user, $mountPoints); - } - - /** * Get the mount cache which can be used to search for mounts without setting up the filesystem * * @return IUserMountCache @@ -222,4 +212,10 @@ class MountProviderCollection implements IMountProviderCollection, Emitter { }, []); return $mounts; } + + public function clearProviders() { + $this->providers = []; + $this->homeProviders = []; + $this->rootProviders = []; + } } diff --git a/lib/private/Files/Filesystem.php b/lib/private/Files/Filesystem.php index e439b746bf6..1aedad93aa1 100644 --- a/lib/private/Files/Filesystem.php +++ b/lib/private/Files/Filesystem.php @@ -38,13 +38,12 @@ namespace OC\Files; use OC\Cache\CappedMemoryCache; -use OC\Files\Config\MountProviderCollection; use OC\Files\Mount\MountPoint; -use OC\Lockdown\Filesystem\NullStorage; -use OCP\Files\Config\IMountProvider; +use OC\User\NoUserException; +use OCP\EventDispatcher\IEventDispatcher; +use OCP\Files\Events\Node\FilesystemTornDownEvent; use OCP\Files\NotFoundException; use OCP\Files\Storage\IStorageFactory; -use OCP\ILogger; use OCP\IUser; use OCP\IUserManager; @@ -259,11 +258,7 @@ class Filesystem { \OC_Util::setupFS(); } $mount = self::$mounts->find($path); - if ($mount) { - return $mount->getMountPoint(); - } else { - return ''; - } + return $mount->getMountPoint(); } /** @@ -319,11 +314,7 @@ class Filesystem { */ public static function resolvePath($path) { $mount = self::getMountManager()->find($path); - if ($mount) { - return [$mount->getStorage(), rtrim($mount->getInternalPath($path), '/')]; - } else { - return [null, null]; - } + return [$mount->getStorage(), rtrim($mount->getInternalPath($path), '/')]; } public static function init($user, $root) { @@ -332,6 +323,13 @@ class Filesystem { } self::getLoader(); self::$defaultInstance = new View($root); + /** @var IEventDispatcher $eventDispatcher */ + $eventDispatcher = \OC::$server->get(IEventDispatcher::class); + $eventDispatcher->addListener(FilesystemTornDownEvent::class, function () { + self::$defaultInstance = null; + self::$usersSetup = []; + self::$loaded = false; + }); if (!self::$mounts) { self::$mounts = \OC::$server->getMountManager(); @@ -358,106 +356,16 @@ class Filesystem { * @throws \OC\User\NoUserException if the user is not available */ public static function initMountPoints($user = '') { - $userManager = \OC::$server->getUserManager(); - if (is_string($user)) { - if ($user === '') { - $user = \OC_User::getUser(); - } - - $userObject = $userManager->get($user); - } elseif ($user instanceof IUser) { - $userObject = $user; - $user = $userObject->getUID(); - } else { - $userObject = null; - } - - if ($userObject === null || $user === false || $user === '') { - throw new \OC\User\NoUserException('Attempted to initialize mount points for null user and no user in session'); - } - - if (isset(self::$usersSetup[$user])) { - return; - } - - self::$usersSetup[$user] = true; - - if (is_null($userObject)) { - \OCP\Util::writeLog('files', ' Backends provided no user object for ' . $user, ILogger::ERROR); - // reset flag, this will make it possible to rethrow the exception if called again - unset(self::$usersSetup[$user]); - throw new \OC\User\NoUserException('Backends provided no user object for ' . $user); - } - - $realUid = $userObject->getUID(); - // workaround in case of different casings - if ($user !== $realUid) { - $stack = json_encode(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 50)); - \OCP\Util::writeLog('files', 'initMountPoints() called with wrong user casing. This could be a bug. Expected: "' . $realUid . '" got "' . $user . '". Stack: ' . $stack, ILogger::WARN); - $user = $realUid; - - // again with the correct casing - if (isset(self::$usersSetup[$user])) { - return; - } - - self::$usersSetup[$user] = true; - } - - if (\OC::$server->getLockdownManager()->canAccessFilesystem()) { - /** @var \OC\Files\Config\MountProviderCollection $mountConfigManager */ - $mountConfigManager = \OC::$server->getMountProviderCollection(); - - // home mounts are handled seperate since we need to ensure this is mounted before we call the other mount providers - $homeMount = $mountConfigManager->getHomeMountForUser($userObject); - self::getMountManager()->addMount($homeMount); - - if ($homeMount->getStorageRootId() === -1) { - $homeMount->getStorage()->mkdir(''); - $homeMount->getStorage()->getScanner()->scan(''); - } - - \OC\Files\Filesystem::getStorage($user); - - // Chance to mount for other storages - if ($userObject) { - $mounts = $mountConfigManager->addMountForUser($userObject, self::getMountManager()); - $mounts[] = $homeMount; - $mountConfigManager->registerMounts($userObject, $mounts); - } - - self::listenForNewMountProviders($mountConfigManager, $userManager); + /** @var IUserManager $userManager */ + $userManager = \OC::$server->get(IUserManager::class); + + $userObject = ($user instanceof IUser) ? $user : $userManager->get($user); + if ($userObject) { + /** @var SetupManager $setupManager */ + $setupManager = \OC::$server->get(SetupManager::class); + $setupManager->setupForUser($userObject); } else { - self::getMountManager()->addMount(new MountPoint( - new NullStorage([]), - '/' . $user - )); - self::getMountManager()->addMount(new MountPoint( - new NullStorage([]), - '/' . $user . '/files' - )); - } - \OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', ['user' => $user]); - } - - /** - * Get mounts from mount providers that are registered after setup - * - * @param MountProviderCollection $mountConfigManager - * @param IUserManager $userManager - */ - private static function listenForNewMountProviders(MountProviderCollection $mountConfigManager, IUserManager $userManager) { - if (!self::$listeningForProviders) { - self::$listeningForProviders = true; - $mountConfigManager->listen('\OC\Files\Config', 'registerMountProvider', function (IMountProvider $provider) use ($userManager) { - foreach (Filesystem::$usersSetup as $user => $setup) { - $userObject = $userManager->get($user); - if ($userObject) { - $mounts = $provider->getMountsForUser($userObject, Filesystem::getLoader()); - array_walk($mounts, [self::$mounts, 'addMount']); - } - } - }); + throw new NoUserException(); } } @@ -474,8 +382,7 @@ class Filesystem { * tear down the filesystem, removing all storage providers */ public static function tearDown() { - self::clearMounts(); - self::$defaultInstance = null; + \OC_Util::tearDownFS(); } /** @@ -493,16 +400,6 @@ class Filesystem { } /** - * clear all mounts and storage backends - */ - public static function clearMounts() { - if (self::$mounts) { - self::$usersSetup = []; - self::$mounts->clear(); - } - } - - /** * mount an \OC\Files\Storage\Storage in our virtual filesystem * * @param \OC\Files\Storage\Storage|string $class diff --git a/lib/private/Files/Mount/Manager.php b/lib/private/Files/Mount/Manager.php index 22b05b1f384..66832690363 100644 --- a/lib/private/Files/Mount/Manager.php +++ b/lib/private/Files/Mount/Manager.php @@ -26,26 +26,30 @@ declare(strict_types=1); * along with this program. If not, see <http://www.gnu.org/licenses/> * */ + namespace OC\Files\Mount; use OC\Cache\CappedMemoryCache; use OC\Files\Filesystem; +use OC\Files\SetupManager; +use OC\Files\SetupManagerFactory; use OCP\Files\Mount\IMountManager; use OCP\Files\Mount\IMountPoint; +use OCP\Files\NotFoundException; class Manager implements IMountManager { /** @var MountPoint[] */ - private $mounts = []; - - /** @var CappedMemoryCache */ - private $pathCache; - - /** @var CappedMemoryCache */ - private $inPathCache; - - public function __construct() { + private array $mounts = []; + /** @var CappedMemoryCache<IMountPoint> */ + private CappedMemoryCache $pathCache; + /** @var CappedMemoryCache<IMountPoint[]> */ + private CappedMemoryCache $inPathCache; + private SetupManager $setupManager; + + public function __construct(SetupManagerFactory $setupManagerFactory) { $this->pathCache = new CappedMemoryCache(); $this->inPathCache = new CappedMemoryCache(); + $this->setupManager = $setupManagerFactory->create($this); } /** @@ -81,26 +85,14 @@ class Manager implements IMountManager { $this->inPathCache->clear(); } - private function setupForFind(string $path) { - if (strpos($path, '/appdata_' . \OC_Util::getInstanceId()) === 0) { - // for appdata, we only setup the root bits, not the user bits - \OC_Util::setupRootFS(); - } elseif (strpos($path, '/files_external/uploads/') === 0) { - // for OC\Security\CertificateManager, we only setup the root bits, not the user bits - \OC_Util::setupRootFS(); - } else { - \OC_Util::setupFS(); - } - } - /** * Find the mount for $path * * @param string $path - * @return MountPoint|null + * @return IMountPoint */ - public function find(string $path) { - $this->setupForFind($path); + public function find(string $path): IMountPoint { + $this->setupManager->setupForPath($path); $path = Filesystem::normalizePath($path); if (isset($this->pathCache[$path])) { @@ -113,10 +105,8 @@ class Manager implements IMountManager { if (isset($this->mounts[$mountPoint])) { $this->pathCache[$path] = $this->mounts[$mountPoint]; return $this->mounts[$mountPoint]; - } - - if ($current === '') { - return null; + } elseif ($current === '') { + break; } $current = dirname($current); @@ -124,16 +114,18 @@ class Manager implements IMountManager { $current = ''; } } + + throw new NotFoundException("No mount for path " . $path . " existing mounts: " . implode(",", array_keys($this->mounts))); } /** * Find all mounts in $path * * @param string $path - * @return MountPoint[] + * @return IMountPoint[] */ public function findIn(string $path): array { - $this->setupForFind($path); + $this->setupManager->setupForPath($path); $path = $this->formatPath($path); if (isset($this->inPathCache[$path])) { @@ -163,7 +155,7 @@ class Manager implements IMountManager { * Find mounts by storage id * * @param string $id - * @return MountPoint[] + * @return IMountPoint[] */ public function findByStorageId(string $id): array { \OC_Util::setupFS(); @@ -180,7 +172,7 @@ class Manager implements IMountManager { } /** - * @return MountPoint[] + * @return IMountPoint[] */ public function getAll(): array { return $this->mounts; @@ -190,7 +182,7 @@ class Manager implements IMountManager { * Find mounts by numeric storage id * * @param int $id - * @return MountPoint[] + * @return IMountPoint[] */ public function findByNumericId(int $id): array { $storageId = \OC\Files\Cache\Storage::getStorageId($id); @@ -208,4 +200,8 @@ class Manager implements IMountManager { } return $path; } + + public function getSetupManager(): SetupManager { + return $this->setupManager; + } } diff --git a/lib/private/Files/Node/Root.php b/lib/private/Files/Node/Root.php index b5707c87543..88ac4a31d34 100644 --- a/lib/private/Files/Node/Root.php +++ b/lib/private/Files/Node/Root.php @@ -35,13 +35,17 @@ namespace OC\Files\Node; use OC\Cache\CappedMemoryCache; use OC\Files\Mount\Manager; use OC\Files\Mount\MountPoint; +use OC\Files\View; use OC\Hooks\PublicEmitter; use OC\User\NoUserException; +use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\Config\IUserMountCache; +use OCP\Files\Events\Node\FilesystemTornDownEvent; use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; use OCP\ILogger; +use OCP\IUser; use OCP\IUserManager; /** @@ -64,35 +68,32 @@ use OCP\IUserManager; * @package OC\Files\Node */ class Root extends Folder implements IRootFolder { - /** @var Manager */ - private $mountManager; - /** @var PublicEmitter */ - private $emitter; - /** @var null|\OC\User\User */ - private $user; - /** @var CappedMemoryCache */ - private $userFolderCache; - /** @var IUserMountCache */ - private $userMountCache; - /** @var ILogger */ - private $logger; - /** @var IUserManager */ - private $userManager; + private Manager $mountManager; + private PublicEmitter $emitter; + private ?IUser $user; + private CappedMemoryCache $userFolderCache; + private IUserMountCache $userMountCache; + private ILogger $logger; + private IUserManager $userManager; + private IEventDispatcher $eventDispatcher; /** - * @param \OC\Files\Mount\Manager $manager - * @param \OC\Files\View $view - * @param \OC\User\User|null $user + * @param Manager $manager + * @param View $view + * @param IUser|null $user * @param IUserMountCache $userMountCache * @param ILogger $logger * @param IUserManager $userManager */ - public function __construct($manager, + public function __construct( + $manager, $view, $user, - IUserMountCache $userMountCache, - ILogger $logger, - IUserManager $userManager) { + IUserMountCache $userMountCache, + ILogger $logger, + IUserManager $userManager, + IEventDispatcher $eventDispatcher + ) { parent::__construct($this, $view, ''); $this->mountManager = $manager; $this->user = $user; @@ -101,6 +102,9 @@ class Root extends Folder implements IRootFolder { $this->userMountCache = $userMountCache; $this->logger = $logger; $this->userManager = $userManager; + $eventDispatcher->addListener(FilesystemTornDownEvent::class, function () { + $this->userFolderCache = new CappedMemoryCache(); + }); } /** @@ -267,21 +271,21 @@ class Root extends Folder implements IRootFolder { * @return int */ public function getId() { - return null; + return 0; } /** * @return array */ public function stat() { - return null; + return []; } /** * @return int */ public function getMTime() { - return null; + return 0; } /** @@ -289,14 +293,14 @@ class Root extends Folder implements IRootFolder { * @return int */ public function getSize($includeMounts = true) { - return null; + return 0; } /** * @return string */ public function getEtag() { - return null; + return ''; } /** @@ -393,10 +397,6 @@ class Root extends Folder implements IRootFolder { return $this->userFolderCache->get($userId); } - public function clearCache() { - $this->userFolderCache = new CappedMemoryCache(); - } - public function getUserMountCache() { return $this->userMountCache; } diff --git a/lib/private/Files/SetupManager.php b/lib/private/Files/SetupManager.php new file mode 100644 index 00000000000..f9276ef4171 --- /dev/null +++ b/lib/private/Files/SetupManager.php @@ -0,0 +1,283 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2022 Robin Appelman <robin@icewind.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Files; + +use OC\Files\Config\MountProviderCollection; +use OC\Files\Mount\MountPoint; +use OC\Files\ObjectStore\HomeObjectStoreStorage; +use OC\Files\Storage\Common; +use OC\Files\Storage\Home; +use OC\Files\Storage\Storage; +use OC\Files\Storage\Wrapper\Availability; +use OC\Files\Storage\Wrapper\Encoding; +use OC\Files\Storage\Wrapper\PermissionsMask; +use OC\Files\Storage\Wrapper\Quota; +use OC\Lockdown\Filesystem\NullStorage; +use OC_App; +use OC_Hook; +use OC_Util; +use OCP\Constants; +use OCP\Diagnostics\IEventLogger; +use OCP\EventDispatcher\IEventDispatcher; +use OCP\Files\Config\IMountProvider; +use OCP\Files\Config\IUserMountCache; +use OCP\Files\Events\Node\FilesystemTornDownEvent; +use OCP\Files\Mount\IMountManager; +use OCP\Files\Mount\IMountPoint; +use OCP\Files\Storage\IStorage; +use OCP\IUser; +use OCP\IUserManager; +use OCP\Lockdown\ILockdownManager; + +class SetupManager { + private bool $rootSetup = false; + private IEventLogger $eventLogger; + private MountProviderCollection $mountProviderCollection; + private IMountManager $mountManager; + private IUserManager $userManager; + private array $setupUsers = []; + private IEventDispatcher $eventDispatcher; + private IUserMountCache $userMountCache; + private ILockdownManager $lockdownManager; + private bool $listeningForProviders; + + public function __construct( + IEventLogger $eventLogger, + MountProviderCollection $mountProviderCollection, + IMountManager $mountManager, + IUserManager $userManager, + IEventDispatcher $eventDispatcher, + IUserMountCache $userMountCache, + ILockdownManager $lockdownManager + ) { + $this->eventLogger = $eventLogger; + $this->mountProviderCollection = $mountProviderCollection; + $this->mountManager = $mountManager; + $this->userManager = $userManager; + $this->eventDispatcher = $eventDispatcher; + $this->userMountCache = $userMountCache; + $this->lockdownManager = $lockdownManager; + $this->listeningForProviders = false; + } + + private function setupBuiltinWrappers() { + Filesystem::addStorageWrapper('mount_options', function ($mountPoint, IStorage $storage, IMountPoint $mount) { + if ($storage->instanceOfStorage(Common::class)) { + $storage->setMountOptions($mount->getOptions()); + } + return $storage; + }); + + Filesystem::addStorageWrapper('enable_sharing', function ($mountPoint, IStorage $storage, IMountPoint $mount) { + if (!$mount->getOption('enable_sharing', true)) { + return new PermissionsMask([ + 'storage' => $storage, + 'mask' => Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE, + ]); + } + return $storage; + }); + + // install storage availability wrapper, before most other wrappers + Filesystem::addStorageWrapper('oc_availability', function ($mountPoint, IStorage $storage) { + if (!$storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage') && !$storage->isLocal()) { + return new Availability(['storage' => $storage]); + } + return $storage; + }); + + Filesystem::addStorageWrapper('oc_encoding', function ($mountPoint, IStorage $storage, IMountPoint $mount) { + if ($mount->getOption('encoding_compatibility', false) && !$storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage') && !$storage->isLocal()) { + return new Encoding(['storage' => $storage]); + } + return $storage; + }); + + Filesystem::addStorageWrapper('oc_quota', function ($mountPoint, $storage) { + // set up quota for home storages, even for other users + // which can happen when using sharing + + /** + * @var Storage $storage + */ + if ($storage->instanceOfStorage(HomeObjectStoreStorage::class) || $storage->instanceOfStorage(Home::class)) { + if (is_object($storage->getUser())) { + $quota = OC_Util::getUserQuota($storage->getUser()); + if ($quota !== \OCP\Files\FileInfo::SPACE_UNLIMITED) { + return new Quota(['storage' => $storage, 'quota' => $quota, 'root' => 'files']); + } + } + } + + return $storage; + }); + + Filesystem::addStorageWrapper('readonly', function ($mountPoint, IStorage $storage, IMountPoint $mount) { + /* + * Do not allow any operations that modify the storage + */ + if ($mount->getOption('readonly', false)) { + return new PermissionsMask([ + 'storage' => $storage, + 'mask' => Constants::PERMISSION_ALL & ~( + Constants::PERMISSION_UPDATE | + Constants::PERMISSION_CREATE | + Constants::PERMISSION_DELETE + ), + ]); + } + return $storage; + }); + } + + /** + * Setup the full filesystem for the specified user + */ + public function setupForUser(IUser $user): void { + $this->setupRoot(); + + if (in_array($user->getUID(), $this->setupUsers, true)) { + return; + } + $this->setupUsers[] = $user->getUID(); + + $this->eventLogger->start('setup_fs', 'Setup filesystem'); + + $prevLogging = Filesystem::logWarningWhenAddingStorageWrapper(false); + + OC_Hook::emit('OC_Filesystem', 'preSetup', ['user' => $user->getUID()]); + + Filesystem::logWarningWhenAddingStorageWrapper($prevLogging); + + $userDir = '/' . $user->getUID() . '/files'; + + Filesystem::init($user, $userDir); + + if ($this->lockdownManager->canAccessFilesystem()) { + // home mounts are handled separate since we need to ensure this is mounted before we call the other mount providers + $homeMount = $this->mountProviderCollection->getHomeMountForUser($user); + $this->mountManager->addMount($homeMount); + + if ($homeMount->getStorageRootId() === -1) { + $homeMount->getStorage()->mkdir(''); + $homeMount->getStorage()->getScanner()->scan(''); + } + + // Chance to mount for other storages + $mounts = $this->mountProviderCollection->addMountForUser($user, $this->mountManager); + $mounts[] = $homeMount; + $this->userMountCache->registerMounts($user, $mounts); + + $this->listenForNewMountProviders(); + } else { + $this->mountManager->addMount(new MountPoint( + new NullStorage([]), + '/' . $user->getUID() + )); + $this->mountManager->addMount(new MountPoint( + new NullStorage([]), + '/' . $user->getUID() . '/files' + )); + } + \OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', ['user' => $user->getUID()]); + + OC_Hook::emit('OC_Filesystem', 'setup', ['user' => $user->getUID(), 'user_dir' => $userDir]); + + $this->eventLogger->end('setup_fs'); + } + + /** + * Set up the root filesystem + */ + public function setupRoot(): void { + //setting up the filesystem twice can only lead to trouble + if ($this->rootSetup) { + return; + } + $this->rootSetup = true; + + $this->eventLogger->start('setup_root_fs', 'Setup root filesystem'); + + // load all filesystem apps before, so no setup-hook gets lost + OC_App::loadApps(['filesystem']); + $prevLogging = Filesystem::logWarningWhenAddingStorageWrapper(false); + + $this->setupBuiltinWrappers(); + + Filesystem::logWarningWhenAddingStorageWrapper($prevLogging); + + $rootMounts = $this->mountProviderCollection->getRootMounts(); + foreach ($rootMounts as $rootMountProvider) { + $this->mountManager->addMount($rootMountProvider); + } + + $this->eventLogger->end('setup_root_fs'); + } + + /** + * Set up the filesystem for the specified path + */ + public function setupForPath(string $path): void { + if (substr_count($path, '/') < 2 || strpos($path, '/appdata_' . \OC_Util::getInstanceId()) === 0 || strpos($path, '/files_external/') === 0) { + $this->setupRoot(); + return; + } else { + [, $userId] = explode('/', $path); + } + + $user = $this->userManager->get($userId); + + if (!$user) { + $this->setupRoot(); + return; + } + + $this->setupForUser($user); + } + + public function tearDown() { + $this->setupUsers = []; + $this->rootSetup = false; + $this->mountManager->clear(); + $this->eventDispatcher->dispatchTyped(new FilesystemTornDownEvent()); + } + + /** + * Get mounts from mount providers that are registered after setup + */ + private function listenForNewMountProviders() { + if (!$this->listeningForProviders) { + $this->listeningForProviders = true; + $this->mountProviderCollection->listen('\OC\Files\Config', 'registerMountProvider', function (IMountProvider $provider) { + foreach ($this->setupUsers as $userId) { + $user = $this->userManager->get($userId); + if ($user) { + $mounts = $provider->getMountsForUser($user, Filesystem::getLoader()); + array_walk($mounts, [$this->mountManager, 'addMount']); + } + } + }); + } + } +} diff --git a/lib/private/Files/SetupManagerFactory.php b/lib/private/Files/SetupManagerFactory.php new file mode 100644 index 00000000000..5dd1601570d --- /dev/null +++ b/lib/private/Files/SetupManagerFactory.php @@ -0,0 +1,66 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2022 Robin Appelman <robin@icewind.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Files; + +use OCP\Diagnostics\IEventLogger; +use OCP\EventDispatcher\IEventDispatcher; +use OCP\Files\Config\IMountProviderCollection; +use OCP\Files\Config\IUserMountCache; +use OCP\Files\Mount\IMountManager; +use OCP\IUserManager; +use OCP\Lockdown\ILockdownManager; + +class SetupManagerFactory { + private IEventLogger $eventLogger; + private IMountProviderCollection $mountProviderCollection; + private IUserManager $userManager; + private IEventDispatcher $eventDispatcher; + private IUserMountCache $userMountCache; + private ILockdownManager $lockdownManager; + private ?SetupManager $setupManager; + + public function __construct( + IEventLogger $eventLogger, + IMountProviderCollection $mountProviderCollection, + IUserManager $userManager, + IEventDispatcher $eventDispatcher, + IUserMountCache $userMountCache, + ILockdownManager $lockdownManager + ) { + $this->eventLogger = $eventLogger; + $this->mountProviderCollection = $mountProviderCollection; + $this->userManager = $userManager; + $this->eventDispatcher = $eventDispatcher; + $this->userMountCache = $userMountCache; + $this->lockdownManager = $lockdownManager; + $this->setupManager = null; + } + + public function create(IMountManager $mountManager): SetupManager { + if (!$this->setupManager) { + $this->setupManager = new SetupManager($this->eventLogger, $this->mountProviderCollection, $mountManager, $this->userManager, $this->eventDispatcher, $this->userMountCache, $this->lockdownManager); + } + return $this->setupManager; + } +} diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php index 3cdc6166840..779e0611591 100644 --- a/lib/private/Files/View.php +++ b/lib/private/Files/View.php @@ -274,7 +274,7 @@ class View { /** * remove mount point * - * @param \OC\Files\Mount\MoveableMount $mount + * @param IMountPoint $mount * @param string $path relative to data/ * @return boolean */ @@ -719,7 +719,7 @@ class View { $postFix = (substr($path, -1) === '/') ? '/' : ''; $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); $mount = Filesystem::getMountManager()->find($absolutePath . $postFix); - if ($mount and $mount->getInternalPath($absolutePath) === '') { + if ($mount->getInternalPath($absolutePath) === '') { return $this->removeMount($mount, $absolutePath); } if ($this->is_dir($path)) { @@ -1383,10 +1383,6 @@ class View { $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); $mount = Filesystem::getMountManager()->find($path); - if (!$mount) { - \OC::$server->getLogger()->warning('Mountpoint not found for path: ' . $path); - return false; - } $storage = $mount->getStorage(); $internalPath = $mount->getInternalPath($path); if ($storage) { @@ -1488,7 +1484,7 @@ class View { $rootEntry = $subCache->get(''); if (!$rootEntry) { - $subScanner = $subStorage->getScanner(''); + $subScanner = $subStorage->getScanner(); try { $subScanner->scanFile(''); } catch (\OCP\Files\StorageNotAvailableException $e) { @@ -1739,12 +1735,13 @@ class View { $manager = Filesystem::getMountManager(); $mounts = $manager->findIn($this->fakeRoot); $mounts[] = $manager->find($this->fakeRoot); - // reverse the array so we start with the storage this view is in + $mounts = array_filter($mounts); + // reverse the array, so we start with the storage this view is in // which is the most likely to contain the file we're looking for $mounts = array_reverse($mounts); - // put non shared mounts in front of the shared mount - // this prevent unneeded recursion into shares + // put non-shared mounts in front of the shared mount + // this prevents unneeded recursion into shares usort($mounts, function (IMountPoint $a, IMountPoint $b) { return $a instanceof SharedMount && (!$b instanceof SharedMount) ? 1 : -1; }); @@ -1915,14 +1912,10 @@ class View { * @param string $absolutePath absolute path * @param bool $useParentMount true to return parent mount instead of whatever * is mounted directly on the given path, false otherwise - * @return \OC\Files\Mount\MountPoint mount point for which to apply locks + * @return IMountPoint mount point for which to apply locks */ private function getMountForLock($absolutePath, $useParentMount = false) { - $results = []; $mount = Filesystem::getMountManager()->find($absolutePath); - if (!$mount) { - return $results; - } if ($useParentMount) { // find out if something is mounted directly on the path diff --git a/lib/private/Server.php b/lib/private/Server.php index 8d1f377251c..38720ab71c0 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -95,6 +95,7 @@ use OC\Files\Mount\RootMountProvider; use OC\Files\Node\HookConnector; use OC\Files\Node\LazyRoot; use OC\Files\Node\Root; +use OC\Files\SetupManager; use OC\Files\Storage\StorageFactory; use OC\Files\Template\TemplateManager; use OC\Files\Type\Loader; @@ -216,6 +217,7 @@ use OCP\L10N\IFactory; use OCP\LDAP\ILDAPProvider; use OCP\LDAP\ILDAPProviderFactory; use OCP\Lock\ILockingProvider; +use OCP\Lockdown\ILockdownManager; use OCP\Log\ILogFactory; use OCP\Mail\IMailer; use OCP\Remote\Api\IApiFactory; @@ -423,7 +425,8 @@ class Server extends ServerContainer implements IServerContainer { null, $c->get(IUserMountCache::class), $this->get(ILogger::class), - $this->get(IUserManager::class) + $this->get(IUserManager::class), + $this->get(IEventDispatcher::class), ); $previewConnector = new \OC\Preview\WatcherConnector( @@ -1091,6 +1094,11 @@ class Server extends ServerContainer implements IServerContainer { /** @deprecated 19.0.0 */ $this->registerDeprecatedAlias('LockingProvider', ILockingProvider::class); + $this->registerAlias(ILockdownManager::class, 'LockdownManager'); + $this->registerService(SetupManager::class, function ($c) { + // create the setupmanager through the mount manager to resolve the cyclic dependency + return $c->get(\OC\Files\Mount\Manager::class)->getSetupManager(); + }); $this->registerAlias(IMountManager::class, \OC\Files\Mount\Manager::class); /** @deprecated 19.0.0 */ $this->registerDeprecatedAlias('MountManager', IMountManager::class); diff --git a/lib/private/legacy/OC_Util.php b/lib/private/legacy/OC_Util.php index 40dcbb13b93..ceed79bc9d5 100644 --- a/lib/private/legacy/OC_Util.php +++ b/lib/private/legacy/OC_Util.php @@ -66,6 +66,7 @@ use bantu\IniGetWrapper\IniGetWrapper; use OC\AppFramework\Http\Request; +use OC\Files\SetupManager; use OCP\Files\Template\ITemplateManager; use OCP\IConfig; use OCP\IGroupManager; @@ -78,8 +79,6 @@ class OC_Util { public static $scripts = []; public static $styles = []; public static $headers = []; - private static $rootFsSetup = false; - private static $fsSetup = false; /** @var array Local cache of version.php */ private static $versionCache = null; @@ -89,122 +88,6 @@ class OC_Util { } /** - * Can be set up - * - * @param string $user - * @return boolean - * @description configure the initial filesystem based on the configuration - * @suppress PhanDeprecatedFunction - * @suppress PhanAccessMethodInternal - */ - public static function setupRootFS(string $user = '') { - //setting up the filesystem twice can only lead to trouble - if (self::$rootFsSetup) { - return false; - } - - \OC::$server->getEventLogger()->start('setup_root_fs', 'Setup root filesystem'); - - // load all filesystem apps before, so no setup-hook gets lost - OC_App::loadApps(['filesystem']); - - self::$rootFsSetup = true; - - \OC\Files\Filesystem::initMountManager(); - - $prevLogging = \OC\Files\Filesystem::logWarningWhenAddingStorageWrapper(false); - \OC\Files\Filesystem::addStorageWrapper('mount_options', function ($mountPoint, \OCP\Files\Storage $storage, \OCP\Files\Mount\IMountPoint $mount) { - if ($storage->instanceOfStorage('\OC\Files\Storage\Common')) { - /** @var \OC\Files\Storage\Common $storage */ - $storage->setMountOptions($mount->getOptions()); - } - return $storage; - }); - - \OC\Files\Filesystem::addStorageWrapper('enable_sharing', function ($mountPoint, \OCP\Files\Storage\IStorage $storage, \OCP\Files\Mount\IMountPoint $mount) { - if (!$mount->getOption('enable_sharing', true)) { - return new \OC\Files\Storage\Wrapper\PermissionsMask([ - 'storage' => $storage, - 'mask' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_SHARE - ]); - } - return $storage; - }); - - // install storage availability wrapper, before most other wrappers - \OC\Files\Filesystem::addStorageWrapper('oc_availability', function ($mountPoint, \OCP\Files\Storage\IStorage $storage) { - if (!$storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage') && !$storage->isLocal()) { - return new \OC\Files\Storage\Wrapper\Availability(['storage' => $storage]); - } - return $storage; - }); - - \OC\Files\Filesystem::addStorageWrapper('oc_encoding', function ($mountPoint, \OCP\Files\Storage $storage, \OCP\Files\Mount\IMountPoint $mount) { - if ($mount->getOption('encoding_compatibility', false) && !$storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage') && !$storage->isLocal()) { - return new \OC\Files\Storage\Wrapper\Encoding(['storage' => $storage]); - } - return $storage; - }); - - \OC\Files\Filesystem::addStorageWrapper('oc_quota', function ($mountPoint, $storage) { - // set up quota for home storages, even for other users - // which can happen when using sharing - - /** - * @var \OC\Files\Storage\Storage $storage - */ - if ($storage->instanceOfStorage('\OC\Files\Storage\Home') - || $storage->instanceOfStorage('\OC\Files\ObjectStore\HomeObjectStoreStorage') - ) { - /** @var \OC\Files\Storage\Home $storage */ - if (is_object($storage->getUser())) { - $quota = OC_Util::getUserQuota($storage->getUser()); - if ($quota !== \OCP\Files\FileInfo::SPACE_UNLIMITED) { - return new \OC\Files\Storage\Wrapper\Quota(['storage' => $storage, 'quota' => $quota, 'root' => 'files']); - } - } - } - - return $storage; - }); - - \OC\Files\Filesystem::addStorageWrapper('readonly', function ($mountPoint, \OCP\Files\Storage\IStorage $storage, \OCP\Files\Mount\IMountPoint $mount) { - /* - * Do not allow any operations that modify the storage - */ - if ($mount->getOption('readonly', false)) { - return new \OC\Files\Storage\Wrapper\PermissionsMask([ - 'storage' => $storage, - 'mask' => \OCP\Constants::PERMISSION_ALL & ~( - \OCP\Constants::PERMISSION_UPDATE | - \OCP\Constants::PERMISSION_CREATE | - \OCP\Constants::PERMISSION_DELETE - ), - ]); - } - return $storage; - }); - - OC_Hook::emit('OC_Filesystem', 'preSetup', ['user' => $user]); - - \OC\Files\Filesystem::logWarningWhenAddingStorageWrapper($prevLogging); - - /** @var \OCP\Files\Config\IMountProviderCollection $mountProviderCollection */ - $mountProviderCollection = \OC::$server->query(\OCP\Files\Config\IMountProviderCollection::class); - $rootMountProviders = $mountProviderCollection->getRootMounts(); - - /** @var \OC\Files\Mount\Manager $mountManager */ - $mountManager = \OC\Files\Filesystem::getMountManager(); - foreach ($rootMountProviders as $rootMountProvider) { - $mountManager->addMount($rootMountProvider); - } - - \OC::$server->getEventLogger()->end('setup_root_fs'); - - return true; - } - - /** * Setup the file system * * @param string|null $user @@ -214,14 +97,6 @@ class OC_Util { * @suppress PhanAccessMethodInternal */ public static function setupFS(?string $user = '') { - self::setupRootFS($user ?? ''); - - if (self::$fsSetup) { - return false; - } - - \OC::$server->getEventLogger()->start('setup_fs', 'Setup filesystem'); - // If we are not forced to load a specific user we load the one that is logged in if ($user === '') { $userObject = \OC::$server->get(\OCP\IUserSession::class)->getUser(); @@ -229,18 +104,14 @@ class OC_Util { $userObject = \OC::$server->get(\OCP\IUserManager::class)->get($user); } - //if we aren't logged in, or the user doesn't exist, there is no use to set up the filesystem - if ($userObject) { - self::$fsSetup = true; - - $userDir = '/' . $userObject->getUID() . '/files'; - - //jail the user into his "home" directory - \OC\Files\Filesystem::init($userObject, $userDir); + /** @var SetupManager $setupManager */ + $setupManager = \OC::$server->get(SetupManager::class); - OC_Hook::emit('OC_Filesystem', 'setup', ['user' => $userObject->getUID(), 'user_dir' => $userDir]); + if ($userObject) { + $setupManager->setupForUser($userObject); + } else { + $setupManager->setupRoot(); } - \OC::$server->getEventLogger()->end('setup_fs'); return true; } @@ -394,10 +265,9 @@ class OC_Util { * @suppress PhanUndeclaredMethod */ public static function tearDownFS() { - \OC\Files\Filesystem::tearDown(); - \OC::$server->getRootFolder()->clearCache(); - self::$fsSetup = false; - self::$rootFsSetup = false; + /** @var SetupManager $setupManager */ + $setupManager = \OC::$server->get(SetupManager::class); + $setupManager->tearDown(); } /** diff --git a/lib/public/Files/Config/ICachedMountFileInfo.php b/lib/public/Files/Config/ICachedMountFileInfo.php index 4de0a1218b4..e6aa2ec38c8 100644 --- a/lib/public/Files/Config/ICachedMountFileInfo.php +++ b/lib/public/Files/Config/ICachedMountFileInfo.php @@ -34,11 +34,11 @@ interface ICachedMountFileInfo extends ICachedMountInfo { * @return string * @since 13.0.0 */ - public function getInternalPath(); + public function getInternalPath(): string; /** * @return string * @since 13.0.0 */ - public function getPath(); + public function getPath(): string; } diff --git a/lib/public/Files/Config/ICachedMountInfo.php b/lib/public/Files/Config/ICachedMountInfo.php index 812e79cdbc8..dafd2423fdc 100644 --- a/lib/public/Files/Config/ICachedMountInfo.php +++ b/lib/public/Files/Config/ICachedMountInfo.php @@ -35,31 +35,31 @@ interface ICachedMountInfo { * @return IUser * @since 9.0.0 */ - public function getUser(); + public function getUser(): IUser; /** * @return int the numeric storage id of the mount * @since 9.0.0 */ - public function getStorageId(); + public function getStorageId(): int; /** * @return int the fileid of the root of the mount * @since 9.0.0 */ - public function getRootId(); + public function getRootId(): int; /** - * @return Node the root node of the mount + * @return Node|null the root node of the mount * @since 9.0.0 */ - public function getMountPointNode(); + public function getMountPointNode(): ?Node; /** * @return string the mount point of the mount for the user * @since 9.0.0 */ - public function getMountPoint(); + public function getMountPoint(): string; /** * Get the id of the configured mount @@ -67,7 +67,7 @@ interface ICachedMountInfo { * @return int|null mount id or null if not applicable * @since 9.1.0 */ - public function getMountId(); + public function getMountId(): ?int; /** * Get the internal path (within the storage) of the root of the mount @@ -75,7 +75,7 @@ interface ICachedMountInfo { * @return string * @since 11.0.0 */ - public function getRootInternalPath(); + public function getRootInternalPath(): string; /** * Get the class of the mount provider that this mount originates from diff --git a/lib/public/Files/Events/Node/FilesystemTornDownEvent.php b/lib/public/Files/Events/Node/FilesystemTornDownEvent.php new file mode 100644 index 00000000000..3e7780c827e --- /dev/null +++ b/lib/public/Files/Events/Node/FilesystemTornDownEvent.php @@ -0,0 +1,34 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2022 Robin Appelman <robin@icewind.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP\Files\Events\Node; + +use OCP\EventDispatcher\Event; + +/** + * Event fired after the filesystem has been torn down + * + * @since 24.0.0 + */ +class FilesystemTornDownEvent extends Event { +} diff --git a/lib/public/Files/Mount/IMountManager.php b/lib/public/Files/Mount/IMountManager.php index 1e8c674f8f5..aa760f53e96 100644 --- a/lib/public/Files/Mount/IMountManager.php +++ b/lib/public/Files/Mount/IMountManager.php @@ -37,7 +37,7 @@ interface IMountManager { /** * Add a new mount * - * @param \OCP\Files\Mount\IMountPoint $mount + * @param IMountPoint $mount * @since 8.2.0 */ public function addMount(IMountPoint $mount); @@ -63,16 +63,16 @@ interface IMountManager { * Find the mount for $path * * @param string $path - * @return \OCP\Files\Mount\IMountPoint|null + * @return IMountPoint * @since 8.2.0 */ - public function find(string $path); + public function find(string $path): ?IMountPoint; /** * Find all mounts in $path * * @param string $path - * @return \OCP\Files\Mount\IMountPoint[] + * @return IMountPoint[] * @since 8.2.0 */ public function findIn(string $path): array; @@ -88,13 +88,13 @@ interface IMountManager { * Find mounts by storage id * * @param string $id - * @return \OCP\Files\Mount\IMountPoint[] + * @return IMountPoint[] * @since 8.2.0 */ public function findByStorageId(string $id): array; /** - * @return \OCP\Files\Mount\IMountPoint[] + * @return IMountPoint[] * @since 8.2.0 */ public function getAll(): array; @@ -103,7 +103,7 @@ interface IMountManager { * Find mounts by numeric storage id * * @param int $id - * @return \OCP\Files\Mount\IMountPoint[] + * @return IMountPoint[] * @since 8.2.0 */ public function findByNumericId(int $id): array; diff --git a/tests/lib/Cache/FileCacheTest.php b/tests/lib/Cache/FileCacheTest.php index a800fd005d9..41675b7c461 100644 --- a/tests/lib/Cache/FileCacheTest.php +++ b/tests/lib/Cache/FileCacheTest.php @@ -23,6 +23,7 @@ namespace Test\Cache; use OC\Files\Storage\Local; +use OCP\Files\Mount\IMountManager; use Test\Traits\UserTrait; /** @@ -68,15 +69,12 @@ class FileCacheTest extends TestCache { //clear all proxies and hooks so we can do clean testing \OC_Hook::clear('OC_Filesystem'); - //set up temporary storage - $this->storage = \OC\Files\Filesystem::getStorage('/'); - \OC\Files\Filesystem::clearMounts(); + /** @var IMountManager $manager */ + $manager = \OC::$server->get(IMountManager::class); + $manager->removeMount('/test'); + $storage = new \OC\Files\Storage\Temporary([]); - \OC\Files\Filesystem::mount($storage, [], '/'); - $datadir = str_replace('local::', '', $storage->getId()); - $config = \OC::$server->getConfig(); - $this->datadir = $config->getSystemValue('cachedirectory', \OC::$SERVERROOT.'/data/cache'); - $config->setSystemValue('cachedirectory', $datadir); + \OC\Files\Filesystem::mount($storage, [], '/test/cache'); //set up the users dir $this->rootView = new \OC\Files\View(''); @@ -94,17 +92,12 @@ class FileCacheTest extends TestCache { } \OC_User::setUserId($this->user); - \OC::$server->getConfig()->setSystemValue('cachedirectory', $this->datadir); if ($this->instance) { $this->instance->clear(); $this->instance = null; } - // Restore the original mount point - \OC\Files\Filesystem::clearMounts(); - \OC\Files\Filesystem::mount($this->storage, [], '/'); - parent::tearDown(); } diff --git a/tests/lib/Files/Cache/UpdaterLegacyTest.php b/tests/lib/Files/Cache/UpdaterLegacyTest.php index 6d6cc08b3de..be0390db15e 100644 --- a/tests/lib/Files/Cache/UpdaterLegacyTest.php +++ b/tests/lib/Files/Cache/UpdaterLegacyTest.php @@ -10,6 +10,7 @@ namespace Test\Files\Cache; use OC\Files\Filesystem as Filesystem; use OC\Files\View; +use OCP\Files\Mount\IMountManager; /** * Class UpdaterLegacyTest @@ -61,7 +62,10 @@ class UpdaterLegacyTest extends \Test\TestCase { Filesystem::init(self::$user, '/' . self::$user . '/files'); - Filesystem::clearMounts(); + /** @var IMountManager $manager */ + $manager = \OC::$server->get(IMountManager::class); + $manager->removeMount('/' . self::$user); + Filesystem::mount($this->storage, [], '/' . self::$user . '/files'); \OC_Hook::clear('OC_Filesystem'); diff --git a/tests/lib/Files/Cache/UpdaterTest.php b/tests/lib/Files/Cache/UpdaterTest.php index 4c99b24d9d6..7e0f6866793 100644 --- a/tests/lib/Files/Cache/UpdaterTest.php +++ b/tests/lib/Files/Cache/UpdaterTest.php @@ -50,8 +50,6 @@ class UpdaterTest extends \Test\TestCase { } protected function tearDown(): void { - Filesystem::clearMounts(); - $this->logout(); parent::tearDown(); } diff --git a/tests/lib/Files/Config/UserMountCacheTest.php b/tests/lib/Files/Config/UserMountCacheTest.php index 321ed2196fd..0922dab3672 100644 --- a/tests/lib/Files/Config/UserMountCacheTest.php +++ b/tests/lib/Files/Config/UserMountCacheTest.php @@ -45,6 +45,8 @@ class UserMountCacheTest extends TestCase { private $fileIds = []; protected function setUp(): void { + parent::setUp(); + $this->fileIds = []; $this->connection = \OC::$server->getDatabaseConnection(); $config = $this->getMockBuilder(IConfig::class) diff --git a/tests/lib/Files/Mount/ManagerTest.php b/tests/lib/Files/Mount/ManagerTest.php index 1e80ec17ea1..f69f8b239bb 100644 --- a/tests/lib/Files/Mount/ManagerTest.php +++ b/tests/lib/Files/Mount/ManagerTest.php @@ -8,6 +8,7 @@ namespace Test\Files\Mount; +use OC\Files\SetupManagerFactory; use OC\Files\Storage\Temporary; class LongId extends Temporary { @@ -24,12 +25,10 @@ class ManagerTest extends \Test\TestCase { protected function setUp(): void { parent::setUp(); - $this->manager = new \OC\Files\Mount\Manager(); + $this->manager = new \OC\Files\Mount\Manager($this->createMock(SetupManagerFactory::class)); } public function testFind() { - $this->assertNull($this->manager->find('/')); - $rootMount = new \OC\Files\Mount\MountPoint(new Temporary([]), '/'); $this->manager->addMount($rootMount); $this->assertEquals($rootMount, $this->manager->find('/')); diff --git a/tests/lib/Files/Node/FileTest.php b/tests/lib/Files/Node/FileTest.php index 6b5aaabbc28..c381fd9b2be 100644 --- a/tests/lib/Files/Node/FileTest.php +++ b/tests/lib/Files/Node/FileTest.php @@ -35,7 +35,7 @@ class FileTest extends NodeTest { public function testGetContent() { /** @var \OC\Files\Node\Root|\PHPUnit\Framework\MockObject\MockObject $root */ $root = $this->getMockBuilder('\OC\Files\Node\Root') - ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $hook = function ($file) { @@ -65,7 +65,7 @@ class FileTest extends NodeTest { /** @var \OC\Files\Node\Root|\PHPUnit\Framework\MockObject\MockObject $root */ $root = $this->getMockBuilder('\OC\Files\Node\Root') - ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $root->expects($this->any()) @@ -84,7 +84,7 @@ class FileTest extends NodeTest { public function testPutContent() { /** @var \OC\Files\Node\Root|\PHPUnit\Framework\MockObject\MockObject $root */ $root = $this->getMockBuilder('\OC\Files\Node\Root') - ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $root->expects($this->any()) @@ -111,7 +111,7 @@ class FileTest extends NodeTest { /** @var \OC\Files\Node\Root|\PHPUnit\Framework\MockObject\MockObject $root */ $root = $this->getMockBuilder('\OC\Files\Node\Root') - ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $this->view->expects($this->once()) @@ -126,7 +126,7 @@ class FileTest extends NodeTest { public function testGetMimeType() { /** @var \OC\Files\Node\Root|\PHPUnit\Framework\MockObject\MockObject $root */ $root = $this->getMockBuilder('\OC\Files\Node\Root') - ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $this->view->expects($this->once()) @@ -149,7 +149,8 @@ class FileTest extends NodeTest { $this->user, $this->userMountCache, $this->logger, - $this->userManager + $this->userManager, + $this->eventDispatcher ); $hook = function ($file) { @@ -184,7 +185,8 @@ class FileTest extends NodeTest { $this->user, $this->userMountCache, $this->logger, - $this->userManager + $this->userManager, + $this->eventDispatcher ); $hooksCalled = 0; $hook = function ($file) use (&$hooksCalled) { @@ -223,7 +225,8 @@ class FileTest extends NodeTest { $this->user, $this->userMountCache, $this->logger, - $this->userManager + $this->userManager, + $this->eventDispatcher ); $hook = function ($file) { throw new \Exception('Hooks are not supposed to be called'); @@ -248,7 +251,8 @@ class FileTest extends NodeTest { $this->user, $this->userMountCache, $this->logger, - $this->userManager + $this->userManager, + $this->eventDispatcher ); $hook = function () { throw new \Exception('Hooks are not supposed to be called'); @@ -273,7 +277,8 @@ class FileTest extends NodeTest { $this->user, $this->userMountCache, $this->logger, - $this->userManager + $this->userManager, + $this->eventDispatcher ); $hook = function () { throw new \Exception('Hooks are not supposed to be called'); diff --git a/tests/lib/Files/Node/FolderTest.php b/tests/lib/Files/Node/FolderTest.php index 72bd15d3922..d604786905d 100644 --- a/tests/lib/Files/Node/FolderTest.php +++ b/tests/lib/Files/Node/FolderTest.php @@ -61,7 +61,7 @@ class FolderTest extends NodeTest { */ $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $root->expects($this->any()) ->method('getUser') @@ -93,7 +93,7 @@ class FolderTest extends NodeTest { */ $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $root->expects($this->any()) ->method('getUser') @@ -113,7 +113,7 @@ class FolderTest extends NodeTest { */ $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $root->expects($this->any()) ->method('getUser') @@ -136,7 +136,7 @@ class FolderTest extends NodeTest { */ $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $root->expects($this->any()) ->method('getUser') @@ -157,7 +157,7 @@ class FolderTest extends NodeTest { */ $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $root->expects($this->any()) ->method('getUser') @@ -187,7 +187,7 @@ class FolderTest extends NodeTest { */ $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $root->method('getUser') ->willReturn($this->user); @@ -207,7 +207,7 @@ class FolderTest extends NodeTest { */ $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $root->expects($this->any()) ->method('getUser') @@ -237,7 +237,7 @@ class FolderTest extends NodeTest { */ $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $root->method('getUser') ->willReturn($this->user); @@ -257,7 +257,7 @@ class FolderTest extends NodeTest { */ $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $root->method('getUser') ->willReturn($this->user); @@ -277,7 +277,7 @@ class FolderTest extends NodeTest { */ $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $root->method('getUser') ->willReturn($this->user); @@ -321,7 +321,7 @@ class FolderTest extends NodeTest { $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) ->setMethods(['getUser', 'getMountsIn', 'getMount']) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $root->expects($this->any()) ->method('getUser') @@ -364,7 +364,7 @@ class FolderTest extends NodeTest { */ $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $root->method('getUser') ->willReturn($this->user); @@ -407,7 +407,7 @@ class FolderTest extends NodeTest { */ $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $root->expects($this->any()) ->method('getUser') @@ -479,7 +479,7 @@ class FolderTest extends NodeTest { $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) ->setMethods(['getMountsIn', 'getMount']) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $storage = $this->createMock(\OC\Files\Storage\Storage::class); $mount = new MountPoint($storage, '/bar'); @@ -530,7 +530,7 @@ class FolderTest extends NodeTest { $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) ->setMethods(['getMountsIn', 'getMount']) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $storage = $this->createMock(\OC\Files\Storage\Storage::class); $mount = new MountPoint($storage, '/bar'); @@ -577,7 +577,7 @@ class FolderTest extends NodeTest { $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) ->setMethods(['getMountsIn', 'getMount']) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $storage = $this->createMock(\OC\Files\Storage\Storage::class); $mount = new MountPoint($storage, '/bar'); @@ -627,7 +627,7 @@ class FolderTest extends NodeTest { $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) ->setMethods(['getMountsIn', 'getMount']) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $storage = $this->createMock(\OC\Files\Storage\Storage::class); $mount1 = new MountPoint($storage, '/bar'); @@ -697,7 +697,7 @@ class FolderTest extends NodeTest { $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) ->setMethods(['getUser', 'getMountsIn', 'getMount']) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $view->expects($this->any()) @@ -725,7 +725,7 @@ class FolderTest extends NodeTest { /** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\Node\Root $root */ $root = $this->getMockBuilder(Root::class) ->setMethods(['getUser', 'getMountsIn', 'getMount']) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); /** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\FileInfo $folderInfo */ $folderInfo = $this->getMockBuilder(FileInfo::class) @@ -793,7 +793,7 @@ class FolderTest extends NodeTest { /** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\Node\Root $root */ $root = $this->getMockBuilder(Root::class) ->setMethods(['getUser', 'getMountsIn', 'getMount']) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); /** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\FileInfo $folderInfo */ $folderInfo = $this->getMockBuilder(FileInfo::class) @@ -860,7 +860,7 @@ class FolderTest extends NodeTest { /** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\Node\Root $root */ $root = $this->getMockBuilder(Root::class) ->setMethods(['getUser', 'getMountsIn', 'getMount']) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); /** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\FileInfo $folderInfo */ $folderInfo = $this->getMockBuilder(FileInfo::class) @@ -947,7 +947,7 @@ class FolderTest extends NodeTest { */ $view = $this->createMock(View::class); $root = $this->getMockBuilder(Root::class) - ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->getMock(); $root->expects($this->any()) ->method('getUser') diff --git a/tests/lib/Files/Node/HookConnectorTest.php b/tests/lib/Files/Node/HookConnectorTest.php index 7990abad231..5e0b4017243 100644 --- a/tests/lib/Files/Node/HookConnectorTest.php +++ b/tests/lib/Files/Node/HookConnectorTest.php @@ -78,7 +78,8 @@ class HookConnectorTest extends TestCase { \OC::$server->getUserManager()->get($this->userId), \OC::$server->getUserMountCache(), $this->createMock(ILogger::class), - $this->createMock(IUserManager::class) + $this->createMock(IUserManager::class), + $this->createMock(IEventDispatcher::class) ); $this->legacyDispatcher = \OC::$server->getEventDispatcher(); $this->eventDispatcher = \OC::$server->query(IEventDispatcher::class); diff --git a/tests/lib/Files/Node/IntegrationTest.php b/tests/lib/Files/Node/IntegrationTest.php index 26cdf398d94..71e8793ad6f 100644 --- a/tests/lib/Files/Node/IntegrationTest.php +++ b/tests/lib/Files/Node/IntegrationTest.php @@ -11,9 +11,11 @@ namespace Test\Files\Node; use OC\Files\Node\Root; use OC\Files\Storage\Temporary; use OC\Files\View; -use OC\User\User; +use OCP\EventDispatcher\IEventDispatcher; +use OCP\Files\Mount\IMountManager; use OCP\ILogger; use OCP\IUserManager; +use Test\Traits\UserTrait; /** * Class IntegrationTest @@ -23,6 +25,8 @@ use OCP\IUserManager; * @package Test\Files\Node */ class IntegrationTest extends \Test\TestCase { + use UserTrait; + /** * @var \OC\Files\Node\Root $root */ @@ -41,11 +45,12 @@ class IntegrationTest extends \Test\TestCase { protected function setUp(): void { parent::setUp(); - $manager = \OC\Files\Filesystem::getMountManager(); + /** @var IMountManager $manager */ + $manager = \OC::$server->get(IMountManager::class); \OC_Hook::clear('OC_Filesystem'); - $user = new User($this->getUniqueID('user'), new \Test\Util\User\Dummy, \OC::$server->getEventDispatcher()); + $user = $this->createUser($this->getUniqueID('user'), ''); $this->loginAsUser($user->getUID()); $this->view = new View(); @@ -55,7 +60,8 @@ class IntegrationTest extends \Test\TestCase { $user, \OC::$server->getUserMountCache(), $this->createMock(ILogger::class), - $this->createMock(IUserManager::class) + $this->createMock(IUserManager::class), + $this->createMock(IEventDispatcher::class) ); $storage = new Temporary([]); $subStorage = new Temporary([]); @@ -63,6 +69,7 @@ class IntegrationTest extends \Test\TestCase { $this->storages[] = $subStorage; $this->root->mount($storage, '/'); $this->root->mount($subStorage, '/substorage/'); + $manager->removeMount('/' . $user->getUID()); } protected function tearDown(): void { diff --git a/tests/lib/Files/Node/NodeTest.php b/tests/lib/Files/Node/NodeTest.php index 6ea5a6d7ffa..a60a20b99f3 100644 --- a/tests/lib/Files/Node/NodeTest.php +++ b/tests/lib/Files/Node/NodeTest.php @@ -11,6 +11,7 @@ namespace Test\Files\Node; use OC\Files\FileInfo; use OC\Files\Mount\Manager; use OC\Files\View; +use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\IRootFolder; use OCP\Files\Node; use OCP\Files\NotFoundException; @@ -39,6 +40,8 @@ abstract class NodeTest extends \Test\TestCase { protected $logger; /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ protected $userManager; + /** @var IEventDispatcher|\PHPUnit\Framework\MockObject\MockObject */ + protected $eventDispatcher; protected function setUp(): void { parent::setUp(); @@ -55,8 +58,9 @@ abstract class NodeTest extends \Test\TestCase { ->getMock(); $this->logger = $this->createMock(ILogger::class); $this->userManager = $this->createMock(IUserManager::class); + $this->eventDispatcher = $this->createMock(IEventDispatcher::class); $this->root = $this->getMockBuilder('\OC\Files\Node\Root') - ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->eventDispatcher]) ->getMock(); } @@ -151,7 +155,8 @@ abstract class NodeTest extends \Test\TestCase { $this->user, $this->userMountCache, $this->logger, - $this->userManager + $this->userManager, + $this->eventDispatcher ); $root->listen('\OC\Files', 'preDelete', $preListener); @@ -409,7 +414,8 @@ abstract class NodeTest extends \Test\TestCase { $this->user, $this->userMountCache, $this->logger, - $this->userManager + $this->userManager, + $this->eventDispatcher ); $root->listen('\OC\Files', 'preTouch', $preListener); $root->listen('\OC\Files', 'postTouch', $postListener); @@ -592,7 +598,7 @@ abstract class NodeTest extends \Test\TestCase { public function testMoveCopyHooks($operationMethod, $viewMethod, $preHookName, $postHookName) { /** @var IRootFolder|\PHPUnit\Framework\MockObject\MockObject $root */ $root = $this->getMockBuilder('\OC\Files\Node\Root') - ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager]) + ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher]) ->setMethods(['get']) ->getMock(); diff --git a/tests/lib/Files/Node/RootTest.php b/tests/lib/Files/Node/RootTest.php index 13fdcb65902..a7f7dc02e01 100644 --- a/tests/lib/Files/Node/RootTest.php +++ b/tests/lib/Files/Node/RootTest.php @@ -13,6 +13,7 @@ use OC\Files\FileInfo; use OC\Files\Mount\Manager; use OC\Files\Node\Folder; use OC\Files\View; +use OCP\EventDispatcher\IEventDispatcher; use OCP\ILogger; use OCP\IUser; use OCP\IUserManager; @@ -33,6 +34,8 @@ class RootTest extends \Test\TestCase { private $logger; /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ private $userManager; + /** @var IEventDispatcher|\PHPUnit\Framework\MockObject\MockObject */ + private $eventDispatcher; protected function setUp(): void { parent::setUp(); @@ -46,6 +49,7 @@ class RootTest extends \Test\TestCase { ->getMock(); $this->logger = $this->createMock(ILogger::class); $this->userManager = $this->createMock(IUserManager::class); + $this->eventDispatcher = $this->createMock(IEventDispatcher::class); } protected function getFileInfo($data) { @@ -71,7 +75,8 @@ class RootTest extends \Test\TestCase { $this->user, $this->userMountCache, $this->logger, - $this->userManager + $this->userManager, + $this->eventDispatcher ); $view->expects($this->once()) @@ -107,7 +112,8 @@ class RootTest extends \Test\TestCase { $this->user, $this->userMountCache, $this->logger, - $this->userManager + $this->userManager, + $this->eventDispatcher ); $view->expects($this->once()) @@ -135,7 +141,8 @@ class RootTest extends \Test\TestCase { $this->user, $this->userMountCache, $this->logger, - $this->userManager + $this->userManager, + $this->eventDispatcher ); $root->get('/../foo'); @@ -157,7 +164,8 @@ class RootTest extends \Test\TestCase { $this->user, $this->userMountCache, $this->logger, - $this->userManager + $this->userManager, + $this->eventDispatcher ); $root->get('/bar/foo'); @@ -170,7 +178,8 @@ class RootTest extends \Test\TestCase { $this->user, $this->userMountCache, $this->logger, - $this->userManager + $this->userManager, + $this->eventDispatcher ); $user = $this->createMock(IUser::class); $user @@ -210,7 +219,8 @@ class RootTest extends \Test\TestCase { null, $this->userMountCache, $this->logger, - $this->userManager + $this->userManager, + $this->eventDispatcher ); $this->userManager ->expects($this->once()) diff --git a/tests/lib/Files/PathVerificationTest.php b/tests/lib/Files/PathVerificationTest.php index 18637daf9d7..3570acfaab4 100644 --- a/tests/lib/Files/PathVerificationTest.php +++ b/tests/lib/Files/PathVerificationTest.php @@ -30,7 +30,7 @@ class PathVerificationTest extends \Test\TestCase { $this->view = new View(); } - + public function testPathVerificationFileNameTooLong() { $this->expectException(\OCP\Files\InvalidPathException::class); $this->expectExceptionMessage('File name is too long'); diff --git a/tests/lib/Files/ViewTest.php b/tests/lib/Files/ViewTest.php index 15c9400864b..7b735720ff1 100644 --- a/tests/lib/Files/ViewTest.php +++ b/tests/lib/Files/ViewTest.php @@ -11,6 +11,7 @@ use OC\Cache\CappedMemoryCache; use OC\Files\Cache\Watcher; use OC\Files\Filesystem; use OC\Files\Mount\MountPoint; +use OC\Files\SetupManager; use OC\Files\Storage\Common; use OC\Files\Storage\Storage; use OC\Files\Storage\Temporary; @@ -19,6 +20,7 @@ use OCP\Constants; use OCP\Files\Config\IMountProvider; use OCP\Files\FileInfo; use OCP\Files\GenericFileException; +use OCP\Files\Mount\IMountManager; use OCP\Files\Storage\IStorage; use OCP\Lock\ILockingProvider; use OCP\Lock\LockedException; @@ -104,9 +106,10 @@ class ViewTest extends \Test\TestCase { $this->groupObject->addUser($this->userObject); self::loginAsUser($this->user); - // clear mounts but somehow keep the root storage - // that was initialized above... - Filesystem::clearMounts(); + + /** @var IMountManager $manager */ + $manager = \OC::$server->get(IMountManager::class); + $manager->removeMount('/test'); $this->tempStorage = null; } @@ -125,6 +128,10 @@ class ViewTest extends \Test\TestCase { self::logout(); + /** @var SetupManager $setupManager */ + $setupManager = \OC::$server->get(SetupManager::class); + $setupManager->setupRoot(); + $this->userObject->delete(); $this->groupObject->delete(); @@ -224,12 +231,14 @@ class ViewTest extends \Test\TestCase { $storage1 = $this->getTestStorage(); $storage2 = $this->getTestStorage(); $storage3 = $this->getTestStorage(); + Filesystem::mount($storage1, [], '/'); Filesystem::mount($storage2, [], '/substorage'); Filesystem::mount($storage3, [], '/folder/anotherstorage'); $rootView = new View(''); + $cachedData = $rootView->getFileInfo('/foo.txt'); /** @var int $id1 */ $id1 = $cachedData['fileid']; @@ -316,7 +325,6 @@ class ViewTest extends \Test\TestCase { public function testCacheIncompleteFolder() { $storage1 = $this->getTestStorage(false); - Filesystem::clearMounts(); Filesystem::mount($storage1, [], '/incomplete'); $rootView = new View('/incomplete'); diff --git a/tests/lib/HelperStorageTest.php b/tests/lib/HelperStorageTest.php index 4166d606366..6d7ea513d3f 100644 --- a/tests/lib/HelperStorageTest.php +++ b/tests/lib/HelperStorageTest.php @@ -9,6 +9,8 @@ namespace Test; use OC\Files\Storage\Temporary; +use OCP\Files\Mount\IMountManager; +use Test\Traits\UserTrait; /** * Test the storage functions of OC_Helper @@ -16,6 +18,8 @@ use OC\Files\Storage\Temporary; * @group DB */ class HelperStorageTest extends \Test\TestCase { + use UserTrait; + /** @var string */ private $user; /** @var \OC\Files\Storage\Storage */ @@ -27,14 +31,15 @@ class HelperStorageTest extends \Test\TestCase { parent::setUp(); $this->user = $this->getUniqueID('user_'); - \OC_User::useBackend('dummy'); - \OC::$server->getUserManager()->createUser($this->user, $this->user); + $this->createUser($this->user, $this->user); - $this->storage = \OC\Files\Filesystem::getStorage('/'); \OC\Files\Filesystem::tearDown(); \OC_User::setUserId($this->user); \OC\Files\Filesystem::init($this->user, '/' . $this->user . '/files'); - \OC\Files\Filesystem::clearMounts(); + + /** @var IMountManager $manager */ + $manager = \OC::$server->get(IMountManager::class); + $manager->removeMount('/' . $this->user); $this->storageMock = null; } @@ -47,13 +52,8 @@ class HelperStorageTest extends \Test\TestCase { $this->storageMock = null; } \OC\Files\Filesystem::tearDown(); - \OC\Files\Filesystem::mount($this->storage, [], '/'); \OC_User::setUserId(''); - $user = \OC::$server->getUserManager()->get($this->user); - if ($user !== null) { - $user->delete(); - } \OC::$server->getConfig()->deleteAllUserValues($this->user); parent::tearDown(); diff --git a/tests/lib/SubAdminTest.php b/tests/lib/SubAdminTest.php index a3a795ce392..907abf4b7d8 100644 --- a/tests/lib/SubAdminTest.php +++ b/tests/lib/SubAdminTest.php @@ -49,6 +49,8 @@ class SubAdminTest extends \Test\TestCase { private $groups; protected function setUp(): void { + parent::setUp(); + $this->users = []; $this->groups = []; diff --git a/tests/lib/TestCase.php b/tests/lib/TestCase.php index b5dcd76faf9..256fb95a85b 100644 --- a/tests/lib/TestCase.php +++ b/tests/lib/TestCase.php @@ -25,14 +25,21 @@ namespace Test; use DOMDocument; use DOMNode; use OC\Command\QueueBus; +use OC\Files\Config\MountProviderCollection; use OC\Files\Filesystem; +use OC\Files\Mount\CacheMountProvider; +use OC\Files\Mount\LocalHomeMountProvider; +use OC\Files\Mount\RootMountProvider; +use OC\Files\SetupManager; use OC\Template\Base; use OCP\Command\IBus; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Defaults; +use OCP\IConfig; use OCP\IDBConnection; use OCP\IL10N; use OCP\Security\ISecureRandom; +use Psr\Log\LoggerInterface; abstract class TestCase extends \PHPUnit\Framework\TestCase { /** @var \OC\Command\QueueBus */ @@ -276,6 +283,22 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase { self::tearDownAfterClassCleanStrayHooks(); self::tearDownAfterClassCleanStrayLocks(); + /** @var SetupManager $setupManager */ + $setupManager = \OC::$server->get(SetupManager::class); + $setupManager->tearDown(); + + /** @var MountProviderCollection $mountProviderCollection */ + $mountProviderCollection = \OC::$server->get(MountProviderCollection::class); + $mountProviderCollection->clearProviders(); + + /** @var IConfig $config */ + $config = \OC::$server->get(IConfig::class); + $mountProviderCollection->registerProvider(new CacheMountProvider($config)); + $mountProviderCollection->registerHomeProvider(new LocalHomeMountProvider()); + $mountProviderCollection->registerRootProvider(new RootMountProvider($config, \OC::$server->get(LoggerInterface::class))); + + $setupManager->setupRoot(); + parent::tearDownAfterClass(); } diff --git a/tests/lib/Traits/EncryptionTrait.php b/tests/lib/Traits/EncryptionTrait.php index 6b74f7ca8ee..9cb64c12d00 100644 --- a/tests/lib/Traits/EncryptionTrait.php +++ b/tests/lib/Traits/EncryptionTrait.php @@ -9,12 +9,13 @@ namespace Test\Traits; use OC\Encryption\EncryptionWrapper; -use OC\Files\Filesystem; +use OC\Files\SetupManager; use OC\Memcache\ArrayCache; use OCA\Encryption\AppInfo\Application; use OCA\Encryption\KeyManager; use OCA\Encryption\Users\Setup; use OCP\Encryption\IManager; +use OCP\IUserManager; /** * Enables encryption @@ -31,6 +32,11 @@ trait EncryptionTrait { private $originalEncryptionModule; + /** @var IUserManager */ + private $userManager; + /** @var SetupManager */ + private $setupManager; + /** * @var \OCP\IConfig */ @@ -47,18 +53,20 @@ trait EncryptionTrait { // needed for fully logout \OC::$server->getUserSession()->setUser(null); - Filesystem::tearDown(); + $this->setupManager->tearDown(); + \OC_User::setUserId($user); $this->postLogin(); \OC_Util::setupFS($user); - if (\OC::$server->getUserManager()->userExists($user)) { + if ($this->userManager->userExists($user)) { \OC::$server->getUserFolder($user); } } protected function setupForUser($name, $password) { - \OC_Util::tearDownFS(); - \OC_Util::setupFS($name); + $this->setupManager->tearDown(); + $this->setupManager->setupForUser($this->userManager->get($name)); + $container = $this->encryptionApp->getContainer(); /** @var KeyManager $keyManager */ $keyManager = $container->query(KeyManager::class); @@ -86,6 +94,9 @@ trait EncryptionTrait { $this->markTestSkipped('Encryption not ready'); } + $this->userManager = \OC::$server->get(IUserManager::class); + $this->setupManager = \OC::$server->get(SetupManager::class); + \OC_App::loadApp('encryption'); $this->encryptionApp = new Application([], $isReady); diff --git a/tests/lib/Traits/UserTrait.php b/tests/lib/Traits/UserTrait.php index 229087a5200..3f7cfe419db 100644 --- a/tests/lib/Traits/UserTrait.php +++ b/tests/lib/Traits/UserTrait.php @@ -8,6 +8,21 @@ namespace Test\Traits; +use OC\User\User; +use OCP\IUser; + +class DummyUser extends User { + private string $uid; + + public function __construct(string $uid) { + $this->uid = $uid; + } + + public function getUID(): string { + return $this->uid; + } +} + /** * Allow creating users in a temporary backend */ @@ -17,8 +32,9 @@ trait UserTrait { */ protected $userBackend; - protected function createUser($name, $password) { + protected function createUser($name, $password): IUser { $this->userBackend->createUser($name, $password); + return new DummyUser($name); } protected function setUpUserTrait() { |