diff --git a/typo3/sysext/frontend/Classes/Http/RequestHandler.php b/typo3/sysext/frontend/Classes/Http/RequestHandler.php index f323914befee466e4114fe212abfeb564875f8df..c7755dab753adcbefc73ede03f487e4d5758e672 100644 --- a/typo3/sysext/frontend/Classes/Http/RequestHandler.php +++ b/typo3/sysext/frontend/Classes/Http/RequestHandler.php @@ -24,7 +24,6 @@ use TYPO3\CMS\Core\Http\NullResponse; use TYPO3\CMS\Core\Http\RequestHandlerInterface; use TYPO3\CMS\Core\Http\Response; use TYPO3\CMS\Core\TimeTracker\TimeTracker; -use TYPO3\CMS\Core\Type\Bitmask\Permission; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; use TYPO3\CMS\Frontend\Page\PageGenerator; @@ -70,29 +69,6 @@ class RequestHandler implements RequestHandlerInterface, PsrRequestHandlerInterf /** @var TypoScriptFrontendController $controller */ $controller = $GLOBALS['TSFE']; - // Process the ID, type and other parameters. - // After this point we have an array, $page in TSFE, which is the page-record - // of the current page, $id. - $this->timeTracker->push('Process ID', ''); - $controller->checkAlternativeIdMethods(); - $controller->clear_preview(); - $controller->determineId(); - - // Now, if there is a backend user logged in and he has NO access to this page, - // then re-evaluate the id shown!. - if ($controller->isBackendUserLoggedIn() && !$GLOBALS['BE_USER']->doesUserHaveAccess($controller->page, Permission::PAGE_SHOW)) { - // Remove user - unset($GLOBALS['BE_USER']); - $controller->beUserLogin = false; - // Re-evaluate the page-id. - $controller->checkAlternativeIdMethods(); - $controller->clear_preview(); - $controller->determineId(); - } - - $controller->makeCacheHash(); - $this->timeTracker->pull(); - // Admin Panel & Frontend editing if ($controller->isBackendUserLoggedIn()) { $GLOBALS['BE_USER']->initializeFrontendEdit(); diff --git a/typo3/sysext/frontend/Classes/Middleware/PageResolver.php b/typo3/sysext/frontend/Classes/Middleware/PageResolver.php new file mode 100644 index 0000000000000000000000000000000000000000..1ed9c1c13b5e2c699a44f41dc13edbbe634e3c12 --- /dev/null +++ b/typo3/sysext/frontend/Classes/Middleware/PageResolver.php @@ -0,0 +1,79 @@ +<?php +declare(strict_types = 1); +namespace TYPO3\CMS\Frontend\Middleware; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Server\MiddlewareInterface; +use Psr\Http\Server\RequestHandlerInterface; +use TYPO3\CMS\Core\Type\Bitmask\Permission; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; + +/** + * Process the ID, type and other parameters. + * After this point we have an array, TSFE->page, which is the page-record of the current page, $TSFE->id. + * + * Now, if there is a backend user logged in and he has NO access to this page, + * then re-evaluate the id shown! + */ +class PageResolver implements MiddlewareInterface +{ + /** + * Resolve the page ID + * + * @param ServerRequestInterface $request + * @param RequestHandlerInterface $handler + * @return ResponseInterface + */ + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface + { + $GLOBALS['TSFE']->siteScript = $request->getAttribute('normalizedParams')->getSiteScript(); + $this->checkAlternativeIdMethods($GLOBALS['TSFE']); + $GLOBALS['TSFE']->clear_preview(); + $GLOBALS['TSFE']->determineId(); + + // No access? Then remove user & Re-evaluate the page-id + if ($GLOBALS['TSFE']->isBackendUserLoggedIn() && !$GLOBALS['BE_USER']->doesUserHaveAccess($GLOBALS['TSFE']->page, Permission::PAGE_SHOW)) { + unset($GLOBALS['BE_USER']); + $GLOBALS['TSFE']->beUserLogin = false; + $this->checkAlternativeIdMethods($GLOBALS['TSFE']); + $GLOBALS['TSFE']->clear_preview(); + $GLOBALS['TSFE']->determineId(); + } + + // Evaluate the cache hash parameter + $GLOBALS['TSFE']->makeCacheHash(); + + return $handler->handle($request); + } + + /** + * Provides ways to bypass the '?id=[xxx]&type=[xx]' format, using either PATH_INFO or Server Rewrites + * + * Two options: + * 1) Use PATH_INFO (also Apache) to extract id and type from that var. Does not require any special modules compiled with apache. (less typical) + * 2) Using hook which enables features like those provided from "realurl" extension (AKA "Speaking URLs") + */ + protected function checkAlternativeIdMethods(TypoScriptFrontendController $tsfe) + { + // Call post processing function for custom URL methods. + $_params = ['pObj' => &$tsfe]; + foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['checkAlternativeIdMethods-PostProc'] ?? [] as $_funcRef) { + GeneralUtility::callUserFunction($_funcRef, $_params, $tsfe); + } + } +} diff --git a/typo3/sysext/frontend/Configuration/RequestMiddlewares.php b/typo3/sysext/frontend/Configuration/RequestMiddlewares.php index d7fb8ca439ea4fad803967644aec7ca7140bbdef..f5367b67e5c33cbdec5219a6f718acdf1a566d7c 100644 --- a/typo3/sysext/frontend/Configuration/RequestMiddlewares.php +++ b/typo3/sysext/frontend/Configuration/RequestMiddlewares.php @@ -69,5 +69,13 @@ return [ 'typo3/cms-frontend/tsfe', ] ], + 'typo3/cms-frontend/page-resolver' => [ + 'target' => \TYPO3\CMS\Frontend\Middleware\PageResolver::class, + 'after' => [ + 'typo3/cms-frontend/tsfe', + 'typo3/cms-frontend/authentication', + 'typo3/cms-frontend/backend-user-authentication', + ] + ], ] ];