From 2245b4df79183a78d1917652f393a8147400f87c Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 25 Jan 2017 12:42:21 +0100 Subject: [PATCH] Properly handle deleted users in UserMountCache When encountering entries from a deleted user, discard such entries. --- lib/private/Files/Config/UserMountCache.php | 31 +++++++++++++++++-- tests/lib/Files/Config/UserMountCacheTest.php | 26 ++++++++++++++++ 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/lib/private/Files/Config/UserMountCache.php b/lib/private/Files/Config/UserMountCache.php index 422cbd92f7ef..58520c8b7fcc 100644 --- a/lib/private/Files/Config/UserMountCache.php +++ b/lib/private/Files/Config/UserMountCache.php @@ -170,9 +170,34 @@ private function removeFromCache(ICachedMountInfo $mount) { private function dbRowToMountInfo(array $row) { $user = $this->userManager->get($row['user_id']); + if ($user === null) { + // user does not exist any more, delete all mounts of that user directly + $builder = $this->connection->getQueryBuilder(); + $query = $builder->delete('mounts') + ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($row['user_id']))); + $query->execute(); + return null; + } return new CachedMountInfo($user, (int)$row['storage_id'], (int)$row['root_id'], $row['mount_point']); } + /** + * Convert DB rows to CachedMountInfo + * + * @param array $rows DB rows + * @return CachedMountInfo[] + */ + private function convertRows($rows) { + $mountInfos = []; + foreach ($rows as $row) { + $mountInfo = $this->dbRowToMountInfo($row); + if (!is_null($mountInfo)) { + $mountInfos[] = $mountInfo; + } + } + return $mountInfos; + } + /** * @param IUser $user * @return ICachedMountInfo[] @@ -186,7 +211,7 @@ public function getMountsForUser(IUser $user) { $rows = $query->execute()->fetchAll(); - $this->mountsForUsers[$user->getUID()] = array_map([$this, 'dbRowToMountInfo'], $rows); + $this->mountsForUsers[$user->getUID()] = $this->convertRows($rows); } return $this->mountsForUsers[$user->getUID()]; } @@ -203,7 +228,7 @@ public function getMountsForStorageId($numericStorageId) { $rows = $query->execute()->fetchAll(); - return array_map([$this, 'dbRowToMountInfo'], $rows); + return $this->convertRows($rows); } /** @@ -218,7 +243,7 @@ public function getMountsForRootId($rootFileId) { $rows = $query->execute()->fetchAll(); - return array_map([$this, 'dbRowToMountInfo'], $rows); + return $this->convertRows($rows); } /** diff --git a/tests/lib/Files/Config/UserMountCacheTest.php b/tests/lib/Files/Config/UserMountCacheTest.php index ed1a930c0f3e..f262b3d3f196 100644 --- a/tests/lib/Files/Config/UserMountCacheTest.php +++ b/tests/lib/Files/Config/UserMountCacheTest.php @@ -46,6 +46,7 @@ public function setUp() { $userBackend = new Dummy(); $userBackend->createUser('u1', ''); $userBackend->createUser('u2', ''); + $userBackend->createUser('u3', ''); $this->userManager->registerBackend($userBackend); $this->cache = new \OC\Files\Config\UserMountCache($this->connection, $this->userManager, $this->createMock('\OC\Log')); } @@ -183,15 +184,19 @@ public function testChangeMounts() { public function testGetMountsForUser() { $user1 = $this->userManager->get('u1'); $user2 = $this->userManager->get('u2'); + $user3 = $this->userManager->get('u3'); $mount1 = new MountPoint($this->getStorage(1, 2), '/foo/'); $mount2 = new MountPoint($this->getStorage(3, 4), '/bar/'); $this->cache->registerMounts($user1, [$mount1, $mount2]); $this->cache->registerMounts($user2, [$mount2]); + $this->cache->registerMounts($user3, [$mount2]); $this->clearCache(); + $user3->delete(); + $cachedMounts = $this->cache->getMountsForUser($user1); $this->assertCount(2, $cachedMounts); @@ -204,6 +209,9 @@ public function testGetMountsForUser() { $this->assertEquals($user1, $cachedMounts[1]->getUser()); $this->assertEquals(4, $cachedMounts[1]->getRootId()); $this->assertEquals(3, $cachedMounts[1]->getStorageId()); + + $cachedMounts = $this->cache->getMountsForUser($user3); + $this->assertEmpty($cachedMounts); } public function testGetMountsByStorageId() { @@ -372,4 +380,22 @@ public function testGetMountsForFileIdSubFolderMountOutside() { $this->assertCount(0, $cachedMounts); } + + public function testGetMountsForFileIdDeletedUser() { + $user1 = $this->userManager->get('u1'); + + $rootId = $this->createCacheEntry('', 2); + + $mount1 = new MountPoint($this->getStorage(2, $rootId), '/foo/'); + + $this->cache->registerMounts($user1, [$mount1]); + + $user1->delete(); + + $this->clearCache(); + + $cachedMounts = $this->cache->getMountsForFileId($rootId); + + $this->assertEmpty($cachedMounts); + } }