move user mountpoint setup to setupmanager

Signed-off-by: Robin Appelman <robin@icewind.nl>
pull/31431/head
Robin Appelman 2 years ago
parent d81713e5c1
commit 07a7dcb824
No known key found for this signature in database
GPG Key ID: 42B69D8A64526EFB

@ -1164,6 +1164,7 @@ return array(
'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',

@ -1193,6 +1193,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'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',

@ -183,16 +183,6 @@ class MountProviderCollection implements IMountProviderCollection, Emitter {
$this->emit('\OC\Files\Config', 'registerHomeMountProvider', [$provider]);
}
/**
* 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
*

@ -41,6 +41,7 @@ use OC\Cache\CappedMemoryCache;
use OC\Files\Config\MountProviderCollection;
use OC\Files\Mount\MountPoint;
use OC\Lockdown\Filesystem\NullStorage;
use OC\User\NoUserException;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Config\IMountProvider;
use OCP\Files\Events\Node\FilesystemTornDownEvent;
@ -367,106 +368,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();
/** @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 {
$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);
} 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();
}
}

@ -23,6 +23,8 @@ declare(strict_types=1);
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;
@ -31,19 +33,24 @@ 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\IMountProviderCollection;
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\ILogger;
use OCP\IUser;
use OCP\IUserManager;
use OCP\Lockdown\ILockdownManager;
class SetupManager {
private bool $rootSetup = false;
@ -53,19 +60,27 @@ class SetupManager {
private IUserManager $userManager;
private array $setupUsers = [];
private IEventDispatcher $eventDispatcher;
private IUserMountCache $userMountCache;
private ILockdownManager $lockdownManager;
private bool $listeningForProviders;
public function __construct(
IEventLogger $eventLogger,
IMountProviderCollection $mountProviderCollection,
IMountManager $mountManager,
IUserManager $userManager,
IEventDispatcher $eventDispatcher
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() {
@ -161,6 +176,34 @@ class SetupManager {
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');
@ -221,4 +264,22 @@ class SetupManager {
$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']);
}
}
});
}
}
}

@ -26,32 +26,40 @@ 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
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->setupManager = new SetupManager($this->eventLogger, $this->mountProviderCollection, $mountManager, $this->userManager, $this->eventDispatcher, $this->userMountCache, $this->lockdownManager);
}
return $this->setupManager;
}

@ -217,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;
@ -1093,6 +1094,7 @@ 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();

Loading…
Cancel
Save