propagate etags for all user of a share

This commit is contained in:
Robin Appelman 2015-03-09 16:20:18 +01:00
parent 518d5aadf5
commit 30ad56813a
14 changed files with 521 additions and 93 deletions

View File

@ -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

View File

@ -0,0 +1,51 @@
<?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\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');
}
}

View File

@ -25,9 +25,6 @@
*/
namespace OCA\Files_Sharing\AppInfo;
use OCA\Files_Sharing\Application;
use OCP\API;
$application = new Application();
$application->registerRoutes($this, [
'resources' => [

View File

@ -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');

View File

@ -0,0 +1,70 @@
<?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 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);
}
}

View File

@ -0,0 +1,56 @@
<?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 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();
}
}
}

View File

@ -0,0 +1,113 @@
<?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 = [];
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');
}
}

View File

@ -0,0 +1,108 @@
<?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\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());
}
});
}
}

View File

@ -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;
}
}

View File

@ -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() {

View File

@ -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);
}
/**

View File

@ -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());
}
}

View File

@ -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);
}

View File

@ -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();
}
}