@@ -24,6 +24,7 @@ namespace OC\Files\Config; | |||
use OC\Hooks\Emitter; | |||
use OC\Hooks\EmitterTrait; | |||
use OCP\Files\Config\IHomeMountProvider; | |||
use OCP\Files\Config\IMountProviderCollection; | |||
use OCP\Files\Config\IMountProvider; | |||
use OCP\Files\Config\IUserMountCache; | |||
@@ -34,6 +35,11 @@ use OCP\IUser; | |||
class MountProviderCollection implements IMountProviderCollection, Emitter { | |||
use EmitterTrait; | |||
/** | |||
* @var \OCP\Files\Config\IHomeMountProvider[] | |||
*/ | |||
private $homeProviders = []; | |||
/** | |||
* @var \OCP\Files\Config\IMountProvider[] | |||
*/ | |||
@@ -77,6 +83,25 @@ class MountProviderCollection implements IMountProviderCollection, Emitter { | |||
}, array()); | |||
} | |||
/** | |||
* Get the configured home mount for this user | |||
* | |||
* @param \OCP\IUser $user | |||
* @return \OCP\Files\Mount\IMountPoint | |||
* @since 9.1.0 | |||
*/ | |||
public function getHomeMountForUser(IUser $user) { | |||
/** @var \OCP\Files\Config\IHomeMountProvider[] $providers */ | |||
$providers = array_reverse($this->homeProviders); // call the latest registered provider first to give apps an opportunity to overwrite builtin | |||
foreach ($providers as $homeProvider) { | |||
if ($mount = $homeProvider->getHomeMountForUser($user, $this->loader)) { | |||
$mount->setMountPoint('/' . $user->getUID()); //make sure the mountpoint is what we expect | |||
return $mount; | |||
} | |||
} | |||
throw new \Exception('No home storage configured for user ' . $user); | |||
} | |||
/** | |||
* Add a provider for mount points | |||
* | |||
@@ -87,6 +112,17 @@ class MountProviderCollection implements IMountProviderCollection, Emitter { | |||
$this->emit('\OC\Files\Config', 'registerMountProvider', [$provider]); | |||
} | |||
/** | |||
* Add a provider for home mount points | |||
* | |||
* @param \OCP\Files\Config\IHomeMountProvider $provider | |||
* @since 9.1.0 | |||
*/ | |||
public function registerHomeProvider(IHomeMountProvider $provider) { | |||
$this->homeProviders[] = $provider; | |||
$this->emit('\OC\Files\Config', 'registerHomeMountProvider', [$provider]); | |||
} | |||
/** | |||
* Cache mounts for user | |||
* |
@@ -397,7 +397,6 @@ class Filesystem { | |||
if (isset(self::$usersSetup[$user])) { | |||
return; | |||
} | |||
$root = \OC_User::getHome($user); | |||
$userManager = \OC::$server->getUserManager(); | |||
$userObject = $userManager->get($user); | |||
@@ -409,50 +408,26 @@ class Filesystem { | |||
self::$usersSetup[$user] = true; | |||
$homeStorage = \OC::$server->getConfig()->getSystemValue('objectstore'); | |||
if (!empty($homeStorage)) { | |||
// sanity checks | |||
if (empty($homeStorage['class'])) { | |||
\OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR); | |||
} | |||
if (!isset($homeStorage['arguments'])) { | |||
$homeStorage['arguments'] = array(); | |||
} | |||
// instantiate object store implementation | |||
$homeStorage['arguments']['objectstore'] = new $homeStorage['class']($homeStorage['arguments']); | |||
// mount with home object store implementation | |||
$homeStorage['class'] = '\OC\Files\ObjectStore\HomeObjectStoreStorage'; | |||
} else { | |||
$homeStorage = array( | |||
//default home storage configuration: | |||
'class' => '\OC\Files\Storage\Home', | |||
'arguments' => array() | |||
); | |||
} | |||
$homeStorage['arguments']['user'] = $userObject; | |||
/** @var \OC\Files\Config\MountProviderCollection $mountConfigManager */ | |||
$mountConfigManager = \OC::$server->getMountProviderCollection(); | |||
// check for legacy home id (<= 5.0.12) | |||
if (\OC\Files\Cache\Storage::exists('local::' . $root . '/')) { | |||
$homeStorage['arguments']['legacy'] = true; | |||
} | |||
// home mounts are handled seperate since we need to ensure this is mounted before we call the other mount providers | |||
$homeMount = $mountConfigManager->getHomeMountForUser($userObject); | |||
$mount = new MountPoint($homeStorage['class'], '/' . $user, $homeStorage['arguments'], self::getLoader()); | |||
self::getMountManager()->addMount($mount); | |||
self::getMountManager()->addMount($homeMount); | |||
$home = \OC\Files\Filesystem::getStorage($user); | |||
\OC\Files\Filesystem::getStorage($user); | |||
// Chance to mount for other storages | |||
/** @var \OC\Files\Config\MountProviderCollection $mountConfigManager */ | |||
$mountConfigManager = \OC::$server->getMountProviderCollection(); | |||
if ($userObject) { | |||
$mounts = $mountConfigManager->getMountsForUser($userObject); | |||
array_walk($mounts, array(self::$mounts, 'addMount')); | |||
$mounts[] = $mount; | |||
$mounts[] = $homeMount; | |||
$mountConfigManager->registerMounts($userObject, $mounts); | |||
} | |||
self::listenForNewMountProviders($mountConfigManager, $userManager); | |||
\OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user, 'user_dir' => $root)); | |||
\OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user)); | |||
} | |||
/** |
@@ -0,0 +1,46 @@ | |||
<?php | |||
/** | |||
* @author Robin Appelman <icewind@owncloud.com> | |||
* | |||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* 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, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace OC\Files\Mount; | |||
use OCP\Files\Config\IHomeMountProvider; | |||
use OCP\Files\Storage\IStorageFactory; | |||
use OCP\IUser; | |||
/** | |||
* Mount provider for regular posix home folders | |||
*/ | |||
class LocalHomeMountProvider implements IHomeMountProvider { | |||
/** | |||
* Get the cache mount for a user | |||
* | |||
* @param IUser $user | |||
* @param IStorageFactory $loader | |||
* @return \OCP\Files\Mount\IMountPoint[] | |||
*/ | |||
public function getHomeMountForUser(IUser $user, IStorageFactory $loader) { | |||
$arguments = ['user' => $user]; | |||
if (\OC\Files\Cache\Storage::exists('local::' . $user->getHome() . '/')) { | |||
$arguments['legacy'] = true; | |||
} | |||
return new MountPoint('\OC\Files\Storage\Home', '/' . $user->getUID(), $arguments, $loader); | |||
} | |||
} |
@@ -0,0 +1,73 @@ | |||
<?php | |||
/** | |||
* @author Robin Appelman <icewind@owncloud.com> | |||
* | |||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* 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, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace OC\Files\Mount; | |||
use OCP\Files\Config\IHomeMountProvider; | |||
use OCP\Files\Storage\IStorageFactory; | |||
use OCP\IConfig; | |||
use OCP\IUser; | |||
/** | |||
* Mount provider for object store home storages | |||
*/ | |||
class ObjectHomeMountProvider implements IHomeMountProvider { | |||
/** | |||
* @var IConfig | |||
*/ | |||
private $config; | |||
/** | |||
* ObjectStoreHomeMountProvider constructor. | |||
* | |||
* @param IConfig $config | |||
*/ | |||
public function __construct(IConfig $config) { | |||
$this->config = $config; | |||
} | |||
/** | |||
* Get the cache mount for a user | |||
* | |||
* @param IUser $user | |||
* @param IStorageFactory $loader | |||
* @return \OCP\Files\Mount\IMountPoint[] | |||
*/ | |||
public function getHomeMountForUser(IUser $user, IStorageFactory $loader) { | |||
$config = $this->config->getSystemValue('objectstore'); | |||
if (!is_array($config)) { | |||
return null; //fall back to local home provider | |||
} | |||
// sanity checks | |||
if (empty($config['class'])) { | |||
\OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR); | |||
} | |||
if (!isset($config['arguments'])) { | |||
$config['arguments'] = []; | |||
} | |||
$config['arguments']['user'] = $user; | |||
// instantiate object store implementation | |||
$config['arguments']['objectstore'] = new $config['class']($config['arguments']); | |||
return new MountPoint('\OC\Files\ObjectStore\HomeObjectStoreStorage', '/' . $user->getUID(), $config['arguments'], $loader); | |||
} | |||
} |
@@ -49,6 +49,8 @@ use OC\Diagnostics\QueryLogger; | |||
use OC\Files\Config\UserMountCache; | |||
use OC\Files\Config\UserMountCacheListener; | |||
use OC\Files\Mount\CacheMountProvider; | |||
use OC\Files\Mount\LocalHomeMountProvider; | |||
use OC\Files\Mount\ObjectHomeMountProvider; | |||
use OC\Files\Node\HookConnector; | |||
use OC\Files\Node\LazyRoot; | |||
use OC\Files\Node\Root; | |||
@@ -479,6 +481,8 @@ class Server extends ServerContainer implements IServerContainer { | |||
$config = $c->getConfig(); | |||
$manager->registerProvider(new CacheMountProvider($config)); | |||
$manager->registerHomeProvider(new LocalHomeMountProvider()); | |||
$manager->registerHomeProvider(new ObjectHomeMountProvider($config)); | |||
return $manager; | |||
}); |
@@ -0,0 +1,43 @@ | |||
<?php | |||
/** | |||
* @author Morris Jobke <hey@morrisjobke.de> | |||
* @author Robin Appelman <icewind@owncloud.com> | |||
* | |||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* 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, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace OCP\Files\Config; | |||
use OCP\Files\Storage\IStorageFactory; | |||
use OCP\IUser; | |||
/** | |||
* Provides | |||
* | |||
* @since 9.1.0 | |||
*/ | |||
interface IHomeMountProvider { | |||
/** | |||
* Get all mountpoints applicable for the user | |||
* | |||
* @param \OCP\IUser $user | |||
* @param \OCP\Files\Storage\IStorageFactory $loader | |||
* @return \OCP\Files\Mount\IMountPoint|null | |||
* @since 9.1.0 | |||
*/ | |||
public function getHomeMountForUser(IUser $user, IStorageFactory $loader); | |||
} |
@@ -39,6 +39,15 @@ interface IMountProviderCollection { | |||
*/ | |||
public function getMountsForUser(IUser $user); | |||
/** | |||
* Get the configured home mount for this user | |||
* | |||
* @param \OCP\IUser $user | |||
* @return \OCP\Files\Mount\IMountPoint | |||
* @since 9.1.0 | |||
*/ | |||
public function getHomeMountForUser(IUser $user); | |||
/** | |||
* Add a provider for mount points | |||
* | |||
@@ -47,6 +56,14 @@ interface IMountProviderCollection { | |||
*/ | |||
public function registerProvider(IMountProvider $provider); | |||
/** | |||
* Add a provider for home mount points | |||
* | |||
* @param \OCP\Files\Config\IHomeMountProvider $provider | |||
* @since 9.1.0 | |||
*/ | |||
public function registerHomeProvider(IHomeMountProvider $provider); | |||
/** | |||
* Get the mount cache which can be used to search for mounts without setting up the filesystem | |||
* |