From cabe2873c47004798eadd39d9f1ad811e7227137 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 22 May 2014 01:40:42 +0200 Subject: Make personal external mount points (re)movable from the files app --- apps/files_external/lib/config.php | 35 +++++++++++++++++++++++++++- apps/files_external/lib/personalmount.php | 38 +++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 apps/files_external/lib/personalmount.php (limited to 'apps') diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 28e28ffcde6..46c4f94eec6 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -104,8 +104,15 @@ class OC_Mount_Config { */ public static function initMountPointsHook($data) { $mountPoints = self::getAbsoluteMountPoints($data['user']); + $loader = \OC\Files\Filesystem::getLoader(); + $manager = \OC\Files\Filesystem::getMountManager(); foreach ($mountPoints as $mountPoint => $options) { - \OC\Files\Filesystem::mount($options['class'], $options['options'], $mountPoint); + if ($options['personal']){ + $mount = new \OCA\Files_External\PersonalMount($options['class'], $mountPoint, $options['options'], $loader); + } else{ + $mount = new \OC\Files\Mount\Mount($options['class'], $mountPoint, $options['options'], $loader); + } + $manager->addMount($mount); } } @@ -135,6 +142,7 @@ class OC_Mount_Config { // Global mount points (is this redundant?) if (isset($mountConfig[self::MOUNT_TYPE_GLOBAL])) { foreach ($mountConfig[self::MOUNT_TYPE_GLOBAL] as $mountPoint => $options) { + $options['personal'] = false; $options['options'] = self::decryptPasswords($options['options']); if (!isset($options['priority'])) { $options['priority'] = $backends[$options['class']]['priority']; @@ -178,6 +186,7 @@ class OC_Mount_Config { foreach ($options as &$option) { $option = self::setUserVars($user, $option); } + $options['personal'] = false; $options['options'] = self::decryptPasswords($options['options']); if (!isset($options['priority'])) { $options['priority'] = $backends[$options['class']]['priority']; @@ -203,6 +212,7 @@ class OC_Mount_Config { foreach ($options as &$option) { $option = self::setUserVars($user, $option); } + $options['personal'] = false; $options['options'] = self::decryptPasswords($options['options']); if (!isset($options['priority'])) { $options['priority'] = $backends[$options['class']]['priority']; @@ -224,6 +234,7 @@ class OC_Mount_Config { $mountConfig = self::readData($user); if (isset($mountConfig[self::MOUNT_TYPE_USER][$user])) { foreach ($mountConfig[self::MOUNT_TYPE_USER][$user] as $mountPoint => $options) { + $options['personal'] = true; $options['options'] = self::decryptPasswords($options['options']); // Always override previous config @@ -520,6 +531,28 @@ class OC_Mount_Config { return true; } + /** + * + * @param string $mountPoint Mount point + * @param string $target The new mount point + * @param string $mountType MOUNT_TYPE_GROUP | MOUNT_TYPE_USER + * @return bool + */ + public static function movePersonalMountPoint($mountPoint, $target, $mountType) { + $mountPoint = rtrim($mountPoint, '/'); + $user = OCP\User::getUser(); + $mountPoints = self::readData($user); + if (!isset($mountPoints[$mountType][$user][$mountPoint])) { + return false; + } + $mountPoints[$mountType][$user][$target] = $mountPoints[$mountType][$user][$mountPoint]; + // Remove old mount point + unset($mountPoints[$mountType][$user][$mountPoint]); + + self::writeData($user, $mountPoints); + return true; + } + /** * Read the mount points in the config file into an array * @param string|null $user If not null, personal for $user, otherwise system diff --git a/apps/files_external/lib/personalmount.php b/apps/files_external/lib/personalmount.php new file mode 100644 index 00000000000..c3e97092520 --- /dev/null +++ b/apps/files_external/lib/personalmount.php @@ -0,0 +1,38 @@ + + * 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\Mount\Mount; +use OC\Files\Mount\MoveableMount; + +/** + * Person mount points can be moved by the user + */ +class PersonalMount extends Mount implements MoveableMount { + /** + * Move the mount point to $target + * + * @param string $target the target mount point + * @return bool + */ + public function moveMount($target) { + $result = \OC_Mount_Config::movePersonalMountPoint($this->getMountPoint(), $target, \OC_Mount_Config::MOUNT_TYPE_USER); + $this->setMountPoint($target); + return $result; + } + + /** + * Remove the mount points + * + * @return bool + */ + public function removeMount() { + return \OC_Mount_Config::removeMountPoint($this->mountPoint, \OC_Mount_Config::MOUNT_TYPE_USER, \OCP\User::getUser(), true); + } +} -- cgit v1.2.3 From 14ce44acc8c44ebf669c46496c6b17524b3e2a4e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 22 May 2014 01:41:27 +0200 Subject: Move shared mount moving from the storage to the mount --- apps/files_sharing/lib/sharedmount.php | 113 +++++++++++++++++++++ apps/files_sharing/lib/sharedstorage.php | 166 ++++++++----------------------- 2 files changed, 157 insertions(+), 122 deletions(-) create mode 100644 apps/files_sharing/lib/sharedmount.php (limited to 'apps') diff --git a/apps/files_sharing/lib/sharedmount.php b/apps/files_sharing/lib/sharedmount.php new file mode 100644 index 00000000000..f761f1b7bae --- /dev/null +++ b/apps/files_sharing/lib/sharedmount.php @@ -0,0 +1,113 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCA\Files_Sharing; + +use OC\Files\Filesystem; +use OC\Files\Mount\Mount; +use OC\Files\Mount\MoveableMount; +use OC\Files\Storage\Shared; + +/** + * Person mount points can be moved by the user + */ +class SharedMount extends Mount implements MoveableMount { + /** + * @var \OC\Files\Storage\Shared $storage + */ + protected $storage = null; + + /** + * Format a path to be relative to the /user/files/ directory + * + * @param string $path the absolute path + * @return string e.g. turns '/admin/files/test.txt' into '/test.txt' + */ + private function stripUserFilesPath($path) { + $trimmed = ltrim($path, '/'); + $split = explode('/', $trimmed); + + // it is not a file relative to data/user/files + if (count($split) < 3 || $split[1] !== 'files') { + \OCP\Util::writeLog('file sharing', + 'Can not strip userid and "files/" from path: ' . $path, + \OCP\Util::DEBUG); + return false; + } + + // skip 'user' and 'files' + $sliced = array_slice($split, 2); + $relPath = implode('/', $sliced); + + return '/' . $relPath; + } + + /** + * Move the mount point to $target + * + * @param string $target the target mount point + * @return bool + */ + public function moveMount($target) { + // it shouldn't be possible to move a Shared storage into another one + list($targetStorage,) = Filesystem::resolvePath($target); + if ($targetStorage instanceof Shared) { + \OCP\Util::writeLog('file sharing', + 'It is not allowed to move one mount point into another one', + \OCP\Util::DEBUG); + return false; + } + + $relTargetPath = $this->stripUserFilesPath($target); + $share = $this->storage->getShare(); + + // if the user renames a mount point from a group share we need to create a new db entry + // for the unique name + if ($this->storage->getShareType() === \OCP\Share::SHARE_TYPE_GROUP && $this->storage->uniqueNameSet() === false) { + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`, `item_target`,' + . ' `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,' + . ' `file_target`, `token`, `parent`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)'); + $arguments = array($share['item_type'], $share['item_source'], $share['item_target'], + 2, \OCP\User::getUser(), $share['uid_owner'], $share['permissions'], $share['stime'], $share['file_source'], + $relTargetPath, $share['token'], $share['id']); + + } else { + // rename mount point + $query = \OC_DB::prepare( + 'UPDATE `*PREFIX*share` + SET `file_target` = ? + WHERE `id` = ?' + ); + $arguments = array($relTargetPath, $this->storage->getShareId()); + } + + $result = $query->execute($arguments); + + if ($result) { + $this->setMountPoint($target); + $this->storage->setUniqueName(); + $this->storage->setMountPoint($relTargetPath); + + } else { + \OCP\Util::writeLog('file sharing', + 'Could not rename mount point for shared folder "' . $this->getMountPoint() . '" to "' . $target . '"', + \OCP\Util::ERROR); + } + + return $result; + } + + /** + * Remove the mount points + * + * @return mixed + * @return bool + */ + public function removeMount() { + } +} diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index f93982ee857..2418b830cbc 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -22,6 +22,8 @@ */ namespace OC\Files\Storage; +use OC\Files\Filesystem; +use OCA\Files_Sharing\SharedMount; /** * Convert target path to source path and pass the function call to the correct storage provider @@ -266,124 +268,12 @@ class Shared extends \OC\Files\Storage\Common { return false; } - /** - * Format a path to be relative to the /user/files/ directory - * @param string $path the absolute path - * @return string e.g. turns '/admin/files/test.txt' into '/test.txt' - */ - private static function stripUserFilesPath($path) { - $trimmed = ltrim($path, '/'); - $split = explode('/', $trimmed); - - // it is not a file relative to data/user/files - if (count($split) < 3 || $split[1] !== 'files') { - \OCP\Util::writeLog('file sharing', - 'Can not strip userid and "files/" from path: ' . $path, - \OCP\Util::DEBUG); - return false; - } - - // skip 'user' and 'files' - $sliced = array_slice($split, 2); - $relPath = implode('/', $sliced); - - return '/' . $relPath; - } - - /** - * rename a shared folder/file - * @param string $sourcePath - * @param string $targetPath - * @return bool - */ - private function renameMountPoint($sourcePath, $targetPath) { - - // it shouldn't be possible to move a Shared storage into another one - list($targetStorage, ) = \OC\Files\Filesystem::resolvePath($targetPath); - if ($targetStorage->instanceOfStorage('\OC\Files\Storage\Shared')) { - \OCP\Util::writeLog('file sharing', - 'It is not allowed to move one mount point into another one', - \OCP\Util::DEBUG); - return false; - } - - $relTargetPath = $this->stripUserFilesPath($targetPath); - - if ($relTargetPath === false) { - \OCP\Util::writeLog('file sharing', 'Wrong target path given: ' . $targetPath, \OCP\Util::ERROR); - return false; - } - - $result = self::updateFileTarget($relTargetPath, $this->share); - - if ($result) { - // update the mount manager with the new paths - $mountManager = \OC\Files\Filesystem::getMountManager(); - $mount = $mountManager->find($sourcePath); - $mount->setMountPoint($targetPath . '/'); - $mountManager->addMount($mount); - $mountManager->removeMount($sourcePath . '/'); - $this->setUniqueName(); - $this->setMountPoint($relTargetPath); - - } else { - \OCP\Util::writeLog('file sharing', - 'Could not rename mount point for shared folder "' . $sourcePath . '" to "' . $targetPath . '"', - \OCP\Util::ERROR); - } - - return (bool)$result; - } - - /** - * @update fileTarget in the database if the mount point changed - * @param string $newPath - * @param array $share reference to the share which should be modified - * @return type - */ - private static function updateFileTarget($newPath, &$share) { - // if the user renames a mount point from a group share we need to create a new db entry - // for the unique name - if ($share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP && - (isset($share['unique_name']) && $share['unique_name'])) { - $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`, `item_target`,' - .' `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,' - .' `file_target`, `token`, `parent`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)'); - $arguments = array($share['item_type'], $share['item_source'], $share['item_target'], - 2, \OCP\User::getUser(), $share['uid_owner'], $share['permissions'], $share['stime'], $share['file_source'], - $newPath, $share['token'], $share['id']); - - } else { - // rename mount point - $query = \OC_DB::prepare( - 'Update `*PREFIX*share` - SET `file_target` = ? - WHERE `id` = ?' - ); - $arguments = array($newPath, $share['id']); - } - - return $query->execute($arguments); - } - public function rename($path1, $path2) { - $sourceMountPoint = \OC\Files\Filesystem::getMountPoint($path1); - $targetMountPoint = \OC\Files\Filesystem::getMountPoint($path2); $relPath1 = \OCA\Files_Sharing\Helper::stripUserFilesPath($path1); $relPath2 = \OCA\Files_Sharing\Helper::stripUserFilesPath($path2); - // if we renamed the mount point we need to adjust the file_target in the - // database - if (\OC\Files\Filesystem::normalizePath($sourceMountPoint) === \OC\Files\Filesystem::normalizePath($path1)) { - return $this->renameMountPoint($path1, $path2); - } - - - if ( // Within the same mount point, we only need UPDATE permissions - ($sourceMountPoint === $targetMountPoint && $this->isUpdatable($sourceMountPoint)) || - // otherwise DELETE and CREATE permissions required - ($this->isDeletable($path1) && $this->isCreatable(dirname($path2)))) { + if ($this->isUpdatable('')) { $pathinfo = pathinfo($relPath1); // for part files we need to ask for the owner and path from the parent directory because @@ -486,16 +376,22 @@ class Shared extends \OC\Files\Storage\Common { public static function setup($options) { $shares = \OCP\Share::getItemsSharedWith('file'); + $manager = Filesystem::getMountManager(); + $loader = Filesystem::getLoader(); if (!\OCP\User::isLoggedIn() || \OCP\User::getUser() != $options['user'] || $shares ) { foreach ($shares as $share) { self::verifyMountPoint($share); - \OC\Files\Filesystem::mount('\OC\Files\Storage\Shared', - array( - 'share' => $share, - ), - $options['user_dir'] . '/' . $share['file_target']); + $mount = new SharedMount( + '\OC\Files\Storage\Shared', + $options['user_dir'] . '/' . $share['file_target'], + array( + 'share' => $share, + ), + $loader + ); + $manager->addMount($mount); } } } @@ -536,28 +432,54 @@ class Shared extends \OC\Files\Storage\Common { return $this->share['file_target']; } - private function setMountPoint($path) { + public function setMountPoint($path) { $this->share['file_target'] = $path; } + public function getShareType() { + return $this->share['share_type']; + } + + /** + * does the group share already has a user specific unique name + * @return bool + */ + public function uniqueNameSet() { + return (isset($this->share['unique_name']) && $this->share['unique_name']); + } + /** * the share now uses a unique name of this user * * @brief the share now uses a unique name of this user */ - private function setUniqueName() { + public function setUniqueName() { $this->share['unique_name'] = true; } /** - * @brief get the user who shared the file - * + * get share ID + * @return integer unique share ID + */ + public function getShareId() { + return $this->share['id']; + } + + /** + * get the user who shared the file * @return string */ public function getSharedFrom() { return $this->share['uid_owner']; } + /** + * @return array + */ + public function getShare() { + return $this->share; + } + /** * return share type, can be "file" or "folder" * @return string -- cgit v1.2.3 From a66c2e6a4757b5d97e120897df1085e4410b279a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 22 May 2014 01:53:33 +0200 Subject: Fix the removeMount for personal mounts --- apps/files_external/lib/config.php | 1 + apps/files_external/lib/personalmount.php | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'apps') diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 46c4f94eec6..6f78e569b64 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -517,6 +517,7 @@ class OC_Mount_Config { } else { $mountPoint = '/$user/files/'.ltrim($mountPoint, '/'); } + $mountPoint = \OC\Files\Filesystem::normalizePath($mountPoint); $mountPoints = self::readData($isPersonal ? OCP\User::getUser() : NULL); // Remove mount point unset($mountPoints[$mountType][$applicable][$mountPoint]); diff --git a/apps/files_external/lib/personalmount.php b/apps/files_external/lib/personalmount.php index c3e97092520..708128d644a 100644 --- a/apps/files_external/lib/personalmount.php +++ b/apps/files_external/lib/personalmount.php @@ -33,6 +33,8 @@ class PersonalMount extends Mount implements MoveableMount { * @return bool */ public function removeMount() { - return \OC_Mount_Config::removeMountPoint($this->mountPoint, \OC_Mount_Config::MOUNT_TYPE_USER, \OCP\User::getUser(), true); + $user = \OCP\User::getUser(); + $relativeMountPoint = substr($this->getMountPoint(), strlen('/' . $user . '/files/')); + return \OC_Mount_Config::removeMountPoint($relativeMountPoint, \OC_Mount_Config::MOUNT_TYPE_USER, $user , true); } } -- cgit v1.2.3 From bf5e9357fc5dacc0bc951e7c60fe7105533a56fb Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 27 May 2014 11:05:31 +0200 Subject: don't allow to share single files with delete permissions, user should only be possible to unshare a single file but never to delete it --- apps/files_sharing/appinfo/update.php | 38 +++++ apps/files_sharing/appinfo/version | 2 +- apps/files_sharing/js/share.js | 9 +- apps/files_sharing/lib/sharedstorage.php | 23 ++- apps/files_sharing/tests/share.php | 108 ++++++++++++++ apps/files_sharing/tests/update.php | 233 +++++++++++++++++++++++++++++++ apps/files_sharing/tests/updater.php | 125 ----------------- lib/private/share/share.php | 5 + 8 files changed, 413 insertions(+), 130 deletions(-) create mode 100644 apps/files_sharing/tests/share.php create mode 100644 apps/files_sharing/tests/update.php (limited to 'apps') diff --git a/apps/files_sharing/appinfo/update.php b/apps/files_sharing/appinfo/update.php index bc8cda42313..bc17915613c 100644 --- a/apps/files_sharing/appinfo/update.php +++ b/apps/files_sharing/appinfo/update.php @@ -1,6 +1,11 @@ execute(array('file')); + + $updatedRows = array(); + + while ($row = $result->fetchRow()) { + if ($row['permissions'] & \OCP\PERMISSION_DELETE) { + $updatedRows[$row['id']] = (int)$row['permissions'] & ~\OCP\PERMISSION_DELETE; + } + } + + $chunkedPermissionList = array_chunk($updatedRows, $chunkSize, true); + + foreach ($chunkedPermissionList as $subList) { + $statement = "UPDATE `*PREFIX*share` SET `permissions` = CASE `id` "; + //update share table + $ids = implode(',', array_keys($subList)); + foreach ($subList as $id => $permission) { + $statement .= "WHEN " . $id . " THEN " . $permission . " "; + } + $statement .= ' END WHERE `id` IN (' . $ids . ')'; + + $query = OCP\DB::prepare($statement); + $query->execute(); + } + +} + /** * update script for the removal of the logical "Shared" folder, we create physical "Shared" folder and * update the users file_target so that it doesn't make any difference for the user diff --git a/apps/files_sharing/appinfo/version b/apps/files_sharing/appinfo/version index 267577d47e4..2eb3c4fe4ee 100644 --- a/apps/files_sharing/appinfo/version +++ b/apps/files_sharing/appinfo/version @@ -1 +1 @@ -0.4.1 +0.5 diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js index d63a590fb8e..47fe0bd2c57 100644 --- a/apps/files_sharing/js/share.js +++ b/apps/files_sharing/js/share.js @@ -18,12 +18,17 @@ var oldCreateRow = OCA.Files.FileList.prototype._createRow; OCA.Files.FileList.prototype._createRow = function(fileData) { var tr = oldCreateRow.apply(this, arguments); + var sharePermissions = fileData.permissions; + if (fileData.type === 'file') { + // files can't be shared with delete permissions + sharePermissions = sharePermissions & ~OC.PERMISSION_DELETE; + } + tr.attr('data-share-permissions', sharePermissions); if (fileData.shareOwner) { tr.attr('data-share-owner', fileData.shareOwner); // user should always be able to rename a mount point if (fileData.isShareMountPoint) { tr.attr('data-permissions', fileData.permissions | OC.PERMISSION_UPDATE); - tr.attr('data-reshare-permissions', fileData.permissions); } } if (fileData.recipientsDisplayName) { @@ -94,7 +99,7 @@ if ($tr.data('type') === 'dir') { itemType = 'folder'; } - var possiblePermissions = $tr.data('reshare-permissions'); + var possiblePermissions = $tr.data('share-permissions'); if (_.isUndefined(possiblePermissions)) { possiblePermissions = $tr.data('permissions'); } diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 2418b830cbc..c5b5060893a 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -128,7 +128,18 @@ class Shared extends \OC\Files\Storage\Common { return false; } + /** + * Delete the directory if DELETE permission is granted + * @param string $path + * @return boolean + */ public function rmdir($path) { + + // never delete a share mount point + if(empty($path)) { + return false; + } + if (($source = $this->getSourcePath($path)) && $this->isDeletable($path)) { list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->rmdir($internalPath); @@ -256,9 +267,17 @@ class Shared extends \OC\Files\Storage\Common { return false; } + /** + * Delete the file if DELETE permission is granted + * @param string $path + * @return boolean + */ public function unlink($path) { - // Delete the file if DELETE permission is granted - $path = ($path === false) ? '' : $path; + + // never delete a share mount point + if (empty($path)) { + return false; + } if ($source = $this->getSourcePath($path)) { if ($this->isDeletable($path)) { list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); diff --git a/apps/files_sharing/tests/share.php b/apps/files_sharing/tests/share.php new file mode 100644 index 00000000000..a81f84ef061 --- /dev/null +++ b/apps/files_sharing/tests/share.php @@ -0,0 +1,108 @@ + + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 library. If not, see . + * + */ + +require_once __DIR__ . '/base.php'; + +use OCA\Files\Share; + +/** + * Class Test_Files_Sharing + */ +class Test_Files_Sharing extends Test_Files_Sharing_Base { + + const TEST_FOLDER_NAME = '/folder_share_api_test'; + + private static $tempStorage; + + function setUp() { + parent::setUp(); + + $this->folder = self::TEST_FOLDER_NAME; + $this->subfolder = '/subfolder_share_api_test'; + $this->subsubfolder = '/subsubfolder_share_api_test'; + + $this->filename = '/share-api-test.txt'; + + // save file with content + $this->view->file_put_contents($this->filename, $this->data); + $this->view->mkdir($this->folder); + $this->view->mkdir($this->folder . $this->subfolder); + $this->view->mkdir($this->folder . $this->subfolder . $this->subsubfolder); + $this->view->file_put_contents($this->folder.$this->filename, $this->data); + $this->view->file_put_contents($this->folder . $this->subfolder . $this->filename, $this->data); + } + + function tearDown() { + $this->view->unlink($this->filename); + $this->view->deleteAll($this->folder); + + self::$tempStorage = null; + + parent::tearDown(); + } + + /** + * shared files should never have delete permissions + * @dataProvider DataProviderTestFileSharePermissions + */ + function testFileSharePermissions($permission, $expectedPermissions) { + + $fileinfo = $this->view->getFileInfo($this->filename); + + $result = \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing::TEST_FILES_SHARING_API_USER2, $permission); + + $this->assertTrue($result); + + $result = \OCP\Share::getItemShared('file', null); + + $this->assertTrue(is_array($result)); + + // test should return exactly one shares created from testCreateShare() + $this->assertTrue(count($result) === 1); + + $share = reset($result); + $this->assertSame($expectedPermissions, $share['permissions']); + + \OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing::TEST_FILES_SHARING_API_USER2); + } + + function DataProviderTestFileSharePermissions() { + $permission1 = \OCP\PERMISSION_ALL; + $permission2 = \OCP\PERMISSION_DELETE; + $permission3 = \OCP\PERMISSION_READ; + $permission4 = \OCP\PERMISSION_READ | \OCP\PERMISSION_UPDATE; + $permission5 = \OCP\PERMISSION_READ | \OCP\PERMISSION_DELETE; + $permission6 = \OCP\PERMISSION_READ | \OCP\PERMISSION_UPDATE | \OCP\PERMISSION_DELETE; + + return array( + array($permission1, \OCP\PERMISSION_ALL & ~\OCP\PERMISSION_DELETE), + array($permission2, 0), + array($permission3, $permission3), + array($permission4, $permission4), + array($permission5, $permission3), + array($permission6, $permission4), + ); + } + +} diff --git a/apps/files_sharing/tests/update.php b/apps/files_sharing/tests/update.php new file mode 100644 index 00000000000..b0215d68176 --- /dev/null +++ b/apps/files_sharing/tests/update.php @@ -0,0 +1,233 @@ + + * 2014 Bjoern Schiessle + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 library. If not, see . + * + */ + +require_once __DIR__ . '/../appinfo/update.php'; +require_once __DIR__ . '/base.php'; + +/** + * Class Test_Files_Sharing_Update + */ +class Test_Files_Sharing_Update_Routine extends Test_Files_Sharing_Base { + + const TEST_FOLDER_NAME = '/folder_share_api_test'; + + function setUp() { + parent::setUp(); + + $this->folder = self::TEST_FOLDER_NAME; + + $this->filename = '/share-api-test.txt'; + + // save file with content + $this->view->file_put_contents($this->filename, $this->data); + $this->view->mkdir($this->folder); + $this->view->file_put_contents($this->folder . '/' . $this->filename, $this->data); + } + + function tearDown() { + $this->view->unlink($this->filename); + $this->view->deleteAll($this->folder); + + $removeShares = \OC_DB::prepare('DELETE FROM `*PREFIX*share`'); + $removeShares->execute(); + $removeItems = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache`'); + $removeItems->execute(); + + parent::tearDown(); + } + + /** + * test update of file permission. The update should remove from all shared + * files the delete permission + */ + function testUpdateFilePermissions() { + + self::prepareDBUpdateFilePermissions(); + // run the update routine to update the share permission + updateFilePermissions(2); + + // verify results + $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share`'); + $result = $query->execute(array()); + + while ($row = $result->fetchRow()) { + if ($row['item_type'] === 'file') { + // for all files the delete permission should be removed + $this->assertSame(0, (int)$row['permissions'] & \OCP\PERMISSION_DELETE); + } else { + // for all other the permission shouldn't change + $this->assertSame(31, (int)$row['permissions'] & \OCP\PERMISSION_ALL); + } + } + + // cleanup + $this->cleanupSharedTable(); + } + + /** + * @medium + */ + function testRemoveBrokenShares() { + + $this->prepareFileCache(); + + // check if there are just 3 shares (see setUp - precondition: empty table) + $countShares = \OC_DB::prepare('SELECT COUNT(`id`) FROM `*PREFIX*share`'); + $result = $countShares->execute()->fetchOne(); + $this->assertEquals(3, $result); + + // check if there are just 2 items (see setUp - precondition: empty table) + $countItems = \OC_DB::prepare('SELECT COUNT(`fileid`) FROM `*PREFIX*filecache`'); + $result = $countItems->execute()->fetchOne(); + $this->assertEquals(2, $result); + + // execute actual code which should be tested + \OC\Files\Cache\Shared_Updater::fixBrokenSharesOnAppUpdate(); + + // check if there are just 2 shares (one gets killed by the code as there is no filecache entry for this) + $countShares = \OC_DB::prepare('SELECT COUNT(`id`) FROM `*PREFIX*share`'); + $result = $countShares->execute()->fetchOne(); + $this->assertEquals(2, $result); + + // check if the share of file '200' is removed as there is no entry for this in filecache table + $countShares = \OC_DB::prepare('SELECT COUNT(`id`) FROM `*PREFIX*share` WHERE `file_source` = 200'); + $result = $countShares->execute()->fetchOne(); + $this->assertEquals(0, $result); + + // check if there are just 2 items + $countItems = \OC_DB::prepare('SELECT COUNT(`fileid`) FROM `*PREFIX*filecache`'); + $result = $countItems->execute()->fetchOne(); + $this->assertEquals(2, $result); + } + + /** + * test update for the removal of the logical "Shared" folder. It should update + * the file_target for every share and create a physical "Shared" folder for each user + */ + function testRemoveSharedFolder() { + self::prepareDB(); + // run the update routine to remove the shared folder and replace it with a real folder + removeSharedFolder(false, 2); + + // verify results + $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share`'); + $result = $query->execute(array()); + + $newDBContent = $result->fetchAll(); + + foreach ($newDBContent as $row) { + if ((int)$row['share_type'] === \OCP\Share::SHARE_TYPE_USER) { + $this->assertSame('/Shared', substr($row['file_target'], 0, strlen('/Shared'))); + } else { + $this->assertSame('/ShouldNotChange', $row['file_target']); + } + } + + // cleanup + $this->cleanupSharedTable(); + + } + + private function cleanupSharedTable() { + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*share`'); + $query->execute(); + } + + /** + * prepare sharing table for testRemoveSharedFolder() + */ + private function prepareDB() { + $this->cleanupSharedTable(); + // add items except one - because this is the test case for the broken share table + $addItems = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`share_type`, `item_type`, ' . + '`share_with`, `uid_owner` , `file_target`) ' . + 'VALUES (?, ?, ?, ?, ?)'); + $items = array( + array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user1', 'admin' , '/foo'), + array(\OCP\Share::SHARE_TYPE_USER, 'folder', 'user2', 'admin', '/foo2'), + array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user3', 'admin', '/foo3'), + array(\OCP\Share::SHARE_TYPE_USER, 'folder', 'user4', 'admin', '/foo4'), + array(\OCP\Share::SHARE_TYPE_LINK, 'file', 'user1', 'admin', '/ShouldNotChange'), + array(\OCP\Share::SHARE_TYPE_CONTACT, 'contact', 'admin', 'user1', '/ShouldNotChange'), + + ); + foreach($items as $item) { + // the number is used as path_hash + $addItems->execute($item); + } + } + + /** + * prepare sharing table for testUpdateFilePermissions() + */ + private function prepareDBUpdateFilePermissions() { + $this->cleanupSharedTable(); + // add items except one - because this is the test case for the broken share table + $addItems = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`share_type`, `item_type`, ' . + '`share_with`, `uid_owner` , `file_target`, `permissions`) ' . + 'VALUES (?, ?, ?, ?, ?, ?)'); + $items = array( + array(\OCP\Share::SHARE_TYPE_LINK, 'file', 'user1', 'admin', '/foo', \OCP\PERMISSION_ALL), + array(\OCP\Share::SHARE_TYPE_CONTACT, 'contact', 'admin', 'user1', '/foo', \OCP\PERMISSION_ALL), + array(\OCP\Share::SHARE_TYPE_USER, 'folder', 'user4', 'admin', '/foo', \OCP\PERMISSION_ALL), + array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user3', 'admin', '/foo3', \OCP\PERMISSION_ALL), + array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user1', 'admin' , '/foo', \OCP\PERMISSION_DELETE), + array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user1', 'admin' , '/foo', \OCP\PERMISSION_READ & \OCP\PERMISSION_DELETE), + array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user1', 'admin' , '/foo', \OCP\PERMISSION_SHARE & \OCP\PERMISSION_UPDATE), + array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user1', 'admin' , '/foo', \OCP\PERMISSION_ALL), + array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user1', 'admin' , '/foo', \OCP\PERMISSION_SHARE & \OCP\PERMISSION_READ & \OCP\PERMISSION_DELETE), + ); + foreach($items as $item) { + // the number is used as path_hash + $addItems->execute($item); + } + } + + /** + * prepare file cache for testRemoveBrokenShares() + */ + private function prepareFileCache() { + // some previous tests didn't clean up and therefore this has to be done here + // FIXME: DIRTY HACK - TODO: find tests, that don't clean up and fix it there + $this->tearDown(); + + // add items except one - because this is the test case for the broken share table + $addItems = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache` (`storage`, `path_hash`, ' . + '`parent`, `mimetype`, `mimepart`, `size`, `mtime`, `storage_mtime`) ' . + 'VALUES (1, ?, 1, 1, 1, 1, 1, 1)'); + $items = array(1, 3); + $fileIds = array(); + foreach($items as $item) { + // the number is used as path_hash + $addItems->execute(array($item)); + $fileIds[] = \OC_DB::insertId('*PREFIX*filecache'); + } + + $addShares = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`file_source`, `item_type`, `uid_owner`) VALUES (?, \'file\', 1)'); + // the number is used as item_source + $addShares->execute(array($fileIds[0])); + $addShares->execute(array(200)); // id of "deleted" file + $addShares->execute(array($fileIds[1])); + } + +} diff --git a/apps/files_sharing/tests/updater.php b/apps/files_sharing/tests/updater.php index 1b851cccf6c..8183e7067a4 100644 --- a/apps/files_sharing/tests/updater.php +++ b/apps/files_sharing/tests/updater.php @@ -47,11 +47,6 @@ class Test_Files_Sharing_Updater extends Test_Files_Sharing_Base { $this->view->unlink($this->filename); $this->view->deleteAll($this->folder); - $removeShares = \OC_DB::prepare('DELETE FROM `*PREFIX*share`'); - $removeShares->execute(); - $removeItems = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache`'); - $removeItems->execute(); - parent::tearDown(); } @@ -111,124 +106,4 @@ class Test_Files_Sharing_Updater extends Test_Files_Sharing_Base { } } - /** - * @medium - */ - function testRemoveBrokenShares() { - - $this->prepareFileCache(); - - // check if there are just 3 shares (see setUp - precondition: empty table) - $countShares = \OC_DB::prepare('SELECT COUNT(`id`) FROM `*PREFIX*share`'); - $result = $countShares->execute()->fetchOne(); - $this->assertEquals(3, $result); - - // check if there are just 2 items (see setUp - precondition: empty table) - $countItems = \OC_DB::prepare('SELECT COUNT(`fileid`) FROM `*PREFIX*filecache`'); - $result = $countItems->execute()->fetchOne(); - $this->assertEquals(2, $result); - - // execute actual code which should be tested - \OC\Files\Cache\Shared_Updater::fixBrokenSharesOnAppUpdate(); - - // check if there are just 2 shares (one gets killed by the code as there is no filecache entry for this) - $countShares = \OC_DB::prepare('SELECT COUNT(`id`) FROM `*PREFIX*share`'); - $result = $countShares->execute()->fetchOne(); - $this->assertEquals(2, $result); - - // check if the share of file '200' is removed as there is no entry for this in filecache table - $countShares = \OC_DB::prepare('SELECT COUNT(`id`) FROM `*PREFIX*share` WHERE `file_source` = 200'); - $result = $countShares->execute()->fetchOne(); - $this->assertEquals(0, $result); - - // check if there are just 2 items - $countItems = \OC_DB::prepare('SELECT COUNT(`fileid`) FROM `*PREFIX*filecache`'); - $result = $countItems->execute()->fetchOne(); - $this->assertEquals(2, $result); - } - - /** - * test update for the removal of the logical "Shared" folder. It should update - * the file_target for every share and create a physical "Shared" folder for each user - */ - function testRemoveSharedFolder() { - self::prepareDB(); - // run the update routine to remove the shared folder and replace it with a real folder - removeSharedFolder(false, 2); - - // verify results - $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share`'); - $result = $query->execute(array()); - - $newDBContent = $result->fetchAll(); - - foreach ($newDBContent as $row) { - if ((int)$row['share_type'] === \OCP\Share::SHARE_TYPE_USER) { - $this->assertSame('/Shared', substr($row['file_target'], 0, strlen('/Shared'))); - } else { - $this->assertSame('/ShouldNotChange', $row['file_target']); - } - } - - // cleanup - $this->cleanupSharedTable(); - - } - - private function cleanupSharedTable() { - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*share`'); - $query->execute(); - } - - /** - * prepare sharing table for testRemoveSharedFolder() - */ - private function prepareDB() { - $this->cleanupSharedTable(); - // add items except one - because this is the test case for the broken share table - $addItems = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`share_type`, `item_type`, ' . - '`share_with`, `uid_owner` , `file_target`) ' . - 'VALUES (?, ?, ?, ?, ?)'); - $items = array( - array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user1', 'admin' , '/foo'), - array(\OCP\Share::SHARE_TYPE_USER, 'folder', 'user2', 'admin', '/foo2'), - array(\OCP\Share::SHARE_TYPE_USER, 'file', 'user3', 'admin', '/foo3'), - array(\OCP\Share::SHARE_TYPE_USER, 'folder', 'user4', 'admin', '/foo4'), - array(\OCP\Share::SHARE_TYPE_LINK, 'file', 'user1', 'admin', '/ShouldNotChange'), - array(\OCP\Share::SHARE_TYPE_CONTACT, 'contact', 'admin', 'user1', '/ShouldNotChange'), - - ); - foreach($items as $item) { - // the number is used as path_hash - $addItems->execute($item); - } - } - - /** - * prepare file cache for testRemoveBrokenShares() - */ - private function prepareFileCache() { - // some previous tests didn't clean up and therefore this has to be done here - // FIXME: DIRTY HACK - TODO: find tests, that don't clean up and fix it there - $this->tearDown(); - - // add items except one - because this is the test case for the broken share table - $addItems = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache` (`storage`, `path_hash`, ' . - '`parent`, `mimetype`, `mimepart`, `size`, `mtime`, `storage_mtime`) ' . - 'VALUES (1, ?, 1, 1, 1, 1, 1, 1)'); - $items = array(1, 3); - $fileIds = array(); - foreach($items as $item) { - // the number is used as path_hash - $addItems->execute(array($item)); - $fileIds[] = \OC_DB::insertId('*PREFIX*filecache'); - } - - $addShares = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`file_source`, `item_type`, `uid_owner`) VALUES (?, \'file\', 1)'); - // the number is used as item_source - $addShares->execute(array($fileIds[0])); - $addShares->execute(array(200)); // id of "deleted" file - $addShares->execute(array($fileIds[1])); - } - } diff --git a/lib/private/share/share.php b/lib/private/share/share.php index 2126a1d2dd4..10b3cc34467 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -519,6 +519,11 @@ class Share extends \OC\Share\Constants { } } + // single file shares should never have delete permissions + if ($itemType === 'file') { + $permissions = (int)$permissions & ~\OCP\PERMISSION_DELETE; + } + // Verify share type and sharing conditions are met if ($shareType === self::SHARE_TYPE_USER) { if ($shareWith == $uidOwner) { -- cgit v1.2.3 From dea5219244b5d931db102b02d95e72f784eec7d1 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 27 May 2014 14:24:35 +0200 Subject: Fix folder name for storage root --- apps/files/lib/helper.php | 2 +- lib/private/files/fileinfo.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'apps') diff --git a/apps/files/lib/helper.php b/apps/files/lib/helper.php index 7d8906e2251..b84b6c06d30 100644 --- a/apps/files/lib/helper.php +++ b/apps/files/lib/helper.php @@ -113,7 +113,7 @@ class Helper if (\OC::$server->getPreviewManager()->isMimeSupported($i['mimetype'])) { $entry['isPreviewAvailable'] = true; } - $entry['name'] = $i['name']; + $entry['name'] = $i->getName(); $entry['permissions'] = $i['permissions']; $entry['mimetype'] = $i['mimetype']; $entry['size'] = $i['size']; diff --git a/lib/private/files/fileinfo.php b/lib/private/files/fileinfo.php index e7afeb4ccce..d012c0c5a63 100644 --- a/lib/private/files/fileinfo.php +++ b/lib/private/files/fileinfo.php @@ -108,7 +108,7 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { * @return string */ public function getName() { - return $this->data['name']; + return basename($this->getPath()); } /** -- cgit v1.2.3 From 1b0b977678b703a994e088eb7c23bdcddb24f6ce Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 27 May 2014 15:07:53 +0200 Subject: remove share mount --- apps/files_sharing/lib/sharedmount.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'apps') diff --git a/apps/files_sharing/lib/sharedmount.php b/apps/files_sharing/lib/sharedmount.php index f761f1b7bae..f1704504f64 100644 --- a/apps/files_sharing/lib/sharedmount.php +++ b/apps/files_sharing/lib/sharedmount.php @@ -105,9 +105,12 @@ class SharedMount extends Mount implements MoveableMount { /** * Remove the mount points * - * @return mixed * @return bool */ public function removeMount() { + $storage = $this->getStorage(); + $result = \OCP\Share::unshareFromSelf($storage->getItemType(), $storage->getMountPoint()); + + return $result; } } -- 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 'apps') 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 884b9a0ecf5c8bfba4e8b988ee39c705dcc892cd Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 27 May 2014 16:28:32 +0200 Subject: bring back updateFileTarget() got lost during last rebase --- apps/files_sharing/lib/sharedstorage.php | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'apps') diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index c5b5060893a..f8c241425d3 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -442,6 +442,37 @@ class Shared extends \OC\Files\Storage\Common { } } + /** + * update fileTarget in the database if the mount point changed + * @param string $newPath + * @param array $share reference to the share which should be modified + * @return type + */ + private static function updateFileTarget($newPath, &$share) { + // if the user renames a mount point from a group share we need to create a new db entry + // for the unique name + if ($share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP && $this->uniqueNameSet() === false) { + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`, `item_target`,' + .' `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,' + .' `file_target`, `token`, `parent`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)'); + $arguments = array($share['item_type'], $share['item_source'], $share['item_target'], + 2, \OCP\User::getUser(), $share['uid_owner'], $share['permissions'], $share['stime'], $share['file_source'], + $newPath, $share['token'], $share['id']); + + $this->setUniqueName(); + } else { + // rename mount point + $query = \OC_DB::prepare( + 'Update `*PREFIX*share` + SET `file_target` = ? + WHERE `id` = ?' + ); + $arguments = array($newPath, $share['id']); + } + + return $query->execute($arguments); + } + /** * return mount point of share, relative to data/user/files * -- cgit v1.2.3 From 5132ae5e69fa0d02c05f789fcda4609f291b638f Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 27 May 2014 20:48:41 +0200 Subject: fix mount point move up if the parent no longer exists --- apps/files_sharing/lib/sharedmount.php | 82 ++++++++++++++++++++++++-------- apps/files_sharing/lib/sharedstorage.php | 59 ----------------------- 2 files changed, 61 insertions(+), 80 deletions(-) (limited to 'apps') diff --git a/apps/files_sharing/lib/sharedmount.php b/apps/files_sharing/lib/sharedmount.php index f1704504f64..873740f4a2d 100644 --- a/apps/files_sharing/lib/sharedmount.php +++ b/apps/files_sharing/lib/sharedmount.php @@ -22,6 +22,66 @@ class SharedMount extends Mount implements MoveableMount { */ protected $storage = null; + public function __construct($storage, $mountpoint, $arguments = null, $loader = null) { + parent::__construct($storage, $mountpoint, $arguments, $loader); + + self::verifyMountPoint($arguments['share']); + } + + /** + * check if the parent folder exists otherwise move the mount point up + */ + private static function verifyMountPoint(&$share) { + + $mountPoint = basename($share['file_target']); + $parent = dirname($share['file_target']); + + while (!\OC\Files\Filesystem::is_dir($parent)) { + $parent = dirname($parent); + } + + $newMountPoint = \OCA\Files_Sharing\Helper::generateUniqueTarget( + \OC\Files\Filesystem::normalizePath($parent . '/' . $mountPoint), + array(), + new \OC\Files\View('/' . \OCP\User::getUser() . '/files') + ); + + if($newMountPoint !== $share['file_target']) { + self::updateFileTarget($newMountPoint, $share); + $share['file_target'] = $newMountPoint; + $share['unique_name'] = true; + } + } + + /** + * update fileTarget in the database if the mount point changed + * @param string $newPath + * @param array $share reference to the share which should be modified + * @return type + */ + private static function updateFileTarget($newPath, &$share) { + // if the user renames a mount point from a group share we need to create a new db entry + // for the unique name + if ($share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP && $this->uniqueNameSet() === false) { + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`, `item_target`,' + .' `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,' + .' `file_target`, `token`, `parent`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)'); + $arguments = array($share['item_type'], $share['item_source'], $share['item_target'], + 2, \OCP\User::getUser(), $share['uid_owner'], $share['permissions'], $share['stime'], $share['file_source'], + $newPath, $share['token'], $share['id']); + } else { + // rename mount point + $query = \OC_DB::prepare( + 'Update `*PREFIX*share` + SET `file_target` = ? + WHERE `id` = ?' + ); + $arguments = array($newPath, $share['id']); + } + + return $query->execute($arguments); + } + /** * Format a path to be relative to the /user/files/ directory * @@ -66,27 +126,7 @@ class SharedMount extends Mount implements MoveableMount { $relTargetPath = $this->stripUserFilesPath($target); $share = $this->storage->getShare(); - // if the user renames a mount point from a group share we need to create a new db entry - // for the unique name - if ($this->storage->getShareType() === \OCP\Share::SHARE_TYPE_GROUP && $this->storage->uniqueNameSet() === false) { - $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`, `item_target`,' - . ' `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,' - . ' `file_target`, `token`, `parent`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)'); - $arguments = array($share['item_type'], $share['item_source'], $share['item_target'], - 2, \OCP\User::getUser(), $share['uid_owner'], $share['permissions'], $share['stime'], $share['file_source'], - $relTargetPath, $share['token'], $share['id']); - - } else { - // rename mount point - $query = \OC_DB::prepare( - 'UPDATE `*PREFIX*share` - SET `file_target` = ? - WHERE `id` = ?' - ); - $arguments = array($relTargetPath, $this->storage->getShareId()); - } - - $result = $query->execute($arguments); + $result = $this->updateFileTarget($relTargetPath, $share); if ($result) { $this->setMountPoint($target); diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index f8c241425d3..1456ad18888 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -401,7 +401,6 @@ class Shared extends \OC\Files\Storage\Common { || $shares ) { foreach ($shares as $share) { - self::verifyMountPoint($share); $mount = new SharedMount( '\OC\Files\Storage\Shared', $options['user_dir'] . '/' . $share['file_target'], @@ -415,64 +414,6 @@ class Shared extends \OC\Files\Storage\Common { } } - /** - * check if the parent folder exists otherwise move the mount point up - * - * @param array $share reference to the share we want to check - */ - private static function verifyMountPoint(&$share) { - $mountPoint = basename($share['file_target']); - $parent = dirname($share['file_target']); - - while (!\OC\Files\Filesystem::is_dir($parent)) { - $parent = dirname($parent); - } - - $newMountPoint = \OCA\Files_Sharing\Helper::generateUniqueTarget( - \OC\Files\Filesystem::normalizePath($parent . '/' . $mountPoint), - array(), - new \OC\Files\View('/' . \OCP\User::getUser() . '/files') - ); - - if($newMountPoint !== $share['file_target']) { - - self::updateFileTarget($newMountPoint, $share); - $share['file_target'] = $newMountPoint; - - } - } - - /** - * update fileTarget in the database if the mount point changed - * @param string $newPath - * @param array $share reference to the share which should be modified - * @return type - */ - private static function updateFileTarget($newPath, &$share) { - // if the user renames a mount point from a group share we need to create a new db entry - // for the unique name - if ($share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP && $this->uniqueNameSet() === false) { - $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`, `item_target`,' - .' `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,' - .' `file_target`, `token`, `parent`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)'); - $arguments = array($share['item_type'], $share['item_source'], $share['item_target'], - 2, \OCP\User::getUser(), $share['uid_owner'], $share['permissions'], $share['stime'], $share['file_source'], - $newPath, $share['token'], $share['id']); - - $this->setUniqueName(); - } else { - // rename mount point - $query = \OC_DB::prepare( - 'Update `*PREFIX*share` - SET `file_target` = ? - WHERE `id` = ?' - ); - $arguments = array($newPath, $share['id']); - } - - return $query->execute($arguments); - } - /** * return mount point of share, relative to data/user/files * -- cgit v1.2.3 From 24f3f6823eb6c7d293295864799f4d19aeee3783 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 27 May 2014 21:15:25 +0200 Subject: get unique_name value directly from the share array --- apps/files_sharing/lib/sharedmount.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apps') diff --git a/apps/files_sharing/lib/sharedmount.php b/apps/files_sharing/lib/sharedmount.php index 873740f4a2d..97d6f464f3d 100644 --- a/apps/files_sharing/lib/sharedmount.php +++ b/apps/files_sharing/lib/sharedmount.php @@ -62,7 +62,7 @@ class SharedMount extends Mount implements MoveableMount { private static function updateFileTarget($newPath, &$share) { // if the user renames a mount point from a group share we need to create a new db entry // for the unique name - if ($share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP && $this->uniqueNameSet() === false) { + if ($share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP && $share['unique_name'] === false) { $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`, `item_target`,' .' `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,' .' `file_target`, `token`, `parent`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)'); -- cgit v1.2.3 From cf5eb0fef546de0523157e943a97abcc8f3d1186 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 27 May 2014 21:15:39 +0200 Subject: remove unused variable --- apps/files_encryption/hooks/hooks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apps') diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 99edcf25ec5..f546ef72373 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -658,7 +658,7 @@ class Hooks { 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); + $sharingUsers = \OCP\Share::getUsersSharingFile($path, $user); if (!in_array(\OCP\User::getUser(), $sharingUsers['users'])) { Keymanager::delShareKey($view, array(\OCP\User::getUser()), $path); } -- cgit v1.2.3 From 844b1e3fc6aae56926cac27b2402fa16cda2c60a Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 27 May 2014 21:51:23 +0200 Subject: add additional unit tests --- apps/files_sharing/lib/sharedmount.php | 8 +- apps/files_sharing/tests/sharedmount.php | 139 +++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 3 deletions(-) create mode 100644 apps/files_sharing/tests/sharedmount.php (limited to 'apps') diff --git a/apps/files_sharing/lib/sharedmount.php b/apps/files_sharing/lib/sharedmount.php index 97d6f464f3d..0e2f19ef337 100644 --- a/apps/files_sharing/lib/sharedmount.php +++ b/apps/files_sharing/lib/sharedmount.php @@ -23,9 +23,9 @@ class SharedMount extends Mount implements MoveableMount { protected $storage = null; public function __construct($storage, $mountpoint, $arguments = null, $loader = null) { - parent::__construct($storage, $mountpoint, $arguments, $loader); - + // first update the mount point before creating the parent self::verifyMountPoint($arguments['share']); + parent::__construct($storage, $mountpoint, $arguments, $loader); } /** @@ -79,7 +79,9 @@ class SharedMount extends Mount implements MoveableMount { $arguments = array($newPath, $share['id']); } - return $query->execute($arguments); + $result = $query->execute($arguments); + + return $result === 1 ? true : false; } /** diff --git a/apps/files_sharing/tests/sharedmount.php b/apps/files_sharing/tests/sharedmount.php new file mode 100644 index 00000000000..2bdaf0a72f5 --- /dev/null +++ b/apps/files_sharing/tests/sharedmount.php @@ -0,0 +1,139 @@ + + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 library. If not, see . + * + */ + +require_once __DIR__ . '/base.php'; + +/** + * Class Test_Files_Sharing_Api + */ +class Test_Files_Sharing_Mount extends Test_Files_Sharing_Base { + + function setUp() { + parent::setUp(); + + $this->folder = '/folder_share_storage_test'; + + $this->filename = '/share-api-storage.txt'; + + + $this->view->mkdir($this->folder); + + // save file with content + $this->view->file_put_contents($this->filename, "root file"); + $this->view->file_put_contents($this->folder . $this->filename, "file in subfolder"); + } + + function tearDown() { + $this->view->unlink($this->folder); + $this->view->unlink($this->filename); + + parent::tearDown(); + } + + /** + * test if the mount point moves up if the parent folder no longer exists + */ + function testShareMountLoseParentFolder() { + + // share to user + $fileinfo = $this->view->getFileInfo($this->folder); + $result = \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2, 31); + + $statement = "UPDATE `*PREFIX*share` SET `file_target` = ? where `share_with` = ?"; + $query = \OC_DB::prepare($statement); + $arguments = array('/foo/bar' . $this->folder, self::TEST_FILES_SHARING_API_USER2); + $query->execute($arguments); + + $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share`'); + $result = $query->execute(); + + $shares = $result->fetchAll(); + + $this->assertSame(1, count($shares)); + + $share = reset($shares); + $this->assertSame('/foo/bar' . $this->folder, $share['file_target']); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + + // share should have moved up + + $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share`'); + $result = $query->execute(); + + $shares = $result->fetchAll(); + + $this->assertSame(1, count($shares)); + + $share = reset($shares); + $this->assertSame($this->folder, $share['file_target']); + + //cleanup + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2); + $this->view->unlink($this->folder); + } + + /** + * @medium + */ + function testDeleteParentOfMountPoint() { + + // share to user + $fileinfo = $this->view->getFileInfo($this->folder); + $result = \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2, 31); + + $this->assertTrue($result); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + $user2View = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); + $this->assertTrue($user2View->file_exists($this->folder)); + + // create a local folder + $result = $user2View->mkdir('localfolder'); + $this->assertTrue($result); + + // move mount point to local folder + $result = $user2View->rename($this->folder, '/localfolder/' . $this->folder); + $this->assertTrue($result); + + // mount point in the root folder should no longer exist + $this->assertFalse($user2View->is_dir($this->folder)); + + // delete the local folder + $result = $user2View->unlink('/localfolder'); + $this->assertTrue($result); + + //enforce reload of the mount points + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + + //mount point should be back at the root + $this->assertTrue($user2View->is_dir($this->folder)); + + //cleanup + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + $this->view->unlink($this->folder); + } + +} -- cgit v1.2.3 From 0ce07bb6c4235d6fd735dbc870aad9ce7850736d Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 27 May 2014 22:43:20 +0200 Subject: update mount point if file_target changed --- apps/files_sharing/lib/sharedmount.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'apps') diff --git a/apps/files_sharing/lib/sharedmount.php b/apps/files_sharing/lib/sharedmount.php index 0e2f19ef337..84eb4e78773 100644 --- a/apps/files_sharing/lib/sharedmount.php +++ b/apps/files_sharing/lib/sharedmount.php @@ -24,8 +24,9 @@ class SharedMount extends Mount implements MoveableMount { public function __construct($storage, $mountpoint, $arguments = null, $loader = null) { // first update the mount point before creating the parent - self::verifyMountPoint($arguments['share']); - parent::__construct($storage, $mountpoint, $arguments, $loader); + $newMountPoint = self::verifyMountPoint($arguments['share']); + $absMountPoint = '/' . \OCP\User::getUser() . '/files' . $newMountPoint; + parent::__construct($storage, $absMountPoint, $arguments, $loader); } /** @@ -51,6 +52,8 @@ class SharedMount extends Mount implements MoveableMount { $share['file_target'] = $newMountPoint; $share['unique_name'] = true; } + + return $newMountPoint; } /** -- cgit v1.2.3 From 9a48e8725321eb4f282ee49f14af01efad0471ef Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 27 May 2014 23:50:44 +0200 Subject: make sure that we have a path relative to data/user/files to work with --- apps/files_sharing/lib/sharedstorage.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'apps') diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 1456ad18888..c98cde0a8e9 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -289,8 +289,9 @@ class Shared extends \OC\Files\Storage\Common { public function rename($path1, $path2) { - $relPath1 = \OCA\Files_Sharing\Helper::stripUserFilesPath($path1); - $relPath2 = \OCA\Files_Sharing\Helper::stripUserFilesPath($path2); + // we need the paths relative to data/user/files + $relPath1 = $this->getMountPoint() . '/' . $path1; + $relPath2 = $this->getMountPoint() . '/' . $path2; if ($this->isUpdatable('')) { -- cgit v1.2.3 From 501f98f084d243007ee64ad7a4386964d98f536a Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 27 May 2014 23:51:24 +0200 Subject: update share API tests, file shares never have delete permissions --- apps/files_sharing/tests/api.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'apps') diff --git a/apps/files_sharing/tests/api.php b/apps/files_sharing/tests/api.php index 6d0ed434ef2..3c683afacb4 100644 --- a/apps/files_sharing/tests/api.php +++ b/apps/files_sharing/tests/api.php @@ -784,7 +784,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { $fileInfo = $this->view->getFileInfo($this->filename); $result = \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, - \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31); + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, \OCP\PERMISSION_ALL); // share was successful? $this->assertTrue($result); @@ -816,9 +816,11 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { $this->assertTrue(is_array($linkShare)); $this->assertTrue(is_array($userShare)); - // update permissions + // check if share have expected permissions, single shared files never have + // delete permissions + $this->assertEquals(\OCP\PERMISSION_ALL & ~\OCP\PERMISSION_DELETE, $userShare['permissions']); - $this->assertEquals('31', $userShare['permissions']); + // update permissions $params = array(); $params['id'] = $userShare['id']; @@ -893,7 +895,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { $items = \OCP\Share::getItemShared('file', null); // make sure that we found a link share and a user share - $this->assertEquals(count($items), 1); + $this->assertEquals(1, count($items)); $linkShare = null; -- cgit v1.2.3 From 42a362f2491e5731ce7cc242891c58dd41a76d00 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 28 May 2014 13:47:50 +0200 Subject: Fix phpdoc and comments --- apps/files_sharing/lib/sharedmount.php | 4 ++-- apps/files_sharing/lib/sharedstorage.php | 1 + apps/files_sharing/tests/share.php | 2 +- lib/private/files/mount/mount.php | 1 + 4 files changed, 5 insertions(+), 3 deletions(-) (limited to 'apps') diff --git a/apps/files_sharing/lib/sharedmount.php b/apps/files_sharing/lib/sharedmount.php index 84eb4e78773..79d6991264e 100644 --- a/apps/files_sharing/lib/sharedmount.php +++ b/apps/files_sharing/lib/sharedmount.php @@ -1,6 +1,6 @@ + * Copyright (c) 2014 Robin Appelman * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. @@ -14,7 +14,7 @@ use OC\Files\Mount\MoveableMount; use OC\Files\Storage\Shared; /** - * Person mount points can be moved by the user + * Shared mount points can be moved by the user */ class SharedMount extends Mount implements MoveableMount { /** diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index c98cde0a8e9..ea0e420a5c4 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -293,6 +293,7 @@ class Shared extends \OC\Files\Storage\Common { $relPath1 = $this->getMountPoint() . '/' . $path1; $relPath2 = $this->getMountPoint() . '/' . $path2; + // check for update permissions on the share if ($this->isUpdatable('')) { $pathinfo = pathinfo($relPath1); diff --git a/apps/files_sharing/tests/share.php b/apps/files_sharing/tests/share.php index a81f84ef061..195fac461be 100644 --- a/apps/files_sharing/tests/share.php +++ b/apps/files_sharing/tests/share.php @@ -3,7 +3,7 @@ * ownCloud * * @author Bjoern Schiessle - * @copyright 2013 Bjoern Schiessle + * @copyright 2014 Bjoern Schiessle * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/private/files/mount/mount.php b/lib/private/files/mount/mount.php index 7561cd7311b..04bccbcab87 100644 --- a/lib/private/files/mount/mount.php +++ b/lib/private/files/mount/mount.php @@ -142,6 +142,7 @@ class Mount { } else { $internalPath = substr($path, strlen($this->mountPoint)); } + // substr returns false instead of an empty string, we always want a string return (string)$internalPath; } -- cgit v1.2.3 From a5752a846318f9204c0fe81cf3020b1a923dac38 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 28 May 2014 18:18:51 +0200 Subject: fix db query --- apps/files_sharing/appinfo/update.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apps') diff --git a/apps/files_sharing/appinfo/update.php b/apps/files_sharing/appinfo/update.php index bc17915613c..fc547ba349d 100644 --- a/apps/files_sharing/appinfo/update.php +++ b/apps/files_sharing/appinfo/update.php @@ -21,7 +21,7 @@ if (version_compare($installedVersion, '0.3.5.6', '<')) { * should only be able to unshare single files but never to delete them. */ function updateFilePermissions($chunkSize = 99) { - $query = OCP\DB::prepare('SELECT * FROM `*PREFIX*share` WHERE item_type = ?'); + $query = OCP\DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `item_type` = ?'); $result = $query->execute(array('file')); $updatedRows = array(); -- cgit v1.2.3 From 28615cca9c64615768c1f1d44dd110e065bbdd6a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 3 Jun 2014 10:48:03 +0200 Subject: Fix unit tests --- apps/files/tests/helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apps') diff --git a/apps/files/tests/helper.php b/apps/files/tests/helper.php index 9b3603cd563..f269cc70ed5 100644 --- a/apps/files/tests/helper.php +++ b/apps/files/tests/helper.php @@ -17,7 +17,7 @@ class Test_Files_Helper extends \PHPUnit_Framework_TestCase { private function makeFileInfo($name, $size, $mtime, $isDir = false) { return new \OC\Files\FileInfo( - '/', + '/' . $name, null, '/', array( -- cgit v1.2.3 From ea07f0a18ee1e5dba06fa7421412cf9465d758a2 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 3 Jun 2014 15:02:42 +0200 Subject: Fix unit test --- apps/files/tests/ajax_rename.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apps') diff --git a/apps/files/tests/ajax_rename.php b/apps/files/tests/ajax_rename.php index 9928053e501..fed366aa8eb 100644 --- a/apps/files/tests/ajax_rename.php +++ b/apps/files/tests/ajax_rename.php @@ -81,7 +81,7 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { $this->viewMock->expects($this->any()) ->method('getFileInfo') ->will($this->returnValue(new \OC\Files\FileInfo( - '/', + '/new_name', new \OC\Files\Storage\Local(array('datadir' => '/')), '/', array( -- cgit v1.2.3 From ad5d8d7980199a7cb08547a3bd46527407749ea6 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 3 Jun 2014 16:56:04 +0200 Subject: nake sure ti create new db entry when user renames a group share --- apps/files_sharing/lib/sharedmount.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apps') diff --git a/apps/files_sharing/lib/sharedmount.php b/apps/files_sharing/lib/sharedmount.php index 79d6991264e..8d0ecbc6789 100644 --- a/apps/files_sharing/lib/sharedmount.php +++ b/apps/files_sharing/lib/sharedmount.php @@ -65,7 +65,7 @@ class SharedMount extends Mount implements MoveableMount { private static function updateFileTarget($newPath, &$share) { // if the user renames a mount point from a group share we need to create a new db entry // for the unique name - if ($share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP && $share['unique_name'] === false) { + if ($share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP && empty($share['unique_name'])) { $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`, `item_target`,' .' `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,' .' `file_target`, `token`, `parent`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)'); -- cgit v1.2.3 From ca6631a710c925052d9ed673a447149bf3a16af3 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 3 Jun 2014 19:29:00 +0200 Subject: add some tests --- apps/files_sharing/tests/sharedmount.php | 60 +++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) (limited to 'apps') diff --git a/apps/files_sharing/tests/sharedmount.php b/apps/files_sharing/tests/sharedmount.php index 2bdaf0a72f5..f8c65734184 100644 --- a/apps/files_sharing/tests/sharedmount.php +++ b/apps/files_sharing/tests/sharedmount.php @@ -94,7 +94,7 @@ class Test_Files_Sharing_Mount extends Test_Files_Sharing_Base { $this->view->unlink($this->folder); } - /** + /** * @medium */ function testDeleteParentOfMountPoint() { @@ -136,4 +136,62 @@ class Test_Files_Sharing_Mount extends Test_Files_Sharing_Base { $this->view->unlink($this->folder); } + function testMoveSharedFile() { + $fileinfo = $this->view->getFileInfo($this->filename); + $result = \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2, 31); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + + \OC\Files\Filesystem::rename($this->filename, "newFileName"); + + $this->assertTrue(\OC\Files\Filesystem::file_exists('newFileName')); + $this->assertFalse(\OC\Files\Filesystem::file_exists($this->filename)); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + $this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename)); + $this->assertFalse(\OC\Files\Filesystem::file_exists("newFileName")); + + //cleanup + \OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2); + } + + /** + * share file with a group if a user renames the file the filename should not change + * for the other users + */ + function testMoveGroupShare () { + \OC_Group::createGroup('testGroup'); + \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER1, 'testGroup'); + \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup'); + \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER3, 'testGroup'); + + $fileinfo = $this->view->getFileInfo($this->filename); + $result = \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, + "testGroup", 31); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + + $this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename)); + + \OC\Files\Filesystem::rename($this->filename, "newFileName"); + + $this->assertTrue(\OC\Files\Filesystem::file_exists('newFileName')); + $this->assertFalse(\OC\Files\Filesystem::file_exists($this->filename)); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER3); + $this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename)); + $this->assertFalse(\OC\Files\Filesystem::file_exists("newFileName")); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER3); + $this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename)); + $this->assertFalse(\OC\Files\Filesystem::file_exists("newFileName")); + + //cleanup + \OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, 'testGroup'); + \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER1, 'testGroup'); + \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup'); + \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER3, 'testGroup'); + } + } -- cgit v1.2.3 From 574de2d91b1bb913385e308d5e53b0e7faa29d8e Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 3 Jun 2014 19:47:23 +0200 Subject: the mount point always have delete permissions to allow unmount --- apps/files_sharing/lib/sharedstorage.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apps') diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index ea0e420a5c4..6b2873302a5 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -106,8 +106,8 @@ class Shared extends \OC\Files\Storage\Common { */ public function getPermissions($target = '') { $permissions = $this->share['permissions']; - // part file are always have delete permissions - if (pathinfo($target, PATHINFO_EXTENSION) === 'part') { + // part files and the mount point always have delete permissions + if ($target === '' || pathinfo($target, PATHINFO_EXTENSION) === 'part') { $permissions |= \OCP\PERMISSION_DELETE; } -- cgit v1.2.3 From 09970e1816644661d4ad1984793232c880aac1ac Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 4 Jun 2014 13:00:32 +0200 Subject: update unit tests and make sure that we return the right permissions for files within a shared folder and for the shared folder itself --- apps/files_sharing/tests/permissions.php | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'apps') diff --git a/apps/files_sharing/tests/permissions.php b/apps/files_sharing/tests/permissions.php index 5ac251b0527..0a222b08512 100644 --- a/apps/files_sharing/tests/permissions.php +++ b/apps/files_sharing/tests/permissions.php @@ -111,5 +111,10 @@ class Test_Files_Sharing_Permissions extends Test_Files_Sharing_Base { $this->assertEquals(7, $contents[0]['permissions']); $this->assertEquals('textfile1.txt', $contents[1]['name']); $this->assertEquals(7, $contents[1]['permissions']); + + // the share mount point should always have delete permissions to allow the user + // to unmount it + $restrictedShare = $this->secondView->getFileInfo('files/shareddirrestricted'); + $this->assertEquals(7 | \OCP\PERMISSION_DELETE, $restrictedShare['permissions']); } } -- cgit v1.2.3 From 86d7371d0c797d5c97198eebf9152ad748961927 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 4 Jun 2014 18:41:47 +0200 Subject: fix unshareFromSelf() --- apps/files_sharing/lib/sharedstorage.php | 21 ++++++----- apps/files_sharing/tests/share.php | 65 ++++++++++++++++++++++++++++++++ lib/private/share/share.php | 61 +++++++++++++++++++----------- 3 files changed, 115 insertions(+), 32 deletions(-) (limited to 'apps') diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 6b2873302a5..59de2dfa4c4 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -403,15 +403,18 @@ class Shared extends \OC\Files\Storage\Common { || $shares ) { foreach ($shares as $share) { - $mount = new SharedMount( - '\OC\Files\Storage\Shared', - $options['user_dir'] . '/' . $share['file_target'], - array( - 'share' => $share, - ), - $loader - ); - $manager->addMount($mount); + // don't mount shares where we have no permissions + if ($share['permissions'] > 0) { + $mount = new SharedMount( + '\OC\Files\Storage\Shared', + $options['user_dir'] . '/' . $share['file_target'], + array( + 'share' => $share, + ), + $loader + ); + $manager->addMount($mount); + } } } } diff --git a/apps/files_sharing/tests/share.php b/apps/files_sharing/tests/share.php index 195fac461be..d3ca1816c75 100644 --- a/apps/files_sharing/tests/share.php +++ b/apps/files_sharing/tests/share.php @@ -60,6 +60,71 @@ class Test_Files_Sharing extends Test_Files_Sharing_Base { parent::tearDown(); } + function testUnshareFromSelf() { + + \OC_Group::createGroup('testGroup'); + \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup'); + \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER3, 'testGroup'); + + $fileinfo = $this->view->getFileInfo($this->filename); + + $pathinfo = pathinfo($this->filename); + + $duplicate = '/' . $pathinfo['filename'] . ' (2).' . $pathinfo['extension']; + + $result = \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing::TEST_FILES_SHARING_API_USER2, 31); + + $this->assertTrue($result); + + $result = \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, + 'testGroup', 31); + + $this->assertTrue($result); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + $this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename)); + $this->assertTrue(\OC\Files\Filesystem::file_exists($duplicate)); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER3); + $this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename)); + $this->assertFalse(\OC\Files\Filesystem::file_exists($duplicate)); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + \OC\Files\Filesystem::unlink($this->filename); + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + $this->assertFalse(\OC\Files\Filesystem::file_exists($this->filename)); + $this->assertTrue(\OC\Files\Filesystem::file_exists($duplicate)); + + // for user3 nothing should change + self::loginHelper(self::TEST_FILES_SHARING_API_USER3); + $this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename)); + $this->assertFalse(\OC\Files\Filesystem::file_exists($duplicate)); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + \OC\Files\Filesystem::unlink($duplicate); + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + $this->assertFalse(\OC\Files\Filesystem::file_exists($this->filename)); + $this->assertFalse(\OC\Files\Filesystem::file_exists($duplicate)); + + // for user3 nothing should change + self::loginHelper(self::TEST_FILES_SHARING_API_USER3); + $this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename)); + $this->assertFalse(\OC\Files\Filesystem::file_exists($duplicate)); + + //cleanup + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + \OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, + 'testGroup'); + \OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2); + \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup'); + \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup'); + \OC_Group::deleteGroup('testGroup'); + + + } + /** * shared files should never have delete permissions * @dataProvider DataProviderTestFileSharePermissions diff --git a/lib/private/share/share.php b/lib/private/share/share.php index 10b3cc34467..646405a37b5 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -717,33 +717,48 @@ class Share extends \OC\Share\Constants { * Unsharing from self is not allowed for items inside collections */ public static function unshareFromSelf($itemType, $itemTarget) { - $item = self::getItemSharedWith($itemType, $itemTarget); - if (!empty($item)) { - if ((int)$item['share_type'] === self::SHARE_TYPE_GROUP) { - // Insert an extra row for the group share and set permission - // to 0 to prevent it from showing up for the user - $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share`' + + if ($itemType === 'file' || $itemType === 'folder') { + $statement = 'SELECT * FROM `*PREFIX*share` WHERE `item_type` = ? and `file_target` = ?'; + } else { + $statement = 'SELECT * FROM `*PREFIX*share` WHERE `item_type` = ? and `item_target` = ?'; + } + + $query = \OCP\DB::prepare($statement); + $result = $query->execute(array($itemType, $itemTarget)); + + $shares = $result->fetchAll(); + + $itemUnshared = false; + foreach ($shares as $share) { + if ((int)$share['share_type'] === \OCP\Share::SHARE_TYPE_USER) { + Helper::delete($share['id']); + $itemUnshared = true; + break; + } elseif ((int)$share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP) { + $groupShare = $share; + } elseif ((int)$share['share_type'] === self::$shareTypeGroupUserUnique) { + $uniqueGroupShare = $share; + } + } + + if (!$itemUnshared && isset($groupShare)) { + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share`' .' (`item_type`, `item_source`, `item_target`, `parent`, `share_type`,' .' `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`, `file_target`)' .' VALUES (?,?,?,?,?,?,?,?,?,?,?)'); - $query->execute(array($item['item_type'], $item['item_source'], $item['item_target'], - $item['id'], self::$shareTypeGroupUserUnique, - \OC_User::getUser(), $item['uid_owner'], 0, $item['stime'], $item['file_source'], - $item['file_target'])); - \OC_DB::insertid('*PREFIX*share'); - // Delete all reshares by this user of the group share - Helper::delete($item['id'], true, \OC_User::getUser()); - } else if ((int)$item['share_type'] === self::$shareTypeGroupUserUnique) { - // Set permission to 0 to prevent it from showing up for the user - $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = ? WHERE `id` = ?'); - $query->execute(array(0, $item['id'])); - Helper::delete($item['id'], true); - } else { - Helper::delete($item['id']); - } - return true; + $query->execute(array($groupShare['item_type'], $groupShare['item_source'], $groupShare['item_target'], + $groupShare['id'], self::$shareTypeGroupUserUnique, + \OC_User::getUser(), $groupShare['uid_owner'], 0, $groupShare['stime'], $groupShare['file_source'], + $groupShare['file_target'])); + $itemUnshared = true; + } elseif (!$itemUnshared && isset($uniqueGroupShare)) { + $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = ? WHERE `id` = ?'); + $query->execute(array(0, $uniqueGroupShare['id'])); + $itemUnshared = true; } - return false; + + return $itemUnshared; } /** -- cgit v1.2.3 From 60ea4388edb3f3c5aebb3afbedc0ff5c29bc4c7b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 5 Jun 2014 12:45:33 +0200 Subject: Limit permissions to share permissions --- apps/files_sharing/lib/cache.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'apps') diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index f6c42e930d1..d0919f0dfdc 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -94,6 +94,7 @@ class Shared_Cache extends Cache { $data['is_share_mount_point'] = true; } $data['uid_owner'] = $this->storage->getOwner($file); + $data['permissions'] = $data['permissions'] & $this->storage->getPermissions(''); return $data; } } else { @@ -130,6 +131,7 @@ class Shared_Cache extends Cache { $data['name'] = basename($this->storage->getMountPoint()); $data['is_share_mount_point'] = true; } + $data['permissions'] = $data['permissions'] & $this->storage->getPermissions(''); return $data; } return false; @@ -157,6 +159,7 @@ class Shared_Cache extends Cache { $sourceFolderContent[$key]['path'] = $dir . $c['name']; $sourceFolderContent[$key]['uid_owner'] = $parent['uid_owner']; $sourceFolderContent[$key]['displayname_owner'] = $parent['uid_owner']; + $sourceFolderContent[$key]['permissions'] = $sourceFolderContent[$key]['permissions'] & $this->storage->getPermissions(''); } return $sourceFolderContent; -- cgit v1.2.3 From 0b2ae314c7ea58c5105070dbcbada2212c3851dc Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 5 Jun 2014 13:24:41 +0200 Subject: check if permissions exists --- apps/files_sharing/lib/cache.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'apps') diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index d0919f0dfdc..b2594aa0b4d 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -94,7 +94,11 @@ class Shared_Cache extends Cache { $data['is_share_mount_point'] = true; } $data['uid_owner'] = $this->storage->getOwner($file); - $data['permissions'] = $data['permissions'] & $this->storage->getPermissions(''); + if (isset($data['permissions'])) { + $data['permissions'] = $data['permissions'] & $this->storage->getPermissions(''); + } else { + $data['permissions'] = $this->storage->getPermissions(''); + } return $data; } } else { -- cgit v1.2.3