diff options
author | Vincent Petry <vincent@nextcloud.com> | 2022-02-10 09:58:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-10 09:58:57 +0100 |
commit | e80e0d515f2db24dcaad82e5880ff102912849d8 (patch) | |
tree | 5477c8c4d47f5880ed6e2f8d8ff2f1a933bb01e4 | |
parent | b22f680e7790df5dfe500d789bbdf3ab379ec257 (diff) | |
parent | de260001f1992c9a711be436a58dc19b8e876180 (diff) | |
download | nextcloud-server-e80e0d515f2db24dcaad82e5880ff102912849d8.tar.gz nextcloud-server-e80e0d515f2db24dcaad82e5880ff102912849d8.zip |
Merge pull request #30942 from nextcloud/appdata-lite-filesystem
only setup part of the filesystem for appdata requests
-rw-r--r-- | lib/private/Files/Filesystem.php | 47 | ||||
-rw-r--r-- | lib/private/Files/Mount/Manager.php | 13 | ||||
-rw-r--r-- | lib/private/legacy/OC_User.php | 2 | ||||
-rw-r--r-- | lib/private/legacy/OC_Util.php | 71 | ||||
-rw-r--r-- | tests/lib/Cache/FileCacheTest.php | 22 |
5 files changed, 86 insertions, 69 deletions
diff --git a/lib/private/Files/Filesystem.php b/lib/private/Files/Filesystem.php index fb300134c86..e439b746bf6 100644 --- a/lib/private/Files/Filesystem.php +++ b/lib/private/Files/Filesystem.php @@ -45,6 +45,7 @@ use OCP\Files\Config\IMountProvider; use OCP\Files\NotFoundException; use OCP\Files\Storage\IStorageFactory; use OCP\ILogger; +use OCP\IUser; use OCP\IUserManager; class Filesystem { @@ -240,9 +241,7 @@ class Filesystem { * @return \OC\Files\Mount\Manager */ public static function getMountManager($user = '') { - if (!self::$mounts) { - \OC_Util::setupFS($user); - } + self::initMountManager(); return self::$mounts; } @@ -292,10 +291,7 @@ class Filesystem { * @return \OC\Files\Storage\Storage|null */ public static function getStorage($mountPoint) { - if (!self::$mounts) { - \OC_Util::setupFS(); - } - $mount = self::$mounts->find($mountPoint); + $mount = self::getMountManager()->find($mountPoint); return $mount->getStorage(); } @@ -304,10 +300,7 @@ class Filesystem { * @return Mount\MountPoint[] */ public static function getMountByStorageId($id) { - if (!self::$mounts) { - \OC_Util::setupFS(); - } - return self::$mounts->findByStorageId($id); + return self::getMountManager()->findByStorageId($id); } /** @@ -315,10 +308,7 @@ class Filesystem { * @return Mount\MountPoint[] */ public static function getMountByNumericId($id) { - if (!self::$mounts) { - \OC_Util::setupFS(); - } - return self::$mounts->findByNumericId($id); + return self::getMountManager()->findByNumericId($id); } /** @@ -328,10 +318,7 @@ class Filesystem { * @return array an array consisting of the storage and the internal path */ public static function resolvePath($path) { - if (!self::$mounts) { - \OC_Util::setupFS(); - } - $mount = self::$mounts->find($path); + $mount = self::getMountManager()->find($path); if ($mount) { return [$mount->getStorage(), rtrim($mount->getInternalPath($path), '/')]; } else { @@ -367,14 +354,25 @@ class Filesystem { /** * Initialize system and personal mount points for a user * - * @param string $user + * @param string|IUser|null $user * @throws \OC\User\NoUserException if the user is not available */ public static function initMountPoints($user = '') { - if ($user == '') { - $user = \OC_User::getUser(); + $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 ($user === null || $user === false || $user === '') { + + if ($userObject === null || $user === false || $user === '') { throw new \OC\User\NoUserException('Attempted to initialize mount points for null user and no user in session'); } @@ -384,9 +382,6 @@ class Filesystem { self::$usersSetup[$user] = true; - $userManager = \OC::$server->getUserManager(); - $userObject = $userManager->get($user); - 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 diff --git a/lib/private/Files/Mount/Manager.php b/lib/private/Files/Mount/Manager.php index d9abab8997a..8c6f1acceec 100644 --- a/lib/private/Files/Mount/Manager.php +++ b/lib/private/Files/Mount/Manager.php @@ -81,6 +81,15 @@ 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(); + } else { + \OC_Util::setupFS(); + } + } + /** * Find the mount for $path * @@ -88,7 +97,7 @@ class Manager implements IMountManager { * @return MountPoint|null */ public function find(string $path) { - \OC_Util::setupFS(); + $this->setupForFind($path); $path = Filesystem::normalizePath($path); if (isset($this->pathCache[$path])) { @@ -121,7 +130,7 @@ class Manager implements IMountManager { * @return MountPoint[] */ public function findIn(string $path): array { - \OC_Util::setupFS(); + $this->setupForFind($path); $path = $this->formatPath($path); if (isset($this->inPathCache[$path])) { diff --git a/lib/private/legacy/OC_User.php b/lib/private/legacy/OC_User.php index 27c4f6b2857..bc47359dafc 100644 --- a/lib/private/legacy/OC_User.php +++ b/lib/private/legacy/OC_User.php @@ -323,7 +323,7 @@ class OC_User { /** * get the user id of the user currently logged in. * - * @return string|bool uid or false + * @return string|false uid or false */ public static function getUser() { $uid = \OC::$server->getSession() ? \OC::$server->getSession()->get('user_id') : null; diff --git a/lib/private/legacy/OC_Util.php b/lib/private/legacy/OC_Util.php index abe7e59f695..9110678537f 100644 --- a/lib/private/legacy/OC_Util.php +++ b/lib/private/legacy/OC_Util.php @@ -81,6 +81,7 @@ class OC_Util { public static $styles = []; public static $headers = []; private static $rootMounted = false; + private static $rootFsSetup = false; private static $fsSetup = false; /** @var array Local cache of version.php */ @@ -186,30 +187,18 @@ class OC_Util { * @suppress PhanDeprecatedFunction * @suppress PhanAccessMethodInternal */ - public static function setupFS($user = '') { + public static function setupRootFS(string $user = '') { //setting up the filesystem twice can only lead to trouble - if (self::$fsSetup) { + if (self::$rootFsSetup) { 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 === null) { - $user = ''; - } elseif ($user == "" && \OC::$server->getUserSession()->isLoggedIn()) { - $user = OC_User::getUser(); - } + \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']); - // the filesystem will finish when $user is not empty, - // mark fs setup here to avoid doing the setup from loading - // OC_Filesystem - if ($user != '') { - self::$fsSetup = true; - } + self::$rootFsSetup = true; \OC\Files\Filesystem::initMountManager(); @@ -277,10 +266,10 @@ class OC_Util { 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 - ), + \OCP\Constants::PERMISSION_UPDATE | + \OCP\Constants::PERMISSION_CREATE | + \OCP\Constants::PERMISSION_DELETE + ), ]); } return $storage; @@ -313,19 +302,46 @@ class OC_Util { $mountManager->addMount($rootMountProvider); } - if ($user != '' && !\OC::$server->getUserManager()->userExists($user)) { - \OC::$server->getEventLogger()->end('setup_fs'); + \OC::$server->getEventLogger()->end('setup_root_fs'); + + return true; + } + + /** + * Setup the file system + * + * @param string|null $user + * @return boolean + * @description configure the initial filesystem based on the configuration + * @suppress PhanDeprecatedFunction + * @suppress PhanAccessMethodInternal + */ + public static function setupFS(?string $user = '') { + self::setupRootFS($user ?? ''); + + if (self::$fsSetup) { return false; } - //if we aren't logged in, there is no use to set up the filesystem - if ($user != "") { - $userDir = '/' . $user . '/files'; + \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(); + } else { + $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($user, $userDir); + \OC\Files\Filesystem::init($userObject, $userDir); - OC_Hook::emit('OC_Filesystem', 'setup', ['user' => $user, 'user_dir' => $userDir]); + OC_Hook::emit('OC_Filesystem', 'setup', ['user' => $userObject->getUID(), 'user_dir' => $userDir]); } \OC::$server->getEventLogger()->end('setup_fs'); return true; @@ -484,6 +500,7 @@ class OC_Util { \OC\Files\Filesystem::tearDown(); \OC::$server->getRootFolder()->clearCache(); self::$fsSetup = false; + self::$rootFsSetup = false; self::$rootMounted = false; } diff --git a/tests/lib/Cache/FileCacheTest.php b/tests/lib/Cache/FileCacheTest.php index 5791e28eb0c..a800fd005d9 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 Test\Traits\UserTrait; /** * Class FileCacheTest @@ -32,6 +33,8 @@ use OC\Files\Storage\Local; * @package Test\Cache */ class FileCacheTest extends TestCache { + use UserTrait; + /** * @var string * */ @@ -56,6 +59,12 @@ class FileCacheTest extends TestCache { protected function setUp(): void { parent::setUp(); + //login + $this->createUser('test', 'test'); + + $this->user = \OC_User::getUser(); + \OC_User::setUserId('test'); + //clear all proxies and hooks so we can do clean testing \OC_Hook::clear('OC_Filesystem'); @@ -69,15 +78,6 @@ class FileCacheTest extends TestCache { $this->datadir = $config->getSystemValue('cachedirectory', \OC::$SERVERROOT.'/data/cache'); $config->setSystemValue('cachedirectory', $datadir); - \OC_User::clearBackends(); - \OC_User::useBackend(new \Test\Util\User\Dummy()); - - //login - \OC::$server->getUserManager()->createUser('test', 'test'); - - $this->user = \OC_User::getUser(); - \OC_User::setUserId('test'); - //set up the users dir $this->rootView = new \OC\Files\View(''); $this->rootView->mkdir('/test'); @@ -101,10 +101,6 @@ class FileCacheTest extends TestCache { $this->instance = null; } - //tear down the users dir aswell - $user = \OC::$server->getUserManager()->get('test'); - $user->delete(); - // Restore the original mount point \OC\Files\Filesystem::clearMounts(); \OC\Files\Filesystem::mount($this->storage, [], '/'); |