From 60a659c87e1a3cb2c65dc330cb64c3414fd4b648 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 22 May 2014 01:39:24 +0200 Subject: Add a system for (re)movable mount points --- lib/private/files/view.php | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) (limited to 'lib/private/files/view.php') diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 1dc6c405bcf..a2188f393fa 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -26,6 +26,7 @@ namespace OC\Files; use OC\Files\Cache\Updater; +use OC\Files\Mount\MoveableMount; class View { private $fakeRoot = ''; @@ -357,10 +358,8 @@ class View { } $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); - list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); - if (!($storage instanceof \OC\Files\Storage\Shared) && - (!$internalPath || $internalPath === '' || $internalPath === '/') - ) { + $mount = Filesystem::getMountManager()->find($absolutePath . $postFix); + if (!($mount instanceof MoveableMount) && $mount->getInternalPath($absolutePath) === '') { // do not allow deleting the storage's root / the mount point // because for some storages it might delete the whole contents // but isn't supposed to work that way @@ -411,18 +410,19 @@ class View { if ($run) { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); - list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); + $manager = Filesystem::getMountManager(); + $mount = $manager->find($absolutePath1 . $postFix1); + $storage1 = $mount->getStorage(); + $internalPath1 = $mount->getInternalPath($absolutePath1 . $postFix1); list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2); - // if source and target are on the same storage we can call the rename operation from the - // storage. If it is a "Shared" file/folder we call always the rename operation of the - // shared storage to handle mount point renaming, etc correctly - if ($storage1 instanceof \OC\Files\Storage\Shared) { - if ($storage1) { - $result = $storage1->rename($absolutePath1, $absolutePath2); - \OC_FileProxy::runPostProxies('rename', $absolutePath1, $absolutePath2); - } else { - $result = false; - } + if ($internalPath1 == '' and $mount instanceof MoveableMount) { + /** + * @var \OC\Files\Mount\Mount | \OC\Files\Mount\MoveableMount $mount + */ + $sourceMountPoint = $mount->getMountPoint(); + $result = $mount->moveMount($absolutePath2); + $manager->moveMount($sourceMountPoint, $mount->getMountPoint()); + \OC_FileProxy::runPostProxies('rename', $absolutePath1, $absolutePath2); } elseif ($mp1 == $mp2) { if ($storage1) { $result = $storage1->rename($internalPath1, $internalPath2); @@ -888,10 +888,6 @@ class View { return $result; } $path = Filesystem::normalizePath($this->fakeRoot . '/' . $directory); - /** - * @var \OC\Files\Storage\Storage $storage - * @var string $internalPath - */ list($storage, $internalPath) = Filesystem::resolvePath($path); if ($storage) { $cache = $storage->getCache($internalPath); @@ -924,9 +920,10 @@ class View { } //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders - $mountPoints = Filesystem::getMountPoints($path); + $mounts = Filesystem::getMountManager()->findIn($path); $dirLength = strlen($path); - foreach ($mountPoints as $mountPoint) { + foreach ($mounts as $mount) { + $mountPoint = $mount->getMountPoint(); $subStorage = Filesystem::getStorage($mountPoint); if ($subStorage) { $subCache = $subStorage->getCache(''); @@ -953,7 +950,7 @@ class View { $permissions = $rootEntry['permissions']; // do not allow renaming/deleting the mount point if they are not shared files/folders // for shared files/folders we use the permissions given by the owner - if ($subStorage instanceof \OC\Files\Storage\Shared) { + if ($mount instanceof MoveableMount) { $rootEntry['permissions'] = $permissions; } else { $rootEntry['permissions'] = $permissions & (\OCP\PERMISSION_ALL - (\OCP\PERMISSION_UPDATE | \OCP\PERMISSION_DELETE)); -- cgit v1.2.3 From 4fbc991ea2bd66f1f918c9c6abf501ca767a8a8d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 22 May 2014 01:52:55 +0200 Subject: Add the removing logic for mounts --- lib/private/files/view.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'lib/private/files/view.php') diff --git a/lib/private/files/view.php b/lib/private/files/view.php index a2188f393fa..1515769116f 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -359,11 +359,15 @@ class View { $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); $mount = Filesystem::getMountManager()->find($absolutePath . $postFix); - if (!($mount instanceof MoveableMount) && $mount->getInternalPath($absolutePath) === '') { - // do not allow deleting the storage's root / the mount point - // because for some storages it might delete the whole contents - // but isn't supposed to work that way - return false; + if ($mount->getInternalPath($absolutePath) === '') { + if ($mount instanceof MoveableMount) { + return $mount->removeMount(); + } else { + // do not allow deleting the storage's root / the mount point + // because for some storages it might delete the whole contents + // but isn't supposed to work that way + return false; + } } return $this->basicOperation('unlink', $path, array('delete')); } -- cgit v1.2.3 From 329bfd81c33ed95fdc91658cd914611605cd114f Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 27 May 2014 15:09:43 +0200 Subject: remove encryption keys if user unshares a file --- apps/files_encryption/hooks/hooks.php | 55 +++++++++++++++++++++++++++++++++++ apps/files_encryption/lib/helper.php | 2 ++ apps/files_encryption/tests/hooks.php | 6 ++-- lib/private/files/view.php | 13 ++++++++- 4 files changed, 72 insertions(+), 4 deletions(-) (limited to 'lib/private/files/view.php') diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 66e2bccd59f..99edcf25ec5 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -34,6 +34,8 @@ class Hooks { private static $renamedFiles = array(); // file for which we want to delete the keys after the delete operation was successful private static $deleteFiles = array(); + // file for which we want to delete the keys after the delete operation was successful + private static $umountedFiles = array(); /** * Startup encryption backend upon user login @@ -610,4 +612,57 @@ class Hooks { 'path' => $ownerPath); } + /** + * remember files/folders which get unmounted + */ + public static function preUmount($params) { + $path = $params[\OC\Files\Filesystem::signal_param_path]; + $user = \OCP\USER::getUser(); + + $view = new \OC\Files\View(); + $itemType = $view->is_dir('/' . $user . '/files' . $path) ? 'folder' : 'file'; + + $util = new Util($view, $user); + list($owner, $ownerPath) = $util->getUidAndFilename($path); + + self::$umountedFiles[$params[\OC\Files\Filesystem::signal_param_path]] = array( + 'uid' => $owner, + 'path' => $ownerPath, + 'itemType' => $itemType); + } + + public static function postUmount($params) { + + if (!isset(self::$umountedFiles[$params[\OC\Files\Filesystem::signal_param_path]])) { + return true; + } + + $umountedFile = self::$umountedFiles[$params[\OC\Files\Filesystem::signal_param_path]]; + $path = $umountedFile['path']; + $user = $umountedFile['uid']; + $itemType = $umountedFile['itemType']; + + $view = new \OC\Files\View(); + $util = new Util($view, $user); + + // we don't need to remember the file any longer + unset(self::$umountedFiles[$params[\OC\Files\Filesystem::signal_param_path]]); + + // if we unshare a folder we need a list of all (sub-)files + if ($itemType === 'folder') { + $allFiles = $util->getAllFiles($path); + } else { + $allFiles = array($path); + } + + foreach ($allFiles as $path) { + + // check if the user still has access to the file, otherwise delete share key + $sharingUsers = $result = \OCP\Share::getUsersSharingFile($path, $user); + if (!in_array(\OCP\User::getUser(), $sharingUsers['users'])) { + Keymanager::delShareKey($view, array(\OCP\User::getUser()), $path); + } + } + } + } diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php index 564e97e0592..2684bf7be33 100755 --- a/apps/files_encryption/lib/helper.php +++ b/apps/files_encryption/lib/helper.php @@ -65,6 +65,8 @@ class Helper { \OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Encryption\Hooks', 'postRename'); \OCP\Util::connectHook('OC_Filesystem', 'post_delete', 'OCA\Encryption\Hooks', 'postDelete'); \OCP\Util::connectHook('OC_Filesystem', 'delete', 'OCA\Encryption\Hooks', 'preDelete'); + \OCP\Util::connectHook('OC_Filesystem', 'post_umount', 'OCA\Encryption\Hooks', 'postUmount'); + \OCP\Util::connectHook('OC_Filesystem', 'umount', 'OCA\Encryption\Hooks', 'preUmount'); } /** diff --git a/apps/files_encryption/tests/hooks.php b/apps/files_encryption/tests/hooks.php index 95f5996bb8e..a2e3ea30f04 100644 --- a/apps/files_encryption/tests/hooks.php +++ b/apps/files_encryption/tests/hooks.php @@ -257,14 +257,14 @@ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { $this->assertTrue($result); - // now keys from user1s home should be gone - $this->assertFalse($this->rootView->file_exists( + // share key for user2 from user1s home should be gone, all other keys should still exists + $this->assertTrue($this->rootView->file_exists( self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/' . $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey')); $this->assertFalse($this->rootView->file_exists( self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/' . $this->filename . '.' . \Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey')); - $this->assertFalse($this->rootView->file_exists( + $this->assertTrue($this->rootView->file_exists( self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/' . $this->filename . '.key')); // cleanup diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 1515769116f..9b6a370fe3b 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -361,7 +361,18 @@ class View { $mount = Filesystem::getMountManager()->find($absolutePath . $postFix); if ($mount->getInternalPath($absolutePath) === '') { if ($mount instanceof MoveableMount) { - return $mount->removeMount(); + \OC_Hook::emit( + Filesystem::CLASSNAME, "umount", + array(Filesystem::signal_param_path => $path) + ); + $result = $mount->removeMount(); + if ($result) { + \OC_Hook::emit( + Filesystem::CLASSNAME, "post_umount", + array(Filesystem::signal_param_path => $path) + ); + } + return $result; } else { // do not allow deleting the storage's root / the mount point // because for some storages it might delete the whole contents -- cgit v1.2.3 From a432459685a5afb3a9bb844f2bfab2c652fc0d4b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 28 May 2014 13:52:18 +0200 Subject: use triple equals --- lib/private/files/view.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/private/files/view.php') diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 9b6a370fe3b..fac1e64e79e 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -430,7 +430,7 @@ class View { $storage1 = $mount->getStorage(); $internalPath1 = $mount->getInternalPath($absolutePath1 . $postFix1); list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2); - if ($internalPath1 == '' and $mount instanceof MoveableMount) { + if ($internalPath1 === '' and $mount instanceof MoveableMount) { /** * @var \OC\Files\Mount\Mount | \OC\Files\Mount\MoveableMount $mount */ -- cgit v1.2.3 From e362373a30198b0dac6fbc9cd751a5eafe19e21a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 28 May 2014 14:01:40 +0200 Subject: Movable storage root can always be moved and deleted --- lib/private/files/view.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/private/files/view.php') diff --git a/lib/private/files/view.php b/lib/private/files/view.php index fac1e64e79e..d42f6cbf9fe 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -966,7 +966,7 @@ class View { // do not allow renaming/deleting the mount point if they are not shared files/folders // for shared files/folders we use the permissions given by the owner if ($mount instanceof MoveableMount) { - $rootEntry['permissions'] = $permissions; + $rootEntry['permissions'] = $permissions | \OCP\PERMISSION_UPDATE | \OCP\PERMISSION_DELETE; } else { $rootEntry['permissions'] = $permissions & (\OCP\PERMISSION_ALL - (\OCP\PERMISSION_UPDATE | \OCP\PERMISSION_DELETE)); } -- cgit v1.2.3