From 91f13cd6f47b72ab169218f7af104998107258be Mon Sep 17 00:00:00 2001 From: Avinash Gusain Date: Tue, 28 Jan 2025 17:30:14 +0530 Subject: [PATCH 01/11] added check plugin --- lib/Dav/CheckPlugin.php | 92 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 lib/Dav/CheckPlugin.php diff --git a/lib/Dav/CheckPlugin.php b/lib/Dav/CheckPlugin.php new file mode 100644 index 00000000..d13b34d3 --- /dev/null +++ b/lib/Dav/CheckPlugin.php @@ -0,0 +1,92 @@ +server = $server; + + $server->on('method:PROPFIND', [$this, 'blockNextcloudClients']); + $server->on('method:PROPPATCH', [$this, 'blockNextcloudClients']); + $server->on('method:GET', [$this, 'blockNextcloudClients']); + $server->on('method:POST', [$this, 'blockNextcloudClients']); + $server->on('method:PUT', [$this, 'blockNextcloudClients']); + $server->on('method:DELETE', [$this, 'blockNextcloudClients']); + $server->on('method:MKCOL', [$this, 'blockNextcloudClients']); + $server->on('method:MOVE', [$this, 'blockNextcloudClients']); + $server->on('method:COPY', [$this, 'blockNextcloudClients']); + $server->on('method:REPORT', [$this, 'blockNextcloudClients']); + } + + /** + * Block requests from Nextcloud clients based on User-Agent + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return bool + * @throws Forbidden + */ + public function blockNextcloudClients(RequestInterface $request, ResponseInterface $response): bool { + $userAgent = $request->getHeader('User-Agent'); + + if (!$userAgent) { + throw new Forbidden('Missing User-Agent header.'); + } + + // Check if the User-Agent matches any of the blocked patterns + foreach ($this->blockedUserAgents as $pattern) { + if (preg_match($pattern, $userAgent)) { + throw new Forbidden('Access from Nextcloud clients is blocked.'); + } + } + + return true; // Allow other clients + } + + /** + * Returns a plugin name. + * + * @return string + */ + public function getPluginName(): string { + return Application::APPNAME; + } + + /** + * Returns a bunch of meta-data about the plugin. + * + * @return array + */ + public function getPluginInfo(): array { + return [ + 'name' => $this->getPluginName(), + 'description' => 'Block requests from Nextcloud clients based on User-Agent headers.', + ]; + } +} -- GitLab From ab893dab76cf44f23979043188bc39956cee8a11 Mon Sep 17 00:00:00 2001 From: Avinash Gusain Date: Tue, 28 Jan 2025 17:45:24 +0530 Subject: [PATCH 02/11] added check plugin --- lib/AppInfo/Application.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 1beceac8..11b253ed 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -48,6 +48,7 @@ use OCP\User\Events\PasswordUpdatedEvent; use OCP\User\Events\UserChangedEvent; use OCP\Util; + class Application extends App implements IBootstrap { public const APP_ID = 'ecloud-accounts'; @@ -57,6 +58,19 @@ class Application extends App implements IBootstrap { public function register(IRegistrationContext $context): void { Util::connectHook('OC_Filesystem', 'preSetup', $this, 'addStorageWrapper'); + // Get the event dispatcher service + $eventDispatcher = $context->getServerContainer()->get(IEventDispatcher::class); + + // Add a listener for the 'OCA\DAV\Connector\Sabre::addPlugin' event + $eventDispatcher->addListener('OCA\DAV\Connector\Sabre::addPlugin', function (SabrePluginEvent $event) use ($context) { + $eventServer = $event->getServer(); + + if ($eventServer !== null) { + // Register the CheckPlugin + $plugin = $context->getAppContainer()->get(CheckPlugin::class); + $eventServer->addPlugin($plugin); + } + }); $context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class); $context->registerEventListener(BeforeUserDeletedEvent::class, BeforeUserDeletedListener::class); $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); -- GitLab From cd5d5f2e87fb72ba839db5fbd454fa17de2ebd13 Mon Sep 17 00:00:00 2001 From: Avinash Gusain Date: Tue, 28 Jan 2025 19:06:41 +0530 Subject: [PATCH 03/11] fix Application --- lib/AppInfo/Application.php | 22 +++++++++++----------- lib/Dav/CheckPlugin.php | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 11b253ed..f94280ac 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -41,6 +41,7 @@ use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent; +use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\Storage\IStorage; use OCP\IUserManager; use OCP\User\Events\BeforeUserDeletedEvent; @@ -48,7 +49,6 @@ use OCP\User\Events\PasswordUpdatedEvent; use OCP\User\Events\UserChangedEvent; use OCP\Util; - class Application extends App implements IBootstrap { public const APP_ID = 'ecloud-accounts'; @@ -58,6 +58,16 @@ class Application extends App implements IBootstrap { public function register(IRegistrationContext $context): void { Util::connectHook('OC_Filesystem', 'preSetup', $this, 'addStorageWrapper'); + $context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class); + $context->registerEventListener(BeforeUserDeletedEvent::class, BeforeUserDeletedListener::class); + $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); + $context->registerEventListener(StateChanged::class, TwoFactorStateChangedListener::class); + $context->registerEventListener(PasswordUpdatedEvent::class, PasswordUpdatedListener::class); + + $context->registerMiddleware(AccountMiddleware::class); + } + + public function boot(IBootContext $context): void { // Get the event dispatcher service $eventDispatcher = $context->getServerContainer()->get(IEventDispatcher::class); @@ -71,16 +81,6 @@ class Application extends App implements IBootstrap { $eventServer->addPlugin($plugin); } }); - $context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class); - $context->registerEventListener(BeforeUserDeletedEvent::class, BeforeUserDeletedListener::class); - $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); - $context->registerEventListener(StateChanged::class, TwoFactorStateChangedListener::class); - $context->registerEventListener(PasswordUpdatedEvent::class, PasswordUpdatedListener::class); - - $context->registerMiddleware(AccountMiddleware::class); - } - - public function boot(IBootContext $context): void { $serverContainer = $context->getServerContainer(); $serverContainer->registerService('LDAPConnectionService', function ($c) { return new LDAPConnectionService( diff --git a/lib/Dav/CheckPlugin.php b/lib/Dav/CheckPlugin.php index d13b34d3..ca292837 100644 --- a/lib/Dav/CheckPlugin.php +++ b/lib/Dav/CheckPlugin.php @@ -4,7 +4,7 @@ declare(strict_types=1); namespace OCA\EcloudAccounts\Dav; -use OCA\TermsOfService\AppInfo\Application; +use OCA\EcloudAccounts\AppInfo\Application; use Sabre\DAV\Exception\Forbidden; use Sabre\DAV\Server; use Sabre\DAV\ServerPlugin; -- GitLab From 4e0a79ff02eb1b492f25ff90997bc479a4243f57 Mon Sep 17 00:00:00 2001 From: Avinash Gusain Date: Tue, 28 Jan 2025 19:22:03 +0530 Subject: [PATCH 04/11] nextcloud client blocked --- lib/Dav/CheckPlugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Dav/CheckPlugin.php b/lib/Dav/CheckPlugin.php index ca292837..f03801f6 100644 --- a/lib/Dav/CheckPlugin.php +++ b/lib/Dav/CheckPlugin.php @@ -75,7 +75,7 @@ class CheckPlugin extends ServerPlugin { * @return string */ public function getPluginName(): string { - return Application::APPNAME; + return Application::APP_ID; } /** -- GitLab From fa6b1b92c287d3e20240a9ea46759bee77d57901 Mon Sep 17 00:00:00 2001 From: Avinash Gusain Date: Tue, 28 Jan 2025 19:23:36 +0530 Subject: [PATCH 05/11] nextcloud client blocked --- lib/AppInfo/Application.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index f94280ac..42b6b667 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -27,6 +27,7 @@ declare(strict_types=1); namespace OCA\EcloudAccounts\AppInfo; use OC\Files\Filesystem; +use OCA\EcloudAccounts\Dav\CheckPlugin; use OCA\EcloudAccounts\Filesystem\StorageWrapper; use OCA\EcloudAccounts\Listeners\BeforeTemplateRenderedListener; use OCA\EcloudAccounts\Listeners\BeforeUserDeletedListener; @@ -44,6 +45,7 @@ use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\Storage\IStorage; use OCP\IUserManager; +use OCP\SabrePluginEvent; use OCP\User\Events\BeforeUserDeletedEvent; use OCP\User\Events\PasswordUpdatedEvent; use OCP\User\Events\UserChangedEvent; -- GitLab From 8b50104b18757da5873cb7da5f3b2535d9ce0a66 Mon Sep 17 00:00:00 2001 From: Avinash Gusain Date: Tue, 28 Jan 2025 19:29:00 +0530 Subject: [PATCH 06/11] nextcloud info.xml to add dav type --- appinfo/info.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/appinfo/info.xml b/appinfo/info.xml index daef390d..7c1305a2 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -14,6 +14,9 @@ agpl Murena SAS EcloudAccounts + + + tools https://gitlab.e.foundation/e/management/issues -- GitLab From 21447c6dab2afdf1bb00dc874a2390a39bc355ea Mon Sep 17 00:00:00 2001 From: Avinash Gusain Date: Wed, 29 Jan 2025 14:00:41 +0530 Subject: [PATCH 07/11] removed protected --- lib/Dav/CheckPlugin.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Dav/CheckPlugin.php b/lib/Dav/CheckPlugin.php index f03801f6..772e0201 100644 --- a/lib/Dav/CheckPlugin.php +++ b/lib/Dav/CheckPlugin.php @@ -14,10 +14,10 @@ use Sabre\HTTP\ResponseInterface; class CheckPlugin extends ServerPlugin { /** @var Server */ - protected $server; + private $server; /** @var array */ - protected $blockedUserAgents = [ + private $blockedUserAgents = [ '/^Mozilla\/5\.0 \(.*\) mirall\/.*$/', // Nextcloud desktop clients '/^Mozilla\/5\.0 \(Android\) Nextcloud\-android\/.*$/', // Nextcloud Android clients '/^Mozilla\/5\.0 \(iOS\) Nextcloud\-iOS\/.*$/', // Nextcloud iOS clients -- GitLab From 09dbe23c175e52102401447de73a99ce4a8fe630 Mon Sep 17 00:00:00 2001 From: Avinash Gusain Date: Wed, 29 Jan 2025 14:01:38 +0530 Subject: [PATCH 08/11] applied suggestion --- lib/AppInfo/Application.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 42b6b667..682be46f 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -70,7 +70,6 @@ class Application extends App implements IBootstrap { } public function boot(IBootContext $context): void { - // Get the event dispatcher service $eventDispatcher = $context->getServerContainer()->get(IEventDispatcher::class); // Add a listener for the 'OCA\DAV\Connector\Sabre::addPlugin' event -- GitLab From de923d8dd5bbc6e86080b3a7ea7b0c903fc3c15d Mon Sep 17 00:00:00 2001 From: Avinash Gusain Date: Wed, 29 Jan 2025 14:40:16 +0530 Subject: [PATCH 09/11] code refactoring --- lib/AppInfo/Application.php | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 682be46f..53af2ea3 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -71,17 +71,7 @@ class Application extends App implements IBootstrap { public function boot(IBootContext $context): void { $eventDispatcher = $context->getServerContainer()->get(IEventDispatcher::class); - - // Add a listener for the 'OCA\DAV\Connector\Sabre::addPlugin' event - $eventDispatcher->addListener('OCA\DAV\Connector\Sabre::addPlugin', function (SabrePluginEvent $event) use ($context) { - $eventServer = $event->getServer(); - - if ($eventServer !== null) { - // Register the CheckPlugin - $plugin = $context->getAppContainer()->get(CheckPlugin::class); - $eventServer->addPlugin($plugin); - } - }); + $eventDispatcher->addListener('OCA\DAV\Connector\Sabre::addPlugin', [$this, 'registerDavPlugin']); $serverContainer = $context->getServerContainer(); $serverContainer->registerService('LDAPConnectionService', function ($c) { return new LDAPConnectionService( @@ -90,6 +80,18 @@ class Application extends App implements IBootstrap { }); } + /** + * Registers the CheckPlugin for DAV integration + */ + public function registerDavPlugin(SabrePluginEvent $event): void { + $eventServer = $event->getServer(); + + if ($eventServer !== null) { + $plugin = $this->getContainer()->get(CheckPlugin::class); + $eventServer->addPlugin($plugin); + } + } + /** * @internal */ -- GitLab From 30926b4da858b4c8f54c0aca1e92793dfd2123f3 Mon Sep 17 00:00:00 2001 From: Avinash Gusain Date: Wed, 29 Jan 2025 16:26:47 +0530 Subject: [PATCH 10/11] commented filewrapper --- lib/AppInfo/Application.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 53af2ea3..25e3d41c 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -59,7 +59,7 @@ class Application extends App implements IBootstrap { } public function register(IRegistrationContext $context): void { - Util::connectHook('OC_Filesystem', 'preSetup', $this, 'addStorageWrapper'); + // Util::connectHook('OC_Filesystem', 'preSetup', $this, 'addStorageWrapper'); $context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class); $context->registerEventListener(BeforeUserDeletedEvent::class, BeforeUserDeletedListener::class); $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); -- GitLab From 499346e592f09c79c60304693032a3e11ef03cf1 Mon Sep 17 00:00:00 2001 From: Avinash Gusain Date: Wed, 29 Jan 2025 18:50:48 +0530 Subject: [PATCH 11/11] remove comment --- lib/AppInfo/Application.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 25e3d41c..53af2ea3 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -59,7 +59,7 @@ class Application extends App implements IBootstrap { } public function register(IRegistrationContext $context): void { - // Util::connectHook('OC_Filesystem', 'preSetup', $this, 'addStorageWrapper'); + Util::connectHook('OC_Filesystem', 'preSetup', $this, 'addStorageWrapper'); $context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class); $context->registerEventListener(BeforeUserDeletedEvent::class, BeforeUserDeletedListener::class); $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); -- GitLab