From 0e660087844e6edbf2729e687ddb4b3270110578 Mon Sep 17 00:00:00 2001 From: Jonas Date: Tue, 3 Nov 2026 16:25:43 +0100 Subject: [PATCH] fix(sessions): only use share node matching the session document getFileForSession() returned the node of a single-file share without checking it against the session's document, so the share token passed with push, sync and save could belong to a different file. Require the resolved file id to match the session document id. Alaready fixed in stable35 and above, where getFileByIdFromShare() does the same check, as part of #9062. Signed-off-by: Jonas Assisted-by: ClaudeCode:claude-opus-5-5 --- lib/Service/DocumentService.php | 2 +- tests/unit/Service/DocumentServiceTest.php | 29 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/Service/DocumentService.php b/lib/Service/DocumentService.php index 66a8951cacd..3eebe844867 100644 --- a/lib/Service/DocumentService.php +++ b/lib/Service/DocumentService.php @@ -495,7 +495,7 @@ public function getFileForSession(Session $session, ?string $shareToken = null): if ($node instanceof Folder) { $node = $node->getFirstNodeById($session->getDocumentId()); } - if ($node instanceof File) { + if ($node instanceof File && $node->getId() === $session->getDocumentId()) { return $node; } throw new \InvalidArgumentException('No proper share data'); diff --git a/tests/unit/Service/DocumentServiceTest.php b/tests/unit/Service/DocumentServiceTest.php index 8d091f2564f..dea1ddab808 100644 --- a/tests/unit/Service/DocumentServiceTest.php +++ b/tests/unit/Service/DocumentServiceTest.php @@ -3,11 +3,13 @@ namespace OCA\Text\Tests; use OCA\Text\Db\DocumentMapper; +use OCA\Text\Db\Session; use OCA\Text\Db\SessionMapper; use OCA\Text\Db\StepMapper; use OCA\Text\Service\DocumentService; use OCP\Constants; use OCP\Files\Config\IUserMountCache; +use OCP\Files\File; use OCP\Files\Folder; use OCP\Files\IAppData; use OCP\Files\IRootFolder; @@ -17,6 +19,7 @@ use OCP\IConfig; use OCP\IRequest; use OCP\Share\IManager; +use OCP\Share\IShare; use Psr\Log\LoggerInterface; class DocumentServiceTest extends \PHPUnit\Framework\TestCase { @@ -104,4 +107,30 @@ public function testGetFileByIdNoRead() { $this->expectException(NotPermittedException::class); $actual = $this->documentService->getFileById(1234); } + + public function testGetFileForSessionFromShare() { + $file = $this->createMock(File::class); + $file->method('getId')->willReturn(1234); + $share = $this->createMock(IShare::class); + $share->method('getNode')->willReturn($file); + $this->shareManager->method('getShareByToken')->willReturn($share); + + $session = new Session(); + $session->setDocumentId(1234); + $actual = $this->documentService->getFileForSession($session, 'shareToken'); + self::assertEquals($file, $actual); + } + + public function testGetFileForSessionFromShareOfOtherFile() { + $file = $this->createMock(\OCP\Files\File::class); + $file->method('getId')->willReturn(5678); + $share = $this->createMock(IShare::class); + $share->method('getNode')->willReturn($file); + $this->shareManager->method('getShareByToken')->willReturn($share); + + $session = new Session(); + $session->setDocumentId(1234); + $this->expectException(\InvalidArgumentException::class); + $this->documentService->getFileForSession($session, 'shareToken'); + } }