From a228e95ddf95e29a694af40bd9e4dad4b04ce1f0 Mon Sep 17 00:00:00 2001 From: Sujith H Date: Tue, 6 Mar 2018 19:31:23 +0530 Subject: [PATCH] Remove user from the storage setting or storage when user is deleted Remove user from the storage if there are multiple users associated with the storage during deletion of the user. Else remove the storage when user is deleted, since the storage is only associated with the user being deleted. Signed-off-by: Sujith H --- .../Service/GlobalStoragesService.php | 30 +++++ .../External/Service/UserStoragesService.php | 20 +++ lib/private/User/User.php | 6 +- .../Service/IGlobalStoragesService.php | 8 ++ .../External/Service/IUserStoragesService.php | 7 + .../Service/GlobalStoragesServiceTest.php | 120 ++++++++++++++++++ .../Service/UserStoragesServiceTest.php | 62 +++++++++ 7 files changed, 252 insertions(+), 1 deletion(-) diff --git a/lib/private/Files/External/Service/GlobalStoragesService.php b/lib/private/Files/External/Service/GlobalStoragesService.php index 6631367f6fe5..937ebd630b3f 100644 --- a/lib/private/Files/External/Service/GlobalStoragesService.php +++ b/lib/private/Files/External/Service/GlobalStoragesService.php @@ -182,4 +182,34 @@ public function getStorageForAllUsers() { return \array_combine($keys, $configs); } + + /** + * Deletes the external storages mounted to the user + * + * @param $userId + * @return bool + */ + public function deleteAllForUser($userId) { + $result = false; + $mounts = $this->getStorageForAllUsers(); + foreach ($mounts as $mount) { + $applicableUsers = $mount->getApplicableUsers(); + $id = $mount->getId(); + if (\in_array($userId, $applicableUsers, true)) { + if (\count($applicableUsers) === 1) { + //As this storage is associated only with this user. + $this->removeStorage($id); + $result = true; + } else { + $storage = $this->getStorage($id); + $userIndex = \array_search($userId, $applicableUsers, true); + unset($applicableUsers[$userIndex]); + $storage->setApplicableUsers($applicableUsers); + $this->updateStorage($storage); + $result = true; + } + } + } + return $result; + } } diff --git a/lib/private/Files/External/Service/UserStoragesService.php b/lib/private/Files/External/Service/UserStoragesService.php index 966424ef0be6..863f9a3e1888 100644 --- a/lib/private/Files/External/Service/UserStoragesService.php +++ b/lib/private/Files/External/Service/UserStoragesService.php @@ -27,6 +27,7 @@ use OC\Files\Filesystem; use OCP\Files\Config\IUserMountCache; +use OCP\IUser; use OCP\IUserSession; use OCP\Files\External\IStorageConfig; @@ -56,6 +57,7 @@ public function __construct( IUserMountCache $userMountCache ) { $this->userSession = $userSession; + $this->userMountCache = $userMountCache; parent::__construct($backendService, $dbConfig, $userMountCache); } @@ -140,4 +142,22 @@ public function getVisibilityType() { protected function isApplicable(IStorageConfig $config) { return ($config->getApplicableUsers() === [$this->getUser()->getUID()]) && $config->getType() === IStorageConfig::MOUNT_TYPE_PERSONAl; } + + /** + * Deletes the storages mounted to a user + * @param IUser $user + * @return bool + */ + public function deleteAllMountsForUser(IUser $user) { + $getUserMounts = $this->userMountCache->getMountsForUser($user); + $result = false; + if (\count($getUserMounts) > 0) { + foreach ($getUserMounts as $userMount) { + $id = $userMount->getStorageId(); + $this->userMountCache->removeUserStorageMount($id, $user->getUID()); + $result = true; + } + } + return $result; + } } diff --git a/lib/private/User/User.php b/lib/private/User/User.php index 0cf41c4e5df9..5ae515383dab 100644 --- a/lib/private/User/User.php +++ b/lib/private/User/User.php @@ -43,7 +43,6 @@ use OCP\IUserBackend; use OCP\IUserSession; use OCP\User\IChangePasswordBackend; -use OCP\UserInterface; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\GenericEvent; @@ -226,6 +225,11 @@ public function delete() { // Delete the user's keys in preferences \OC::$server->getConfig()->deleteAllUserValues($this->getUID()); + // Delete all mount points for user + \OC::$server->getUserStoragesService()->deleteAllMountsForUser($this); + //Delete external storage or remove user from applicableUsers list + \OC::$server->getGlobalStoragesService()->deleteAllForUser($this->getUID()); + // Delete user files in /data/ if ($homePath !== false) { // FIXME: this operates directly on FS, should use View instead... diff --git a/lib/public/Files/External/Service/IGlobalStoragesService.php b/lib/public/Files/External/Service/IGlobalStoragesService.php index bf92b99cbfae..a1e2ee41a77e 100644 --- a/lib/public/Files/External/Service/IGlobalStoragesService.php +++ b/lib/public/Files/External/Service/IGlobalStoragesService.php @@ -35,4 +35,12 @@ interface IGlobalStoragesService extends IStoragesService { * @since 10.0 */ public function getStorageForAllUsers(); + + /** + * Deletes the external storages mounted to the user + * @param $userId + * @return bool + * @since 10.0.8 + */ + public function deleteAllForUser($userId); } diff --git a/lib/public/Files/External/Service/IUserStoragesService.php b/lib/public/Files/External/Service/IUserStoragesService.php index c8a73da132f9..768b466570ee 100644 --- a/lib/public/Files/External/Service/IUserStoragesService.php +++ b/lib/public/Files/External/Service/IUserStoragesService.php @@ -28,4 +28,11 @@ * @since 10.0 */ interface IUserStoragesService extends IStoragesService { + /** + * Deletes the storages mounted to a user + * @param \OCP\IUser $user + * @return bool + * @since 10.0.8 + */ + public function deleteAllMountsForUser(\OCP\IUser $user); } diff --git a/tests/lib/Files/External/Service/GlobalStoragesServiceTest.php b/tests/lib/Files/External/Service/GlobalStoragesServiceTest.php index 43720082648e..d3907e832518 100644 --- a/tests/lib/Files/External/Service/GlobalStoragesServiceTest.php +++ b/tests/lib/Files/External/Service/GlobalStoragesServiceTest.php @@ -94,6 +94,22 @@ public function storageDataProvider() { 'priority' => 15, ], ], + // single user + [ + [ + 'mountPoint' => 'mountpoint', + 'backendIdentifier' => 'identifier:\Test\Files\External\Backend\DummyBackend', + 'authMechanismIdentifier' => 'identifier:\Auth\Mechanism', + 'backendOptions' => [ + 'option1' => 'value1', + 'option2' => 'value2', + 'password' => 'testPassword', + ], + 'applicableUsers' => ['foo'], + 'applicableGroups' => [], + 'priority' => 15, + ], + ], // some groups [ [ @@ -160,6 +176,110 @@ public function testAddStorage($storageParams) { $this->assertEquals($baseId + 1, $nextStorage->getId()); } + public function providesDeleteAllForUser() { + return [ + //False test + [ + [ + ] + ], + // all users + [ + [ + 'mountPoint' => 'mountpoint', + 'backendIdentifier' => 'identifier:\Test\Files\External\Backend\DummyBackend', + 'authMechanismIdentifier' => 'identifier:\Auth\Mechanism', + 'backendOptions' => [ + 'option1' => 'value1', + 'option2' => 'value2', + 'password' => 'testPassword', + ], + 'applicableUsers' => [], + 'applicableGroups' => [], + 'priority' => 15, + ], + ], + // multiple users + [ + [ + 'mountPoint' => 'mountpoint', + 'backendIdentifier' => 'identifier:\Test\Files\External\Backend\DummyBackend', + 'authMechanismIdentifier' => 'identifier:\Auth\Mechanism', + 'backendOptions' => [ + 'option1' => 'value1', + 'option2' => 'value2', + 'password' => 'testPassword', + ], + 'applicableUsers' => ['user1', 'user2'], + 'applicableGroups' => [], + 'priority' => 15, + ], + ], + // single user + [ + [ + 'mountPoint' => 'mountpoint', + 'backendIdentifier' => 'identifier:\Test\Files\External\Backend\DummyBackend', + 'authMechanismIdentifier' => 'identifier:\Auth\Mechanism', + 'backendOptions' => [ + 'option1' => 'value1', + 'option2' => 'value2', + 'password' => 'testPassword', + ], + 'applicableUsers' => ['foo'], + 'applicableGroups' => [], + 'priority' => 15, + ], + ], + // both users and groups + [ + [ + 'mountPoint' => 'mountpoint', + 'backendIdentifier' => 'identifier:\Test\Files\External\Backend\DummyBackend', + 'authMechanismIdentifier' => 'identifier:\Auth\Mechanism', + 'backendOptions' => [ + 'option1' => 'value1', + 'option2' => 'value2', + 'password' => 'testPassword', + ], + 'applicableUsers' => ['user1', 'user2'], + 'applicableGroups' => ['group1', 'group2'], + 'priority' => 15, + ], + ], + ]; + } + + /** + * @dataProvider providesDeleteAllForUser + */ + public function testDeleteAllForUser($storageParams) { + $this->service = new GlobalStoragesService($this->backendService, $this->dbConfig, $this->mountCache); + if (\count($storageParams) === 0) { + $this->assertFalse($this->service->deleteAllForUser('foo')); + } elseif (\count($storageParams['applicableUsers']) >= 1) { + $storage = $this->makeStorageConfig($storageParams); + $this->service->addStorage($storage); + if (isset($storageParams['applicableUsers'])) { + $initialApplicableUsers = \count($storageParams['applicableUsers']); + $this->assertTrue($this->service->deleteAllForUser($storageParams['applicableUsers'][0])); + if ($initialApplicableUsers > 1) { + $finalApplicableUsers = $this->service->getStorage($storage->getId())->getApplicableUsers(); + if (isset($storageParams['applicableGroups'])) { + $finalApplicableGroups = $this->service->getStorage($storage->getId())->getApplicableGroups(); + $this->assertEquals(\count($storageParams['applicableGroups']), \count($finalApplicableGroups)); + } + $this->assertEquals(1, $initialApplicableUsers - \count($finalApplicableUsers)); + \array_shift($storageParams['applicableUsers']); + $this->assertEquals([], \array_diff($storageParams['applicableUsers'], $finalApplicableUsers)); + } else { + $storages = \count($this->service->getAllStorages()); + $this->assertEquals(0, $storages); + } + } + } + } + /** * @dataProvider storageDataProvider */ diff --git a/tests/lib/Files/External/Service/UserStoragesServiceTest.php b/tests/lib/Files/External/Service/UserStoragesServiceTest.php index e1f3ab74a753..b2a41c23b6e3 100644 --- a/tests/lib/Files/External/Service/UserStoragesServiceTest.php +++ b/tests/lib/Files/External/Service/UserStoragesServiceTest.php @@ -23,12 +23,16 @@ */ namespace Test\Files\External\Service; +use OC\Files\Config\UserMountCache; use OC\Files\External\Service\GlobalStoragesService; use OC\Files\External\Service\UserStoragesService; use OC\Files\External\StorageConfig; use OC\Files\Filesystem; +use OC\Files\Mount\MountPoint; use OCP\Files\External\IStorageConfig; use OCP\Files\External\Service\IStoragesService; +use OCP\ILogger; +use OCP\IUser; use Test\Traits\UserTrait; /** @@ -204,4 +208,62 @@ public function testGetAdminStorage() { $this->service->getStorage($newStorage->getId()); } + + private function getStorage($storageId, $rootId) { + $storageCache = $this->getMockBuilder('\OC\Files\Cache\Storage') + ->disableOriginalConstructor() + ->getMock(); + $storageCache->expects($this->any()) + ->method('getNumericId') + ->will($this->returnValue($storageId)); + + $cache = $this->getMockBuilder('\OC\Files\Cache\Cache') + ->disableOriginalConstructor() + ->getMock(); + $cache->expects($this->any()) + ->method('getId') + ->will($this->returnValue($rootId)); + + $storage = $this->getMockBuilder('\OC\Files\Storage\Storage') + ->disableOriginalConstructor() + ->getMock(); + $storage->expects($this->any()) + ->method('getStorageCache') + ->will($this->returnValue($storageCache)); + $storage->expects($this->any()) + ->method('getCache') + ->will($this->returnValue($cache)); + + return $storage; + } + + public function testDeleteAllMountsForUser() { + $storage1 = $this->getStorage(10, 20); + $storage2 = $this->getStorage(12, 22); + + $mount1 = new MountPoint($storage1, '/foo/'); + $mount2 = new MountPoint($storage2, '/bar/'); + + $dbConnection = \OC::$server->getDatabaseConnection(); + $userManager = \OC::$server->getUserManager(); + $logger = $this->createMock(ILogger::class); + $userMountCache = new UserMountCache($dbConnection, $userManager, $logger); + $user1 = $userManager->createUser('user1', 'user1'); + $user2 = $userManager->createUser('user2', 'user2'); + + $userMountCache->registerMounts($user1, [$mount1, $mount2]); + + $userMountCache->registerMounts($user2, [$mount2]); + + $backendService = \OC::$server->getStoragesBackendService(); + $userSession = \OC::$server->getUserSession(); + $this->service = new UserStoragesService($backendService, $this->dbConfig, $userSession, $userMountCache); + $this->assertTrue($this->service->deleteAllMountsForUser($user1)); + $storarge1Result1 = $userMountCache->getMountsForStorageId(10); + $storarge1Result2 = $userMountCache->getMountsForStorageId(12); + $this->assertEquals(0, \count($storarge1Result1)); + $this->assertEquals(1, \count($storarge1Result2)); + $this->assertEquals(12, $storarge1Result2[0]->getStorageId()); + $this->assertEquals('/bar/', $storarge1Result2[0]->getMountPoint()); + } }