diff options
author | Bernhard Posselt <nukeawhale@gmail.com> | 2013-03-11 02:38:50 -0700 |
---|---|---|
committer | Bernhard Posselt <nukeawhale@gmail.com> | 2013-03-11 02:38:50 -0700 |
commit | 049a4df25939622a83d5ff1a8dbc03f9f7569c78 (patch) | |
tree | 521fbe2492c19f24f496c86cf9725e29b30be327 /apps/files_sharing | |
parent | 75377a6eb4a594afffb363f7eff740ed3f8826d8 (diff) | |
parent | e743386acffe6cb7de4b8d2dac5aeac70f1a74e0 (diff) | |
download | nextcloud-server-049a4df25939622a83d5ff1a8dbc03f9f7569c78.tar.gz nextcloud-server-049a4df25939622a83d5ff1a8dbc03f9f7569c78.zip |
Merge pull request #1786 from owncloud/shared-folder-etags
Include etags for the root of the shared folder
Diffstat (limited to 'apps/files_sharing')
-rw-r--r-- | apps/files_sharing/appinfo/app.php | 6 | ||||
-rw-r--r-- | apps/files_sharing/lib/cache.php | 39 | ||||
-rw-r--r-- | apps/files_sharing/lib/share/file.php | 1 | ||||
-rw-r--r-- | apps/files_sharing/lib/sharedstorage.php | 72 | ||||
-rw-r--r-- | apps/files_sharing/lib/updater.php | 102 |
5 files changed, 181 insertions, 39 deletions
diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php index 5b5893abc93..57116698159 100644 --- a/apps/files_sharing/appinfo/app.php +++ b/apps/files_sharing/appinfo/app.php @@ -5,8 +5,14 @@ OC::$CLASSPATH['OC_Share_Backend_Folder'] = 'files_sharing/lib/share/folder.php' OC::$CLASSPATH['OC\Files\Storage\Shared'] = 'files_sharing/lib/sharedstorage.php'; OC::$CLASSPATH['OC\Files\Cache\Shared_Cache'] = 'files_sharing/lib/cache.php'; OC::$CLASSPATH['OC\Files\Cache\Shared_Permissions'] = 'files_sharing/lib/permissions.php'; +OC::$CLASSPATH['OC\Files\Cache\Shared_Updater'] = 'files_sharing/lib/updater.php'; OC::$CLASSPATH['OC\Files\Cache\Shared_Watcher'] = 'files_sharing/lib/watcher.php'; OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup'); OCP\Share::registerBackend('file', 'OC_Share_Backend_File'); OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file'); OCP\Util::addScript('files_sharing', 'share'); +\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'); +\OC_Hook::connect('OCP\Share', 'post_shared', '\OC\Files\Cache\Shared_Updater', 'shareHook'); +\OC_Hook::connect('OCP\Share', 'pre_unshare', '\OC\Files\Cache\Shared_Updater', 'shareHook');
\ No newline at end of file diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index fb0f6c7b5a6..9fccd0b46f3 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; } /** @@ -41,16 +42,19 @@ class Shared_Cache extends Cache { */ private function getSourceCache($target) { $source = \OC_Share_Backend_File::getSource($target); - if (isset($source['path'])) { - $source['path'] = '/' . $source['uid_owner'] . '/' . $source['path']; - \OC\Files\Filesystem::initMountPoints($source['uid_owner']); - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source['path']); - if ($storage) { - $this->files[$target] = $internalPath; - $cache = $storage->getCache(); - $this->storageId = $storage->getId(); - $this->numericId = $cache->getNumericStorageId(); - return $cache; + if (isset($source['path']) && isset($source['fileOwner'])) { + \OC\Files\Filesystem::initMountPoints($source['fileOwner']); + $mount = \OC\Files\Mount::findByNumericId($source['storage']); + if ($mount) { + $fullPath = $mount->getMountPoint().$source['path']; + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($fullPath); + if ($storage) { + $this->files[$target] = $internalPath; + $cache = $storage->getCache(); + $this->storageId = $storage->getId(); + $this->numericId = $cache->getNumericStorageId(); + return $cache; + } } } return false; @@ -64,7 +68,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 +129,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 fa43e87b49e..62948651806 100644 --- a/apps/files_sharing/lib/share/file.php +++ b/apps/files_sharing/lib/share/file.php @@ -93,6 +93,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 be0e59e6732..ffd4e5ced22 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -45,7 +45,18 @@ class Shared extends \OC\Files\Storage\Common { */ private function getFile($target) { if (!isset($this->files[$target])) { - $this->files[$target] = \OC_Share_Backend_File::getSource($target); + // Check for partial files + if (pathinfo($target, PATHINFO_EXTENSION) === 'part') { + $source = \OC_Share_Backend_File::getSource(substr($target, 0, -5)); + if ($source) { + $source['path'] .= '.part'; + // All partial files have delete permission + $source['permissions'] |= \OCP\PERMISSION_DELETE; + } + } else { + $source = \OC_Share_Backend_File::getSource($target); + } + $this->files[$target] = $source; } return $this->files[$target]; } @@ -280,34 +291,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); + } + } } } } @@ -371,7 +391,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) { diff --git a/apps/files_sharing/lib/updater.php b/apps/files_sharing/lib/updater.php new file mode 100644 index 00000000000..73e7808f24a --- /dev/null +++ b/apps/files_sharing/lib/updater.php @@ -0,0 +1,102 @@ +<?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)) { + while (!empty($users)) { + $reshareUsers = array(); + foreach ($users as $user) { + $etag = \OC\Files\Filesystem::getETag(''); + \OCP\Config::setUserValue($user, 'files_sharing', 'etag', $etag); + // Look for reshares + $reshareUsers = array_merge($reshareUsers, \OCP\Share::getUsersItemShared('file', $info['fileid'], $user, true)); + } + $users = $reshareUsers; + } + // 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']); + } + + /** + * @param array $params + */ + static public function shareHook($params) { + if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') { + $uidOwner = \OCP\User::getUser(); + $users = \OCP\Share::getUsersItemShared($params['itemType'], $params['fileSource'], $uidOwner, true); + if (!empty($users)) { + while (!empty($users)) { + $reshareUsers = array(); + foreach ($users as $user) { + $etag = \OC\Files\Filesystem::getETag(''); + \OCP\Config::setUserValue($user, 'files_sharing', 'etag', $etag); + // Look for reshares + $reshareUsers = array_merge($reshareUsers, \OCP\Share::getUsersItemShared('file', $params['fileSource'], $user, true)); + } + $users = $reshareUsers; + } + } + } + } + +} |