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