From 23355cdbb2635bf7342c808f36d2634bdf8a8268 Mon Sep 17 00:00:00 2001 From: Christoph Schaefer Date: Tue, 5 May 2026 17:00:50 +0200 Subject: [PATCH 1/2] fix(richdocuments): gate conversion with SecureViewService check Server-side conversion bypassed the Secure View / watermark restriction that the viewer enforces, allowing a user with view-only secure access to download a clean copy via the conversion API. Reuse SecureViewService (same logic the viewer uses) to deny conversion for files that should be secured. Handle the documented NotFoundException so a cache miss surfaces as a clear, translated error instead of a 500. Signed-off-by: Christoph Schaefer --- lib/Conversion/ConversionProvider.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/Conversion/ConversionProvider.php b/lib/Conversion/ConversionProvider.php index efc4008c53..4dcccb46e8 100644 --- a/lib/Conversion/ConversionProvider.php +++ b/lib/Conversion/ConversionProvider.php @@ -10,9 +10,11 @@ namespace OCA\Richdocuments\Conversion; use OCA\Richdocuments\Service\RemoteService; +use OCA\Richdocuments\Service\SecureViewService; use OCP\Files\Conversion\ConversionMimeProvider; use OCP\Files\Conversion\IConversionProvider; use OCP\Files\File; +use OCP\Files\NotFoundException; use OCP\IL10N; use OCP\L10N\IFactory; use Psr\Log\LoggerInterface; @@ -53,6 +55,7 @@ public function __construct( private RemoteService $remoteService, private LoggerInterface $logger, IFactory $l10nFactory, + private SecureViewService $secureViewService, ) { $this->l10n = $l10nFactory->get('richdocuments'); } @@ -144,6 +147,23 @@ public function convertFile(File $file, string $targetMimeType): mixed { )); } + if ($this->secureViewService->isEnabled()) { + try { + $secured = $this->secureViewService->shouldSecure( + $file->getInternalPath(), + $file->getStorage(), + ); + } catch (NotFoundException $e) { + $this->logger->warning('Could not determine Secure View status for conversion target', ['exception' => $e]); + throw new \Exception($this->l10n->t('Conversion is unavailable for this file.')); + } + if ($secured) { + throw new \Exception($this->l10n->t( + 'Conversion is blocked because the file is protected by Secure View.' + )); + } + } + return $this->remoteService->convertFileTo($file, $targetFileExtension); } From dde412f95389bc5296d90ad118a0978d8be271f6 Mon Sep 17 00:00:00 2001 From: Christoph Schaefer Date: Wed, 13 May 2026 08:38:53 +0200 Subject: [PATCH 2/2] Update lib/Conversion/ConversionProvider.php Confirmed: with the tryOpen=false change applied, the conversion is blocked with the translated "Conversion is blocked because the file is protected by Secure View." message in the log, instead of the ForbiddenException 500 that occurs with the default tryOpen=true (because fopen() on the SecureView wrapper throws). Accepting the suggestion. Thanks! Co-authored-by: Elizabeth Danzberger Signed-off-by: Christoph Schaefer --- lib/Conversion/ConversionProvider.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Conversion/ConversionProvider.php b/lib/Conversion/ConversionProvider.php index 4dcccb46e8..f2096d222f 100644 --- a/lib/Conversion/ConversionProvider.php +++ b/lib/Conversion/ConversionProvider.php @@ -152,6 +152,7 @@ public function convertFile(File $file, string $targetMimeType): mixed { $secured = $this->secureViewService->shouldSecure( $file->getInternalPath(), $file->getStorage(), + false, ); } catch (NotFoundException $e) { $this->logger->warning('Could not determine Secure View status for conversion target', ['exception' => $e]);