From 5ebc101fd56ae7b26b439dfabee8e64b4e4d27d9 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov Date: Fri, 17 Sep 2021 14:10:06 -0400 Subject: [PATCH] Add `config.php` option not to boot extensions Part of https://github.com/flarum/core/issues/2911 If the `boot_extensions` key is set to false, core will not boot any extensions in the backend, or run any initializers in the frontend. This allows admins to recover their forum without SSH access by disabling extension boot, going to the admin panel, and turning off offending extensions. **Questions/Concerns for Reviewers**: - Should we somehow signal to admins that this mode is enabled, possibly via alert? Otherwise, it might be confusing why extensions are indicated as enabled in the admin dashboard. This is challenging, as the alerts we currently have are in `content.blade.php`, and that view does not have access to payload/config. - Should this require maintenance mode? If we disable all extensions (e.g. tags), some restricted discussions / content will immediately become public. This could lead to leaks via web scraping. --- js/src/common/Application.js | 4 +++- src/Api/Serializer/ForumSerializer.php | 1 + src/Extension/ExtensionServiceProvider.php | 8 +++++++- src/Foundation/Config.php | 5 +++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/js/src/common/Application.js b/js/src/common/Application.js index 65592ad08..bc581cbe0 100644 --- a/js/src/common/Application.js +++ b/js/src/common/Application.js @@ -168,7 +168,9 @@ export default class Application { } boot() { - this.initializers.toArray().forEach((initializer) => initializer(this)); + if (this.data.attributes.bootExtensions) { + this.initializers.toArray().forEach((initializer) => initializer(this)); + } this.store.pushPayload({ data: this.data.resources }); diff --git a/src/Api/Serializer/ForumSerializer.php b/src/Api/Serializer/ForumSerializer.php index a0124fd52..888df743f 100644 --- a/src/Api/Serializer/ForumSerializer.php +++ b/src/Api/Serializer/ForumSerializer.php @@ -77,6 +77,7 @@ class ForumSerializer extends AbstractSerializer 'baseUrl' => $url = $this->url->to('forum')->base(), 'basePath' => parse_url($url, PHP_URL_PATH) ?: '', 'debug' => $this->config->inDebugMode(), + 'bootExtensions' => $this->config->bootExtensions(), 'apiUrl' => $this->url->to('api')->base(), 'welcomeTitle' => $this->settings->get('welcome_title'), 'welcomeMessage' => $this->settings->get('welcome_message'), diff --git a/src/Extension/ExtensionServiceProvider.php b/src/Extension/ExtensionServiceProvider.php index 648b0285e..ea99588ce 100644 --- a/src/Extension/ExtensionServiceProvider.php +++ b/src/Extension/ExtensionServiceProvider.php @@ -11,6 +11,7 @@ namespace Flarum\Extension; use Flarum\Extension\Event\Disabling; use Flarum\Foundation\AbstractServiceProvider; +use Flarum\Foundation\Config; use Illuminate\Contracts\Events\Dispatcher; class ExtensionServiceProvider extends AbstractServiceProvider @@ -28,7 +29,12 @@ class ExtensionServiceProvider extends AbstractServiceProvider // below, so that extensions have a chance to register things on the // container before the core boots up (and starts resolving services). $this->container['flarum']->booting(function () { - $this->container->make('flarum.extensions')->extend($this->container); + /** @var Config */ + $config = $this->container->make(Config::class); + + if ($config->bootExtensions()) { + $this->container->make('flarum.extensions')->extend($this->container); + } }); } diff --git a/src/Foundation/Config.php b/src/Foundation/Config.php index e540bedfa..30466d95c 100644 --- a/src/Foundation/Config.php +++ b/src/Foundation/Config.php @@ -41,6 +41,11 @@ class Config implements ArrayAccess { return $this->data['offline'] ?? false; } + + public function bootExtensions(): bool + { + return $this->data['boot_extensions'] ?? true; + } private function requireKeys(...$keys) {