summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBjörn Schießle <schiessle@owncloud.com>2014-04-24 18:45:45 +0200
committerBjörn Schießle <schiessle@owncloud.com>2014-04-24 18:45:45 +0200
commitf520305848be6994a0726d907a0182aa07da0be8 (patch)
treea5c05f26cf6f9a21dd1bc82abf517634199543e2 /lib
parent40257d9736ce0d7bad02bf4a1baa86d9b1fc8f7f (diff)
parentb312d38d38c4e391765beb0aadb6bd2eafd9cb2c (diff)
downloadnextcloud-server-f520305848be6994a0726d907a0182aa07da0be8.tar.gz
nextcloud-server-f520305848be6994a0726d907a0182aa07da0be8.zip
Merge pull request #8026 from owncloud/remove_shared_folder
remove the "Shared" folder
Diffstat (limited to 'lib')
-rw-r--r--lib/private/connector/sabre/directory.php12
-rw-r--r--lib/private/connector/sabre/file.php11
-rw-r--r--lib/private/connector/sabre/objecttree.php11
-rw-r--r--lib/private/files/mount/manager.php7
-rw-r--r--lib/private/files/mount/mount.php7
-rw-r--r--lib/private/files/view.php37
-rw-r--r--lib/private/share/constants.php8
-rw-r--r--lib/private/share/share.php70
-rw-r--r--lib/public/share.php16
9 files changed, 121 insertions, 58 deletions
diff --git a/lib/private/connector/sabre/directory.php b/lib/private/connector/sabre/directory.php
index 70f45aa1e7f..5d386a772a7 100644
--- a/lib/private/connector/sabre/directory.php
+++ b/lib/private/connector/sabre/directory.php
@@ -50,10 +50,6 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
*/
public function createFile($name, $data = null) {
- if (strtolower($name) === 'shared' && empty($this->path)) {
- throw new \Sabre_DAV_Exception_Forbidden();
- }
-
// for chunked upload also updating a existing file is a "createFile"
// because we create all the chunks before reasamble them to the existing file.
if (isset($_SERVER['HTTP_OC_CHUNKED'])) {
@@ -86,10 +82,6 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
*/
public function createDirectory($name) {
- if (strtolower($name) === 'shared' && empty($this->path)) {
- throw new \Sabre_DAV_Exception_Forbidden();
- }
-
if (!\OC\Files\Filesystem::isCreatable($this->path)) {
throw new \Sabre_DAV_Exception_Forbidden();
}
@@ -196,10 +188,6 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
*/
public function delete() {
- if ($this->path === 'Shared') {
- throw new \Sabre_DAV_Exception_Forbidden();
- }
-
if (!\OC\Files\Filesystem::isDeletable($this->path)) {
throw new \Sabre_DAV_Exception_Forbidden();
}
diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index 750d646a8f5..433b4d805c9 100644
--- a/lib/private/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -71,13 +71,6 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
// mark file as partial while uploading (ignored by the scanner)
$partpath = $this->path . '.ocTransferId' . rand() . '.part';
- // if file is located in /Shared we write the part file to the users
- // root folder because we can't create new files in /shared
- // we extend the name with a random number to avoid overwriting a existing file
- if (dirname($partpath) === 'Shared') {
- $partpath = pathinfo($partpath, PATHINFO_FILENAME) . rand() . '.part';
- }
-
try {
$putOkay = $fs->file_put_contents($partpath, $data);
if ($putOkay === false) {
@@ -149,10 +142,6 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
public function delete() {
$fs = $this->getFS();
- if ($this->path === 'Shared') {
- throw new \Sabre_DAV_Exception_Forbidden();
- }
-
if (!$fs->isDeletable($this->path)) {
throw new \Sabre_DAV_Exception_Forbidden();
}
diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php
index accf020daa2..2956f608380 100644
--- a/lib/private/connector/sabre/objecttree.php
+++ b/lib/private/connector/sabre/objecttree.php
@@ -87,16 +87,19 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
list($sourceDir,) = \Sabre_DAV_URLUtil::splitPath($sourcePath);
list($destinationDir,) = \Sabre_DAV_URLUtil::splitPath($destinationPath);
+ $isShareMountPoint = false;
+ list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath( '/' . \OCP\User::getUser() . '/files/' . $sourcePath);
+ if ($storage instanceof \OC\Files\Storage\Shared && !$internalPath) {
+ $isShareMountPoint = true;
+ }
+
// check update privileges
$fs = $this->getFileView();
- if (!$fs->isUpdatable($sourcePath)) {
+ if (!$fs->isUpdatable($sourcePath) && !$isShareMountPoint) {
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, '/') === '' && strtolower($sourceNode->getName()) === 'shared') {
- throw new \Sabre_DAV_Exception_Forbidden();
- }
if (!$fs->isUpdatable($sourceDir)) {
throw new \Sabre_DAV_Exception_Forbidden();
}
diff --git a/lib/private/files/mount/manager.php b/lib/private/files/mount/manager.php
index ff4a336f347..91460b72730 100644
--- a/lib/private/files/mount/manager.php
+++ b/lib/private/files/mount/manager.php
@@ -24,6 +24,13 @@ class Manager {
}
/**
+ * @param string $mountPoint
+ */
+ public function removeMount($mountPoint) {
+ unset($this->mounts[$mountPoint]);
+ }
+
+ /**
* Find the mount for $path
*
* @param $path
diff --git a/lib/private/files/mount/mount.php b/lib/private/files/mount/mount.php
index 0ce2f5975c7..08d5ddf348b 100644
--- a/lib/private/files/mount/mount.php
+++ b/lib/private/files/mount/mount.php
@@ -66,6 +66,13 @@ class Mount {
}
/**
+ * @param string $mountPoint new mount point
+ */
+ public function setMountPoint($mountPoint) {
+ $this->mountPoint = $mountPoint;
+ }
+
+ /**
* create the storage that is mounted
*
* @return \OC\Files\Storage\Storage
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index 519ed250b1f..58dfc73dcf3 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -348,7 +348,8 @@ class View {
$postFix = (substr($path, -1, 1) === '/') ? '/' : '';
$absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
- if (!$internalPath || $internalPath === '' || $internalPath === '/') {
+ 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
@@ -404,11 +405,21 @@ class View {
if ($run) {
$mp1 = $this->getMountPoint($path1 . $postFix1);
$mp2 = $this->getMountPoint($path2 . $postFix2);
- if ($mp1 == $mp2) {
- list($storage, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1);
- list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2);
- if ($storage) {
- $result = $storage->rename($internalPath1, $internalPath2);
+ 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 ($storage1 instanceof \OC\Files\Storage\Shared) {
+ if ($storage1) {
+ $result = $storage1->rename($absolutePath1, $absolutePath2);
+ \OC_FileProxy::runPostProxies('rename', $absolutePath1, $absolutePath2);
+ } else {
+ $result = false;
+ }
+ } elseif ($mp1 == $mp2) {
+ if ($storage1) {
+ $result = $storage1->rename($internalPath1, $internalPath2);
\OC_FileProxy::runPostProxies('rename', $absolutePath1, $absolutePath2);
} else {
$result = false;
@@ -417,7 +428,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 +441,6 @@ class View {
fclose($target);
if ($result !== false) {
- list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1);
$storage1->unlink($internalPath1);
}
}
@@ -972,8 +981,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) {
@@ -1154,7 +1168,8 @@ class View {
* @var \OC\Files\Mount\Mount $mount
*/
$cache = $mount->getStorage()->getCache();
- if ($internalPath = $cache->getPathById($id)) {
+ $internalPath = $cache->getPathById($id);
+ if (is_string($internalPath)) {
$fullPath = $mount->getMountPoint() . $internalPath;
if (!is_null($path = $this->getRelativePath($fullPath))) {
return $path;
diff --git a/lib/private/share/constants.php b/lib/private/share/constants.php
index 7e4223d10fa..4c398c43c2d 100644
--- a/lib/private/share/constants.php
+++ b/lib/private/share/constants.php
@@ -26,13 +26,13 @@ class Constants {
const SHARE_TYPE_USER = 0;
const SHARE_TYPE_GROUP = 1;
const SHARE_TYPE_LINK = 3;
- const SHARE_TYPE_EMAIL = 4;
- const SHARE_TYPE_CONTACT = 5;
- const SHARE_TYPE_REMOTE = 6;
+ const SHARE_TYPE_EMAIL = 4; // ToDo Check if it is still in use otherwise remove it
+ const SHARE_TYPE_CONTACT = 5; // ToDo Check if it is still in use otherwise remove it
+ const SHARE_TYPE_REMOTE = 6; // ToDo Check if it is still in use otherwise remove it
const FORMAT_NONE = -1;
const FORMAT_STATUSES = -2;
- const FORMAT_SOURCES = -3;
+ const FORMAT_SOURCES = -3; // ToDo Check if it is still in use otherwise remove it
const TOKEN_LENGTH = 32; // see db_structure.xml
diff --git a/lib/private/share/share.php b/lib/private/share/share.php
index 0f69a94453a..c0ce3a1d8af 100644
--- a/lib/private/share/share.php
+++ b/lib/private/share/share.php
@@ -223,7 +223,7 @@ class Share extends \OC\Share\Constants {
} else {
while ($row = $result->fetchRow()) {
foreach ($fileTargets[$row['fileid']] as $uid => $shareData) {
- $sharedPath = '/Shared' . $shareData['file_target'];
+ $sharedPath = $shareData['file_target'];
$sharedPath .= substr($path, strlen($row['path']) -5);
$sharePaths[$uid] = $sharedPath;
}
@@ -253,6 +253,22 @@ class Share extends \OC\Share\Constants {
}
/**
+ * Get the items of item type shared with a user
+ * @param string Item type
+ * @param sting user id for which user we want the shares
+ * @param int Format (optional) Format type must be defined by the backend
+ * @param mixed Parameters (optional)
+ * @param int Number of items to return (optional) Returns all by default
+ * @param bool include collections (optional)
+ * @return Return depends on format
+ */
+ public static function getItemsSharedWithUser($itemType, $user, $format = self::FORMAT_NONE,
+ $parameters = null, $limit = -1, $includeCollections = false) {
+ return self::getItems($itemType, null, self::$shareTypeUserAndGroups, $user, null, $format,
+ $parameters, $limit, $includeCollections);
+ }
+
+ /**
* Get the item of item type shared with the current user
* @param string $itemType
* @param string $itemTarget
@@ -473,6 +489,7 @@ class Share extends \OC\Share\Constants {
$itemSourceName = $itemSource;
}
+
// verify that the file exists before we try to share it
if ($itemType === 'file' or $itemType === 'folder') {
$path = \OC\Files\Filesystem::getPath($itemSource);
@@ -484,6 +501,21 @@ class Share extends \OC\Share\Constants {
}
}
+ //verify that we don't share a folder which already contains a share mount point
+ if ($itemType === 'folder') {
+ $path = '/' . $uidOwner . '/files' . \OC\Files\Filesystem::getPath($itemSource) . '/';
+ $mountManager = \OC\Files\Filesystem::getMountManager();
+ $mounts = $mountManager->getAll();
+ foreach ($mounts as $mountPoint => $mount) {
+ if ($mount->getStorage() instanceof \OC\Files\Storage\Shared && strpos($mountPoint, $path) === 0) {
+ $message = 'Sharing "' . $itemSourceName . '" failed, because it contains files shared with you!';
+ \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+ throw new \Exception($message);
+ }
+
+ }
+ }
+
// Verify share type and sharing conditions are met
if ($shareType === self::SHARE_TYPE_USER) {
if ($shareWith == $uidOwner) {
@@ -876,6 +908,7 @@ class Share extends \OC\Share\Constants {
$hookParams = array(
'itemType' => $item['item_type'],
'itemSource' => $item['item_source'],
+ 'fileSource' => $item['file_source'],
'shareType' => $item['share_type'],
'shareWith' => $item['share_with'],
'itemParent' => $item['parent'],
@@ -1135,6 +1168,7 @@ class Share extends \OC\Share\Constants {
// Filter out duplicate group shares for users with unique targets
if ($row['share_type'] == self::$shareTypeGroupUserUnique && isset($items[$row['parent']])) {
$row['share_type'] = self::SHARE_TYPE_GROUP;
+ $row['unique_name'] = true; // remember that we use a unique name for this user
$row['share_with'] = $items[$row['parent']]['share_with'];
// Remove the parent group share
unset($items[$row['parent']]);
@@ -1173,10 +1207,6 @@ class Share extends \OC\Share\Constants {
// Remove root from file source paths if retrieving own shared items
if (isset($uidOwner) && isset($row['path'])) {
if (isset($row['parent'])) {
- // FIXME: Doesn't always construct the correct path, example:
- // Folder '/a/b', share '/a' and '/a/b' to user2
- // user2 reshares /Shared/b and ask for share status of /Shared/a/b
- // expected result: path=/Shared/a/b; actual result /Shared/b because of the parent
$query = \OC_DB::prepare('SELECT `file_target` FROM `*PREFIX*share` WHERE `id` = ?');
$parentResult = $query->execute(array($row['parent']));
if (\OC_DB::isError($result)) {
@@ -1185,7 +1215,7 @@ class Share extends \OC\Share\Constants {
\OC_Log::ERROR);
} else {
$parentRow = $parentResult->fetchRow();
- $tmpPath = '/Shared' . $parentRow['file_target'];
+ $tmpPath = $parentRow['file_target'];
// find the right position where the row path continues from the target path
$pos = strrpos($row['path'], $parentRow['file_target']);
$subPath = substr($row['path'], $pos);
@@ -1395,8 +1425,8 @@ class Share extends \OC\Share\Constants {
}
}
$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`, `token`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)');
+ .' `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,'
+ .' `file_target`, `token`, `parent`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)');
// Share with a group
if ($shareType == self::SHARE_TYPE_GROUP) {
$groupItemTarget = Helper::generateTarget($itemType, $itemSource, $shareType, $shareWith['group'],
@@ -1440,10 +1470,9 @@ class Share extends \OC\Share\Constants {
} else {
$groupFileTarget = null;
}
- $query->execute(array($itemType, $itemSource, $groupItemTarget, $parent, $shareType,
- $shareWith['group'], $uidOwner, $permissions, time(), $fileSource, $groupFileTarget, $token));
- // Save this id, any extra rows for this group share will need to reference it
- $parent = \OC_DB::insertid('*PREFIX*share');
+ $queriesToExecute = array();
+ $queriesToExecute['groupShare'] = array($itemType, $itemSource, $groupItemTarget, $shareType,
+ $shareWith['group'], $uidOwner, $permissions, time(), $fileSource, $groupFileTarget, $token, $parent);
// Loop through all users of this group in case we need to add an extra row
foreach ($shareWith['users'] as $uid) {
$itemTarget = Helper::generateTarget($itemType, $itemSource, self::SHARE_TYPE_USER, $uid,
@@ -1469,12 +1498,21 @@ class Share extends \OC\Share\Constants {
}
// Insert an extra row for the group share if the item or file target is unique for this user
if ($itemTarget != $groupItemTarget || (isset($fileSource) && $fileTarget != $groupFileTarget)) {
- $query->execute(array($itemType, $itemSource, $itemTarget, $parent,
+ $queriesToExecute[] = array($itemType, $itemSource, $itemTarget,
self::$shareTypeGroupUserUnique, $uid, $uidOwner, $permissions, time(),
- $fileSource, $fileTarget, $token));
+ $fileSource, $fileTarget, $token);
$id = \OC_DB::insertid('*PREFIX*share');
}
}
+ $query->execute($queriesToExecute['groupShare']);
+ // Save this id, any extra rows for this group share will need to reference it
+ $parent = \OC_DB::insertid('*PREFIX*share');
+ unset($queriesToExecute['groupShare']);
+ foreach ($queriesToExecute as $qe) {
+ $qe[] = $parent;
+ $query->execute($qe);
+ }
+
\OC_Hook::emit('OCP\Share', 'post_shared', array(
'itemType' => $itemType,
'itemSource' => $itemSource,
@@ -1534,8 +1572,8 @@ class Share extends \OC\Share\Constants {
} else {
$fileTarget = null;
}
- $query->execute(array($itemType, $itemSource, $itemTarget, $parent, $shareType, $shareWith, $uidOwner,
- $permissions, time(), $fileSource, $fileTarget, $token));
+ $query->execute(array($itemType, $itemSource, $itemTarget, $shareType, $shareWith, $uidOwner,
+ $permissions, time(), $fileSource, $fileTarget, $token, $parent));
$id = \OC_DB::insertid('*PREFIX*share');
\OC_Hook::emit('OCP\Share', 'post_shared', array(
'itemType' => $itemType,
diff --git a/lib/public/share.php b/lib/public/share.php
index c694314ad08..230a517b5ee 100644
--- a/lib/public/share.php
+++ b/lib/public/share.php
@@ -91,6 +91,22 @@ class Share extends \OC\Share\Constants {
}
/**
+ * Get the items of item type shared with a user
+ * @param string Item type
+ * @param sting user id for which user we want the shares
+ * @param int Format (optional) Format type must be defined by the backend
+ * @param mixed Parameters (optional)
+ * @param int Number of items to return (optional) Returns all by default
+ * @param bool include collections (optional)
+ * @return Return depends on format
+ */
+ public static function getItemsSharedWithUser($itemType, $user, $format = self::FORMAT_NONE,
+ $parameters = null, $limit = -1, $includeCollections = false) {
+
+ return \OC\Share\Share::getItemsSharedWithUser($itemType, $user, $format, $parameters, $limit, $includeCollections);
+ }
+
+ /**
* Get the item of item type shared with the current user
* @param string $itemType
* @param string $itemTarget