diff options
-rw-r--r-- | apps/files_sharing/appinfo/app.php | 1 | ||||
-rw-r--r-- | apps/files_sharing/lib/cache.php | 16 | ||||
-rw-r--r-- | apps/files_sharing/lib/share/file.php | 1 | ||||
-rw-r--r-- | apps/files_sharing/lib/sharedstorage.php | 78 | ||||
-rw-r--r-- | apps/files_sharing/lib/updater.php | 77 | ||||
-rw-r--r-- | lib/public/share.php | 23 |
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 |