diff options
author | Vincent Petry <pvince81@owncloud.com> | 2014-10-09 18:18:36 +0200 |
---|---|---|
committer | Vincent Petry <pvince81@owncloud.com> | 2014-10-09 18:18:36 +0200 |
commit | 9dea79e341fcc28e6a4e1d8e88f6a7f6ec1bf3fb (patch) | |
tree | ceb66a37bae3611184e861872eed2e11ffe3ccd5 | |
parent | c82e310e202265dcc9ce78e1a50639ae5ee03c30 (diff) | |
parent | 26e242a8a4480f813d6d1ad15f3bf5c2f5025b48 (diff) | |
download | nextcloud-server-9dea79e341fcc28e6a4e1d8e88f6a7f6ec1bf3fb.tar.gz nextcloud-server-9dea79e341fcc28e6a4e1d8e88f6a7f6ec1bf3fb.zip |
Merge pull request #11305 from owncloud/ext-updateetagonmount
Update etag of parent dir when adding/removing ext storage mount points
-rwxr-xr-x | apps/files_external/lib/config.php | 45 | ||||
-rw-r--r-- | apps/files_external/lib/etagpropagator.php | 126 | ||||
-rw-r--r-- | apps/files_external/tests/etagpropagator.php | 328 | ||||
-rw-r--r-- | apps/files_external/tests/mountconfig.php | 134 | ||||
-rw-r--r-- | lib/private/allconfig.php | 9 | ||||
-rw-r--r-- | lib/private/files/filesystem.php | 5 | ||||
-rw-r--r-- | lib/public/iconfig.php | 7 |
7 files changed, 653 insertions, 1 deletions
diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 952463b8015..92bb891ca21 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -118,6 +118,22 @@ class OC_Mount_Config { } $manager->addMount($mount); } + + if ($data['user']) { + $user = \OC::$server->getUserManager()->get($data['user']); + $userView = new \OC\Files\View('/' . $user->getUID() . '/files'); + $changePropagator = new \OC\Files\Cache\ChangePropagator($userView); + $etagPropagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, \OC::$server->getConfig()); + $etagPropagator->propagateDirtyMountPoints(); + \OCP\Util::connectHook( + \OC\Files\Filesystem::CLASSNAME, + \OC\Files\Filesystem::signal_create_mount, + $etagPropagator, 'updateHook'); + \OCP\Util::connectHook( + \OC\Files\Filesystem::CLASSNAME, + \OC\Files\Filesystem::signal_delete_mount, + $etagPropagator, 'updateHook'); + } } /** @@ -463,6 +479,7 @@ class OC_Mount_Config { $priority = null) { $backends = self::getBackends(); $mountPoint = OC\Files\Filesystem::normalizePath($mountPoint); + $relMountPoint = $mountPoint; if ($mountPoint === '' || $mountPoint === '/') { // can't mount at root folder return false; @@ -495,6 +512,10 @@ class OC_Mount_Config { } $mountPoints = self::readData($isPersonal ? OCP\User::getUser() : NULL); + // who else loves multi-dimensional array ? + $isNew = !isset($mountPoints[$mountType]) || + !isset($mountPoints[$mountType][$applicable]) || + !isset($mountPoints[$mountType][$applicable][$mountPoint]); $mountPoints = self::mergeMountPoints($mountPoints, $mount, $mountType); // Set default priority if none set @@ -510,7 +531,19 @@ class OC_Mount_Config { self::writeData($isPersonal ? OCP\User::getUser() : NULL, $mountPoints); - return self::getBackendStatus($class, $classOptions, $isPersonal); + $result = self::getBackendStatus($class, $classOptions, $isPersonal); + if ($result && $isNew) { + \OC_Hook::emit( + \OC\Files\Filesystem::CLASSNAME, + \OC\Files\Filesystem::signal_create_mount, + array( + \OC\Files\Filesystem::signal_param_path => $relMountPoint, + \OC\Files\Filesystem::signal_param_mount_type => $mountType, + \OC\Files\Filesystem::signal_param_users => $applicable, + ) + ); + } + return $result; } /** @@ -523,6 +556,7 @@ class OC_Mount_Config { */ public static function removeMountPoint($mountPoint, $mountType, $applicable, $isPersonal = false) { // Verify that the mount point applies for the current user + $relMountPoints = $mountPoint; if ($isPersonal) { if ($applicable != OCP\User::getUser()) { return false; @@ -543,6 +577,15 @@ class OC_Mount_Config { } } self::writeData($isPersonal ? OCP\User::getUser() : NULL, $mountPoints); + \OC_Hook::emit( + \OC\Files\Filesystem::CLASSNAME, + \OC\Files\Filesystem::signal_delete_mount, + array( + \OC\Files\Filesystem::signal_param_path => $relMountPoints, + \OC\Files\Filesystem::signal_param_mount_type => $mountType, + \OC\Files\Filesystem::signal_param_users => $applicable, + ) + ); return true; } diff --git a/apps/files_external/lib/etagpropagator.php b/apps/files_external/lib/etagpropagator.php new file mode 100644 index 00000000000..80a3849b150 --- /dev/null +++ b/apps/files_external/lib/etagpropagator.php @@ -0,0 +1,126 @@ +<?php +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCA\Files_External; + +use OC\Files\Filesystem; + +/** + * Updates the etag of parent folders whenever a new external storage mount + * point has been created or deleted. Updates need to be triggered using + * the updateHook() method. + * + * There are two modes of operation: + * - for personal mount points, the etag is propagated directly + * - for system mount points, a dirty flag is saved in the configuration and + * the etag will be updated the next time propagateDirtyMountPoints() is called + */ +class EtagPropagator { + /** + * @var \OCP\IUser + */ + protected $user; + + /** + * @var \OC\Files\Cache\ChangePropagator + */ + protected $changePropagator; + + /** + * @var \OCP\IConfig + */ + protected $config; + + /** + * @param \OCP\IUser $user current user, must match the propagator's + * user + * @param \OC\Files\Cache\ChangePropagator $changePropagator change propagator + * initialized with a view for $user + * @param \OCP\IConfig $config + */ + public function __construct($user, $changePropagator, $config) { + $this->user = $user; + $this->changePropagator = $changePropagator; + $this->config = $config; + } + + /** + * Propagate the etag changes for all mountpoints marked as dirty and mark the mountpoints as clean + * + * @param int $time + */ + public function propagateDirtyMountPoints($time = null) { + if ($time === null) { + $time = time(); + } + $mountPoints = $this->getDirtyMountPoints(); + foreach ($mountPoints as $mountPoint) { + $this->changePropagator->addChange($mountPoint); + $this->config->setUserValue($this->user->getUID(), 'files_external', $mountPoint, $time); + } + if (count($mountPoints)) { + $this->changePropagator->propagateChanges($time); + } + } + + /** + * Get all mountpoints we need to update the etag for + * + * @return string[] + */ + protected function getDirtyMountPoints() { + $dirty = array(); + $mountPoints = $this->config->getAppKeys('files_external'); + foreach ($mountPoints as $mountPoint) { + if (substr($mountPoint, 0, 1) === '/') { + $updateTime = $this->config->getAppValue('files_external', $mountPoint); + $userTime = $this->config->getUserValue($this->user->getUID(), 'files_external', $mountPoint); + if ($updateTime > $userTime) { + $dirty[] = $mountPoint; + } + } + } + return $dirty; + } + + /** + * @param string $mountPoint + * @param int $time + */ + protected function markDirty($mountPoint, $time = null) { + if ($time === null) { + $time = time(); + } + $this->config->setAppValue('files_external', $mountPoint, $time); + } + + /** + * Update etags for mount points for known user + * For global or group mount points, updating the etag for every user is not feasible + * instead we mark the mount point as dirty and update the etag when the filesystem is loaded for the user + * For personal mount points, the change is propagated directly + * + * @param array $params hook parameters + * @param int $time update time to use when marking a mount point as dirty + */ + public function updateHook($params, $time = null) { + if ($time === null) { + $time = time(); + } + $users = $params[Filesystem::signal_param_users]; + $type = $params[Filesystem::signal_param_mount_type]; + $mountPoint = $params[Filesystem::signal_param_path]; + $mountPoint = Filesystem::normalizePath($mountPoint); + if ($type === \OC_Mount_Config::MOUNT_TYPE_GROUP or $users === 'all') { + $this->markDirty($mountPoint, $time); + } else { + $this->changePropagator->addChange($mountPoint); + $this->changePropagator->propagateChanges($time); + } + } +} diff --git a/apps/files_external/tests/etagpropagator.php b/apps/files_external/tests/etagpropagator.php new file mode 100644 index 00000000000..7fa1863f962 --- /dev/null +++ b/apps/files_external/tests/etagpropagator.php @@ -0,0 +1,328 @@ +<?php +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Tests\Files_External; + +use OC\Files\Filesystem; +use OC\User\User; + +class EtagPropagator extends \PHPUnit_Framework_TestCase { + protected function getUser() { + return new User(uniqid(), null); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject | \OC\Files\Cache\ChangePropagator + */ + protected function getChangePropagator() { + return $this->getMockBuilder('\OC\Files\Cache\ChangePropagator') + ->disableOriginalConstructor() + ->getMock(); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject | \OCP\IConfig + */ + protected function getConfig() { + $appConfig = array(); + $userConfig = array(); + $mock = $this->getMockBuilder('\OCP\IConfig') + ->disableOriginalConstructor() + ->getMock(); + + $mock->expects($this->any()) + ->method('getAppValue') + ->will($this->returnCallback(function ($appId, $key, $default = null) use (&$appConfig) { + if (isset($appConfig[$appId]) and isset($appConfig[$appId][$key])) { + return $appConfig[$appId][$key]; + } else { + return $default; + } + })); + $mock->expects($this->any()) + ->method('setAppValue') + ->will($this->returnCallback(function ($appId, $key, $value) use (&$appConfig) { + if (!isset($appConfig[$appId])) { + $appConfig[$appId] = array(); + } + $appConfig[$appId][$key] = $value; + })); + $mock->expects($this->any()) + ->method('getAppKeys') + ->will($this->returnCallback(function ($appId) use (&$appConfig) { + if (!isset($appConfig[$appId])) { + $appConfig[$appId] = array(); + } + return array_keys($appConfig[$appId]); + })); + + $mock->expects($this->any()) + ->method('getUserValue') + ->will($this->returnCallback(function ($userId, $appId, $key, $default = null) use (&$userConfig) { + if (isset($userConfig[$userId]) and isset($userConfig[$userId][$appId]) and isset($userConfig[$userId][$appId][$key])) { + return $userConfig[$userId][$appId][$key]; + } else { + return $default; + } + })); + $mock->expects($this->any()) + ->method('setUserValue') + ->will($this->returnCallback(function ($userId, $appId, $key, $value) use (&$userConfig) { + if (!isset($userConfig[$userId])) { + $userConfig[$userId] = array(); + } + if (!isset($userConfig[$userId][$appId])) { + $userConfig[$userId][$appId] = array(); + } + $userConfig[$userId][$appId][$key] = $value; + })); + + return $mock; + } + + public function testSingleUserMount() { + $time = time(); + $user = $this->getUser(); + $config = $this->getConfig(); + $changePropagator = $this->getChangePropagator(); + $propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config); + + $changePropagator->expects($this->once()) + ->method('addChange') + ->with('/test'); + $changePropagator->expects($this->once()) + ->method('propagateChanges') + ->with($time); + + $propagator->updateHook(array( + Filesystem::signal_param_path => '/test', + Filesystem::signal_param_mount_type => \OC_Mount_Config::MOUNT_TYPE_USER, + Filesystem::signal_param_users => $user->getUID(), + ), $time); + } + + public function testGlobalMountNoDirectUpdate() { + $time = time(); + $user = $this->getUser(); + $config = $this->getConfig(); + $changePropagator = $this->getChangePropagator(); + $propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config); + + // not updated directly + $changePropagator->expects($this->never()) + ->method('addChange'); + $changePropagator->expects($this->never()) + ->method('propagateChanges'); + + $propagator->updateHook(array( + Filesystem::signal_param_path => '/test', + Filesystem::signal_param_mount_type => \OC_Mount_Config::MOUNT_TYPE_USER, + Filesystem::signal_param_users => 'all', + ), $time); + + // mount point marked as dirty + $this->assertEquals(array('/test'), $config->getAppKeys('files_external')); + $this->assertEquals($time, $config->getAppValue('files_external', '/test')); + } + + public function testGroupMountNoDirectUpdate() { + $time = time(); + $user = $this->getUser(); + $config = $this->getConfig(); + $changePropagator = $this->getChangePropagator(); + $propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config); + + // not updated directly + $changePropagator->expects($this->never()) + ->method('addChange'); + $changePropagator->expects($this->never()) + ->method('propagateChanges'); + + $propagator->updateHook(array( + Filesystem::signal_param_path => '/test', + Filesystem::signal_param_mount_type => \OC_Mount_Config::MOUNT_TYPE_GROUP, + Filesystem::signal_param_users => 'test', + ), $time); + + // mount point marked as dirty + $this->assertEquals(array('/test'), $config->getAppKeys('files_external')); + $this->assertEquals($time, $config->getAppValue('files_external', '/test')); + } + + public function testGlobalMountNoDirtyMountPoint() { + $time = time(); + $user = $this->getUser(); + $config = $this->getConfig(); + $changePropagator = $this->getChangePropagator(); + $propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config); + + $changePropagator->expects($this->never()) + ->method('addChange'); + $changePropagator->expects($this->never()) + ->method('propagateChanges'); + + $propagator->propagateDirtyMountPoints($time); + + $this->assertEquals(0, $config->getUserValue($user->getUID(), 'files_external', '/test', 0)); + } + + public function testGlobalMountDirtyMountPointFirstTime() { + $time = time(); + $user = $this->getUser(); + $config = $this->getConfig(); + $changePropagator = $this->getChangePropagator(); + $propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config); + + $config->setAppValue('files_external', '/test', $time - 10); + + $changePropagator->expects($this->once()) + ->method('addChange') + ->with('/test'); + $changePropagator->expects($this->once()) + ->method('propagateChanges') + ->with($time); + + $propagator->propagateDirtyMountPoints($time); + + $this->assertEquals($time, $config->getUserValue($user->getUID(), 'files_external', '/test')); + } + + public function testGlobalMountNonDirtyMountPoint() { + $time = time(); + $user = $this->getUser(); + $config = $this->getConfig(); + $changePropagator = $this->getChangePropagator(); + $propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config); + + $config->setAppValue('files_external', '/test', $time - 10); + $config->setUserValue($user->getUID(), 'files_external', '/test', $time - 10); + + $changePropagator->expects($this->never()) + ->method('addChange'); + $changePropagator->expects($this->never()) + ->method('propagateChanges'); + + $propagator->propagateDirtyMountPoints($time); + + $this->assertEquals($time - 10, $config->getUserValue($user->getUID(), 'files_external', '/test')); + } + + public function testGlobalMountNonDirtyMountPointOtherUser() { + $time = time(); + $user = $this->getUser(); + $user2 = $this->getUser(); + $config = $this->getConfig(); + $changePropagator = $this->getChangePropagator(); + $propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config); + + $config->setAppValue('files_external', '/test', $time - 10); + $config->setUserValue($user2->getUID(), 'files_external', '/test', $time - 10); + + $changePropagator->expects($this->once()) + ->method('addChange') + ->with('/test'); + $changePropagator->expects($this->once()) + ->method('propagateChanges') + ->with($time); + + $propagator->propagateDirtyMountPoints($time); + + $this->assertEquals($time, $config->getUserValue($user->getUID(), 'files_external', '/test')); + } + + public function testGlobalMountDirtyMountPointSecondTime() { + $time = time(); + $user = $this->getUser(); + $config = $this->getConfig(); + $changePropagator = $this->getChangePropagator(); + $propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config); + + $config->setAppValue('files_external', '/test', $time - 10); + $config->setUserValue($user->getUID(), 'files_external', '/test', $time - 20); + + $changePropagator->expects($this->once()) + ->method('addChange') + ->with('/test'); + $changePropagator->expects($this->once()) + ->method('propagateChanges') + ->with($time); + + $propagator->propagateDirtyMountPoints($time); + + $this->assertEquals($time, $config->getUserValue($user->getUID(), 'files_external', '/test')); + } + + public function testGlobalMountMultipleUsers() { + $time = time(); + $config = $this->getConfig(); + $user1 = $this->getUser(); + $user2 = $this->getUser(); + $user3 = $this->getUser(); + $changePropagator1 = $this->getChangePropagator(); + $changePropagator2 = $this->getChangePropagator(); + $changePropagator3 = $this->getChangePropagator(); + $propagator1 = new \OCA\Files_External\EtagPropagator($user1, $changePropagator1, $config); + $propagator2 = new \OCA\Files_External\EtagPropagator($user2, $changePropagator2, $config); + $propagator3 = new \OCA\Files_External\EtagPropagator($user3, $changePropagator3, $config); + + $config->setAppValue('files_external', '/test', $time - 10); + + $changePropagator1->expects($this->once()) + ->method('addChange') + ->with('/test'); + $changePropagator1->expects($this->once()) + ->method('propagateChanges') + ->with($time); + + $propagator1->propagateDirtyMountPoints($time); + + $this->assertEquals($time, $config->getUserValue($user1->getUID(), 'files_external', '/test')); + $this->assertEquals(0, $config->getUserValue($user2->getUID(), 'files_external', '/test', 0)); + $this->assertEquals(0, $config->getUserValue($user3->getUID(), 'files_external', '/test', 0)); + + $changePropagator2->expects($this->once()) + ->method('addChange') + ->with('/test'); + $changePropagator2->expects($this->once()) + ->method('propagateChanges') + ->with($time); + + $propagator2->propagateDirtyMountPoints($time); + + $this->assertEquals($time, $config->getUserValue($user1->getUID(), 'files_external', '/test')); + $this->assertEquals($time, $config->getUserValue($user2->getUID(), 'files_external', '/test', 0)); + $this->assertEquals(0, $config->getUserValue($user3->getUID(), 'files_external', '/test', 0)); + } + + public function testGlobalMountMultipleDirtyMountPoints() { + $time = time(); + $user = $this->getUser(); + $config = $this->getConfig(); + $changePropagator = $this->getChangePropagator(); + $propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config); + + $config->setAppValue('files_external', '/test', $time - 10); + $config->setAppValue('files_external', '/foo', $time - 50); + $config->setAppValue('files_external', '/bar', $time - 70); + + $config->setUserValue($user->getUID(), 'files_external', '/foo', $time - 70); + $config->setUserValue($user->getUID(), 'files_external', '/bar', $time - 70); + + $changePropagator->expects($this->exactly(2)) + ->method('addChange'); + $changePropagator->expects($this->once()) + ->method('propagateChanges') + ->with($time); + + $propagator->propagateDirtyMountPoints($time); + + $this->assertEquals($time, $config->getUserValue($user->getUID(), 'files_external', '/test')); + $this->assertEquals($time, $config->getUserValue($user->getUID(), 'files_external', '/foo')); + $this->assertEquals($time - 70, $config->getUserValue($user->getUID(), 'files_external', '/bar')); + } +} diff --git a/apps/files_external/tests/mountconfig.php b/apps/files_external/tests/mountconfig.php index fc482823843..c11e48b82f3 100644 --- a/apps/files_external/tests/mountconfig.php +++ b/apps/files_external/tests/mountconfig.php @@ -26,6 +26,42 @@ class Test_Mount_Config_Dummy_Storage { } } +class Test_Mount_Config_Hook_Test { + static $signal; + static $params; + + public static function setUpHooks() { + self::clear(); + \OCP\Util::connectHook( + \OC\Files\Filesystem::CLASSNAME, + \OC\Files\Filesystem::signal_create_mount, + '\Test_Mount_Config_Hook_Test', 'createHookCallback'); + \OCP\Util::connectHook( + \OC\Files\Filesystem::CLASSNAME, + \OC\Files\Filesystem::signal_delete_mount, + '\Test_Mount_Config_Hook_Test', 'deleteHookCallback'); + } + + public static function clear() { + self::$signal = null; + self::$params = null; + } + + public static function createHookCallback($params) { + self::$signal = \OC\Files\Filesystem::signal_create_mount; + self::$params = $params; + } + + public static function deleteHookCallback($params) { + self::$signal = \OC\Files\Filesystem::signal_delete_mount; + self::$params = $params; + } + + public static function getLastCall() { + return array(self::$signal, self::$params); + } +} + /** * Class Test_Mount_Config */ @@ -77,9 +113,11 @@ class Test_Mount_Config extends \PHPUnit_Framework_TestCase { ); OC_Mount_Config::$skipTest = true; + Test_Mount_Config_Hook_Test::setupHooks(); } public function tearDown() { + Test_Mount_Config_Hook_Test::clear(); OC_Mount_Config::$skipTest = false; \OC_User::deleteUser(self::TEST_USER2); @@ -337,6 +375,102 @@ class Test_Mount_Config extends \PHPUnit_Framework_TestCase { $this->assertEquals(array_keys($options), array_keys($savedOptions)); } + public function testHooks() { + $mountPoint = '/test'; + $mountType = 'user'; + $applicable = 'all'; + $isPersonal = false; + + $mountConfig = array( + 'host' => 'smbhost', + 'user' => 'smbuser', + 'password' => 'smbpassword', + 'share' => 'smbshare', + 'root' => 'smbroot' + ); + + // write config + $this->assertTrue( + OC_Mount_Config::addMountPoint( + $mountPoint, + '\OC\Files\Storage\SMB', + $mountConfig, + $mountType, + $applicable, + $isPersonal + ) + ); + + list($hookName, $params) = Test_Mount_Config_Hook_Test::getLastCall(); + $this->assertEquals( + \OC\Files\Filesystem::signal_create_mount, + $hookName + ); + $this->assertEquals( + $mountPoint, + $params[\OC\Files\Filesystem::signal_param_path] + ); + $this->assertEquals( + $mountType, + $params[\OC\Files\Filesystem::signal_param_mount_type] + ); + $this->assertEquals( + $applicable, + $params[\OC\Files\Filesystem::signal_param_users] + ); + + Test_Mount_Config_Hook_Test::clear(); + + // edit + $mountConfig['host'] = 'anothersmbhost'; + $this->assertTrue( + OC_Mount_Config::addMountPoint( + $mountPoint, + '\OC\Files\Storage\SMB', + $mountConfig, + $mountType, + $applicable, + $isPersonal + ) + ); + + // hook must not be called on edit + list($hookName, $params) = Test_Mount_Config_Hook_Test::getLastCall(); + $this->assertEquals( + null, + $hookName + ); + + Test_Mount_Config_Hook_Test::clear(); + + $this->assertTrue( + OC_Mount_Config::removeMountPoint( + $mountPoint, + $mountType, + $applicable, + $isPersonal + ) + ); + + list($hookName, $params) = Test_Mount_Config_Hook_Test::getLastCall(); + $this->assertEquals( + \OC\Files\Filesystem::signal_delete_mount, + $hookName + ); + $this->assertEquals( + $mountPoint, + $params[\OC\Files\Filesystem::signal_param_path] + ); + $this->assertEquals( + $mountType, + $params[\OC\Files\Filesystem::signal_param_mount_type] + ); + $this->assertEquals( + $applicable, + $params[\OC\Files\Filesystem::signal_param_users] + ); + } + /** * Test password obfuscation */ diff --git a/lib/private/allconfig.php b/lib/private/allconfig.php index 721ec337ff8..7ebff7cf2db 100644 --- a/lib/private/allconfig.php +++ b/lib/private/allconfig.php @@ -43,6 +43,15 @@ class AllConfig implements \OCP\IConfig { \OCP\Config::deleteSystemValue($key); } + /** + * Get all keys stored for an app + * + * @param string $appName the appName that we stored the value under + * @return string[] the keys stored for the app + */ + public function getAppKeys($appName) { + return \OC::$server->getAppConfig()->getKeys($appName); + } /** * Writes a new app wide value diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php index db46bcfd1ea..cdbbbf3d3cd 100644 --- a/lib/private/files/filesystem.php +++ b/lib/private/files/filesystem.php @@ -158,6 +158,11 @@ class Filesystem { */ const signal_param_run = 'run'; + const signal_create_mount = 'create_mount'; + const signal_delete_mount = 'delete_mount'; + const signal_param_mount_type = 'mounttype'; + const signal_param_users = 'users'; + /** * @var \OC\Files\Storage\Loader $loader */ diff --git a/lib/public/iconfig.php b/lib/public/iconfig.php index 755da09ee6b..404cf030dee 100644 --- a/lib/public/iconfig.php +++ b/lib/public/iconfig.php @@ -58,6 +58,13 @@ interface IConfig { */ public function deleteSystemValue($key); + /** + * Get all keys stored for an app + * + * @param string $appName the appName that we stored the value under + * @return string[] the keys stored for the app + */ + public function getAppKeys($appName); /** * Writes a new app wide value |