mirror of
https://github.com/nextcloud/server.git
synced 2026-04-15 22:11:17 -04:00
start moving filesystem setup logic to it's own place
Signed-off-by: Robin Appelman <robin@icewind.nl>
This commit is contained in:
parent
7630d7a934
commit
15ff65c12f
3 changed files with 215 additions and 141 deletions
|
|
@ -30,18 +30,28 @@ namespace OC\Files\Mount;
|
|||
|
||||
use OC\Cache\CappedMemoryCache;
|
||||
use OC\Files\Filesystem;
|
||||
use OC\Files\SetupManager;
|
||||
use OCP\Diagnostics\IEventLogger;
|
||||
use OCP\Files\Config\IMountProviderCollection;
|
||||
use OCP\Files\Mount\IMountManager;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
use OCP\IUserSession;
|
||||
|
||||
class Manager implements IMountManager {
|
||||
/** @var MountPoint[] */
|
||||
private array $mounts = [];
|
||||
private CappedMemoryCache $pathCache;
|
||||
private CappedMemoryCache $inPathCache;
|
||||
private SetupManager $setupManager;
|
||||
|
||||
public function __construct() {
|
||||
public function __construct(
|
||||
IEventLogger $eventLogger,
|
||||
IMountProviderCollection $mountProviderCollection,
|
||||
IUserSession $userSession
|
||||
) {
|
||||
$this->pathCache = new CappedMemoryCache();
|
||||
$this->inPathCache = new CappedMemoryCache();
|
||||
$this->setupManager = new SetupManager($eventLogger, $mountProviderCollection, $this, $userSession);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -80,12 +90,12 @@ class Manager implements IMountManager {
|
|||
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();
|
||||
$this->setupManager->setupRoot();
|
||||
} elseif (strpos($path, '/files_external/uploads/') === 0) {
|
||||
// for OC\Security\CertificateManager, we only setup the root bits, not the user bits
|
||||
\OC_Util::setupRootFS();
|
||||
$this->setupManager->setupRoot();
|
||||
} else {
|
||||
\OC_Util::setupFS();
|
||||
$this->setupManager->setupForCurrentUser();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
194
lib/private/Files/SetupManager.php
Normal file
194
lib/private/Files/SetupManager.php
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
<?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\Storage\Common;
|
||||
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_App;
|
||||
use OC_Hook;
|
||||
use OC_Util;
|
||||
use OCP\Constants;
|
||||
use OCP\Diagnostics\IEventLogger;
|
||||
use OCP\Files\Config\IMountProviderCollection;
|
||||
use OCP\Files\IHomeStorage;
|
||||
use OCP\Files\Mount\IMountManager;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
use OCP\Files\Storage\IStorage;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserSession;
|
||||
|
||||
class SetupManager {
|
||||
private bool $rootSetup = false;
|
||||
private IEventLogger $eventLogger;
|
||||
private IMountProviderCollection $mountProviderCollection;
|
||||
private IMountManager $mountManager;
|
||||
private IUserSession $userSession;
|
||||
private array $setupUsers = [];
|
||||
|
||||
public function __construct(
|
||||
IEventLogger $eventLogger,
|
||||
IMountProviderCollection $mountProviderCollection,
|
||||
IMountManager $mountManager,
|
||||
IUserSession $userSession
|
||||
) {
|
||||
$this->eventLogger = $eventLogger;
|
||||
$this->mountProviderCollection = $mountProviderCollection;
|
||||
$this->mountManager = $mountManager;
|
||||
$this->userSession = $userSession;
|
||||
}
|
||||
|
||||
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(IHomeStorage::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;
|
||||
});
|
||||
}
|
||||
|
||||
public function setupForCurrentUser() {
|
||||
$user = $this->userSession->getUser();
|
||||
if ($user) {
|
||||
$this->setupForUser($user);
|
||||
} else {
|
||||
$this->setupRoot();
|
||||
}
|
||||
}
|
||||
|
||||
public function setupForUser(IUser $user) {
|
||||
$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);
|
||||
|
||||
OC_Hook::emit('OC_Filesystem', 'setup', ['user' => $user->getUID(), 'user_dir' => $userDir]);
|
||||
|
||||
$this->eventLogger->end('setup_fs');
|
||||
}
|
||||
|
||||
public function setupRoot() {
|
||||
//setting up the filesystem twice can only lead to trouble
|
||||
if ($this->rootSetup) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->eventLogger->start('setup_root_fs', 'Setup root filesystem');
|
||||
|
||||
// load all filesystem apps before, so no setup-hook gets lost
|
||||
OC_App::loadApps(['filesystem']);
|
||||
|
||||
$this->rootSetup = true;
|
||||
$prevLogging = Filesystem::logWarningWhenAddingStorageWrapper(false);
|
||||
|
||||
$this->setupBuiltinWrappers();
|
||||
|
||||
Filesystem::logWarningWhenAddingStorageWrapper($prevLogging);
|
||||
|
||||
$rootMountProviders = $this->mountProviderCollection->getRootMounts();
|
||||
foreach ($rootMountProviders as $rootMountProvider) {
|
||||
$this->mountManager->addMount($rootMountProvider);
|
||||
}
|
||||
|
||||
$this->eventLogger->end('setup_root_fs');
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -88,122 +87,6 @@ class OC_Util {
|
|||
return \OC::$server->getAppManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
|
@ -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,19 +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
|
||||
/** @var SetupManager $setupManager */
|
||||
$setupManager = \OC::$server->get(SetupManager::class);
|
||||
|
||||
if ($userObject) {
|
||||
self::$fsSetup = true;
|
||||
|
||||
$userDir = '/' . $userObject->getUID() . '/files';
|
||||
|
||||
//jail the user into his "home" directory
|
||||
\OC\Files\Filesystem::init($userObject, $userDir);
|
||||
|
||||
OC_Hook::emit('OC_Filesystem', 'setup', ['user' => $userObject->getUID(), 'user_dir' => $userDir]);
|
||||
$setupManager->setupForUser($userObject);
|
||||
} else {
|
||||
$setupManager->setupRoot();
|
||||
}
|
||||
\OC::$server->getEventLogger()->end('setup_fs');
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue