diff options
author | Bjoern Schiessle <schiessle@owncloud.com> | 2014-04-04 18:32:49 +0200 |
---|---|---|
committer | Bjoern Schiessle <schiessle@owncloud.com> | 2014-04-23 12:54:24 +0200 |
commit | a02fb3722bae6655ffdd5b0e6c522331612c255b (patch) | |
tree | e53fd2d97ffe0f413b04f2c45bc3688f7ebeb75f | |
parent | 72bbb9ca20498eba18d6b6a31ed1de2306f90faf (diff) | |
download | nextcloud-server-a02fb3722bae6655ffdd5b0e6c522331612c255b.tar.gz nextcloud-server-a02fb3722bae6655ffdd5b0e6c522331612c255b.zip |
user should be able to rename/delete shared files if the owner allowed it
-rw-r--r-- | apps/files_sharing/lib/cache.php | 9 | ||||
-rw-r--r-- | apps/files_sharing/lib/sharedstorage.php | 102 | ||||
-rw-r--r-- | lib/private/files/view.php | 29 |
3 files changed, 129 insertions, 11 deletions
diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index becd436f798..4017b7ad64a 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -89,6 +89,12 @@ class Shared_Cache extends Cache { return $cache->get($this->files[$file]); } } else { + // if we are at the root of the mount point we want to return the + // cache information for the source item + if (!is_int($file) || $file === 0) { + $file = $this->storage->getSourceId(); + $mountPoint = $this->storage->getMountPoint(); + } $query = \OC_DB::prepare( 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`,' . ' `size`, `mtime`, `encrypted`, `unencrypted_size`' @@ -110,6 +116,9 @@ class Shared_Cache extends Cache { } else { $data['size'] = (int)$data['size']; } + if (isset($mountPoint)) { + $data['path'] = 'files/' . $mountPoint; + } return $data; } return false; diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 25a05a0d1f2..d09a4a22564 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -30,18 +30,34 @@ class Shared extends \OC\Files\Storage\Common { private $mountPoint; // mount point relative to data/user/files private $type; // can be "file" or "folder" + private $shareId; // share Id to identify the share in the database + private $fileSource; // file cache ID of the shared item private $files = array(); public function __construct($arguments) { $this->mountPoint = $arguments['shareTarget']; $this->type = $arguments['shareType']; + $this->shareId = $arguments['shareId']; + $this->fileSource = $arguments['fileSource']; } + /** + * @breif get id of the mount point + * @return string + */ public function getId() { return 'shared::' . $this->mountPoint; } /** + * @breif get file cache of the shared item source + * @return string + */ + public function getSourceId() { + return $this->fileSource; + } + + /** * @brief Get the source file path, permissions, and owner for a shared file * @param string Shared target file path * @param string $target @@ -289,11 +305,89 @@ class Shared extends \OC\Files\Storage\Common { return false; } + /** + * @brief 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; + } + + /** + * @brief rename a shared foder/file + * @param string $sourcePath + * @param string $targetPath + * @return bool + */ + private function renameMountPoint($sourcePath, $targetPath) { + + // it shoulbn't be possible to move a Shared storage into another one + list($targetStorage, ) = \OC\Files\Filesystem::resolvePath($targetPath); + if ($targetStorage instanceof \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); + + // rename mount point + $query = \OC_DB::prepare( + 'Update `*PREFIX*share` + SET `file_target` = ? + WHERE `id` = ?' + ); + + $result = $query->execute(array($relTargetPath, $this->shareId)); + + 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 . '/'); + + } else { + \OCP\Util::writeLog('file sharing', + 'Could not rename mount point for shared folder "' . $sourcePath . '" to "' . $targetPath . '"', + \OCP\Util::ERROR); + } + + return $result; + } + + public function rename($path1, $path2) { + + $sourceMountPoint = \OC\Files\Filesystem::getMountPoint($path1); + + // if we renamed the mount point we need to adjust the file_target in the + // database + if (strlen($sourceMountPoint) >= strlen($path1)) { + return $this->renameMountPoint($path1, $path2); + } + // Renaming/moving is only allowed within shared folders - $pos1 = strpos($path1, '/', 1); - $pos2 = strpos($path2, '/', 1); - if ($pos1 !== false && $pos2 !== false && ($oldSource = $this->getSourcePath($path1))) { + $oldSource = $this->getSourcePath($path1); + if ($oldSource) { $newSource = $this->getSourcePath(dirname($path2)) . '/' . basename($path2); // Within the same folder, we only need UPDATE permissions if (dirname($path1) == dirname($path2) and $this->isUpdatable($path1)) { @@ -405,6 +499,8 @@ class Shared extends \OC\Files\Storage\Common { array( 'shareTarget' => $share['file_target'], 'shareType' => $share['item_type'], + 'shareId' => $share['id'], + 'fileSource' => $share['file_source'], ), $options['user_dir'] . '/' . $share['file_target']); } diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 519ed250b1f..6d630f978ba 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -404,11 +404,21 @@ class View { if ($run) { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); + list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); + list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2); + // if source and target are on the same storage we can call the rename operation from the + // storage. If it is a "Shared" file/folder we call always the rename operation of the + // shared storage to handle mount point renaming, etc correctly if ($mp1 == $mp2) { - list($storage, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); - list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2); - if ($storage) { - $result = $storage->rename($internalPath1, $internalPath2); + if ($storage1) { + $result = $storage1->rename($internalPath1, $internalPath2); + \OC_FileProxy::runPostProxies('rename', $absolutePath1, $absolutePath2); + } else { + $result = false; + } + } elseif ($storage1 instanceof \OC\Files\Storage\Shared) { + if ($storage1) { + $result = $storage1->rename($absolutePath1, $absolutePath2); \OC_FileProxy::runPostProxies('rename', $absolutePath1, $absolutePath2); } else { $result = false; @@ -417,7 +427,6 @@ class View { if ($this->is_dir($path1)) { $result = $this->copy($path1, $path2); if ($result === true) { - list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); $result = $storage1->unlink($internalPath1); } } else { @@ -431,7 +440,6 @@ class View { fclose($target); if ($result !== false) { - list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); $storage1->unlink($internalPath1); } } @@ -972,8 +980,13 @@ class View { $permissions = $subStorage->getPermissions($rootEntry['path']); $subPermissionsCache->set($rootEntry['fileid'], $user, $permissions); } - // do not allow renaming/deleting the mount point - $rootEntry['permissions'] = $permissions & (\OCP\PERMISSION_ALL - (\OCP\PERMISSION_UPDATE | \OCP\PERMISSION_DELETE)); + // do not allow renaming/deleting the mount point if they are not shared files/folders + // for shared files/folders we use the permissions given by the owner + if ($subStorage instanceof \OC\Files\Storage\Shared) { + $rootEntry['permissions'] = $permissions; + } else { + $rootEntry['permissions'] = $permissions & (\OCP\PERMISSION_ALL - (\OCP\PERMISSION_UPDATE | \OCP\PERMISSION_DELETE)); + } //remove any existing entry with the same name foreach ($files as $i => $file) { |