mirror of
https://github.com/nextcloud/server.git
synced 2026-04-15 22:11:17 -04:00
Merge pull request #11305 from owncloud/ext-updateetagonmount
Update etag of parent dir when adding/removing ext storage mount points
This commit is contained in:
commit
9dea79e341
7 changed files with 653 additions and 1 deletions
|
|
@ -118,6 +118,22 @@ class OC_Mount_Config {
|
|||
}
|
||||
$manager->addMount($mount);
|
||||
}
|
||||
|
||||
if ($data['user']) {
|
||||
$user = \OC::$server->getUserManager()->get($data['user']);
|
||||
$userView = new \OC\Files\View('/' . $user->getUID() . '/files');
|
||||
$changePropagator = new \OC\Files\Cache\ChangePropagator($userView);
|
||||
$etagPropagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, \OC::$server->getConfig());
|
||||
$etagPropagator->propagateDirtyMountPoints();
|
||||
\OCP\Util::connectHook(
|
||||
\OC\Files\Filesystem::CLASSNAME,
|
||||
\OC\Files\Filesystem::signal_create_mount,
|
||||
$etagPropagator, 'updateHook');
|
||||
\OCP\Util::connectHook(
|
||||
\OC\Files\Filesystem::CLASSNAME,
|
||||
\OC\Files\Filesystem::signal_delete_mount,
|
||||
$etagPropagator, 'updateHook');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -463,6 +479,7 @@ class OC_Mount_Config {
|
|||
$priority = null) {
|
||||
$backends = self::getBackends();
|
||||
$mountPoint = OC\Files\Filesystem::normalizePath($mountPoint);
|
||||
$relMountPoint = $mountPoint;
|
||||
if ($mountPoint === '' || $mountPoint === '/') {
|
||||
// can't mount at root folder
|
||||
return false;
|
||||
|
|
@ -495,6 +512,10 @@ class OC_Mount_Config {
|
|||
}
|
||||
|
||||
$mountPoints = self::readData($isPersonal ? OCP\User::getUser() : NULL);
|
||||
// who else loves multi-dimensional array ?
|
||||
$isNew = !isset($mountPoints[$mountType]) ||
|
||||
!isset($mountPoints[$mountType][$applicable]) ||
|
||||
!isset($mountPoints[$mountType][$applicable][$mountPoint]);
|
||||
$mountPoints = self::mergeMountPoints($mountPoints, $mount, $mountType);
|
||||
|
||||
// Set default priority if none set
|
||||
|
|
@ -510,7 +531,19 @@ class OC_Mount_Config {
|
|||
|
||||
self::writeData($isPersonal ? OCP\User::getUser() : NULL, $mountPoints);
|
||||
|
||||
return self::getBackendStatus($class, $classOptions, $isPersonal);
|
||||
$result = self::getBackendStatus($class, $classOptions, $isPersonal);
|
||||
if ($result && $isNew) {
|
||||
\OC_Hook::emit(
|
||||
\OC\Files\Filesystem::CLASSNAME,
|
||||
\OC\Files\Filesystem::signal_create_mount,
|
||||
array(
|
||||
\OC\Files\Filesystem::signal_param_path => $relMountPoint,
|
||||
\OC\Files\Filesystem::signal_param_mount_type => $mountType,
|
||||
\OC\Files\Filesystem::signal_param_users => $applicable,
|
||||
)
|
||||
);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -523,6 +556,7 @@ class OC_Mount_Config {
|
|||
*/
|
||||
public static function removeMountPoint($mountPoint, $mountType, $applicable, $isPersonal = false) {
|
||||
// Verify that the mount point applies for the current user
|
||||
$relMountPoints = $mountPoint;
|
||||
if ($isPersonal) {
|
||||
if ($applicable != OCP\User::getUser()) {
|
||||
return false;
|
||||
|
|
@ -543,6 +577,15 @@ class OC_Mount_Config {
|
|||
}
|
||||
}
|
||||
self::writeData($isPersonal ? OCP\User::getUser() : NULL, $mountPoints);
|
||||
\OC_Hook::emit(
|
||||
\OC\Files\Filesystem::CLASSNAME,
|
||||
\OC\Files\Filesystem::signal_delete_mount,
|
||||
array(
|
||||
\OC\Files\Filesystem::signal_param_path => $relMountPoints,
|
||||
\OC\Files\Filesystem::signal_param_mount_type => $mountType,
|
||||
\OC\Files\Filesystem::signal_param_users => $applicable,
|
||||
)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
126
apps/files_external/lib/etagpropagator.php
Normal file
126
apps/files_external/lib/etagpropagator.php
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 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_External;
|
||||
|
||||
use OC\Files\Filesystem;
|
||||
|
||||
/**
|
||||
* Updates the etag of parent folders whenever a new external storage mount
|
||||
* point has been created or deleted. Updates need to be triggered using
|
||||
* the updateHook() method.
|
||||
*
|
||||
* There are two modes of operation:
|
||||
* - for personal mount points, the etag is propagated directly
|
||||
* - for system mount points, a dirty flag is saved in the configuration and
|
||||
* the etag will be updated the next time propagateDirtyMountPoints() is called
|
||||
*/
|
||||
class EtagPropagator {
|
||||
/**
|
||||
* @var \OCP\IUser
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* @var \OC\Files\Cache\ChangePropagator
|
||||
*/
|
||||
protected $changePropagator;
|
||||
|
||||
/**
|
||||
* @var \OCP\IConfig
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @param \OCP\IUser $user 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($user, $changePropagator, $config) {
|
||||
$this->user = $user;
|
||||
$this->changePropagator = $changePropagator;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Propagate the etag changes for all mountpoints marked as dirty and mark the mountpoints as clean
|
||||
*
|
||||
* @param int $time
|
||||
*/
|
||||
public function propagateDirtyMountPoints($time = null) {
|
||||
if ($time === null) {
|
||||
$time = time();
|
||||
}
|
||||
$mountPoints = $this->getDirtyMountPoints();
|
||||
foreach ($mountPoints as $mountPoint) {
|
||||
$this->changePropagator->addChange($mountPoint);
|
||||
$this->config->setUserValue($this->user->getUID(), 'files_external', $mountPoint, $time);
|
||||
}
|
||||
if (count($mountPoints)) {
|
||||
$this->changePropagator->propagateChanges($time);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all mountpoints we need to update the etag for
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getDirtyMountPoints() {
|
||||
$dirty = array();
|
||||
$mountPoints = $this->config->getAppKeys('files_external');
|
||||
foreach ($mountPoints as $mountPoint) {
|
||||
if (substr($mountPoint, 0, 1) === '/') {
|
||||
$updateTime = $this->config->getAppValue('files_external', $mountPoint);
|
||||
$userTime = $this->config->getUserValue($this->user->getUID(), 'files_external', $mountPoint);
|
||||
if ($updateTime > $userTime) {
|
||||
$dirty[] = $mountPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $dirty;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mountPoint
|
||||
* @param int $time
|
||||
*/
|
||||
protected function markDirty($mountPoint, $time = null) {
|
||||
if ($time === null) {
|
||||
$time = time();
|
||||
}
|
||||
$this->config->setAppValue('files_external', $mountPoint, $time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update etags for mount points for known user
|
||||
* For global or group mount points, updating the etag for every user is not feasible
|
||||
* instead we mark the mount point as dirty and update the etag when the filesystem is loaded for the user
|
||||
* For personal mount points, the change is propagated directly
|
||||
*
|
||||
* @param array $params hook parameters
|
||||
* @param int $time update time to use when marking a mount point as dirty
|
||||
*/
|
||||
public function updateHook($params, $time = null) {
|
||||
if ($time === null) {
|
||||
$time = time();
|
||||
}
|
||||
$users = $params[Filesystem::signal_param_users];
|
||||
$type = $params[Filesystem::signal_param_mount_type];
|
||||
$mountPoint = $params[Filesystem::signal_param_path];
|
||||
$mountPoint = Filesystem::normalizePath($mountPoint);
|
||||
if ($type === \OC_Mount_Config::MOUNT_TYPE_GROUP or $users === 'all') {
|
||||
$this->markDirty($mountPoint, $time);
|
||||
} else {
|
||||
$this->changePropagator->addChange($mountPoint);
|
||||
$this->changePropagator->propagateChanges($time);
|
||||
}
|
||||
}
|
||||
}
|
||||
328
apps/files_external/tests/etagpropagator.php
Normal file
328
apps/files_external/tests/etagpropagator.php
Normal file
|
|
@ -0,0 +1,328 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 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 Tests\Files_External;
|
||||
|
||||
use OC\Files\Filesystem;
|
||||
use OC\User\User;
|
||||
|
||||
class EtagPropagator extends \PHPUnit_Framework_TestCase {
|
||||
protected function getUser() {
|
||||
return new User(uniqid(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \PHPUnit_Framework_MockObject_MockObject | \OC\Files\Cache\ChangePropagator
|
||||
*/
|
||||
protected function getChangePropagator() {
|
||||
return $this->getMockBuilder('\OC\Files\Cache\ChangePropagator')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \PHPUnit_Framework_MockObject_MockObject | \OCP\IConfig
|
||||
*/
|
||||
protected function getConfig() {
|
||||
$appConfig = array();
|
||||
$userConfig = array();
|
||||
$mock = $this->getMockBuilder('\OCP\IConfig')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$mock->expects($this->any())
|
||||
->method('getAppValue')
|
||||
->will($this->returnCallback(function ($appId, $key, $default = null) use (&$appConfig) {
|
||||
if (isset($appConfig[$appId]) and isset($appConfig[$appId][$key])) {
|
||||
return $appConfig[$appId][$key];
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}));
|
||||
$mock->expects($this->any())
|
||||
->method('setAppValue')
|
||||
->will($this->returnCallback(function ($appId, $key, $value) use (&$appConfig) {
|
||||
if (!isset($appConfig[$appId])) {
|
||||
$appConfig[$appId] = array();
|
||||
}
|
||||
$appConfig[$appId][$key] = $value;
|
||||
}));
|
||||
$mock->expects($this->any())
|
||||
->method('getAppKeys')
|
||||
->will($this->returnCallback(function ($appId) use (&$appConfig) {
|
||||
if (!isset($appConfig[$appId])) {
|
||||
$appConfig[$appId] = array();
|
||||
}
|
||||
return array_keys($appConfig[$appId]);
|
||||
}));
|
||||
|
||||
$mock->expects($this->any())
|
||||
->method('getUserValue')
|
||||
->will($this->returnCallback(function ($userId, $appId, $key, $default = null) use (&$userConfig) {
|
||||
if (isset($userConfig[$userId]) and isset($userConfig[$userId][$appId]) and isset($userConfig[$userId][$appId][$key])) {
|
||||
return $userConfig[$userId][$appId][$key];
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}));
|
||||
$mock->expects($this->any())
|
||||
->method('setUserValue')
|
||||
->will($this->returnCallback(function ($userId, $appId, $key, $value) use (&$userConfig) {
|
||||
if (!isset($userConfig[$userId])) {
|
||||
$userConfig[$userId] = array();
|
||||
}
|
||||
if (!isset($userConfig[$userId][$appId])) {
|
||||
$userConfig[$userId][$appId] = array();
|
||||
}
|
||||
$userConfig[$userId][$appId][$key] = $value;
|
||||
}));
|
||||
|
||||
return $mock;
|
||||
}
|
||||
|
||||
public function testSingleUserMount() {
|
||||
$time = time();
|
||||
$user = $this->getUser();
|
||||
$config = $this->getConfig();
|
||||
$changePropagator = $this->getChangePropagator();
|
||||
$propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config);
|
||||
|
||||
$changePropagator->expects($this->once())
|
||||
->method('addChange')
|
||||
->with('/test');
|
||||
$changePropagator->expects($this->once())
|
||||
->method('propagateChanges')
|
||||
->with($time);
|
||||
|
||||
$propagator->updateHook(array(
|
||||
Filesystem::signal_param_path => '/test',
|
||||
Filesystem::signal_param_mount_type => \OC_Mount_Config::MOUNT_TYPE_USER,
|
||||
Filesystem::signal_param_users => $user->getUID(),
|
||||
), $time);
|
||||
}
|
||||
|
||||
public function testGlobalMountNoDirectUpdate() {
|
||||
$time = time();
|
||||
$user = $this->getUser();
|
||||
$config = $this->getConfig();
|
||||
$changePropagator = $this->getChangePropagator();
|
||||
$propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config);
|
||||
|
||||
// not updated directly
|
||||
$changePropagator->expects($this->never())
|
||||
->method('addChange');
|
||||
$changePropagator->expects($this->never())
|
||||
->method('propagateChanges');
|
||||
|
||||
$propagator->updateHook(array(
|
||||
Filesystem::signal_param_path => '/test',
|
||||
Filesystem::signal_param_mount_type => \OC_Mount_Config::MOUNT_TYPE_USER,
|
||||
Filesystem::signal_param_users => 'all',
|
||||
), $time);
|
||||
|
||||
// mount point marked as dirty
|
||||
$this->assertEquals(array('/test'), $config->getAppKeys('files_external'));
|
||||
$this->assertEquals($time, $config->getAppValue('files_external', '/test'));
|
||||
}
|
||||
|
||||
public function testGroupMountNoDirectUpdate() {
|
||||
$time = time();
|
||||
$user = $this->getUser();
|
||||
$config = $this->getConfig();
|
||||
$changePropagator = $this->getChangePropagator();
|
||||
$propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config);
|
||||
|
||||
// not updated directly
|
||||
$changePropagator->expects($this->never())
|
||||
->method('addChange');
|
||||
$changePropagator->expects($this->never())
|
||||
->method('propagateChanges');
|
||||
|
||||
$propagator->updateHook(array(
|
||||
Filesystem::signal_param_path => '/test',
|
||||
Filesystem::signal_param_mount_type => \OC_Mount_Config::MOUNT_TYPE_GROUP,
|
||||
Filesystem::signal_param_users => 'test',
|
||||
), $time);
|
||||
|
||||
// mount point marked as dirty
|
||||
$this->assertEquals(array('/test'), $config->getAppKeys('files_external'));
|
||||
$this->assertEquals($time, $config->getAppValue('files_external', '/test'));
|
||||
}
|
||||
|
||||
public function testGlobalMountNoDirtyMountPoint() {
|
||||
$time = time();
|
||||
$user = $this->getUser();
|
||||
$config = $this->getConfig();
|
||||
$changePropagator = $this->getChangePropagator();
|
||||
$propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config);
|
||||
|
||||
$changePropagator->expects($this->never())
|
||||
->method('addChange');
|
||||
$changePropagator->expects($this->never())
|
||||
->method('propagateChanges');
|
||||
|
||||
$propagator->propagateDirtyMountPoints($time);
|
||||
|
||||
$this->assertEquals(0, $config->getUserValue($user->getUID(), 'files_external', '/test', 0));
|
||||
}
|
||||
|
||||
public function testGlobalMountDirtyMountPointFirstTime() {
|
||||
$time = time();
|
||||
$user = $this->getUser();
|
||||
$config = $this->getConfig();
|
||||
$changePropagator = $this->getChangePropagator();
|
||||
$propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config);
|
||||
|
||||
$config->setAppValue('files_external', '/test', $time - 10);
|
||||
|
||||
$changePropagator->expects($this->once())
|
||||
->method('addChange')
|
||||
->with('/test');
|
||||
$changePropagator->expects($this->once())
|
||||
->method('propagateChanges')
|
||||
->with($time);
|
||||
|
||||
$propagator->propagateDirtyMountPoints($time);
|
||||
|
||||
$this->assertEquals($time, $config->getUserValue($user->getUID(), 'files_external', '/test'));
|
||||
}
|
||||
|
||||
public function testGlobalMountNonDirtyMountPoint() {
|
||||
$time = time();
|
||||
$user = $this->getUser();
|
||||
$config = $this->getConfig();
|
||||
$changePropagator = $this->getChangePropagator();
|
||||
$propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config);
|
||||
|
||||
$config->setAppValue('files_external', '/test', $time - 10);
|
||||
$config->setUserValue($user->getUID(), 'files_external', '/test', $time - 10);
|
||||
|
||||
$changePropagator->expects($this->never())
|
||||
->method('addChange');
|
||||
$changePropagator->expects($this->never())
|
||||
->method('propagateChanges');
|
||||
|
||||
$propagator->propagateDirtyMountPoints($time);
|
||||
|
||||
$this->assertEquals($time - 10, $config->getUserValue($user->getUID(), 'files_external', '/test'));
|
||||
}
|
||||
|
||||
public function testGlobalMountNonDirtyMountPointOtherUser() {
|
||||
$time = time();
|
||||
$user = $this->getUser();
|
||||
$user2 = $this->getUser();
|
||||
$config = $this->getConfig();
|
||||
$changePropagator = $this->getChangePropagator();
|
||||
$propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config);
|
||||
|
||||
$config->setAppValue('files_external', '/test', $time - 10);
|
||||
$config->setUserValue($user2->getUID(), 'files_external', '/test', $time - 10);
|
||||
|
||||
$changePropagator->expects($this->once())
|
||||
->method('addChange')
|
||||
->with('/test');
|
||||
$changePropagator->expects($this->once())
|
||||
->method('propagateChanges')
|
||||
->with($time);
|
||||
|
||||
$propagator->propagateDirtyMountPoints($time);
|
||||
|
||||
$this->assertEquals($time, $config->getUserValue($user->getUID(), 'files_external', '/test'));
|
||||
}
|
||||
|
||||
public function testGlobalMountDirtyMountPointSecondTime() {
|
||||
$time = time();
|
||||
$user = $this->getUser();
|
||||
$config = $this->getConfig();
|
||||
$changePropagator = $this->getChangePropagator();
|
||||
$propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config);
|
||||
|
||||
$config->setAppValue('files_external', '/test', $time - 10);
|
||||
$config->setUserValue($user->getUID(), 'files_external', '/test', $time - 20);
|
||||
|
||||
$changePropagator->expects($this->once())
|
||||
->method('addChange')
|
||||
->with('/test');
|
||||
$changePropagator->expects($this->once())
|
||||
->method('propagateChanges')
|
||||
->with($time);
|
||||
|
||||
$propagator->propagateDirtyMountPoints($time);
|
||||
|
||||
$this->assertEquals($time, $config->getUserValue($user->getUID(), 'files_external', '/test'));
|
||||
}
|
||||
|
||||
public function testGlobalMountMultipleUsers() {
|
||||
$time = time();
|
||||
$config = $this->getConfig();
|
||||
$user1 = $this->getUser();
|
||||
$user2 = $this->getUser();
|
||||
$user3 = $this->getUser();
|
||||
$changePropagator1 = $this->getChangePropagator();
|
||||
$changePropagator2 = $this->getChangePropagator();
|
||||
$changePropagator3 = $this->getChangePropagator();
|
||||
$propagator1 = new \OCA\Files_External\EtagPropagator($user1, $changePropagator1, $config);
|
||||
$propagator2 = new \OCA\Files_External\EtagPropagator($user2, $changePropagator2, $config);
|
||||
$propagator3 = new \OCA\Files_External\EtagPropagator($user3, $changePropagator3, $config);
|
||||
|
||||
$config->setAppValue('files_external', '/test', $time - 10);
|
||||
|
||||
$changePropagator1->expects($this->once())
|
||||
->method('addChange')
|
||||
->with('/test');
|
||||
$changePropagator1->expects($this->once())
|
||||
->method('propagateChanges')
|
||||
->with($time);
|
||||
|
||||
$propagator1->propagateDirtyMountPoints($time);
|
||||
|
||||
$this->assertEquals($time, $config->getUserValue($user1->getUID(), 'files_external', '/test'));
|
||||
$this->assertEquals(0, $config->getUserValue($user2->getUID(), 'files_external', '/test', 0));
|
||||
$this->assertEquals(0, $config->getUserValue($user3->getUID(), 'files_external', '/test', 0));
|
||||
|
||||
$changePropagator2->expects($this->once())
|
||||
->method('addChange')
|
||||
->with('/test');
|
||||
$changePropagator2->expects($this->once())
|
||||
->method('propagateChanges')
|
||||
->with($time);
|
||||
|
||||
$propagator2->propagateDirtyMountPoints($time);
|
||||
|
||||
$this->assertEquals($time, $config->getUserValue($user1->getUID(), 'files_external', '/test'));
|
||||
$this->assertEquals($time, $config->getUserValue($user2->getUID(), 'files_external', '/test', 0));
|
||||
$this->assertEquals(0, $config->getUserValue($user3->getUID(), 'files_external', '/test', 0));
|
||||
}
|
||||
|
||||
public function testGlobalMountMultipleDirtyMountPoints() {
|
||||
$time = time();
|
||||
$user = $this->getUser();
|
||||
$config = $this->getConfig();
|
||||
$changePropagator = $this->getChangePropagator();
|
||||
$propagator = new \OCA\Files_External\EtagPropagator($user, $changePropagator, $config);
|
||||
|
||||
$config->setAppValue('files_external', '/test', $time - 10);
|
||||
$config->setAppValue('files_external', '/foo', $time - 50);
|
||||
$config->setAppValue('files_external', '/bar', $time - 70);
|
||||
|
||||
$config->setUserValue($user->getUID(), 'files_external', '/foo', $time - 70);
|
||||
$config->setUserValue($user->getUID(), 'files_external', '/bar', $time - 70);
|
||||
|
||||
$changePropagator->expects($this->exactly(2))
|
||||
->method('addChange');
|
||||
$changePropagator->expects($this->once())
|
||||
->method('propagateChanges')
|
||||
->with($time);
|
||||
|
||||
$propagator->propagateDirtyMountPoints($time);
|
||||
|
||||
$this->assertEquals($time, $config->getUserValue($user->getUID(), 'files_external', '/test'));
|
||||
$this->assertEquals($time, $config->getUserValue($user->getUID(), 'files_external', '/foo'));
|
||||
$this->assertEquals($time - 70, $config->getUserValue($user->getUID(), 'files_external', '/bar'));
|
||||
}
|
||||
}
|
||||
|
|
@ -26,6 +26,42 @@ class Test_Mount_Config_Dummy_Storage {
|
|||
}
|
||||
}
|
||||
|
||||
class Test_Mount_Config_Hook_Test {
|
||||
static $signal;
|
||||
static $params;
|
||||
|
||||
public static function setUpHooks() {
|
||||
self::clear();
|
||||
\OCP\Util::connectHook(
|
||||
\OC\Files\Filesystem::CLASSNAME,
|
||||
\OC\Files\Filesystem::signal_create_mount,
|
||||
'\Test_Mount_Config_Hook_Test', 'createHookCallback');
|
||||
\OCP\Util::connectHook(
|
||||
\OC\Files\Filesystem::CLASSNAME,
|
||||
\OC\Files\Filesystem::signal_delete_mount,
|
||||
'\Test_Mount_Config_Hook_Test', 'deleteHookCallback');
|
||||
}
|
||||
|
||||
public static function clear() {
|
||||
self::$signal = null;
|
||||
self::$params = null;
|
||||
}
|
||||
|
||||
public static function createHookCallback($params) {
|
||||
self::$signal = \OC\Files\Filesystem::signal_create_mount;
|
||||
self::$params = $params;
|
||||
}
|
||||
|
||||
public static function deleteHookCallback($params) {
|
||||
self::$signal = \OC\Files\Filesystem::signal_delete_mount;
|
||||
self::$params = $params;
|
||||
}
|
||||
|
||||
public static function getLastCall() {
|
||||
return array(self::$signal, self::$params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Test_Mount_Config
|
||||
*/
|
||||
|
|
@ -77,9 +113,11 @@ class Test_Mount_Config extends \PHPUnit_Framework_TestCase {
|
|||
);
|
||||
|
||||
OC_Mount_Config::$skipTest = true;
|
||||
Test_Mount_Config_Hook_Test::setupHooks();
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
Test_Mount_Config_Hook_Test::clear();
|
||||
OC_Mount_Config::$skipTest = false;
|
||||
|
||||
\OC_User::deleteUser(self::TEST_USER2);
|
||||
|
|
@ -337,6 +375,102 @@ class Test_Mount_Config extends \PHPUnit_Framework_TestCase {
|
|||
$this->assertEquals(array_keys($options), array_keys($savedOptions));
|
||||
}
|
||||
|
||||
public function testHooks() {
|
||||
$mountPoint = '/test';
|
||||
$mountType = 'user';
|
||||
$applicable = 'all';
|
||||
$isPersonal = false;
|
||||
|
||||
$mountConfig = array(
|
||||
'host' => 'smbhost',
|
||||
'user' => 'smbuser',
|
||||
'password' => 'smbpassword',
|
||||
'share' => 'smbshare',
|
||||
'root' => 'smbroot'
|
||||
);
|
||||
|
||||
// write config
|
||||
$this->assertTrue(
|
||||
OC_Mount_Config::addMountPoint(
|
||||
$mountPoint,
|
||||
'\OC\Files\Storage\SMB',
|
||||
$mountConfig,
|
||||
$mountType,
|
||||
$applicable,
|
||||
$isPersonal
|
||||
)
|
||||
);
|
||||
|
||||
list($hookName, $params) = Test_Mount_Config_Hook_Test::getLastCall();
|
||||
$this->assertEquals(
|
||||
\OC\Files\Filesystem::signal_create_mount,
|
||||
$hookName
|
||||
);
|
||||
$this->assertEquals(
|
||||
$mountPoint,
|
||||
$params[\OC\Files\Filesystem::signal_param_path]
|
||||
);
|
||||
$this->assertEquals(
|
||||
$mountType,
|
||||
$params[\OC\Files\Filesystem::signal_param_mount_type]
|
||||
);
|
||||
$this->assertEquals(
|
||||
$applicable,
|
||||
$params[\OC\Files\Filesystem::signal_param_users]
|
||||
);
|
||||
|
||||
Test_Mount_Config_Hook_Test::clear();
|
||||
|
||||
// edit
|
||||
$mountConfig['host'] = 'anothersmbhost';
|
||||
$this->assertTrue(
|
||||
OC_Mount_Config::addMountPoint(
|
||||
$mountPoint,
|
||||
'\OC\Files\Storage\SMB',
|
||||
$mountConfig,
|
||||
$mountType,
|
||||
$applicable,
|
||||
$isPersonal
|
||||
)
|
||||
);
|
||||
|
||||
// hook must not be called on edit
|
||||
list($hookName, $params) = Test_Mount_Config_Hook_Test::getLastCall();
|
||||
$this->assertEquals(
|
||||
null,
|
||||
$hookName
|
||||
);
|
||||
|
||||
Test_Mount_Config_Hook_Test::clear();
|
||||
|
||||
$this->assertTrue(
|
||||
OC_Mount_Config::removeMountPoint(
|
||||
$mountPoint,
|
||||
$mountType,
|
||||
$applicable,
|
||||
$isPersonal
|
||||
)
|
||||
);
|
||||
|
||||
list($hookName, $params) = Test_Mount_Config_Hook_Test::getLastCall();
|
||||
$this->assertEquals(
|
||||
\OC\Files\Filesystem::signal_delete_mount,
|
||||
$hookName
|
||||
);
|
||||
$this->assertEquals(
|
||||
$mountPoint,
|
||||
$params[\OC\Files\Filesystem::signal_param_path]
|
||||
);
|
||||
$this->assertEquals(
|
||||
$mountType,
|
||||
$params[\OC\Files\Filesystem::signal_param_mount_type]
|
||||
);
|
||||
$this->assertEquals(
|
||||
$applicable,
|
||||
$params[\OC\Files\Filesystem::signal_param_users]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test password obfuscation
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -43,6 +43,15 @@ class AllConfig implements \OCP\IConfig {
|
|||
\OCP\Config::deleteSystemValue($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all keys stored for an app
|
||||
*
|
||||
* @param string $appName the appName that we stored the value under
|
||||
* @return string[] the keys stored for the app
|
||||
*/
|
||||
public function getAppKeys($appName) {
|
||||
return \OC::$server->getAppConfig()->getKeys($appName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a new app wide value
|
||||
|
|
|
|||
|
|
@ -158,6 +158,11 @@ class Filesystem {
|
|||
*/
|
||||
const signal_param_run = 'run';
|
||||
|
||||
const signal_create_mount = 'create_mount';
|
||||
const signal_delete_mount = 'delete_mount';
|
||||
const signal_param_mount_type = 'mounttype';
|
||||
const signal_param_users = 'users';
|
||||
|
||||
/**
|
||||
* @var \OC\Files\Storage\Loader $loader
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -58,6 +58,13 @@ interface IConfig {
|
|||
*/
|
||||
public function deleteSystemValue($key);
|
||||
|
||||
/**
|
||||
* Get all keys stored for an app
|
||||
*
|
||||
* @param string $appName the appName that we stored the value under
|
||||
* @return string[] the keys stored for the app
|
||||
*/
|
||||
public function getAppKeys($appName);
|
||||
|
||||
/**
|
||||
* Writes a new app wide value
|
||||
|
|
|
|||
Loading…
Reference in a new issue