diff --git a/src/Admin/AdminServiceProvider.php b/src/Admin/AdminServiceProvider.php index 05a9a2048..f9a9c6f7c 100644 --- a/src/Admin/AdminServiceProvider.php +++ b/src/Admin/AdminServiceProvider.php @@ -49,7 +49,19 @@ class AdminServiceProvider extends AbstractServiceProvider return $routes; }); - $this->app->singleton('flarum.admin.middleware', function (Application $app) { + $this->app->singleton('flarum.admin.middleware', function () { + return [ + HttpMiddleware\ParseJsonBody::class, + HttpMiddleware\StartSession::class, + HttpMiddleware\RememberFromCookie::class, + HttpMiddleware\AuthenticateWithSession::class, + HttpMiddleware\CheckCsrfToken::class, + HttpMiddleware\SetLocale::class, + Middleware\RequireAdministrateAbility::class, + ]; + }); + + $this->app->singleton('flarum.admin.handler', function (Application $app) { $pipe = new MiddlewarePipe; // All requests should first be piped through our global error handler @@ -59,21 +71,15 @@ class AdminServiceProvider extends AbstractServiceProvider $app->tagged(Reporter::class) )); - $pipe->pipe($app->make(HttpMiddleware\ParseJsonBody::class)); - $pipe->pipe($app->make(HttpMiddleware\StartSession::class)); - $pipe->pipe($app->make(HttpMiddleware\RememberFromCookie::class)); - $pipe->pipe($app->make(HttpMiddleware\AuthenticateWithSession::class)); - $pipe->pipe($app->make(HttpMiddleware\CheckCsrfToken::class)); - $pipe->pipe($app->make(HttpMiddleware\SetLocale::class)); - $pipe->pipe($app->make(Middleware\RequireAdministrateAbility::class)); + foreach ($this->app->make('flarum.admin.middleware') as $middleware) { + $pipe->pipe($this->app->make($middleware)); + } event(new ConfigureMiddleware($pipe, 'admin')); - return $pipe; - }); - - $this->app->afterResolving('flarum.admin.middleware', function (MiddlewarePipe $pipe) { $pipe->pipe(new HttpMiddleware\DispatchRoute($this->app->make('flarum.admin.routes'))); + + return $pipe; }); $this->app->bind('flarum.assets.admin', function () { diff --git a/src/Api/ApiServiceProvider.php b/src/Api/ApiServiceProvider.php index e8eacc7d4..398a037ff 100644 --- a/src/Api/ApiServiceProvider.php +++ b/src/Api/ApiServiceProvider.php @@ -45,7 +45,20 @@ class ApiServiceProvider extends AbstractServiceProvider return $routes; }); - $this->app->singleton('flarum.api.middleware', function (Application $app) { + $this->app->singleton('flarum.api.middleware', function () { + return [ + HttpMiddleware\ParseJsonBody::class, + Middleware\FakeHttpMethods::class, + HttpMiddleware\StartSession::class, + HttpMiddleware\RememberFromCookie::class, + HttpMiddleware\AuthenticateWithSession::class, + HttpMiddleware\AuthenticateWithHeader::class, + HttpMiddleware\CheckCsrfToken::class, + HttpMiddleware\SetLocale::class, + ]; + }); + + $this->app->singleton('flarum.api.handler', function (Application $app) { $pipe = new MiddlewarePipe; $pipe->pipe(new HttpMiddleware\HandleErrors( @@ -54,22 +67,15 @@ class ApiServiceProvider extends AbstractServiceProvider $app->tagged(Reporter::class) )); - $pipe->pipe($app->make(HttpMiddleware\ParseJsonBody::class)); - $pipe->pipe($app->make(Middleware\FakeHttpMethods::class)); - $pipe->pipe($app->make(HttpMiddleware\StartSession::class)); - $pipe->pipe($app->make(HttpMiddleware\RememberFromCookie::class)); - $pipe->pipe($app->make(HttpMiddleware\AuthenticateWithSession::class)); - $pipe->pipe($app->make(HttpMiddleware\AuthenticateWithHeader::class)); - $pipe->pipe($app->make(HttpMiddleware\CheckCsrfToken::class)); - $pipe->pipe($app->make(HttpMiddleware\SetLocale::class)); + foreach ($this->app->make('flarum.api.middleware') as $middleware) { + $pipe->pipe($this->app->make($middleware)); + } event(new ConfigureMiddleware($pipe, 'api')); - return $pipe; - }); - - $this->app->afterResolving('flarum.api.middleware', function (MiddlewarePipe $pipe) { $pipe->pipe(new HttpMiddleware\DispatchRoute($this->app->make('flarum.api.routes'))); + + return $pipe; }); } diff --git a/src/Extend/Middleware.php b/src/Extend/Middleware.php index 7f003a5bb..b6058ecf0 100644 --- a/src/Extend/Middleware.php +++ b/src/Extend/Middleware.php @@ -11,11 +11,14 @@ namespace Flarum\Extend; use Flarum\Extension\Extension; use Illuminate\Contracts\Container\Container; -use Laminas\Stratigility\MiddlewarePipe; class Middleware implements ExtenderInterface { - protected $middlewares = []; + protected $addMiddlewares = []; + protected $removeMiddlewares = []; + protected $replaceMiddlewares = []; + protected $insertBeforeMiddlewares = []; + protected $insertAfterMiddlewares = []; protected $frontend; public function __construct(string $frontend) @@ -25,17 +28,74 @@ class Middleware implements ExtenderInterface public function add($middleware) { - $this->middlewares[] = $middleware; + $this->addMiddlewares[] = $middleware; + + return $this; + } + + public function replace($originalMiddleware, $newMiddleware) + { + $this->replaceMiddlewares[$originalMiddleware] = $newMiddleware; + + return $this; + } + + public function remove($middleware) + { + $this->removeMiddlewares[] = $middleware; + + return $this; + } + + public function insertBefore($originalMiddleware, $newMiddleware) + { + $this->replaceMiddlewares[$originalMiddleware] = $newMiddleware; + + return $this; + } + + public function insertAfter($originalMiddleware, $newMiddleware) + { + $this->replaceMiddlewares[$originalMiddleware] = $newMiddleware; return $this; } public function extend(Container $container, Extension $extension = null) { - $container->resolving("flarum.{$this->frontend}.middleware", function (MiddlewarePipe $pipe) use ($container) { - foreach ($this->middlewares as $middleware) { - $pipe->pipe($container->make($middleware)); + $container->extend("flarum.{$this->frontend}.middleware", function ($existingMiddleware) { + foreach ($this->addMiddlewares as $addMiddleware) { + $existingMiddleware[] = $addMiddleware; } + + foreach ($this->replaceMiddlewares as $originalMiddleware => $newMiddleware) { + $existingMiddleware = array_replace($existingMiddleware, + array_fill_keys( + array_keys($existingMiddleware, $originalMiddleware), + $newMiddleware + ) + ); + } + + foreach ($this->insertBeforeMiddlewares as $originalMiddleware => $newMiddleware) { + array_splice($existingMiddleware, + array_search($originalMiddleware, $existingMiddleware), + 0, + $newMiddleware + ); + } + + foreach ($this->insertAfterMiddlewares as $originalMiddleware => $newMiddleware) { + array_splice($existingMiddleware, + array_search($originalMiddleware, $existingMiddleware) + 1, + 0, + $newMiddleware + ); + } + + $existingMiddleware = array_diff($existingMiddleware, $this->removeMiddlewares); + + return $existingMiddleware; }); } } diff --git a/src/Forum/ForumServiceProvider.php b/src/Forum/ForumServiceProvider.php index 0c2865eaf..7e4061a17 100644 --- a/src/Forum/ForumServiceProvider.php +++ b/src/Forum/ForumServiceProvider.php @@ -59,7 +59,20 @@ class ForumServiceProvider extends AbstractServiceProvider $this->setDefaultRoute($routes); }); - $this->app->singleton('flarum.forum.middleware', function (Application $app) { + $this->app->singleton('flarum.forum.middleware', function () { + return [ + HttpMiddleware\ParseJsonBody::class, + HttpMiddleware\CollectGarbage::class, + HttpMiddleware\StartSession::class, + HttpMiddleware\RememberFromCookie::class, + HttpMiddleware\AuthenticateWithSession::class, + HttpMiddleware\CheckCsrfToken::class, + HttpMiddleware\SetLocale::class, + HttpMiddleware\ShareErrorsFromSession::class + ]; + }); + + $this->app->singleton('flarum.forum.handler', function (Application $app) { $pipe = new MiddlewarePipe; // All requests should first be piped through our global error handler @@ -69,22 +82,15 @@ class ForumServiceProvider extends AbstractServiceProvider $app->tagged(Reporter::class) )); - $pipe->pipe($app->make(HttpMiddleware\ParseJsonBody::class)); - $pipe->pipe($app->make(HttpMiddleware\CollectGarbage::class)); - $pipe->pipe($app->make(HttpMiddleware\StartSession::class)); - $pipe->pipe($app->make(HttpMiddleware\RememberFromCookie::class)); - $pipe->pipe($app->make(HttpMiddleware\AuthenticateWithSession::class)); - $pipe->pipe($app->make(HttpMiddleware\CheckCsrfToken::class)); - $pipe->pipe($app->make(HttpMiddleware\SetLocale::class)); - $pipe->pipe($app->make(HttpMiddleware\ShareErrorsFromSession::class)); + foreach ($this->app->make('flarum.forum.middleware') as $middleware) { + $pipe->pipe($this->app->make($middleware)); + } event(new ConfigureMiddleware($pipe, 'forum')); - return $pipe; - }); - - $this->app->afterResolving('flarum.forum.middleware', function (MiddlewarePipe $pipe) { $pipe->pipe(new HttpMiddleware\DispatchRoute($this->app->make('flarum.forum.routes'))); + + return $pipe; }); $this->app->bind('flarum.assets.forum', function () { diff --git a/src/Foundation/InstalledApp.php b/src/Foundation/InstalledApp.php index 7707a5981..f7c4e959d 100644 --- a/src/Foundation/InstalledApp.php +++ b/src/Foundation/InstalledApp.php @@ -63,9 +63,9 @@ class InstalledApp implements AppInterface $pipe->pipe(new OriginalMessages); $pipe->pipe( new BasePathRouter([ - $this->subPath('api') => 'flarum.api.middleware', - $this->subPath('admin') => 'flarum.admin.middleware', - '/' => 'flarum.forum.middleware', + $this->subPath('api') => 'flarum.api.handler', + $this->subPath('admin') => 'flarum.admin.handler', + '/' => 'flarum.forum.handler', ]) ); $pipe->pipe(new RequestHandler($this->container));