Merge pull request #30942 from nextcloud/appdata-lite-filesystem

only setup part of the filesystem for appdata requests
This commit is contained in:
Vincent Petry 2022-02-10 09:58:57 +01:00 committed by GitHub
commit e80e0d515f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 86 additions and 69 deletions

View file

@ -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

View file

@ -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])) {

View file

@ -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;

View file

@ -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;
}

View file

@ -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, [], '/');