summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Schiessle <schiessle@owncloud.com>2014-04-04 18:32:49 +0200
committerBjoern Schiessle <schiessle@owncloud.com>2014-04-23 12:54:24 +0200
commita02fb3722bae6655ffdd5b0e6c522331612c255b (patch)
treee53fd2d97ffe0f413b04f2c45bc3688f7ebeb75f
parent72bbb9ca20498eba18d6b6a31ed1de2306f90faf (diff)
downloadnextcloud-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.php9
-rw-r--r--apps/files_sharing/lib/sharedstorage.php102
-rw-r--r--lib/private/files/view.php29
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) {