From 53e330201a73664fcbeddb9836775ede6801e917 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 16 Jul 2024 17:02:36 +0200 Subject: [PATCH 1/5] fix: improve query for finding unscanned files Signed-off-by: Robin Appelman --- lib/BackgroundJob/BackgroundScanner.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/BackgroundJob/BackgroundScanner.php b/lib/BackgroundJob/BackgroundScanner.php index 92eecf3..b6066ca 100644 --- a/lib/BackgroundJob/BackgroundScanner.php +++ b/lib/BackgroundJob/BackgroundScanner.php @@ -20,6 +20,7 @@ use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\Config\IUserMountCache; use OCP\Files\File; +use OCP\Files\FileInfo; use OCP\Files\IMimeTypeLoader; use OCP\Files\IRootFolder; use OCP\Files\Node; @@ -200,15 +201,19 @@ protected function getSizeLimitExpression(IQueryBuilder $qb) { * @throws \OCP\DB\Exception */ public function getUnscannedFiles() { - $dirMimeTypeId = $this->mimeTypeLoader->getId('httpd/unix-directory'); + $dirMimeTypeId = $this->mimeTypeLoader->getId(FileInfo::MIMETYPE_FOLDER); $query = $this->db->getQueryBuilder(); $query->select('fc.fileid') ->from('filecache', 'fc') + ->leftJoin('fc', 'storages', 's', $query->expr()->eq('fc.storage', 's.numeric_id')) ->leftJoin('fc', 'files_antivirus', 'fa', $query->expr()->eq('fc.fileid', 'fa.fileid')) ->where($query->expr()->isNull('fa.fileid')) - ->andWhere($query->expr()->neq('mimetype', $query->expr()->literal($dirMimeTypeId))) - ->andWhere($query->expr()->like('path', $query->expr()->literal('files/%'))) + ->andWhere($query->expr()->neq('mimetype', $query->createNamedParameter($dirMimeTypeId))) + ->andWhere($query->expr()->orX( + $query->expr()->like('path', $query->createNamedParameter('files/%')), + $query->expr()->notLike('s.id', $query->createNamedParameter("home::%")) + )) ->andWhere($this->getSizeLimitExpression($query)) ->setMaxResults($this->getBatchSize() * 10); From d2829fa465070b3dc096b3053fd98f3483c00b57 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 16 Jul 2024 17:05:27 +0200 Subject: [PATCH 2/5] docs: clearify different background scanner file listing queries Signed-off-by: Robin Appelman --- lib/BackgroundJob/BackgroundScanner.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/BackgroundJob/BackgroundScanner.php b/lib/BackgroundJob/BackgroundScanner.php index b6066ca..329ec80 100644 --- a/lib/BackgroundJob/BackgroundScanner.php +++ b/lib/BackgroundJob/BackgroundScanner.php @@ -197,6 +197,8 @@ protected function getSizeLimitExpression(IQueryBuilder $qb) { } /** + * Find files in the filecache that have never been scanned + * * @return \Iterator * @throws \OCP\DB\Exception */ @@ -225,6 +227,8 @@ public function getUnscannedFiles() { /** + * Find files that have been updated since they got last scanned + * * @return \Iterator * @throws \OCP\DB\Exception */ @@ -245,6 +249,8 @@ public function getToRescanFiles() { /** + * Find files that have been last scanned more than 28 days ago + * * @return \Iterator * @throws \OCP\DB\Exception */ From a23302860fe5f66c882acc0c16a3ace253b537a8 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 18 Jul 2024 14:55:29 +0200 Subject: [PATCH 3/5] improve tests for background scanner Signed-off-by: Robin Appelman --- tests/BackgroundScannerTest.php | 23 ++++++++++++++++++++--- tests/TemporaryHome.php | 24 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 tests/TemporaryHome.php diff --git a/tests/BackgroundScannerTest.php b/tests/BackgroundScannerTest.php index 33cf6cf..6838f7f 100644 --- a/tests/BackgroundScannerTest.php +++ b/tests/BackgroundScannerTest.php @@ -35,22 +35,28 @@ class BackgroundScannerTest extends TestBase { use UserTrait; use MountProviderTrait; - /** @var Folder */ - private $homeDirectory; + private Folder $homeDirectory; + private Folder $externalDirectory; protected function setUp(): void { parent::setUp(); $this->createUser("av", "av"); - $storage = new Temporary(); + $storage = new TemporaryHome(); $storage->mkdir('files'); $storage->getScanner()->scan(''); + + $external = new Temporary(); + $external->getScanner()->scan(''); + $this->registerMount("av", $storage, "av"); + $this->registerMount("av", $external, "av/files/external"); $this->loginAsUser("av"); /** @var IRootFolder $root */ $root = \OC::$server->get(IRootFolder::class); $this->homeDirectory = $root->getUserFolder("av"); + $this->externalDirectory = $this->homeDirectory->get('external'); } private function markAllScanned() { @@ -120,6 +126,17 @@ public function testGetUnscannedFiles() { $scanner = $this->getBackgroundScanner(); $newFileId = $this->homeDirectory->newFile("foo", "bar")->getId(); + $this->homeDirectory->getParent()->newFile("outside", "bar")->getId(); + + $outdated = iterator_to_array($scanner->getUnscannedFiles()); + $this->assertEquals([$newFileId], $outdated); + } + + public function testGetUnscannedFilesExternal() { + $this->markAllScanned(); + + $scanner = $this->getBackgroundScanner(); + $newFileId = $this->homeDirectory->newFile("external/foo2", "bar2")->getId(); $outdated = iterator_to_array($scanner->getUnscannedFiles()); $this->assertEquals([$newFileId], $outdated); diff --git a/tests/TemporaryHome.php b/tests/TemporaryHome.php new file mode 100644 index 0000000..09c20f8 --- /dev/null +++ b/tests/TemporaryHome.php @@ -0,0 +1,24 @@ + + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCA\Files_Antivirus\Tests; + +class TemporaryHome extends \OC\Files\Storage\Temporary { + private string $id; + + public function __construct($arguments = null) { + parent::__construct($arguments); + $this->id = uniqid(); + } + + public function getId() { + return "home::" . $this->id; + } + +} From 900734cbfc674167296b0aa22e7a39306caf115a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 18 Jul 2024 15:33:02 +0200 Subject: [PATCH 4/5] 5.5.7 Signed-off-by: Robin Appelman --- appinfo/info.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appinfo/info.xml b/appinfo/info.xml index 300b29b..c6f580f 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -14,7 +14,7 @@ This application inspects files that are uploaded to Nextcloud for viruses before they are written to the Nextcloud storage. If a file is identified as a virus, it is either logged or not uploaded to the server. The application relies on the underlying ClamAV virus scanning engine, which the admin points Nextcloud to when configuring the application. Alternatively, a Kaspersky Scan Engine can be configured, which has to run on a separate server. For this app to be effective, the ClamAV virus definitions should be kept up to date. Also note that enabling this app will impact system performance as additional processing is required for every upload. More information is available in the Antivirus documentation. ]]> - 5.5.6 + 5.5.7 agpl Manuel Delgado @@ -44,7 +44,7 @@ For this app to be effective, the ClamAV virus definitions should be kept up to https://raw.githubusercontent.com/nextcloud/files_antivirus/master/screenshots/1.png - + From cd379ee8a4a11553a4f265b2233c6207c6987def Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 18 Jul 2024 15:55:21 +0200 Subject: [PATCH 5/5] php 7.4 compat Signed-off-by: Robin Appelman --- lib/Scanner/ICAP.php | 2 +- lib/Scanner/ScannerFactory.php | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/Scanner/ICAP.php b/lib/Scanner/ICAP.php index 674c325..11a994c 100644 --- a/lib/Scanner/ICAP.php +++ b/lib/Scanner/ICAP.php @@ -76,7 +76,7 @@ public function initScanner() { if (str_contains($path, '.ocTransferId') && str_ends_with($path, '.part')) { [$path] = explode('.ocTransferId', $path, 2); } - $remote = $this->request?->getRemoteAddress(); + $remote = $this->request ? $this->request->getRemoteAddress() : null; $encodedPath = implode("/", array_map("rawurlencode", explode("/", $path))); if ($this->mode === ICAPClient::MODE_REQ_MOD) { $this->icapRequest = $this->icapClient->reqmod($this->service, [ diff --git a/lib/Scanner/ScannerFactory.php b/lib/Scanner/ScannerFactory.php index f682765..329fca5 100644 --- a/lib/Scanner/ScannerFactory.php +++ b/lib/Scanner/ScannerFactory.php @@ -13,11 +13,18 @@ use Psr\Container\ContainerInterface; class ScannerFactory { + protected AppConfig $appConfig; + protected ContainerInterface $serverContainer; + protected IRequest $request; + public function __construct( - protected AppConfig $appConfig, - private ContainerInterface $serverContainer, - private IRequest $request, + AppConfig $appConfig, + ContainerInterface $serverContainer, + IRequest $request ) { + $this->appConfig = $appConfig; + $this->serverContainer = $serverContainer; + $this->request = $request; } /**