From: Tim Düsterhus Date: Fri, 20 May 2022 07:49:02 +0000 (+0200) Subject: Add `CheckForOfflineMode` middleware X-Git-Tag: 6.0.0_Alpha_1~1266^2~2 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=7633d48b8010e6f1dd7b84cd90d01da40d5dba2c;p=GitHub%2FWoltLab%2FWCF.git Add `CheckForOfflineMode` middleware --- diff --git a/wcfsetup/install/files/lib/http/middleware/CheckForOfflineMode.class.php b/wcfsetup/install/files/lib/http/middleware/CheckForOfflineMode.class.php new file mode 100644 index 0000000000..47ef960891 --- /dev/null +++ b/wcfsetup/install/files/lib/http/middleware/CheckForOfflineMode.class.php @@ -0,0 +1,87 @@ + + * @package WoltLabSuite\Core\Http\Middleware + * @since 5.6 + */ +final class CheckForOfflineMode implements MiddlewareInterface +{ + /** + * @inheritDoc + */ + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface + { + if ( + !$this->offlineModeEnabled() + || RequestHandler::getInstance()->isACPRequest() + || $this->userCanBypassOfflineMode() + ) { + return $handler->handle($request); + } + + if (RequestHandler::getInstance()->getActiveRequest()->isAvailableDuringOfflineMode()) { + return $handler->handle($request); + } + + return HeaderUtil::withNoCacheHeaders($this->getOfflineResponse($request)); + } + + private function getOfflineResponse(ServerRequestInterface $request): ResponseInterface + { + if ($this->isAjaxRequest($request)) { + throw new AJAXException( + WCF::getLanguage()->getDynamicVariable('wcf.ajax.error.permissionDenied'), + AJAXException::INSUFFICIENT_PERMISSIONS + ); + } else { + BoxHandler::disablePageLayout(); + NoticeHandler::disableNotices(); + + return new HtmlResponse( + WCF::getTPL()->fetchStream( + 'offline', + 'wcf', + [ + 'templateName' => 'offline', + 'templateNameApplication' => 'wcf', + ] + ), + 503 + ); + } + } + + private function offlineModeEnabled(): bool + { + return \defined('OFFLINE') && OFFLINE; + } + + private function userCanBypassOfflineMode(): bool + { + return WCF::getSession()->getPermission('admin.general.canViewPageDuringOfflineMode'); + } + + private function isAjaxRequest(ServerRequestInterface $request): bool + { + return $request->getHeaderLine('x-requested-with') === 'XMLHttpRequest'; + } +} diff --git a/wcfsetup/install/files/lib/system/request/RequestHandler.class.php b/wcfsetup/install/files/lib/system/request/RequestHandler.class.php index 819dd3c6bf..b426b354e8 100644 --- a/wcfsetup/install/files/lib/system/request/RequestHandler.class.php +++ b/wcfsetup/install/files/lib/system/request/RequestHandler.class.php @@ -6,16 +6,15 @@ use Laminas\Diactoros\ServerRequestFactory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; use wcf\http\LegacyPlaceholderResponse; use wcf\http\middleware\AddAcpSecurityHeaders; +use wcf\http\middleware\CheckForOfflineMode; use wcf\http\middleware\EnforceCacheControlPrivate; use wcf\http\middleware\EnforceFrameOptions; use wcf\http\Pipeline; use wcf\system\application\ApplicationHandler; -use wcf\system\box\BoxHandler; use wcf\system\exception\AJAXException; use wcf\system\exception\IllegalLinkException; use wcf\system\exception\NamedUserException; use wcf\system\exception\SystemException; -use wcf\system\notice\NoticeHandler; use wcf\system\SingletonFactory; use wcf\system\WCF; use wcf\util\FileUtil; @@ -97,12 +96,11 @@ class RequestHandler extends SingletonFactory $this->checkAppEvaluation(); - $this->checkOfflineMode(); - $pipeline = new Pipeline([ new AddAcpSecurityHeaders(), new EnforceCacheControlPrivate(), new EnforceFrameOptions(), + new CheckForOfflineMode(), ]); $response = $pipeline->process($psrRequest, $this->getActiveRequest()); @@ -251,40 +249,6 @@ class RequestHandler extends SingletonFactory } } - /** - * @since 5.5 - */ - private function checkOfflineMode() - { - if (!$this->isACPRequest() && \defined('OFFLINE') && OFFLINE) { - if ( - !WCF::getSession()->getPermission('admin.general.canViewPageDuringOfflineMode') - && !$this->getActiveRequest()->isAvailableDuringOfflineMode() - ) { - if ( - isset($_SERVER['HTTP_X_REQUESTED_WITH']) - && ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') - ) { - throw new AJAXException( - WCF::getLanguage()->getDynamicVariable('wcf.ajax.error.permissionDenied'), - AJAXException::INSUFFICIENT_PERMISSIONS - ); - } else { - @\header('HTTP/1.1 503 Service Unavailable'); - BoxHandler::disablePageLayout(); - NoticeHandler::disableNotices(); - WCF::getTPL()->assign([ - 'templateName' => 'offline', - 'templateNameApplication' => 'wcf', - ]); - WCF::getTPL()->display('offline'); - } - - exit; - } - } - } - /** * @since 5.5 */