[Pkg-owncloud-commits] [owncloud] 90/215: propagate etags for all user of a share

David Prévot taffit at moszumanska.debian.org
Tue May 5 01:01:27 UTC 2015


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch stable8
in repository owncloud.

commit 30ad56813a16908e3862c353256f2a6d0f05fe3a
Author: Robin Appelman <icewind at owncloud.com>
Date:   Mon Mar 9 16:20:18 2015 +0100

    propagate etags for all user of a share
---
 apps/files_sharing/appinfo/app.php                 |  37 ++++---
 apps/files_sharing/appinfo/application.php         |  51 ++++++++++
 apps/files_sharing/appinfo/routes.php              |   3 -
 apps/files_sharing/lib/helper.php                  |   2 -
 apps/files_sharing/lib/mountprovider.php           |  70 +++++++++++++
 .../lib/propagation/changewatcher.php              |  56 ++++++++++
 .../lib/propagation/propagationmanager.php         | 113 +++++++++++++++++++++
 .../lib/propagation/recipientpropagator.php        | 108 ++++++++++++++++++++
 apps/files_sharing/lib/sharedmount.php             |  18 ++++
 apps/files_sharing/lib/sharedstorage.php           |  50 ++++-----
 apps/files_sharing/lib/updater.php                 |  39 -------
 apps/files_sharing/tests/propagation.php           |  48 +++++++++
 apps/files_sharing/tests/testcase.php              |   7 +-
 lib/private/share/share.php                        |  12 +++
 14 files changed, 521 insertions(+), 93 deletions(-)

diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php
index d009fbc..19d3b6c 100644
--- a/apps/files_sharing/appinfo/app.php
+++ b/apps/files_sharing/appinfo/app.php
@@ -25,31 +25,38 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>
  *
  */
+
+namespace OCA\Files_Sharing\Appinfo;
+
 $l = \OC::$server->getL10N('files_sharing');
 
-OC::$CLASSPATH['OC_Share_Backend_File'] = 'files_sharing/lib/share/file.php';
-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\SharedScanner'] = 'files_sharing/lib/scanner.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';
-OC::$CLASSPATH['OCA\Files\Share\Maintainer'] = 'files_sharing/lib/maintainer.php';
-OC::$CLASSPATH['OCA\Files\Share\Proxy'] = 'files_sharing/lib/proxy.php';
+\OC::$CLASSPATH['OC_Share_Backend_File'] = 'files_sharing/lib/share/file.php';
+\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\SharedScanner'] = 'files_sharing/lib/scanner.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';
+\OC::$CLASSPATH['OCA\Files\Share\Maintainer'] = 'files_sharing/lib/maintainer.php';
+\OC::$CLASSPATH['OCA\Files\Share\Proxy'] = 'files_sharing/lib/proxy.php';
 
 // Exceptions
-OC::$CLASSPATH['OCA\Files_Sharing\Exceptions\BrokenPath'] = 'files_sharing/lib/exceptions.php';
+\OC::$CLASSPATH['OCA\Files_Sharing\Exceptions\BrokenPath'] = 'files_sharing/lib/exceptions.php';
+
+$application = new Application();
+$application->registerMountProviders();
+$application->setupPropagation();
 
 \OCP\App::registerAdmin('files_sharing', 'settings-admin');
 
 \OCA\Files_Sharing\Helper::registerHooks();
 
-OCP\Share::registerBackend('file', 'OC_Share_Backend_File');
-OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file');
+\OCP\Share::registerBackend('file', 'OC_Share_Backend_File');
+\OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file');
 
-OCP\Util::addScript('files_sharing', 'share');
-OCP\Util::addScript('files_sharing', 'external');
+\OCP\Util::addScript('files_sharing', 'share');
+\OCP\Util::addScript('files_sharing', 'external');
 
 // FIXME: registering a job here will cause additional useless SQL queries
 // when the route is not cron.php, needs a better way
diff --git a/apps/files_sharing/appinfo/application.php b/apps/files_sharing/appinfo/application.php
new file mode 100644
index 0000000..6848c9e
--- /dev/null
+++ b/apps/files_sharing/appinfo/application.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) 2015 Robin Appelman <icewind at owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCA\Files_Sharing\Appinfo;
+
+use OCA\Files_Sharing\MountProvider;
+use OCA\Files_Sharing\Propagation\PropagationManager;
+use OCP\AppFramework\App;
+use \OCP\IContainer;
+
+class Application extends App {
+	public function __construct(array $urlParams = array()) {
+		parent::__construct('files_sharing', $urlParams);
+		$container = $this->getContainer();
+
+		$container->registerService('MountProvider', function (IContainer $c) {
+			/** @var \OCP\IServerContainer $server */
+			$server = $c->query('ServerContainer');
+			return new MountProvider(
+				$server->getConfig(),
+				$c->query('PropagationManager')
+			);
+		});
+
+		$container->registerService('PropagationManager', function (IContainer $c) {
+			/** @var \OCP\IServerContainer $server */
+			$server = $c->query('ServerContainer');
+			return new PropagationManager(
+				$server->getUserSession(),
+				$server->getConfig()
+			);
+		});
+	}
+
+	public function registerMountProviders() {
+		/** @var \OCP\IServerContainer $server */
+		$server = $this->getContainer()->query('ServerContainer');
+		$mountProviderCollection = $server->getMountProviderCollection();
+		$mountProviderCollection->registerProvider($this->getContainer()->query('MountProvider'));
+	}
+
+	public function setupPropagation() {
+		$propagationManager = $this->getContainer()->query('PropagationManager');
+		\OCP\Util::connectHook('OC_Filesystem', 'setup', $propagationManager, 'globalSetup');
+	}
+}
diff --git a/apps/files_sharing/appinfo/routes.php b/apps/files_sharing/appinfo/routes.php
index 9ac3a1f..db4566e 100644
--- a/apps/files_sharing/appinfo/routes.php
+++ b/apps/files_sharing/appinfo/routes.php
@@ -25,9 +25,6 @@
  */
 namespace OCA\Files_Sharing\AppInfo;
 
-use OCA\Files_Sharing\Application;
-use OCP\API;
-
 $application = new Application();
 $application->registerRoutes($this, [
 	'resources' => [
diff --git a/apps/files_sharing/lib/helper.php b/apps/files_sharing/lib/helper.php
index 5b5525e..05b0352 100644
--- a/apps/files_sharing/lib/helper.php
+++ b/apps/files_sharing/lib/helper.php
@@ -30,9 +30,7 @@ namespace OCA\Files_Sharing;
 class Helper {
 
 	public static function registerHooks() {
-		\OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup');
 		\OCP\Util::connectHook('OC_Filesystem', 'setup', '\OCA\Files_Sharing\External\Manager', 'setup');
-		\OCP\Util::connectHook('OC_Filesystem', 'post_write', '\OC\Files\Cache\Shared_Updater', 'writeHook');
 		\OCP\Util::connectHook('OC_Filesystem', 'delete', '\OC\Files\Cache\Shared_Updater', 'deleteHook');
 		\OCP\Util::connectHook('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Shared_Updater', 'renameHook');
 		\OCP\Util::connectHook('OC_Filesystem', 'post_delete', '\OCA\Files_Sharing\Hooks', 'unshareChildren');
diff --git a/apps/files_sharing/lib/mountprovider.php b/apps/files_sharing/lib/mountprovider.php
new file mode 100644
index 0000000..0ba44ec
--- /dev/null
+++ b/apps/files_sharing/lib/mountprovider.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Copyright (c) 2015 Robin Appelman <icewind at owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCA\Files_Sharing;
+
+use OCA\Files_Sharing\Propagation\PropagationManager;
+use OCP\Files\Config\IMountProvider;
+use OCP\Files\Storage\IStorageFactory;
+use OCP\IConfig;
+use OCP\IUser;
+
+class MountProvider implements IMountProvider {
+	/**
+	 * @var \OCP\IConfig
+	 */
+	protected $config;
+
+	/**
+	 * @var \OCA\Files_Sharing\Propagation\PropagationManager
+	 */
+	protected $propagationManager;
+
+	/**
+	 * @param \OCP\IConfig $config
+	 * @param \OCA\Files_Sharing\Propagation\PropagationManager $propagationManager
+	 */
+	function __construct(IConfig $config, PropagationManager $propagationManager) {
+		$this->config = $config;
+		$this->propagationManager = $propagationManager;
+	}
+
+
+	/**
+	 * Get all mountpoints applicable for the user
+	 *
+	 * @param \OCP\IUser $user
+	 * @param \OCP\Files\Storage\IStorageFactory $storageFactory
+	 * @return \OCP\Files\Mount\IMountPoint[]
+	 */
+	public function getMountsForUser(IUser $user, IStorageFactory $storageFactory) {
+		$shares = \OCP\Share::getItemsSharedWithUser('file', $user->getUID());
+		$propagator = $this->propagationManager->getSharePropagator($user->getUID());
+		$propagator->propagateDirtyMountPoints($shares);
+		$shares = array_filter($shares, function ($share) {
+			return $share['permissions'] > 0;
+		});
+		return array_map(function ($share) use ($user, $storageFactory) {
+			// for updating etags for the share owner when we make changes to this share.
+			$ownerPropagator = $this->propagationManager->getChangePropagator($share['uid_owner']);
+
+			// for updating our etags when changes are made to the share from the owners side (probably indirectly by us trough another share)
+			$this->propagationManager->listenToOwnerChanges($share['uid_owner'], $user->getUID());
+			return new SharedMount(
+				'\OC\Files\Storage\Shared',
+				'/' . $user->getUID() . '/' . $share['file_target'],
+				array(
+					'propagator' => $ownerPropagator,
+					'share' => $share,
+					'user' => $user->getUID()
+				),
+				$storageFactory
+			);
+		}, $shares);
+	}
+}
diff --git a/apps/files_sharing/lib/propagation/changewatcher.php b/apps/files_sharing/lib/propagation/changewatcher.php
new file mode 100644
index 0000000..fa5208b
--- /dev/null
+++ b/apps/files_sharing/lib/propagation/changewatcher.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Copyright (c) 2015 Robin Appelman <icewind at owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCA\Files_Sharing\Propagation;
+
+use OC\Files\Cache\ChangePropagator;
+use OC\Files\View;
+use OCA\Files_Sharing\SharedMount;
+
+/**
+ * Watch for changes made in a shared mount and propagate the changes to the share owner
+ */
+class ChangeWatcher {
+	/**
+	 * The user view for the logged in user
+	 *
+	 * @var \OC\Files\View
+	 */
+	private $baseView;
+
+	function __construct(View $baseView) {
+		$this->baseView = $baseView;
+	}
+
+
+	public function writeHook($params) {
+		$path = $params['path'];
+		$fullPath = $this->baseView->getAbsolutePath($path);
+		$mount = $this->baseView->getMount($path);
+		if ($mount instanceof SharedMount) {
+			$this->propagateForOwner($mount->getShare(), $mount->getInternalPath($fullPath), $mount->getOwnerPropagator());
+		}
+	}
+
+	/**
+	 * @param array $share
+	 * @param string $internalPath
+	 * @param \OC\Files\Cache\ChangePropagator $propagator
+	 */
+	private function propagateForOwner($share, $internalPath, ChangePropagator $propagator) {
+		// note that we have already set up the filesystem for the owner when mounting the share
+		$view = new View('/' . $share['uid_owner'] . '/files');
+
+		$shareRootPath = $view->getPath($share['item_source']);
+		if ($shareRootPath) {
+			$path = $shareRootPath . '/' . $internalPath;
+			$propagator->addChange($path);
+			$propagator->propagateChanges();
+		}
+	}
+}
diff --git a/apps/files_sharing/lib/propagation/propagationmanager.php b/apps/files_sharing/lib/propagation/propagationmanager.php
new file mode 100644
index 0000000..bf530d3
--- /dev/null
+++ b/apps/files_sharing/lib/propagation/propagationmanager.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ * Copyright (c) 2015 Robin Appelman <icewind at owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCA\Files_Sharing\Propagation;
+
+use OC\Files\Filesystem;
+use OC\Files\View;
+use OCP\IConfig;
+use OCP\IUserSession;
+
+
+/**
+ * Keep track of all change and share propagators by owner
+ */
+class PropagationManager {
+	/**
+	 * @var \OCP\IUserSession
+	 */
+	private $userSession;
+
+	/**
+	 * @var \OCP\IConfig
+	 */
+	private $config;
+
+	/**
+	 * Change propagators for share owner
+	 *
+	 * @var \OC\Files\Cache\ChangePropagator[]
+	 */
+	private $changePropagators = [];
+
+	/**
+	 * Recipient propagators
+	 *
+	 * @var \OCA\Files_Sharing\Propagation\RecipientPropagator[]
+	 */
+	private $sharePropagators = [];
+
+	private $globalSetupDone = false;
+
+	function __construct(IUserSession $userSession, IConfig $config) {
+		$this->userSession = $userSession;
+		$this->config = $config;
+	}
+
+	/**
+	 * @param string $user
+	 * @return \OC\Files\Cache\ChangePropagator
+	 */
+	public function getChangePropagator($user) {
+		$activeUser = $this->userSession->getUser();
+
+		// for the local user we want to propagator from the active view, not any cached one
+		if ($activeUser && $activeUser->getUID() === $user && Filesystem::getView() instanceof View) {
+			// it's important that we take the existing propagator here to make sure we can listen to external changes
+			$this->changePropagators[$user] = Filesystem::getView()->getUpdater()->getPropagator();
+		}
+		if (isset($this->changePropagators[$user])) {
+			return $this->changePropagators[$user];
+		}
+		$view = new View('/' . $user . '/files');
+		$this->changePropagators[$user] = $view->getUpdater()->getPropagator();
+		return $this->changePropagators[$user];
+	}
+
+	/**
+	 * @param string $user
+	 * @return \OCA\Files_Sharing\Propagation\RecipientPropagator
+	 */
+	public function getSharePropagator($user) {
+		if (isset($this->sharePropagators[$user])) {
+			return $this->sharePropagators[$user];
+		}
+		$this->sharePropagators[$user] = new RecipientPropagator($user, $this->getChangePropagator($user), $this->config);
+		return $this->sharePropagators[$user];
+	}
+
+	/**
+	 * Attach the propagator to the change propagator of a user to listen to changes made to files shared by the user
+	 *
+	 * @param string $shareOwner
+	 * @param string $user
+	 */
+	public function listenToOwnerChanges($shareOwner, $user) {
+		$sharePropagator = $this->getSharePropagator($user);
+		$ownerPropagator = $this->getChangePropagator($shareOwner);
+		$sharePropagator->attachToPropagator($ownerPropagator, $shareOwner);
+	}
+
+	/**
+	 * To be called from setupFS trough a hook
+	 *
+	 * Sets up listening to changes made to shares owned by the current user
+	 */
+	public function globalSetup() {
+		$user = $this->userSession->getUser();
+		if (!$user) {
+			return;
+		}
+		$watcher = new ChangeWatcher(Filesystem::getView());
+
+		// for marking shares owned by the active user as dirty when a file inside them changes
+		$this->listenToOwnerChanges($user->getUID(), $user->getUID());
+		\OC_Hook::connect('OC_Filesystem', 'write', $watcher, 'writeHook');
+		\OC_Hook::connect('OC_Filesystem', 'delete', $watcher, 'writeHook');
+	}
+}
diff --git a/apps/files_sharing/lib/propagation/recipientpropagator.php b/apps/files_sharing/lib/propagation/recipientpropagator.php
new file mode 100644
index 0000000..da71612
--- /dev/null
+++ b/apps/files_sharing/lib/propagation/recipientpropagator.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * Copyright (c) 2015 Robin Appelman <icewind at owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCA\Files_Sharing\Propagation;
+
+use OC\Files\Cache\ChangePropagator;
+use OC\Share\Share;
+
+/**
+ * Propagate etags for share recipients
+ */
+class RecipientPropagator {
+	/**
+	 * @var string
+	 */
+	protected $userId;
+
+	/**
+	 * @var \OC\Files\Cache\ChangePropagator
+	 */
+	protected $changePropagator;
+
+	/**
+	 * @var \OCP\IConfig
+	 */
+	protected $config;
+
+	/**
+	 * @param string $userId current user, must match the propagator's
+	 * user
+	 * @param \OC\Files\Cache\ChangePropagator $changePropagator change propagator
+	 * initialized with a view for $user
+	 * @param \OCP\IConfig $config
+	 */
+	public function __construct($userId, $changePropagator, $config) {
+		$this->userId = $userId;
+		$this->changePropagator = $changePropagator;
+		$this->config = $config;
+	}
+
+	/**
+	 * Propagate the etag changes for all shares marked as dirty and mark the shares as clean
+	 *
+	 * @param array $shares the shares for the users
+	 * @param int $time
+	 */
+	public function propagateDirtyMountPoints(array $shares, $time = null) {
+		if ($time === null) {
+			$time = time();
+		}
+		$dirtyShares = $this->getDirtyShares($shares);
+		foreach ($dirtyShares as $share) {
+			$this->changePropagator->addChange($share['file_target']);
+		}
+		if (count($dirtyShares)) {
+			$this->config->setUserValue($this->userId, 'files_sharing', 'last_propagate', $time);
+			$this->changePropagator->propagateChanges($time);
+		}
+	}
+
+	/**
+	 * Get all shares we need to update the etag for
+	 *
+	 * @param array $shares the shares for the users
+	 * @return string[]
+	 */
+	protected function getDirtyShares($shares) {
+		$dirty = [];
+		$userTime = $this->config->getUserValue($this->userId, 'files_sharing', 'last_propagate', 0);
+		foreach ($shares as $share) {
+			$updateTime = $this->config->getAppValue('files_sharing', $share['id'], 0);
+			if ($updateTime >= $userTime) {
+				$dirty[] = $share;
+			}
+		}
+		return $dirty;
+	}
+
+	/**
+	 * @param array $share
+	 * @param int $time
+	 */
+	public function markDirty($share, $time = null) {
+		if ($time === null) {
+			$time = time();
+		}
+		$this->config->setAppValue('files_sharing', $share['id'], $time);
+	}
+	/**
+	 * Listen on the propagator for updates made to shares owned by a user
+	 *
+	 * @param \OC\Files\Cache\ChangePropagator $propagator
+	 * @param string $owner
+	 */
+	public function attachToPropagator(ChangePropagator $propagator, $owner) {
+		$propagator->listen('\OC\Files', 'propagate', function ($path, $entry) use ($owner) {
+			$shares = Share::getAllSharesForFileId($entry['fileid']);
+			foreach ($shares as $share) {
+				$this->markDirty($share, time());
+			}
+		});
+	}
+}
diff --git a/apps/files_sharing/lib/sharedmount.php b/apps/files_sharing/lib/sharedmount.php
index da00549..fbf8d05 100644
--- a/apps/files_sharing/lib/sharedmount.php
+++ b/apps/files_sharing/lib/sharedmount.php
@@ -35,8 +35,14 @@ class SharedMount extends MountPoint implements MoveableMount {
 	 */
 	protected $storage = null;
 
+	/**
+	 * @var \OC\Files\Cache\ChangePropagator
+	 */
+	protected $ownerPropagator;
+
 	public function __construct($storage, $mountpoint, $arguments = null, $loader = null) {
 		// first update the mount point before creating the parent
+		$this->ownerPropagator = $arguments['propagator'];
 		$newMountPoint = $this->verifyMountPoint($arguments['share'], $arguments['user']);
 		$absMountPoint = '/' . $arguments['user'] . '/files' . $newMountPoint;
 		parent::__construct($storage, $absMountPoint, $arguments, $loader);
@@ -174,4 +180,16 @@ class SharedMount extends MountPoint implements MoveableMount {
 
 		return $result;
 	}
+
+	public function getShare() {
+		$this->getStorage(); //ensure it exists
+		return $this->storage->getShare();
+	}
+
+	/**
+	 * @return \OC\Files\Cache\ChangePropagator
+	 */
+	public function getOwnerPropagator() {
+		return $this->ownerPropagator;
+	}
 }
diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php
index 8c2f03b..bc01465 100644
--- a/apps/files_sharing/lib/sharedstorage.php
+++ b/apps/files_sharing/lib/sharedstorage.php
@@ -28,8 +28,12 @@
  */
 
 namespace OC\Files\Storage;
+
+use OC\Files\Cache\ChangePropagator;
 use OC\Files\Filesystem;
+use OC\Files\View;
 use OCA\Files_Sharing\ISharedStorage;
+use OCA\Files_Sharing\Propagator;
 use OCA\Files_Sharing\SharedMount;
 
 /**
@@ -47,6 +51,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
 
 	/**
 	 * get id of the mount point
+	 *
 	 * @return string
 	 */
 	public function getId() {
@@ -55,14 +60,16 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
 
 	/**
 	 * get file cache of the shared item source
+	 *
 	 * @return int
 	 */
 	public function getSourceId() {
-		return (int) $this->share['file_source'];
+		return (int)$this->share['file_source'];
 	}
 
 	/**
 	 * Get the source file path, permissions, and owner for a shared file
+	 *
 	 * @param string $target Shared target file path
 	 * @return Returns array with the keys path, permissions, and owner or false if not found
 	 */
@@ -86,6 +93,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
 
 	/**
 	 * Get the source file path for a shared file
+	 *
 	 * @param string $target Shared target file path
 	 * @return string|false source file path or false if not found
 	 */
@@ -109,6 +117,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
 
 	/**
 	 * Get the permissions granted for a shared file
+	 *
 	 * @param string $target Shared target file path
 	 * @return int CRUDS permissions granted
 	 */
@@ -138,13 +147,14 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
 
 	/**
 	 * Delete the directory if DELETE permission is granted
+	 *
 	 * @param string $path
 	 * @return boolean
 	 */
 	public function rmdir($path) {
 
 		// never delete a share mount point
-		if(empty($path)) {
+		if (empty($path)) {
 			return false;
 		}
 
@@ -277,6 +287,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
 
 	/**
 	 * Delete the file if DELETE permission is granted
+	 *
 	 * @param string $path
 	 * @return boolean
 	 */
@@ -426,37 +437,6 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
 		return false;
 	}
 
-	public static function setup($options) {
-		$user = $options['user'];
-		$shares = \OCP\Share::getItemsSharedWithUser('file', $user);
-		$manager = Filesystem::getMountManager();
-		$loader = Filesystem::getLoader();
-		if (
-			!isset(self::$isInitialized[$user]) && (
-				!\OCP\User::isLoggedIn()
-				|| \OCP\User::getUser() != $options['user']
-				|| $shares
-			)
-		) {
-			foreach ($shares as $share) {
-				// don't mount shares where we have no permissions
-				if ($share['permissions'] > 0) {
-					$mount = new SharedMount(
-							'\OC\Files\Storage\Shared',
-							$options['user_dir'] . '/' . $share['file_target'],
-							array(
-								'share' => $share,
-								'user' => $user
-							),
-							$loader
-							);
-					$manager->addMount($mount);
-				}
-			}
-		}
-		self::$isInitialized[$user] = true;
-	}
-
 	/**
 	 * return mount point of share, relative to data/user/files
 	 *
@@ -476,6 +456,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
 
 	/**
 	 * does the group share already has a user specific unique name
+	 *
 	 * @return bool
 	 */
 	public function uniqueNameSet() {
@@ -493,6 +474,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
 
 	/**
 	 * get share ID
+	 *
 	 * @return integer unique share ID
 	 */
 	public function getShareId() {
@@ -501,6 +483,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
 
 	/**
 	 * get the user who shared the file
+	 *
 	 * @return string
 	 */
 	public function getSharedFrom() {
@@ -516,6 +499,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
 
 	/**
 	 * return share type, can be "file" or "folder"
+	 *
 	 * @return string
 	 */
 	public function getItemType() {
diff --git a/apps/files_sharing/lib/updater.php b/apps/files_sharing/lib/updater.php
index 322c031..45cf662 100644
--- a/apps/files_sharing/lib/updater.php
+++ b/apps/files_sharing/lib/updater.php
@@ -50,47 +50,9 @@ class Shared_Updater {
 	}
 
 	/**
-	* Correct the parent folders' ETags for all users shared the file at $target
-	*
-	* @param string $target
-	*/
-	static public function correctFolders($target) {
-
-		// ignore part files
-		if (pathinfo($target, PATHINFO_EXTENSION) === 'part') {
-			return false;
-		}
-
-		// Correct Shared folders of other users shared with
-		$shares = \OCA\Files_Sharing\Helper::getSharesFromItem($target);
-
-		foreach ($shares as $share) {
-			if ((int)$share['share_type'] === \OCP\Share::SHARE_TYPE_USER) {
-				self::correctUsersFolder($share['share_with'], $share['file_target']);
-			} elseif ((int)$share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP) {
-				$users = \OC_Group::usersInGroup($share['share_with']);
-				foreach ($users as $user) {
-					self::correctUsersFolder($user, $share['file_target']);
-				}
-			} else { //unique name for group share
-				self::correctUsersFolder($share['share_with'], $share['file_target']);
-			}
-		}
-	}
-
-	/**
-	 * @param array $params
-	 */
-	static public function writeHook($params) {
-		self::correctFolders($params['path']);
-	}
-
-	/**
 	 * @param array $params
 	 */
 	static public function renameHook($params) {
-		self::correctFolders($params['newpath']);
-		self::correctFolders(pathinfo($params['oldpath'], PATHINFO_DIRNAME));
 		self::renameChildren($params['oldpath'], $params['newpath']);
 	}
 
@@ -99,7 +61,6 @@ class Shared_Updater {
 	 */
 	static public function deleteHook($params) {
 		$path = $params['path'];
-		self::correctFolders($path);
 	}
 
 	/**
diff --git a/apps/files_sharing/tests/propagation.php b/apps/files_sharing/tests/propagation.php
index 1949f78..c42dccc 100644
--- a/apps/files_sharing/tests/propagation.php
+++ b/apps/files_sharing/tests/propagation.php
@@ -242,4 +242,52 @@ class Propagation extends TestCase {
 		$newRootInfo = $view1->getFileInfo('');
 		$this->assertNotEquals($rootInfo->getEtag(), $newRootInfo->getEtag());
 	}
+
+	public function testSizePropagationWhenOwnerChangesFile() {
+		/**
+		 * @var \OC\Files\View $recipientView
+		 * @var \OC\Files\View $ownerView
+		 */
+		list($recipientView, $ownerView) = $this->setupViews();
+		$sharedFolderInfo = $ownerView->getFileInfo('/sharedfolder', false);
+		\OCP\Share::shareItem('folder', $sharedFolderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER1, 31);
+		$ownerRootInfo = $ownerView->getFileInfo('', false);
+		$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
+		$this->assertTrue($recipientView->file_exists('/sharedfolder/subfolder/foo.txt'));
+		$recipientRootInfo = $recipientView->getFileInfo('', false);
+		// when file changed as owner
+		$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+		$ownerView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'foobar');
+		// size of recipient's root stays the same
+		$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
+		$newRecipientRootInfo = $recipientView->getFileInfo('', false);
+		$this->assertEquals($recipientRootInfo->getSize(), $newRecipientRootInfo->getSize());
+		// size of owner's root increases
+		$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+		$newOwnerRootInfo = $ownerView->getFileInfo('', false);
+		$this->assertEquals($ownerRootInfo->getSize() + 3, $newOwnerRootInfo->getSize());
+	}
+
+	public function testSizePropagationWhenRecipientChangesFile() {
+		/**
+		 * @var \OC\Files\View $recipientView
+		 * @var \OC\Files\View $ownerView
+		 */
+		list($recipientView, $ownerView) = $this->setupViews();
+		$sharedFolderInfo = $ownerView->getFileInfo('/sharedfolder', false);
+		\OCP\Share::shareItem('folder', $sharedFolderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER1, 31);
+		$ownerRootInfo = $ownerView->getFileInfo('', false);
+		$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
+		$this->assertTrue($recipientView->file_exists('/sharedfolder/subfolder/foo.txt'));
+		$recipientRootInfo = $recipientView->getFileInfo('', false);
+		// when file changed as recipient
+		$recipientView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'foobar');
+		// size of recipient's root stays the same
+		$newRecipientRootInfo = $recipientView->getFileInfo('', false);
+		$this->assertEquals($recipientRootInfo->getSize(), $newRecipientRootInfo->getSize());
+		// size of owner's root increases
+		$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+		$newOwnerRootInfo = $ownerView->getFileInfo('', false);
+		$this->assertEquals($ownerRootInfo->getSize() + 3, $newOwnerRootInfo->getSize());
+	}
 }
diff --git a/apps/files_sharing/tests/testcase.php b/apps/files_sharing/tests/testcase.php
index b9f8658..5cae54f 100644
--- a/apps/files_sharing/tests/testcase.php
+++ b/apps/files_sharing/tests/testcase.php
@@ -31,6 +31,7 @@ namespace OCA\Files_Sharing\Tests;
 
 use OC\Files\Filesystem;
 use OCA\Files\Share;
+use OCA\Files_Sharing\Appinfo\Application;
 
 /**
  * Class Test_Files_Sharing_Base
@@ -57,6 +58,10 @@ abstract class TestCase extends \Test\TestCase {
 	public static function setUpBeforeClass() {
 		parent::setUpBeforeClass();
 
+		$application = new Application();
+		$application->registerMountProviders();
+		$application->setupPropagation();
+		
 		// reset backend
 		\OC_User::clearBackends();
 		\OC_Group::clearBackends();
@@ -64,7 +69,6 @@ abstract class TestCase extends \Test\TestCase {
 		// clear share hooks
 		\OC_Hook::clear('OCP\\Share');
 		\OC::registerShareHooks();
-		\OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup');
 
 		// create users
 		$backend = new \OC_User_Dummy();
@@ -147,6 +151,7 @@ abstract class TestCase extends \Test\TestCase {
 		\OC::$server->getUserSession()->setUser(null);
 		\OC\Files\Filesystem::tearDown();
 		\OC::$server->getUserSession()->login($user, $password);
+
 		\OC_Util::setupFS($user);
 	}
 
diff --git a/lib/private/share/share.php b/lib/private/share/share.php
index 63bba06..d18bdff 100644
--- a/lib/private/share/share.php
+++ b/lib/private/share/share.php
@@ -2518,6 +2518,7 @@ class Share extends \OC\Share\Constants {
 		$enforcePassword = $config->getAppValue('core', 'shareapi_enforce_links_password', 'no');
 		return ($enforcePassword === "yes") ? true : false;
 	}
+
 	/**
 	 * Get all share entries, including non-unique group items
 	 *
@@ -2530,4 +2531,15 @@ class Share extends \OC\Share\Constants {
 		return $result->fetchAll();
 	}
 
+	/**
+	 * Get all share entries, including non-unique group items for a file
+	 *
+	 * @param int $id
+	 * @return array
+	 */
+	public static function getAllSharesForFileId($id) {
+		$query = 'SELECT * FROM `*PREFIX*share` WHERE `file_source` = ?';
+		$result = \OC::$server->getDatabaseConnection()->executeQuery($query, [$id]);
+		return $result->fetchAll();
+	}
 }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud.git



More information about the Pkg-owncloud-commits mailing list