summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/files_sharing/appinfo/app.php1
-rw-r--r--apps/files_sharing/lib/cache.php16
-rw-r--r--apps/files_sharing/lib/share/file.php1
-rw-r--r--apps/files_sharing/lib/sharedstorage.php78
-rw-r--r--apps/files_sharing/lib/updater.php77
-rw-r--r--lib/public/share.php23
6 files changed, 165 insertions, 31 deletions
diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php
index d3e05cc62d8..f8326db45bb 100644
--- a/apps/files_sharing/appinfo/app.php
+++ b/apps/files_sharing/appinfo/app.php
@@ -5,6 +5,7 @@ OC::$CLASSPATH['OC_Share_Backend_Folder'] = 'apps/files_sharing/lib/share/folder
OC::$CLASSPATH['OC\Files\Storage\Shared'] = "apps/files_sharing/lib/sharedstorage.php";
OC::$CLASSPATH['OC\Files\Cache\Shared_Cache'] = 'apps/files_sharing/lib/cache.php';
OC::$CLASSPATH['OC\Files\Cache\Shared_Permissions'] = 'apps/files_sharing/lib/permissions.php';
+OC::$CLASSPATH['OC\Files\Cache\Shared_Updater'] = 'apps/files_sharing/lib/updater.php';
OC::$CLASSPATH['OC\Files\Cache\Shared_Watcher'] = 'apps/files_sharing/lib/watcher.php';
OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup');
OCP\Share::registerBackend('file', 'OC_Share_Backend_File');
diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php
index fb0f6c7b5a6..6f834e08999 100644
--- a/apps/files_sharing/lib/cache.php
+++ b/apps/files_sharing/lib/cache.php
@@ -28,10 +28,11 @@ namespace OC\Files\Cache;
*/
class Shared_Cache extends Cache {
+ private $storage;
private $files = array();
public function __construct($storage) {
-
+ $this->storage = $storage;
}
/**
@@ -64,7 +65,14 @@ class Shared_Cache extends Cache {
*/
public function get($file) {
if ($file == '') {
- return \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT);
+ $data = \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT);
+ $etag = \OCP\Config::getUserValue(\OCP\User::getUser(), 'files_sharing', 'etag');
+ if (!isset($etag)) {
+ $etag = $this->storage->getETag('');
+ \OCP\Config::setUserValue(\OCP\User::getUser(), 'files_sharing', 'etag', $etag);
+ }
+ $data['etag'] = $etag;
+ return $data;
} else if (is_string($file)) {
if ($cache = $this->getSourceCache($file)) {
return $cache->get($this->files[$file]);
@@ -118,7 +126,9 @@ class Shared_Cache extends Cache {
* @return int file id
*/
public function put($file, array $data) {
- if ($cache = $this->getSourceCache($file)) {
+ if ($file === '' && isset($data['etag'])) {
+ return \OCP\Config::setUserValue(\OCP\User::getUser(), 'files_sharing', 'etag', $data['etag']);
+ } else if ($cache = $this->getSourceCache($file)) {
return $cache->put($this->files[$file], $data);
}
return false;
diff --git a/apps/files_sharing/lib/share/file.php b/apps/files_sharing/lib/share/file.php
index 0aeb763d89a..b5d506b173b 100644
--- a/apps/files_sharing/lib/share/file.php
+++ b/apps/files_sharing/lib/share/file.php
@@ -91,6 +91,7 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent {
$file['size'] = $item['size'];
$file['mtime'] = $item['mtime'];
$file['encrypted'] = $item['encrypted'];
+ $file['etag'] = $item['etag'];
$files[] = $file;
}
return $files;
diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php
index 5a9864b64ba..19abc838258 100644
--- a/apps/files_sharing/lib/sharedstorage.php
+++ b/apps/files_sharing/lib/sharedstorage.php
@@ -45,9 +45,19 @@ class Shared extends \OC\Files\Storage\Common {
*/
private function getFile($target) {
if (!isset($this->files[$target])) {
- $source = \OC_Share_Backend_File::getSource($target);
- if ($source) {
- $source['path'] = '/'.$source['uid_owner'].'/'.$source['path'];
+ // Check for partial files
+ if (pathinfo($target, PATHINFO_EXTENSION) === 'part') {
+ $source = \OC_Share_Backend_File::getSource(substr($target, 0, -5));
+ if ($source) {
+ $source['path'] = '/'.$source['uid_owner'].'/'.$source['path'].'.part';
+ // All partial files have delete permission
+ $source['permissions'] |= \OCP\PERMISSION_DELETE;
+ }
+ } else {
+ $source = \OC_Share_Backend_File::getSource($target);
+ if ($source) {
+ $source['path'] = '/'.$source['uid_owner'].'/'.$source['path'];
+ }
}
$this->files[$target] = $source;
}
@@ -276,34 +286,43 @@ class Shared extends \OC\Files\Storage\Common {
}
public function rename($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))) {
- $newSource = $this->getSourcePath(dirname($path2)).'/'.basename($path2);
- if (dirname($path1) == dirname($path2)) {
- // Rename the file if UPDATE permission is granted
- if ($this->isUpdatable($path1)) {
- list($storage, $oldInternalPath) = \OC\Files\Filesystem::resolvePath($oldSource);
- list( , $newInternalPath) = \OC\Files\Filesystem::resolvePath($newSource);
- return $storage->rename($oldInternalPath, $newInternalPath);
- }
- } else {
- // Move the file if DELETE and CREATE permissions are granted
- if ($this->isDeletable($path1) && $this->isCreatable(dirname($path2))) {
- // Get the root shared folder
- $folder1 = substr($path1, 0, $pos1);
- $folder2 = substr($path2, 0, $pos2);
- // Copy and unlink the file if it exists in a different shared folder
- if ($folder1 != $folder2) {
- if ($this->copy($path1, $path2)) {
- return $this->unlink($path1);
- }
- } else {
+ // Check for partial files
+ if (pathinfo($path1, PATHINFO_EXTENSION) === 'part') {
+ if ($oldSource = $this->getSourcePath($path1)) {
+ list($storage, $oldInternalPath) = \OC\Files\Filesystem::resolvePath($oldSource);
+ $newInternalPath = substr($oldInternalPath, 0, -5);
+ return $storage->rename($oldInternalPath, $newInternalPath);
+ }
+ } else {
+ // 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))) {
+ $newSource = $this->getSourcePath(dirname($path2)).'/'.basename($path2);
+ if (dirname($path1) == dirname($path2)) {
+ // Rename the file if UPDATE permission is granted
+ if ($this->isUpdatable($path1)) {
list($storage, $oldInternalPath) = \OC\Files\Filesystem::resolvePath($oldSource);
list( , $newInternalPath) = \OC\Files\Filesystem::resolvePath($newSource);
return $storage->rename($oldInternalPath, $newInternalPath);
}
+ } else {
+ // Move the file if DELETE and CREATE permissions are granted
+ if ($this->isDeletable($path1) && $this->isCreatable(dirname($path2))) {
+ // Get the root shared folder
+ $folder1 = substr($path1, 0, $pos1);
+ $folder2 = substr($path2, 0, $pos2);
+ // Copy and unlink the file if it exists in a different shared folder
+ if ($folder1 != $folder2) {
+ if ($this->copy($path1, $path2)) {
+ return $this->unlink($path1);
+ }
+ } else {
+ list($storage, $oldInternalPath) = \OC\Files\Filesystem::resolvePath($oldSource);
+ list( , $newInternalPath) = \OC\Files\Filesystem::resolvePath($newSource);
+ return $storage->rename($oldInternalPath, $newInternalPath);
+ }
+ }
}
}
}
@@ -367,7 +386,7 @@ class Shared extends \OC\Files\Storage\Common {
public function free_space($path) {
if ($path == '') {
- return -1;
+ return \OC\Files\FREE_SPACE_UNKNOWN;
}
$source = $this->getSourcePath($path);
if ($source) {
@@ -398,6 +417,9 @@ class Shared extends \OC\Files\Storage\Common {
\OC\Files\Filesystem::mount('\OC\Files\Storage\Shared',
array('sharedFolder' => '/Shared'),
$user_dir.'/Shared/');
+ \OC_Hook::connect('OC_Filesystem', 'post_write', '\OC\Files\Cache\Shared_Updater', 'writeHook');
+ \OC_Hook::connect('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Shared_Updater', 'deleteHook');
+ \OC_Hook::connect('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Shared_Updater', 'renameHook');
}
}
diff --git a/apps/files_sharing/lib/updater.php b/apps/files_sharing/lib/updater.php
new file mode 100644
index 00000000000..a41ce76f933
--- /dev/null
+++ b/apps/files_sharing/lib/updater.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Michael Gapczynski
+ * @copyright 2013 Michael Gapczynski mtgap@owncloud.com
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+namespace OC\Files\Cache;
+
+class Shared_Updater {
+
+ /**
+ * Correct the parent folders' ETags for all users shared the file at $target
+ *
+ * @param string $target
+ */
+ static public function correctFolders($target) {
+ $uid = \OCP\User::getUser();
+ $uidOwner = \OC\Files\Filesystem::getOwner($target);
+ $info = \OC\Files\Filesystem::getFileInfo($target);
+ // Correct Shared folders of other users shared with
+ $users = \OCP\Share::getUsersItemShared('file', $info['fileid'], $uidOwner, true);
+ if (!empty($users)) {
+ foreach ($users as $user) {
+ // The ETag of the logged in user should already be updated
+ if ($user !== $uid) {
+ $etag = \OC\Files\Filesystem::getETag('');
+ \OCP\Config::setUserValue($user, 'files_sharing', 'etag', $etag);
+ }
+ }
+ // Correct folders of shared file owner
+ $target = substr($target, 8);
+ if ($uidOwner !== $uid && $source = \OC_Share_Backend_File::getSource($target)) {
+ \OC\Files\Filesystem::initMountPoints($uidOwner);
+ $source = '/'.$uidOwner.'/'.$source['path'];
+ \OC\Files\Cache\Updater::correctFolder($source, $info['mtime']);
+ }
+ }
+ }
+
+ /**
+ * @param array $params
+ */
+ static public function writeHook($params) {
+ self::correctFolders($params['path']);
+ }
+
+ /**
+ * @param array $params
+ */
+ static public function renameHook($params) {
+ self::correctFolders($params['oldpath']);
+ self::correctFolders($params['newpath']);
+ }
+
+ /**
+ * @param array $params
+ */
+ static public function deleteHook($params) {
+ self::correctFolders($params['path']);
+ }
+
+} \ No newline at end of file
diff --git a/lib/public/share.php b/lib/public/share.php
index 37cf0838ed1..f3c1da74761 100644
--- a/lib/public/share.php
+++ b/lib/public/share.php
@@ -198,6 +198,29 @@ class Share {
}
/**
+ * Get all users an item is shared with
+ * @param string Item type
+ * @param string Item source
+ * @param string Owner
+ * @param bool Include collections
+ * @return Return array of users
+ */
+ public static function getUsersItemShared($itemType, $itemSource, $uidOwner, $includeCollections = false) {
+ $users = array();
+ $items = self::getItems($itemType, $itemSource, null, null, $uidOwner, self::FORMAT_NONE, null, -1, $includeCollections);
+ if ($items) {
+ foreach ($items as $item) {
+ if ((int)$item['share_type'] === self::SHARE_TYPE_USER) {
+ $users[] = $item['share_with'];
+ } else if ((int)$item['share_type'] === self::SHARE_TYPE_GROUP) {
+ $users = array_merge($users, \OC_Group::usersInGroup($item['share_with']));
+ }
+ }
+ }
+ return $users;
+ }
+
+ /**
* @brief Share an item with a user, group, or via private link
* @param string Item type
* @param string Item source