diff --git a/apps/files_sharing/lib/Cache.php b/apps/files_sharing/lib/Cache.php index 26a9bc7b5248c..de427ea8177ba 100644 --- a/apps/files_sharing/lib/Cache.php +++ b/apps/files_sharing/lib/Cache.php @@ -198,4 +198,8 @@ public function getCacheEntryFromSearchResult(ICacheEntry $rawEntry): ?ICacheEnt return null; } } + + public function markRootChanged(): void { + $this->rootUnchanged = false; + } } diff --git a/apps/files_sharing/lib/SharedStorage.php b/apps/files_sharing/lib/SharedStorage.php index 3b42130c0113c..2ac157f7970b6 100644 --- a/apps/files_sharing/lib/SharedStorage.php +++ b/apps/files_sharing/lib/SharedStorage.php @@ -460,7 +460,12 @@ public function getWatcher($path = '', $storage = null): Watcher { // for shares from the home storage we can rely on the home storage to keep itself up to date // for other storages we need use the proper watcher if (!(str_starts_with($storageId, 'home::') || str_starts_with($storageId, 'object::user'))) { + $cache = $this->getCache(); $this->watcher = parent::getWatcher($path, $storage); + if ($cache instanceof Cache && $this->watcher instanceof Watcher) { + $this->watcher->onUpdate([$cache, 'markRootChanged']); + } + return $this->watcher; } } diff --git a/apps/files_sharing/tests/CacheTest.php b/apps/files_sharing/tests/CacheTest.php index 543a7e4649576..1991f3e123ab9 100644 --- a/apps/files_sharing/tests/CacheTest.php +++ b/apps/files_sharing/tests/CacheTest.php @@ -6,9 +6,12 @@ */ namespace OCA\Files_Sharing\Tests; +use OC\Files\Filesystem; use OC\Files\Storage\Temporary; use OC\Files\Storage\Wrapper\Jail; use OCA\Files_Sharing\SharedStorage; +use OCP\Constants; +use OCP\Files\Cache\IWatcher; use OCP\Share\IShare; /** @@ -564,4 +567,38 @@ public function testSearchShareJailedStorage() { $results = $sharedStorage->getCache()->search("foo.txt"); $this->assertCount(1, $results); } + + public function testWatcherRootChange() { + $sourceStorage = new Temporary(); + $sourceStorage->mkdir('shared'); + $sourceStorage->file_put_contents('shared/foo.txt', 'foo'); + $sourceStorage->getScanner()->scan(''); + $sourceStorage->getWatcher()->setPolicy(IWatcher::CHECK_ALWAYS); + $this->registerMount(self::TEST_FILES_SHARING_API_USER1, $sourceStorage, '/' . self::TEST_FILES_SHARING_API_USER1 . '/files/foo'); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + + $rootFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1); + $node = $rootFolder->get('foo/shared'); + $this->assertEquals(3, $node->getSize()); + + $share = $this->shareManager->newShare(); + $share->setNode($node) + ->setShareType(IShare::TYPE_USER) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER2) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setPermissions(Constants::PERMISSION_ALL); + $share = $this->shareManager->createShare($share); + $share->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share); + \OC_Util::tearDownFS(); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + + $view = Filesystem::getView(); + + $sourceStorage->rmdir('shared'); + + $this->assertFalse($view->getFileInfo('shared')); + } } diff --git a/lib/private/Files/Cache/Watcher.php b/lib/private/Files/Cache/Watcher.php index 2e42b716695c4..b6c69dd733074 100644 --- a/lib/private/Files/Cache/Watcher.php +++ b/lib/private/Files/Cache/Watcher.php @@ -33,6 +33,9 @@ class Watcher implements IWatcher { */ protected $scanner; + /** @var callable[] */ + protected $onUpdate = []; + /** * @param \OC\Files\Storage\Storage $storage */ @@ -100,6 +103,9 @@ public function update($path, $cachedData) { if ($this->cache instanceof Cache) { $this->cache->correctFolderSize($path); } + foreach ($this->onUpdate as $callback) { + $callback($path); + } } /** @@ -130,4 +136,11 @@ public function cleanFolder($path) { } } } + + /** + * register a callback to be called whenever the watcher triggers and update + */ + public function onUpdate(callable $callback): void { + $this->onUpdate[] = $callback; + } } diff --git a/lib/private/Files/Cache/Wrapper/JailWatcher.php b/lib/private/Files/Cache/Wrapper/JailWatcher.php index 9bd7da5723389..b1ae516654a10 100644 --- a/lib/private/Files/Cache/Wrapper/JailWatcher.php +++ b/lib/private/Files/Cache/Wrapper/JailWatcher.php @@ -55,4 +55,7 @@ public function cleanFolder($path) { $this->watcher->cleanFolder($this->getSourcePath($path)); } + public function onUpdate(callable $callback): void { + $this->watcher->onUpdate($callback); + } }