summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Petry <vincent@nextcloud.com>2022-02-10 09:58:57 +0100
committerGitHub <noreply@github.com>2022-02-10 09:58:57 +0100
commite80e0d515f2db24dcaad82e5880ff102912849d8 (patch)
tree5477c8c4d47f5880ed6e2f8d8ff2f1a933bb01e4
parentb22f680e7790df5dfe500d789bbdf3ab379ec257 (diff)
parentde260001f1992c9a711be436a58dc19b8e876180 (diff)
downloadnextcloud-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.php47
-rw-r--r--lib/private/Files/Mount/Manager.php13
-rw-r--r--lib/private/legacy/OC_User.php2
-rw-r--r--lib/private/legacy/OC_Util.php71
-rw-r--r--tests/lib/Cache/FileCacheTest.php22
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, [], '/');