aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/dav/appinfo/v1/carddav.php2
-rw-r--r--apps/dav/composer/composer/autoload_classmap.php1
-rw-r--r--apps/dav/composer/composer/autoload_static.php1
-rw-r--r--apps/dav/lib/CardDAV/Validation/CardDavValidatePlugin.php40
-rw-r--r--apps/dav/lib/Server.php2
-rw-r--r--apps/dav/tests/unit/CardDAV/Validation/CardDavValidatePluginTest.php73
6 files changed, 119 insertions, 0 deletions
diff --git a/apps/dav/appinfo/v1/carddav.php b/apps/dav/appinfo/v1/carddav.php
index aa721c95531..72be4712705 100644
--- a/apps/dav/appinfo/v1/carddav.php
+++ b/apps/dav/appinfo/v1/carddav.php
@@ -11,6 +11,7 @@ use OCA\DAV\AppInfo\PluginManager;
use OCA\DAV\CardDAV\AddressBookRoot;
use OCA\DAV\CardDAV\CardDavBackend;
use OCA\DAV\CardDAV\Security\CardDavRateLimitingPlugin;
+use OCA\DAV\CardDAV\Validation\CardDavValidatePlugin;
use OCA\DAV\Connector\LegacyDAVACL;
use OCA\DAV\Connector\Sabre\Auth;
use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin;
@@ -89,6 +90,7 @@ $server->addPlugin(new \OCA\DAV\CardDAV\ImageExportPlugin(new \OCA\DAV\CardDAV\P
)));
$server->addPlugin(new ExceptionLoggerPlugin('carddav', \OC::$server->get(LoggerInterface::class)));
$server->addPlugin(\OCP\Server::get(CardDavRateLimitingPlugin::class));
+$server->addPlugin(\OCP\Server::get(CardDavValidatePlugin::class));
// And off we go!
$server->exec();
diff --git a/apps/dav/composer/composer/autoload_classmap.php b/apps/dav/composer/composer/autoload_classmap.php
index 5d6ad572b9c..d9c0194d52f 100644
--- a/apps/dav/composer/composer/autoload_classmap.php
+++ b/apps/dav/composer/composer/autoload_classmap.php
@@ -141,6 +141,7 @@ return array(
'OCA\\DAV\\CardDAV\\SyncService' => $baseDir . '/../lib/CardDAV/SyncService.php',
'OCA\\DAV\\CardDAV\\SystemAddressbook' => $baseDir . '/../lib/CardDAV/SystemAddressbook.php',
'OCA\\DAV\\CardDAV\\UserAddressBooks' => $baseDir . '/../lib/CardDAV/UserAddressBooks.php',
+ 'OCA\\DAV\\CardDAV\\Validation\\CardDavValidatePlugin' => $baseDir . '/../lib/CardDAV/Validation/CardDavValidatePlugin.php',
'OCA\\DAV\\CardDAV\\Xml\\Groups' => $baseDir . '/../lib/CardDAV/Xml/Groups.php',
'OCA\\DAV\\Command\\CreateAddressBook' => $baseDir . '/../lib/Command/CreateAddressBook.php',
'OCA\\DAV\\Command\\CreateCalendar' => $baseDir . '/../lib/Command/CreateCalendar.php',
diff --git a/apps/dav/composer/composer/autoload_static.php b/apps/dav/composer/composer/autoload_static.php
index 246bddbfdc7..54cc5fe0618 100644
--- a/apps/dav/composer/composer/autoload_static.php
+++ b/apps/dav/composer/composer/autoload_static.php
@@ -156,6 +156,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\CardDAV\\SyncService' => __DIR__ . '/..' . '/../lib/CardDAV/SyncService.php',
'OCA\\DAV\\CardDAV\\SystemAddressbook' => __DIR__ . '/..' . '/../lib/CardDAV/SystemAddressbook.php',
'OCA\\DAV\\CardDAV\\UserAddressBooks' => __DIR__ . '/..' . '/../lib/CardDAV/UserAddressBooks.php',
+ 'OCA\\DAV\\CardDAV\\Validation\\CardDavValidatePlugin' => __DIR__ . '/..' . '/../lib/CardDAV/Validation/CardDavValidatePlugin.php',
'OCA\\DAV\\CardDAV\\Xml\\Groups' => __DIR__ . '/..' . '/../lib/CardDAV/Xml/Groups.php',
'OCA\\DAV\\Command\\CreateAddressBook' => __DIR__ . '/..' . '/../lib/Command/CreateAddressBook.php',
'OCA\\DAV\\Command\\CreateCalendar' => __DIR__ . '/..' . '/../lib/Command/CreateCalendar.php',
diff --git a/apps/dav/lib/CardDAV/Validation/CardDavValidatePlugin.php b/apps/dav/lib/CardDAV/Validation/CardDavValidatePlugin.php
new file mode 100644
index 00000000000..635ab6fcc78
--- /dev/null
+++ b/apps/dav/lib/CardDAV/Validation/CardDavValidatePlugin.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\DAV\CardDAV\Validation;
+
+use OCA\DAV\AppInfo\Application;
+use OCP\IAppConfig;
+use Sabre\DAV\Exception\Forbidden;
+use Sabre\DAV\Server;
+use Sabre\DAV\ServerPlugin;
+use Sabre\HTTP\RequestInterface;
+use Sabre\HTTP\ResponseInterface;
+
+class CardDavValidatePlugin extends ServerPlugin {
+
+ public function __construct(
+ private IAppConfig $config
+ ) {
+ }
+
+ public function initialize(Server $server): void {
+ $server->on('beforeMethod:PUT', [$this, 'beforePut']);
+ }
+
+ public function beforePut(RequestInterface $request, ResponseInterface $response): bool {
+ // evaluate if card size exceeds defined limit
+ $cardSizeLimit = $this->config->getValueInt(Application::APP_ID, 'card_size_limit', 5242880);
+ if ((int) $request->getRawServerValue('CONTENT_LENGTH') > $cardSizeLimit) {
+ throw new Forbidden("VCard object exceeds $cardSizeLimit bytes");
+ }
+ // all tests passed return true
+ return true;
+ }
+
+}
diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php
index bec76a03236..838c6002dca 100644
--- a/apps/dav/lib/Server.php
+++ b/apps/dav/lib/Server.php
@@ -16,6 +16,7 @@ use OCA\DAV\CardDAV\ImageExportPlugin;
use OCA\DAV\CardDAV\MultiGetExportPlugin;
use OCA\DAV\CardDAV\PhotoCache;
use OCA\DAV\CardDAV\Security\CardDavRateLimitingPlugin;
+use OCA\DAV\CardDAV\Validation\CardDavValidatePlugin;
use OCA\DAV\Comments\CommentsPlugin;
use OCA\DAV\Connector\Sabre\AnonymousOptionsPlugin;
use OCA\DAV\Connector\Sabre\Auth;
@@ -181,6 +182,7 @@ class Server {
));
$this->server->addPlugin(\OCP\Server::get(CardDavRateLimitingPlugin::class));
+ $this->server->addPlugin(\OCP\Server::get(CardDavValidatePlugin::class));
}
// system tags plugins
diff --git a/apps/dav/tests/unit/CardDAV/Validation/CardDavValidatePluginTest.php b/apps/dav/tests/unit/CardDAV/Validation/CardDavValidatePluginTest.php
new file mode 100644
index 00000000000..39155aace8b
--- /dev/null
+++ b/apps/dav/tests/unit/CardDAV/Validation/CardDavValidatePluginTest.php
@@ -0,0 +1,73 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCA\DAV\Tests\unit\CardDAV\Validation;
+
+use OCA\DAV\CardDAV\Validation\CardDavValidatePlugin;
+use OCP\IAppConfig;
+use PHPUnit\Framework\MockObject\MockObject;
+use Sabre\DAV\Exception\Forbidden;
+use Sabre\HTTP\RequestInterface;
+use Sabre\HTTP\ResponseInterface;
+use Test\TestCase;
+
+class CardDavValidatePluginTest extends TestCase {
+
+ private CardDavValidatePlugin $plugin;
+ private IAppConfig|MockObject $config;
+ private RequestInterface|MockObject $request;
+ private ResponseInterface|MockObject $response;
+
+ protected function setUp(): void {
+ parent::setUp();
+ // construct mock objects
+ $this->config = $this->createMock(IAppConfig::class);
+ $this->request = $this->createMock(RequestInterface::class);
+ $this->response = $this->createMock(ResponseInterface::class);
+ $this->plugin = new CardDavValidatePlugin(
+ $this->config,
+ );
+ }
+
+ public function testPutSizeLessThenLimit(): void {
+
+ // construct method responses
+ $this->config
+ ->method('getValueInt')
+ ->with('dav', 'card_size_limit', 5242880)
+ ->willReturn(5242880);
+ $this->request
+ ->method('getRawServerValue')
+ ->with('CONTENT_LENGTH')
+ ->willReturn('1024');
+ // test condition
+ $this->assertTrue(
+ $this->plugin->beforePut($this->request, $this->response)
+ );
+
+ }
+
+ public function testPutSizeMoreThenLimit(): void {
+
+ // construct method responses
+ $this->config
+ ->method('getValueInt')
+ ->with('dav', 'card_size_limit', 5242880)
+ ->willReturn(5242880);
+ $this->request
+ ->method('getRawServerValue')
+ ->with('CONTENT_LENGTH')
+ ->willReturn('6242880');
+ $this->expectException(Forbidden::class);
+ // test condition
+ $this->plugin->beforePut($this->request, $this->response);
+
+ }
+
+}