aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private')
-rw-r--r--lib/private/connector/sabre/objecttree.php4
-rw-r--r--lib/private/files/cache/updater.php4
-rw-r--r--lib/private/files/fileinfo.php2
-rw-r--r--lib/private/files/mount/manager.php9
-rw-r--r--lib/private/files/mount/mount.php13
-rw-r--r--lib/private/files/mount/moveablemount.php30
-rw-r--r--lib/private/files/view.php66
-rw-r--r--lib/private/hook.php6
-rw-r--r--lib/private/share/helper.php21
-rw-r--r--lib/private/share/share.php72
10 files changed, 145 insertions, 82 deletions
diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php
index a3de2efaa50..c55a392bca0 100644
--- a/lib/private/connector/sabre/objecttree.php
+++ b/lib/private/connector/sabre/objecttree.php
@@ -126,10 +126,6 @@ class ObjectTree extends \Sabre\DAV\ObjectTree {
throw new \Sabre\DAV\Exception\Forbidden();
}
if ($sourceDir !== $destinationDir) {
- // for a full move we need update privileges on sourcePath and sourceDir as well as destinationDir
- if (ltrim($destinationDir, '/') === '') {
- throw new \Sabre\DAV\Exception\Forbidden();
- }
if (!$this->fileView->isUpdatable($sourceDir)) {
throw new \Sabre\DAV\Exception\Forbidden();
}
diff --git a/lib/private/files/cache/updater.php b/lib/private/files/cache/updater.php
index f6feb6624b2..f15c203cd58 100644
--- a/lib/private/files/cache/updater.php
+++ b/lib/private/files/cache/updater.php
@@ -83,6 +83,10 @@ class Updater {
* @var string $internalTo
*/
list($storageFrom, $internalFrom) = self::resolvePath($from);
+ // if it's a moved mountpoint we dont need to do anything
+ if ($internalFrom === '') {
+ return;
+ }
list($storageTo, $internalTo) = self::resolvePath($to);
if ($storageFrom && $storageTo) {
if ($storageFrom === $storageTo) {
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());
}
/**
diff --git a/lib/private/files/mount/manager.php b/lib/private/files/mount/manager.php
index db1f4600c74..45a9f339fba 100644
--- a/lib/private/files/mount/manager.php
+++ b/lib/private/files/mount/manager.php
@@ -31,6 +31,15 @@ class Manager {
}
/**
+ * @param string $mountPoint
+ * @param string $target
+ */
+ public function moveMount($mountPoint, $target){
+ $this->mounts[$target] = $this->mounts[$mountPoint];
+ unset($this->mounts[$mountPoint]);
+ }
+
+ /**
* Find the mount for $path
*
* @param string $path
diff --git a/lib/private/files/mount/mount.php b/lib/private/files/mount/mount.php
index 7c40853ac95..04bccbcab87 100644
--- a/lib/private/files/mount/mount.php
+++ b/lib/private/files/mount/mount.php
@@ -16,11 +16,11 @@ class Mount {
/**
* @var \OC\Files\Storage\Storage $storage
*/
- private $storage = null;
- private $class;
- private $storageId;
- private $arguments = array();
- private $mountPoint;
+ protected $storage = null;
+ protected $class;
+ protected $storageId;
+ protected $arguments = array();
+ protected $mountPoint;
/**
* @var \OC\Files\Storage\Loader $loader
@@ -142,7 +142,8 @@ class Mount {
} else {
$internalPath = substr($path, strlen($this->mountPoint));
}
- return $internalPath;
+ // substr returns false instead of an empty string, we always want a string
+ return (string)$internalPath;
}
/**
diff --git a/lib/private/files/mount/moveablemount.php b/lib/private/files/mount/moveablemount.php
new file mode 100644
index 00000000000..117649339e9
--- /dev/null
+++ b/lib/private/files/mount/moveablemount.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Files\Mount;
+
+/**
+ * Defines the mount point to be (re)moved by the user
+ */
+interface MoveableMount {
+ /**
+ * Move the mount point to $target
+ *
+ * @param string $target the target mount point
+ * @return bool
+ */
+ public function moveMount($target);
+
+ /**
+ * Remove the mount points
+ *
+ * @return mixed
+ * @return bool
+ */
+ public function removeMount();
+}
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index 1dc6c405bcf..d42f6cbf9fe 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -26,6 +26,7 @@
namespace OC\Files;
use OC\Files\Cache\Updater;
+use OC\Files\Mount\MoveableMount;
class View {
private $fakeRoot = '';
@@ -357,14 +358,27 @@ class View {
}
$postFix = (substr($path, -1, 1) === '/') ? '/' : '';
$absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
- list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
- if (!($storage instanceof \OC\Files\Storage\Shared) &&
- (!$internalPath || $internalPath === '' || $internalPath === '/')
- ) {
- // do not allow deleting the storage's root / the mount point
- // because for some storages it might delete the whole contents
- // but isn't supposed to work that way
- return false;
+ $mount = Filesystem::getMountManager()->find($absolutePath . $postFix);
+ if ($mount->getInternalPath($absolutePath) === '') {
+ if ($mount instanceof MoveableMount) {
+ \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
+ // but isn't supposed to work that way
+ return false;
+ }
}
return $this->basicOperation('unlink', $path, array('delete'));
}
@@ -411,18 +425,19 @@ class View {
if ($run) {
$mp1 = $this->getMountPoint($path1 . $postFix1);
$mp2 = $this->getMountPoint($path2 . $postFix2);
- list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1);
+ $manager = Filesystem::getMountManager();
+ $mount = $manager->find($absolutePath1 . $postFix1);
+ $storage1 = $mount->getStorage();
+ $internalPath1 = $mount->getInternalPath($absolutePath1 . $postFix1);
list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2);
- // if source and target are on the same storage we can call the rename operation from the
- // storage. If it is a "Shared" file/folder we call always the rename operation of the
- // shared storage to handle mount point renaming, etc correctly
- if ($storage1 instanceof \OC\Files\Storage\Shared) {
- if ($storage1) {
- $result = $storage1->rename($absolutePath1, $absolutePath2);
- \OC_FileProxy::runPostProxies('rename', $absolutePath1, $absolutePath2);
- } else {
- $result = false;
- }
+ if ($internalPath1 === '' and $mount instanceof MoveableMount) {
+ /**
+ * @var \OC\Files\Mount\Mount | \OC\Files\Mount\MoveableMount $mount
+ */
+ $sourceMountPoint = $mount->getMountPoint();
+ $result = $mount->moveMount($absolutePath2);
+ $manager->moveMount($sourceMountPoint, $mount->getMountPoint());
+ \OC_FileProxy::runPostProxies('rename', $absolutePath1, $absolutePath2);
} elseif ($mp1 == $mp2) {
if ($storage1) {
$result = $storage1->rename($internalPath1, $internalPath2);
@@ -888,10 +903,6 @@ class View {
return $result;
}
$path = Filesystem::normalizePath($this->fakeRoot . '/' . $directory);
- /**
- * @var \OC\Files\Storage\Storage $storage
- * @var string $internalPath
- */
list($storage, $internalPath) = Filesystem::resolvePath($path);
if ($storage) {
$cache = $storage->getCache($internalPath);
@@ -924,9 +935,10 @@ class View {
}
//add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders
- $mountPoints = Filesystem::getMountPoints($path);
+ $mounts = Filesystem::getMountManager()->findIn($path);
$dirLength = strlen($path);
- foreach ($mountPoints as $mountPoint) {
+ foreach ($mounts as $mount) {
+ $mountPoint = $mount->getMountPoint();
$subStorage = Filesystem::getStorage($mountPoint);
if ($subStorage) {
$subCache = $subStorage->getCache('');
@@ -953,8 +965,8 @@ class View {
$permissions = $rootEntry['permissions'];
// do not allow renaming/deleting the mount point if they are not shared files/folders
// for shared files/folders we use the permissions given by the owner
- if ($subStorage instanceof \OC\Files\Storage\Shared) {
- $rootEntry['permissions'] = $permissions;
+ if ($mount instanceof MoveableMount) {
+ $rootEntry['permissions'] = $permissions | \OCP\PERMISSION_UPDATE | \OCP\PERMISSION_DELETE;
} else {
$rootEntry['permissions'] = $permissions & (\OCP\PERMISSION_ALL - (\OCP\PERMISSION_UPDATE | \OCP\PERMISSION_DELETE));
}
diff --git a/lib/private/hook.php b/lib/private/hook.php
index 30e22847c7f..c9ca58f779e 100644
--- a/lib/private/hook.php
+++ b/lib/private/hook.php
@@ -31,6 +31,12 @@ class OC_Hook{
self::$registered[$signalclass][$signalname] = array();
}
+ // dont connect hooks twice
+ foreach (self::$registered[$signalclass][$signalname] as $hook) {
+ if ($hook['class'] === $slotclass and $hook['name'] === $slotname) {
+ return false;
+ }
+ }
// Connect the hook handler to the requested emitter
self::$registered[$signalclass][$signalname][] = array(
"class" => $slotclass,
diff --git a/lib/private/share/helper.php b/lib/private/share/helper.php
index ab9e0ca4926..c92aa15b4bf 100644
--- a/lib/private/share/helper.php
+++ b/lib/private/share/helper.php
@@ -166,27 +166,6 @@ class Helper extends \OC\Share\Constants {
// Reset parents array, only go through loop again if items are found
$parents = array();
while ($item = $result->fetchRow()) {
- // Search for a duplicate parent share, this occurs when an
- // item is shared to the same user through a group and user or the
- // same item is shared by different users
- $userAndGroups = array_merge(array($item['uid_owner']), \OC_Group::getUserGroups($item['uid_owner']));
- $query = \OC_DB::prepare('SELECT `id`, `permissions` FROM `*PREFIX*share`'
- .' WHERE `item_type` = ?'
- .' AND `item_target` = ?'
- .' AND `share_type` IN (?,?,?)'
- .' AND `share_with` IN (\''.implode('\',\'', $userAndGroups).'\')'
- .' AND `uid_owner` != ? AND `id` != ?');
- $duplicateParent = $query->execute(array($item['item_type'], $item['item_target'],
- self::SHARE_TYPE_USER, self::SHARE_TYPE_GROUP, self::$shareTypeGroupUserUnique,
- $item['uid_owner'], $item['parent']))->fetchRow();
- if ($duplicateParent) {
- // Change the parent to the other item id if share permission is granted
- if ($duplicateParent['permissions'] & \OCP\PERMISSION_SHARE) {
- $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `parent` = ? WHERE `id` = ?');
- $query->execute(array($duplicateParent['id'], $item['id']));
- continue;
- }
- }
$ids[] = $item['id'];
$parents[] = $item['id'];
}
diff --git a/lib/private/share/share.php b/lib/private/share/share.php
index 2126a1d2dd4..f02eacfed74 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) {
@@ -712,33 +717,54 @@ 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`'
+
+ $uid = \OCP\User::getUser();
+
+ 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 &&
+ $share['share_with'] === $uid) {
+ Helper::delete($share['id']);
+ $itemUnshared = true;
+ break;
+ } elseif ((int)$share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP) {
+ if (\OC_Group::inGroup($uid, $share['share_with'])) {
+ $groupShare = $share;
+ }
+ } elseif ((int)$share['share_type'] === self::$shareTypeGroupUserUnique &&
+ $share['share_with'] === $uid) {
+ $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;
}
/**