Merge pull request #14764 from owncloud/shared-etag-propagate
Propagate etags across shared storages
This commit is contained in:
commit
de8c15e1a4
29 changed files with 976 additions and 219 deletions
|
@ -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
|
||||
|
|
124
apps/files_sharing/appinfo/application.php
Normal file
124
apps/files_sharing/appinfo/application.php
Normal file
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2015 Robin Appelman <icewind@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\Helper;
|
||||
use OCA\Files_Sharing\MountProvider;
|
||||
use OCA\Files_Sharing\Propagation\PropagationManager;
|
||||
use OCP\AppFramework\App;
|
||||
use OC\AppFramework\Utility\SimpleContainer;
|
||||
use OCA\Files_Sharing\Controllers\ExternalSharesController;
|
||||
use OCA\Files_Sharing\Controllers\ShareController;
|
||||
use OCA\Files_Sharing\Middleware\SharingCheckMiddleware;
|
||||
use \OCP\IContainer;
|
||||
|
||||
class Application extends App {
|
||||
public function __construct(array $urlParams = array()) {
|
||||
parent::__construct('files_sharing', $urlParams);
|
||||
|
||||
$container = $this->getContainer();
|
||||
$server = $container->getServer();
|
||||
|
||||
/**
|
||||
* Controllers
|
||||
*/
|
||||
$container->registerService('ShareController', function (SimpleContainer $c) use ($server) {
|
||||
return new ShareController(
|
||||
$c->query('AppName'),
|
||||
$c->query('Request'),
|
||||
$c->query('UserSession'),
|
||||
$server->getAppConfig(),
|
||||
$server->getConfig(),
|
||||
$c->query('URLGenerator'),
|
||||
$c->query('UserManager'),
|
||||
$server->getLogger(),
|
||||
$server->getActivityManager()
|
||||
);
|
||||
});
|
||||
$container->registerService('ExternalSharesController', function (SimpleContainer $c) {
|
||||
return new ExternalSharesController(
|
||||
$c->query('AppName'),
|
||||
$c->query('Request'),
|
||||
$c->query('IsIncomingShareEnabled'),
|
||||
$c->query('ExternalManager')
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Core class wrappers
|
||||
*/
|
||||
$container->registerService('UserSession', function (SimpleContainer $c) use ($server) {
|
||||
return $server->getUserSession();
|
||||
});
|
||||
$container->registerService('URLGenerator', function (SimpleContainer $c) use ($server) {
|
||||
return $server->getUrlGenerator();
|
||||
});
|
||||
$container->registerService('UserManager', function (SimpleContainer $c) use ($server) {
|
||||
return $server->getUserManager();
|
||||
});
|
||||
$container->registerService('IsIncomingShareEnabled', function (SimpleContainer $c) {
|
||||
return Helper::isIncomingServer2serverShareEnabled();
|
||||
});
|
||||
$container->registerService('ExternalManager', function (SimpleContainer $c) use ($server) {
|
||||
$user = $server->getUserSession()->getUser();
|
||||
$uid = $user ? $user->getUID() : null;
|
||||
return new \OCA\Files_Sharing\External\Manager(
|
||||
$server->getDatabaseConnection(),
|
||||
\OC\Files\Filesystem::getMountManager(),
|
||||
\OC\Files\Filesystem::getLoader(),
|
||||
$server->getHTTPHelper(),
|
||||
$uid
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Middleware
|
||||
*/
|
||||
$container->registerService('SharingCheckMiddleware', function (SimpleContainer $c) use ($server) {
|
||||
return new SharingCheckMiddleware(
|
||||
$c->query('AppName'),
|
||||
$server->getConfig(),
|
||||
$server->getAppManager()
|
||||
);
|
||||
});
|
||||
|
||||
// Execute middlewares
|
||||
$container->registerMiddleware('SharingCheckMiddleware');
|
||||
|
||||
$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');
|
||||
}
|
||||
}
|
|
@ -25,7 +25,6 @@
|
|||
*/
|
||||
namespace OCA\Files_Sharing\AppInfo;
|
||||
|
||||
use OCA\Files_Sharing\Application;
|
||||
use OCP\API;
|
||||
|
||||
$application = new Application();
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Björn Schießle <schiessle@owncloud.com>
|
||||
* @author Lukas Reschke <lukas@owncloud.com>
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Files_Sharing;
|
||||
|
||||
use OC\AppFramework\Utility\SimpleContainer;
|
||||
use OCA\Files_Sharing\Controllers\ExternalSharesController;
|
||||
use OCA\Files_Sharing\Controllers\ShareController;
|
||||
use OCA\Files_Sharing\Middleware\SharingCheckMiddleware;
|
||||
use \OCP\AppFramework\App;
|
||||
|
||||
/**
|
||||
* @package OCA\Files_Sharing
|
||||
*/
|
||||
class Application extends App {
|
||||
|
||||
|
||||
/**
|
||||
* @param array $urlParams
|
||||
*/
|
||||
public function __construct(array $urlParams=array()){
|
||||
parent::__construct('files_sharing', $urlParams);
|
||||
|
||||
$container = $this->getContainer();
|
||||
$server = $container->getServer();
|
||||
|
||||
/**
|
||||
* Controllers
|
||||
*/
|
||||
$container->registerService('ShareController', function(SimpleContainer $c) use ($server) {
|
||||
return new ShareController(
|
||||
$c->query('AppName'),
|
||||
$c->query('Request'),
|
||||
$c->query('UserSession'),
|
||||
$server->getAppConfig(),
|
||||
$server->getConfig(),
|
||||
$c->query('URLGenerator'),
|
||||
$c->query('UserManager'),
|
||||
$server->getLogger(),
|
||||
$server->getActivityManager()
|
||||
);
|
||||
});
|
||||
$container->registerService('ExternalSharesController', function(SimpleContainer $c) {
|
||||
return new ExternalSharesController(
|
||||
$c->query('AppName'),
|
||||
$c->query('Request'),
|
||||
$c->query('IsIncomingShareEnabled'),
|
||||
$c->query('ExternalManager')
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Core class wrappers
|
||||
*/
|
||||
$container->registerService('UserSession', function(SimpleContainer $c) use ($server) {
|
||||
return $server->getUserSession();
|
||||
});
|
||||
$container->registerService('URLGenerator', function(SimpleContainer $c) use ($server){
|
||||
return $server->getUrlGenerator();
|
||||
});
|
||||
$container->registerService('UserManager', function(SimpleContainer $c) use ($server){
|
||||
return $server->getUserManager();
|
||||
});
|
||||
$container->registerService('IsIncomingShareEnabled', function(SimpleContainer $c) {
|
||||
return Helper::isIncomingServer2serverShareEnabled();
|
||||
});
|
||||
$container->registerService('ExternalManager', function(SimpleContainer $c) use ($server){
|
||||
$user = $server->getUserSession()->getUser();
|
||||
$uid = $user ? $user->getUID() : null;
|
||||
return new \OCA\Files_Sharing\External\Manager(
|
||||
$server->getDatabaseConnection(),
|
||||
\OC\Files\Filesystem::getMountManager(),
|
||||
\OC\Files\Filesystem::getLoader(),
|
||||
$server->getHTTPHelper(),
|
||||
$uid
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Middleware
|
||||
*/
|
||||
$container->registerService('SharingCheckMiddleware', function(SimpleContainer $c) use ($server){
|
||||
return new SharingCheckMiddleware(
|
||||
$c->query('AppName'),
|
||||
$server->getConfig(),
|
||||
$server->getAppManager()
|
||||
);
|
||||
});
|
||||
|
||||
// Execute middlewares
|
||||
$container->registerMiddleware('SharingCheckMiddleware');
|
||||
}
|
||||
|
||||
}
|
|
@ -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');
|
||||
|
|
72
apps/files_sharing/lib/mountprovider.php
Normal file
72
apps/files_sharing/lib/mountprovider.php
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2015 Robin Appelman <icewind@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 OC\Files\Filesystem;
|
||||
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
|
||||
*/
|
||||
public function __construct(IConfig $config, PropagationManager $propagationManager) {
|
||||
$this->config = $config;
|
||||
$this->propagationManager = $propagationManager;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all mountpoints applicable for the user and check for shares where we need to update the etags
|
||||
*
|
||||
* @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) {
|
||||
Filesystem::initMountPoints($share['uid_owner']);
|
||||
// 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);
|
||||
}
|
||||
}
|
76
apps/files_sharing/lib/propagation/changewatcher.php
Normal file
76
apps/files_sharing/lib/propagation/changewatcher.php
Normal file
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2015 Robin Appelman <icewind@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\Filesystem;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @param \OC\Files\View $baseView the view for the logged in user
|
||||
*/
|
||||
public 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());
|
||||
}
|
||||
}
|
||||
|
||||
public function renameHook($params) {
|
||||
$path1 = $params['oldpath'];
|
||||
$path2 = $params['newpath'];
|
||||
$fullPath1 = $this->baseView->getAbsolutePath($path1);
|
||||
$fullPath2 = $this->baseView->getAbsolutePath($path2);
|
||||
$mount1 = $this->baseView->getMount($path1);
|
||||
$mount2 = $this->baseView->getMount($path2);
|
||||
if ($mount1 instanceof SharedMount and $mount1->getInternalPath($fullPath1) !== '') {
|
||||
$this->propagateForOwner($mount1->getShare(), $mount1->getInternalPath($fullPath1), $mount1->getOwnerPropagator());
|
||||
}
|
||||
if ($mount1 !== $mount2 and $mount2 instanceof SharedMount and $mount2->getInternalPath($fullPath2) !== '') {
|
||||
$this->propagateForOwner($mount2->getShare(), $mount2->getInternalPath($fullPath2), $mount2->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 (!is_null($shareRootPath)) {
|
||||
$path = $shareRootPath . '/' . $internalPath;
|
||||
$path = Filesystem::normalizePath($path);
|
||||
$propagator->addChange($path);
|
||||
$propagator->propagateChanges();
|
||||
}
|
||||
}
|
||||
}
|
112
apps/files_sharing/lib/propagation/propagationmanager.php
Normal file
112
apps/files_sharing/lib/propagation/propagationmanager.php
Normal file
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2015 Robin Appelman <icewind@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 = [];
|
||||
|
||||
public 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 recipient propagator for $user to the change propagator of a share owner to mark shares as dirty when the owner makes a change to a share
|
||||
*
|
||||
* @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', 'post_write', $watcher, 'writeHook');
|
||||
\OC_Hook::connect('OC_Filesystem', 'post_delete', $watcher, 'writeHook');
|
||||
\OC_Hook::connect('OC_Filesystem', 'post_rename', $watcher, 'renameHook');
|
||||
}
|
||||
}
|
118
apps/files_sharing/lib/propagation/recipientpropagator.php
Normal file
118
apps/files_sharing/lib/propagation/recipientpropagator.php
Normal file
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2015 Robin Appelman <icewind@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 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 = microtime(true);
|
||||
}
|
||||
$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(floor($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 = microtime(true);
|
||||
}
|
||||
$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) {
|
||||
// propagate down the share tree
|
||||
$this->markDirty($share, microtime(true));
|
||||
|
||||
// propagate up the share tree
|
||||
$user = $share['uid_owner'];
|
||||
$view = new View('/' . $user . '/files');
|
||||
$path = $view->getPath($share['file_source']);
|
||||
$watcher = new ChangeWatcher($view);
|
||||
$watcher->writeHook(['path' => $path]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -25,6 +25,7 @@ namespace OCA\Files_Sharing;
|
|||
|
||||
use OC\Files\Mount\MountPoint;
|
||||
use OC\Files\Mount\MoveableMount;
|
||||
use OC\Files\View;
|
||||
|
||||
/**
|
||||
* Shared mount points can be moved by the user
|
||||
|
@ -35,8 +36,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);
|
||||
|
@ -49,8 +56,9 @@ class SharedMount extends MountPoint implements MoveableMount {
|
|||
|
||||
$mountPoint = basename($share['file_target']);
|
||||
$parent = dirname($share['file_target']);
|
||||
$view = new View('/' . $user . '/files');
|
||||
|
||||
if (!\OC\Files\Filesystem::is_dir($parent)) {
|
||||
if (!$view->is_dir($parent)) {
|
||||
$parent = Helper::getShareFolder();
|
||||
}
|
||||
|
||||
|
@ -174,4 +182,15 @@ class SharedMount extends MountPoint implements MoveableMount {
|
|||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getShare() {
|
||||
return $this->getStorage()->getShare();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \OC\Files\Cache\ChangePropagator
|
||||
*/
|
||||
public function getOwnerPropagator() {
|
||||
return $this->ownerPropagator;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -49,48 +49,10 @@ 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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -113,7 +113,9 @@ class Test_Files_Sharing_Cache extends TestCase {
|
|||
}
|
||||
|
||||
protected function tearDown() {
|
||||
$this->sharedCache->clear();
|
||||
if($this->sharedCache) {
|
||||
$this->sharedCache->clear();
|
||||
}
|
||||
|
||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
namespace OCA\Files_Sharing\Controllers;
|
||||
|
||||
use OC\Files\Filesystem;
|
||||
use OCA\Files_Sharing\Application;
|
||||
use OCA\Files_Sharing\AppInfo\Application;
|
||||
use OCP\AppFramework\Http\NotFoundResponse;
|
||||
use OCP\AppFramework\IAppContainer;
|
||||
use OCP\Files;
|
||||
|
|
345
apps/files_sharing/tests/etagpropagation.php
Normal file
345
apps/files_sharing/tests/etagpropagation.php
Normal file
|
@ -0,0 +1,345 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Vincent Petry <pvince81@owncloud.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Files_sharing\Tests;
|
||||
|
||||
use OC\Files\Filesystem;
|
||||
use OC\Files\View;
|
||||
|
||||
class EtagPropagation extends TestCase {
|
||||
/**
|
||||
* @var \OC\Files\View
|
||||
*/
|
||||
private $rootView;
|
||||
protected $fileIds = []; // [$user=>[$path=>$id]]
|
||||
protected $fileEtags = []; // [$id=>$etag]
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->setUpShares();
|
||||
}
|
||||
|
||||
protected function tearDown() {
|
||||
\OC_Hook::clear('OC_Filesystem', 'post_write');
|
||||
\OC_Hook::clear('OC_Filesystem', 'post_delete');
|
||||
\OC_Hook::clear('OC_Filesystem', 'post_rename');
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* "user1" is the admin who shares a folder "sub1/sub2/folder" with "user2" and "user3"
|
||||
* "user2" receives the folder and puts it in "sub1/sub2/folder"
|
||||
* "user3" receives the folder and puts it in "sub1/sub2/folder"
|
||||
* "user2" reshares the subdir "sub1/sub2/folder/inside" with "user4"
|
||||
* "user4" puts the received "inside" folder into "sub1/sub2/inside" (this is to check if it propagates across multiple subfolders)
|
||||
*/
|
||||
private function setUpShares() {
|
||||
$this->fileIds[self::TEST_FILES_SHARING_API_USER1] = [];
|
||||
$this->fileIds[self::TEST_FILES_SHARING_API_USER2] = [];
|
||||
$this->fileIds[self::TEST_FILES_SHARING_API_USER3] = [];
|
||||
$this->fileIds[self::TEST_FILES_SHARING_API_USER4] = [];
|
||||
|
||||
$this->rootView = new View('');
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
|
||||
$view1 = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files');
|
||||
$view1->mkdir('/sub1/sub2/folder/inside');
|
||||
$view1->mkdir('/directReshare');
|
||||
$view1->mkdir('/sub1/sub2/folder/other');
|
||||
$view1->mkdir('/sub1/sub2/folder/other');
|
||||
$view1->file_put_contents('/sub1/sub2/folder/file.txt', 'foobar');
|
||||
$view1->file_put_contents('/sub1/sub2/folder/inside/file.txt', 'foobar');
|
||||
$folderInfo = $view1->getFileInfo('/sub1/sub2/folder');
|
||||
\OCP\Share::shareItem('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31);
|
||||
\OCP\Share::shareItem('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER3, 31);
|
||||
$folderInfo = $view1->getFileInfo('/directReshare');
|
||||
\OCP\Share::shareItem('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31);
|
||||
$this->fileIds[self::TEST_FILES_SHARING_API_USER1][''] = $view1->getFileInfo('')->getId();
|
||||
$this->fileIds[self::TEST_FILES_SHARING_API_USER1]['sub1'] = $view1->getFileInfo('sub1')->getId();
|
||||
$this->fileIds[self::TEST_FILES_SHARING_API_USER1]['sub1/sub2'] = $view1->getFileInfo('sub1/sub2')->getId();
|
||||
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
|
||||
$view2 = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
|
||||
$view2->mkdir('/sub1/sub2');
|
||||
$view2->rename('/folder', '/sub1/sub2/folder');
|
||||
$insideInfo = $view2->getFileInfo('/sub1/sub2/folder/inside');
|
||||
\OCP\Share::shareItem('folder', $insideInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER4, 31);
|
||||
$folderInfo = $view2->getFileInfo('/directReshare');
|
||||
\OCP\Share::shareItem('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER4, 31);
|
||||
$this->fileIds[self::TEST_FILES_SHARING_API_USER2][''] = $view2->getFileInfo('')->getId();
|
||||
$this->fileIds[self::TEST_FILES_SHARING_API_USER2]['sub1'] = $view2->getFileInfo('sub1')->getId();
|
||||
$this->fileIds[self::TEST_FILES_SHARING_API_USER2]['sub1/sub2'] = $view2->getFileInfo('sub1/sub2')->getId();
|
||||
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER3);
|
||||
$view3 = new View('/' . self::TEST_FILES_SHARING_API_USER3 . '/files');
|
||||
$view3->mkdir('/sub1/sub2');
|
||||
$view3->rename('/folder', '/sub1/sub2/folder');
|
||||
$this->fileIds[self::TEST_FILES_SHARING_API_USER3][''] = $view3->getFileInfo('')->getId();
|
||||
$this->fileIds[self::TEST_FILES_SHARING_API_USER3]['sub1'] = $view3->getFileInfo('sub1')->getId();
|
||||
$this->fileIds[self::TEST_FILES_SHARING_API_USER3]['sub1/sub2'] = $view3->getFileInfo('sub1/sub2')->getId();
|
||||
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER4);
|
||||
$view4 = new View('/' . self::TEST_FILES_SHARING_API_USER4 . '/files');
|
||||
$view4->mkdir('/sub1/sub2');
|
||||
$view4->rename('/inside', '/sub1/sub2/inside');
|
||||
$this->fileIds[self::TEST_FILES_SHARING_API_USER4][''] = $view4->getFileInfo('')->getId();
|
||||
$this->fileIds[self::TEST_FILES_SHARING_API_USER4]['sub1'] = $view4->getFileInfo('sub1')->getId();
|
||||
$this->fileIds[self::TEST_FILES_SHARING_API_USER4]['sub1/sub2'] = $view4->getFileInfo('sub1/sub2')->getId();
|
||||
|
||||
foreach ($this->fileIds as $user => $ids) {
|
||||
$this->loginAsUser($user);
|
||||
foreach ($ids as $id) {
|
||||
$path = $this->rootView->getPath($id);
|
||||
$this->fileEtags[$id] = $this->rootView->getFileInfo($path)->getEtag();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $users
|
||||
* @param string $subPath
|
||||
*/
|
||||
private function assertEtagsChanged($users, $subPath = '') {
|
||||
$oldUser = \OC::$server->getUserSession()->getUser();
|
||||
foreach ($users as $user) {
|
||||
$this->loginAsUser($user);
|
||||
$id = $this->fileIds[$user][$subPath];
|
||||
$path = $this->rootView->getPath($id);
|
||||
$etag = $this->rootView->getFileInfo($path)->getEtag();
|
||||
$this->assertNotEquals($this->fileEtags[$id], $etag, 'Failed asserting that the etag for "' . $subPath . '" of user ' . $user . ' has changed');
|
||||
$this->fileEtags[$id] = $etag;
|
||||
}
|
||||
$this->loginAsUser($oldUser->getUID());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $users
|
||||
* @param string $subPath
|
||||
*/
|
||||
private function assertEtagsNotChanged($users, $subPath = '') {
|
||||
$oldUser = \OC::$server->getUserSession()->getUser();
|
||||
foreach ($users as $user) {
|
||||
$this->loginAsUser($user);
|
||||
$id = $this->fileIds[$user][$subPath];
|
||||
$path = $this->rootView->getPath($id);
|
||||
$etag = $this->rootView->getFileInfo($path)->getEtag();
|
||||
$this->assertEquals($this->fileEtags[$id], $etag, 'Failed asserting that the etag for "' . $subPath . '" of user ' . $user . ' has not changed');
|
||||
$this->fileEtags[$id] = $etag;
|
||||
}
|
||||
$this->loginAsUser($oldUser->getUID());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the etags for the root, /sub1 and /sub1/sub2 have changed
|
||||
*
|
||||
* @param string[] $users
|
||||
*/
|
||||
private function assertEtagsForFoldersChanged($users) {
|
||||
$this->assertEtagsChanged($users);
|
||||
|
||||
$this->assertEtagsChanged($users, 'sub1');
|
||||
$this->assertEtagsChanged($users, 'sub1/sub2');
|
||||
}
|
||||
|
||||
private function assertAllUnchaged() {
|
||||
$users = [self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4];
|
||||
$this->assertEtagsNotChanged($users);
|
||||
}
|
||||
|
||||
public function testOwnerWritesToShare() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
|
||||
Filesystem::file_put_contents('/sub1/sub2/folder/asd.txt', 'bar');
|
||||
$this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4]);
|
||||
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3]);
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
|
||||
public function testOwnerWritesToShareWithReshare() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
|
||||
Filesystem::file_put_contents('/sub1/sub2/folder/inside/bar.txt', 'bar');
|
||||
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
|
||||
public function testOwnerRenameInShare() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
|
||||
$this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4]);
|
||||
Filesystem::rename('/sub1/sub2/folder/file.txt', '/sub1/sub2/folder/renamed.txt');
|
||||
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3]);
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
|
||||
public function testOwnerRenameInReShare() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
|
||||
Filesystem::rename('/sub1/sub2/folder/inside/file.txt', '/sub1/sub2/folder/inside/renamed.txt');
|
||||
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
|
||||
public function testOwnerRenameIntoReShare() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
|
||||
Filesystem::rename('/sub1/sub2/folder/file.txt', '/sub1/sub2/folder/inside/renamed.txt');
|
||||
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
|
||||
public function testOwnerRenameOutOfReShare() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
|
||||
Filesystem::rename('/sub1/sub2/folder/inside/file.txt', '/sub1/sub2/folder/renamed.txt');
|
||||
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
|
||||
public function testOwnerDeleteInShare() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
|
||||
Filesystem::unlink('/sub1/sub2/folder/file.txt');
|
||||
$this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4]);
|
||||
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3]);
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
|
||||
public function testOwnerDeleteInReShare() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
|
||||
Filesystem::unlink('/sub1/sub2/folder/inside/file.txt');
|
||||
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
|
||||
public function testRecipientWritesToShare() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
|
||||
Filesystem::file_put_contents('/sub1/sub2/folder/asd.txt', 'bar');
|
||||
$this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4]);
|
||||
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3]);
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
|
||||
public function testRecipientWritesToReshare() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
|
||||
Filesystem::file_put_contents('/sub1/sub2/folder/inside/asd.txt', 'bar');
|
||||
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
|
||||
public function testRecipientWritesToOtherRecipientsReshare() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER3);
|
||||
Filesystem::file_put_contents('/sub1/sub2/folder/inside/asd.txt', 'bar');
|
||||
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
|
||||
public function testRecipientRenameInShare() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
|
||||
Filesystem::rename('/sub1/sub2/folder/file.txt', '/sub1/sub2/folder/renamed.txt');
|
||||
$this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4]);
|
||||
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3]);
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
|
||||
public function testRecipientRenameInReShare() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
|
||||
Filesystem::rename('/sub1/sub2/folder/inside/file.txt', '/sub1/sub2/folder/inside/renamed.txt');
|
||||
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
|
||||
public function testRecipientRenameResharedFolder() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
|
||||
Filesystem::rename('/directReshare', '/sub1/directReshare');
|
||||
$this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
|
||||
$this->assertEtagsChanged([self::TEST_FILES_SHARING_API_USER2]);
|
||||
|
||||
$this->assertEtagsChanged([self::TEST_FILES_SHARING_API_USER2], 'sub1');
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
|
||||
public function testRecipientDeleteInShare() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
|
||||
Filesystem::unlink('/sub1/sub2/folder/file.txt');
|
||||
$this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4]);
|
||||
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3]);
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
|
||||
public function testRecipientDeleteInReShare() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
|
||||
Filesystem::unlink('/sub1/sub2/folder/inside/file.txt');
|
||||
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
|
||||
public function testReshareRecipientWritesToReshare() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER4);
|
||||
Filesystem::file_put_contents('/sub1/sub2/inside/asd.txt', 'bar');
|
||||
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
|
||||
public function testReshareRecipientRenameInReShare() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER4);
|
||||
Filesystem::rename('/sub1/sub2/inside/file.txt', '/sub1/sub2/inside/renamed.txt');
|
||||
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
|
||||
public function testReshareRecipientDeleteInReShare() {
|
||||
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER4);
|
||||
Filesystem::unlink('/sub1/sub2/inside/file.txt');
|
||||
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
|
||||
self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
|
||||
|
||||
$this->assertAllUnchaged();
|
||||
}
|
||||
}
|
|
@ -103,7 +103,9 @@ class Test_Files_Sharing_Permissions extends OCA\Files_sharing\Tests\TestCase {
|
|||
}
|
||||
|
||||
protected function tearDown() {
|
||||
$this->sharedCache->clear();
|
||||
if ($this->sharedCache) {
|
||||
$this->sharedCache->clear();
|
||||
}
|
||||
|
||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
|
||||
|
||||
|
|
|
@ -368,7 +368,10 @@ class Test_Files_Sharing_Storage extends OCA\Files_sharing\Tests\TestCase {
|
|||
|
||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
|
||||
$this->assertTrue($rootView->file_exists('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/' . $this->folder));
|
||||
OC_Hook::emit('OC_Filesystem', 'setup', array('user' => self::TEST_FILES_SHARING_API_USER3, 'user_dir' => \OC_User::getHome(self::TEST_FILES_SHARING_API_USER3)));
|
||||
|
||||
$mountConfigManager = \OC::$server->getMountProviderCollection();
|
||||
$mounts = $mountConfigManager->getMountsForUser(\OC::$server->getUserManager()->get(self::TEST_FILES_SHARING_API_USER3));
|
||||
array_walk($mounts, array(\OC\Files\Filesystem::getMountManager(), 'addMount'));
|
||||
|
||||
$this->assertTrue($rootView->file_exists('/' . self::TEST_FILES_SHARING_API_USER3 . '/files/' . $this->filename));
|
||||
|
||||
|
|
|
@ -19,11 +19,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Files_Sharing\Tests;
|
||||
namespace OCA\Files_sharing\Tests;
|
||||
|
||||
use OC\Files\View;
|
||||
|
||||
class Propagation extends TestCase {
|
||||
class SizePropagation extends TestCase {
|
||||
|
||||
public function testSizePropagationWhenOwnerChangesFile() {
|
||||
$this->loginHelper(self::TEST_FILES_SHARING_API_USER1);
|
|
@ -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
|
||||
|
@ -42,6 +43,7 @@ abstract class TestCase extends \Test\TestCase {
|
|||
const TEST_FILES_SHARING_API_USER1 = "test-share-user1";
|
||||
const TEST_FILES_SHARING_API_USER2 = "test-share-user2";
|
||||
const TEST_FILES_SHARING_API_USER3 = "test-share-user3";
|
||||
const TEST_FILES_SHARING_API_USER4 = "test-share-user4";
|
||||
|
||||
const TEST_FILES_SHARING_API_GROUP1 = "test-share-group1";
|
||||
|
||||
|
@ -57,6 +59,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 +70,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();
|
||||
|
@ -72,6 +77,7 @@ abstract class TestCase extends \Test\TestCase {
|
|||
$backend->createUser(self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER1);
|
||||
$backend->createUser(self::TEST_FILES_SHARING_API_USER2, self::TEST_FILES_SHARING_API_USER2);
|
||||
$backend->createUser(self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER3);
|
||||
$backend->createUser(self::TEST_FILES_SHARING_API_USER4, self::TEST_FILES_SHARING_API_USER4);
|
||||
|
||||
// create group
|
||||
$groupBackend = new \OC_Group_Dummy();
|
||||
|
@ -147,6 +153,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);
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,9 @@ class Test_Files_Sharing_Watcher extends OCA\Files_sharing\Tests\TestCase {
|
|||
}
|
||||
|
||||
protected function tearDown() {
|
||||
$this->sharedCache->clear();
|
||||
if ($this->sharedCache) {
|
||||
$this->sharedCache->clear();
|
||||
}
|
||||
|
||||
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
|
||||
|
||||
|
|
|
@ -54,7 +54,9 @@ class Test_Trashbin extends \Test\TestCase {
|
|||
// clear share hooks
|
||||
\OC_Hook::clear('OCP\\Share');
|
||||
\OC::registerShareHooks();
|
||||
\OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup');
|
||||
$application = new \OCA\Files_Sharing\AppInfo\Application();
|
||||
$application->registerMountProviders();
|
||||
$application->setupPropagation();
|
||||
|
||||
//disable encryption
|
||||
\OC_App::disable('files_encryption');
|
||||
|
|
|
@ -47,7 +47,9 @@ class Test_Files_Versioning extends \Test\TestCase {
|
|||
\OC_Hook::clear('OCP\\Share');
|
||||
\OC::registerShareHooks();
|
||||
\OCA\Files_Versions\Hooks::connectHooks();
|
||||
\OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup');
|
||||
$application = new \OCA\Files_Sharing\AppInfo\Application();
|
||||
$application->registerMountProviders();
|
||||
$application->setupPropagation();
|
||||
|
||||
// create test user
|
||||
self::loginHelper(self::TEST_VERSIONS_USER2, true);
|
||||
|
|
|
@ -181,6 +181,7 @@ class File extends Node implements IFile {
|
|||
$view = \OC\Files\Filesystem::getView();
|
||||
if ($view) {
|
||||
$hookPath = $view->getRelativePath($this->fileView->getAbsolutePath($this->path));
|
||||
$this->fileView->getUpdater()->propagate($hookPath);
|
||||
if (!$exists) {
|
||||
\OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_post_create, array(
|
||||
\OC\Files\Filesystem::signal_param_path => $hookPath
|
||||
|
|
5
lib/private/files/cache/changepropagator.php
vendored
5
lib/private/files/cache/changepropagator.php
vendored
|
@ -22,12 +22,14 @@
|
|||
|
||||
namespace OC\Files\Cache;
|
||||
|
||||
use OC\Hooks\BasicEmitter;
|
||||
|
||||
/**
|
||||
* Propagates changes in etag and mtime up the filesystem tree
|
||||
*
|
||||
* @package OC\Files\Cache
|
||||
*/
|
||||
class ChangePropagator {
|
||||
class ChangePropagator extends BasicEmitter {
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
|
@ -75,6 +77,7 @@ class ChangePropagator {
|
|||
$cache = $storage->getCache();
|
||||
$entry = $cache->get($internalPath);
|
||||
$cache->update($entry['fileid'], array('mtime' => max($time, $entry['mtime']), 'etag' => $storage->getETag($internalPath)));
|
||||
$this->emit('\OC\Files', 'propagate', [$parent, $entry]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
4
lib/private/files/cache/updater.php
vendored
4
lib/private/files/cache/updater.php
vendored
|
@ -60,6 +60,10 @@ class Updater {
|
|||
$this->enabled = true;
|
||||
}
|
||||
|
||||
public function getPropagator() {
|
||||
return $this->propagator;
|
||||
}
|
||||
|
||||
public function propagate($path, $time = null) {
|
||||
if (Scanner::isPartialFile($path)) {
|
||||
return;
|
||||
|
|
|
@ -658,6 +658,10 @@ class View {
|
|||
} elseif ($result) {
|
||||
if ($internalPath1 !== '') { // dont do a cache update for moved mounts
|
||||
$this->updater->rename($path1, $path2);
|
||||
} else { // only do etag propagation
|
||||
$this->getUpdater()->getPropagator()->addChange($path1);
|
||||
$this->getUpdater()->getPropagator()->addChange($path2);
|
||||
$this->getUpdater()->getPropagator()->propagateChanges();
|
||||
}
|
||||
if ($this->shouldEmitHooks($path1) and $this->shouldEmitHooks($path2)) {
|
||||
\OC_Hook::emit(
|
||||
|
|
|
@ -2530,4 +2530,28 @@ class Share extends Constants {
|
|||
$enforcePassword = $config->getAppValue('core', 'shareapi_enforce_links_password', 'no');
|
||||
return ($enforcePassword === "yes") ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all share entries, including non-unique group items
|
||||
*
|
||||
* @param string $owner
|
||||
* @return array
|
||||
*/
|
||||
public static function getAllSharesForOwner($owner) {
|
||||
$query = 'SELECT * FROM `*PREFIX*share` WHERE `uid_owner` = ?';
|
||||
$result = \OC::$server->getDatabaseConnection()->executeQuery($query, [$owner]);
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,6 @@ class File extends \Test\TestCase {
|
|||
$view = $this->getMock('\OC\Files\View', array('file_put_contents', 'getRelativePath', 'resolvePath'), array());
|
||||
$view->expects($this->any())
|
||||
->method('resolvePath')
|
||||
->with('')
|
||||
->will($this->returnValue(array($storage, '')));
|
||||
$view->expects($this->any())
|
||||
->method('getRelativePath')
|
||||
|
|
|
@ -25,7 +25,9 @@ class EtagTest extends \Test\TestCase {
|
|||
parent::setUp();
|
||||
|
||||
\OC_Hook::clear('OC_Filesystem', 'setup');
|
||||
\OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup');
|
||||
$application = new \OCA\Files_Sharing\AppInfo\Application();
|
||||
$application->registerMountProviders();
|
||||
$application->setupPropagation();
|
||||
\OCP\Share::registerBackend('file', 'OC_Share_Backend_File');
|
||||
\OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file');
|
||||
|
||||
|
|
Loading…
Reference in a new issue