‪TYPO3CMS  9.5
RequestHandler.php
Go to the documentation of this file.
1 <?php
2 declare(strict_types = 1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
18 use Psr\Http\Message\ResponseInterface;
19 use Psr\Http\Message\ServerRequestInterface;
20 use Psr\Http\Server\RequestHandlerInterface as PsrRequestHandlerInterface;
21 use TYPO3\CMS\Core\Configuration\ConfigurationManager;
34 use TYPO3\CMS\Core\Package\PackageManager;
47 
53 class ‪RequestHandler implements ‪RequestHandlerInterface, PsrRequestHandlerInterface
54 {
58  protected ‪$configurationManager;
59 
63  protected ‪$controllers = [
64  'icon' => IconController::class,
65  'layout' => LayoutController::class,
66  'login' => LoginController::class,
67  'maintenance' => MaintenanceController::class,
68  'settings' => SettingsController::class,
69  'upgrade' => UpgradeController::class,
70  'environment' => EnvironmentController::class,
71  ];
72 
76  public function ‪__construct(ConfigurationManager ‪$configurationManager)
77  {
78  $this->configurationManager = ‪$configurationManager;
79  }
80 
87  public function ‪handleRequest(ServerRequestInterface $request): ResponseInterface
88  {
89  return $this->‪handle($request);
90  }
91 
98  public function ‪handle(ServerRequestInterface $request): ResponseInterface
99  {
100  $controllerName = $request->getQueryParams()['install']['controller'] ?? 'layout';
101  $actionName = $request->getParsedBody()['install']['action'] ?? $request->getQueryParams()['install']['action'] ?? 'init';
102 
103  if ($actionName === 'showEnableInstallToolFile' && ‪EnableFileService::isInstallToolEnableFilePermanent()) {
104  $actionName = 'showLogin';
105  }
106 
107  $action = $actionName . 'Action';
108 
109  $session = $this->‪initializeSession();
110  if ($actionName === 'preAccessCheck') {
111  $response = new ‪JsonResponse([
112  'installToolLocked' => !$this->‪checkEnableInstallToolFile(),
113  'isAuthorized' => $session->isAuthorized()
114  ]);
115  } elseif ($actionName === 'init') {
116  $controller = new ‪LayoutController();
117  $response = $controller->initAction($request);
118  } elseif ($actionName === 'checkEnableInstallToolFile') {
119  $response = new ‪JsonResponse([
120  'success' => $this->‪checkEnableInstallToolFile(),
121  ]);
122  } elseif ($actionName === 'showEnableInstallToolFile') {
123  $controller = new ‪LoginController();
124  $response = $controller->showEnableInstallToolFileAction($request);
125  } elseif ($actionName === 'checkLogin') {
126  if (!$this->‪checkEnableInstallToolFile() && !$session->isAuthorizedBackendUserSession()) {
127  throw new \RuntimeException('Not authorized', 1505563556);
128  }
129  if ($session->isExpired() || !$session->isAuthorized()) {
130  // Session expired, log out user, start new session
131  $session->resetSession();
132  $session->startSession();
133  $response = new ‪JsonResponse([
134  'success' => false,
135  ]);
136  } else {
137  $session->refreshSession();
138  $response = new ‪JsonResponse([
139  'success' => true,
140  ]);
141  }
142  } elseif ($actionName === 'showLogin') {
143  if (!$this->‪checkEnableInstallToolFile()) {
144  throw new \RuntimeException('Not authorized', 1505564888);
145  }
146  $controller = new ‪LoginController();
147  $response = $controller->showLoginAction($request);
148  } elseif ($actionName === 'login') {
149  if (!$this->‪checkEnableInstallToolFile()) {
150  throw new \RuntimeException('Not authorized', 1505567462);
151  }
152  $this->‪checkSessionToken($request, $session);
153  $this->‪checkSessionLifetime($session);
154  $password = $request->getParsedBody()['install']['password'] ?? null;
155  $authService = new ‪AuthenticationService($session);
156  if ($authService->loginWithPassword($password)) {
157  $response = new ‪JsonResponse([
158  'success' => true,
159  ]);
160  } else {
161  if ($password === null || empty($password)) {
162  $messageQueue = (new ‪FlashMessageQueue('install'))->enqueue(
163  new ‪FlashMessage('Please enter the install tool password', '', ‪FlashMessage::ERROR)
164  );
165  } else {
166  $hashInstance = GeneralUtility::makeInstance(PasswordHashFactory::class)->getDefaultHashInstance('BE');
167  $hashedPassword = $hashInstance->getHashedPassword($password);
168  $messageQueue = (new ‪FlashMessageQueue('install'))->enqueue(
169  new ‪FlashMessage(
170  'Given password does not match the install tool login password. Calculated hash: ' . $hashedPassword,
171  '',
173  )
174  );
175  }
176  $response = new ‪JsonResponse([
177  'success' => false,
178  'status' => $messageQueue,
179  ]);
180  }
181  } elseif ($actionName === 'logout') {
184  }
185  $formProtection = ‪FormProtectionFactory::get(
186  InstallToolFormProtection::class
187  );
188  $formProtection->clean();
189  $session->destroySession();
190  $response = new ‪JsonResponse([
191  'success' => true,
192  ]);
193  } else {
194  $enforceReferrerResponse = $this->‪enforceReferrer($request);
195  if ($enforceReferrerResponse instanceof ResponseInterface) {
196  return $enforceReferrerResponse;
197  }
198  if (
199  !$this->‪checkSessionToken($request, $session)
200  || !$this->‪checkSessionLifetime($session)
201  || !$session->isAuthorized()
202  ) {
203  return new ‪HtmlResponse('', 403);
204  }
205  $session->refreshSession();
206  if (!array_key_exists($controllerName, $this->controllers)) {
207  throw new \RuntimeException(
208  'Unknown controller ' . $controllerName,
209  1505215756
210  );
211  }
214  $controller = new $this->controllers[$controllerName];
215  if (!method_exists($controller, $action)) {
216  throw new \RuntimeException(
217  'Unknown action method ' . $action . ' in controller ' . $controllerName,
218  1505216027
219  );
220  }
221  $response = $controller->$action($request);
222  }
223 
224  return $response;
225  }
226 
235  public function ‪canHandleRequest(ServerRequestInterface $request): bool
236  {
237  $basicIntegrity = $this->‪checkIfEssentialConfigurationExists()
238  && !empty(‪$GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword'])
240  if (!$basicIntegrity) {
241  return false;
242  }
243  return true;
244  }
245 
251  public function ‪getPriority(): int
252  {
253  return 50;
254  }
255 
261  protected function ‪checkEnableInstallToolFile()
262  {
264  }
265 
273  protected function ‪initializeSession()
274  {
275  $session = new ‪SessionService();
276  if (!$session->hasSession()) {
277  $session->startSession();
278  }
279  return $session;
280  }
281 
289  protected function ‪checkSessionToken(ServerRequestInterface $request, ‪SessionService $session): bool
290  {
291  $postValues = $request->getParsedBody()['install'];
292  // no post data is there, so no token check necessary
293  if (empty($postValues)) {
294  return true;
295  }
296  $tokenOk = false;
297  // A token must be given as soon as there is POST data
298  if (isset($postValues['token'])) {
299  $formProtection = ‪FormProtectionFactory::get(
300  InstallToolFormProtection::class
301  );
302  $action = (string)$postValues['action'];
303  if ($action === '') {
304  throw new \RuntimeException(
305  'No POST action given for token check',
306  1369326593
307  );
308  }
309  $tokenOk = $formProtection->validateToken($postValues['token'], 'installTool', $action);
310  }
311  if (!$tokenOk) {
312  $session->‪resetSession();
313  $session->‪startSession();
314  }
315  return $tokenOk;
316  }
317 
325  protected function ‪checkSessionLifetime(‪SessionService $session): bool
326  {
327  $isExpired = $session->‪isExpired();
328  if ($isExpired) {
329  // Session expired, log out user, start new session
330  $session->‪resetSession();
331  $session->‪startSession();
332  }
333  return !$isExpired;
334  }
335 
341  protected function ‪checkIfEssentialConfigurationExists(): bool
342  {
343  return file_exists($this->configurationManager->getLocalConfigurationFileLocation());
344  }
345 
352  protected function ‪recreatePackageStatesFileIfMissing(): void
353  {
354  if (!file_exists(‪Environment::getLegacyConfigPath() . '/PackageStates.php')) {
355  // We need a FailsafePackageManager at this moment, however this is given
356  // As Bootstrap is registering the FailsafePackageManager object as a singleton instance
357  // of the main PackageManager class. See \TYPO3\CMS\Core\Core\Bootstrap::init()
359  $packageManager = GeneralUtility::makeInstance(PackageManager::class);
360  $packages = $packageManager->getAvailablePackages();
361  foreach ($packages as $package) {
362  if ($package instanceof ‪PackageInterface && $package->‪isPartOfMinimalUsableSystem()) {
363  $packageManager->activatePackage($package->getPackageKey());
364  }
365  }
366  $packageManager->forceSortAndSavePackageStates();
367  }
368  }
369 
378  protected function ‪enforceReferrer(ServerRequestInterface $request): ?ResponseInterface
379  {
380  if (!(new ‪Features())->isFeatureEnabled('security.backend.enforceReferrer')) {
381  return null;
382  }
383  return (new ‪ReferrerEnforcer($request))->handle([
384  'flags' => ['refresh-always'],
385  'subject' => 'Install Tool',
386  ]);
387  }
388 }
‪TYPO3\CMS\Core\Http\Security\ReferrerEnforcer
Definition: ReferrerEnforcer.php:31
‪TYPO3\CMS\Install\Http\RequestHandler\$configurationManager
‪ConfigurationManager $configurationManager
Definition: RequestHandler.php:57
‪TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory
Definition: PasswordHashFactory.php:25
‪TYPO3\CMS\Core\Package\PackageInterface\isPartOfMinimalUsableSystem
‪bool isPartOfMinimalUsableSystem()
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory\get
‪static TYPO3 CMS Core FormProtection AbstractFormProtection get($classNameOrType='default',... $constructorArguments)
Definition: FormProtectionFactory.php:72
‪TYPO3\CMS\Install\Http\RequestHandler\__construct
‪__construct(ConfigurationManager $configurationManager)
Definition: RequestHandler.php:74
‪TYPO3\CMS\Install\Controller\UpgradeController
Definition: UpgradeController.php:76
‪TYPO3\CMS\Install\Controller\EnvironmentController
Definition: EnvironmentController.php:46
‪TYPO3\CMS\Install\Service\EnableFileService
Definition: EnableFileService.php:24
‪TYPO3\CMS\Install\Http\RequestHandler\initializeSession
‪SessionService initializeSession()
Definition: RequestHandler.php:271
‪TYPO3\CMS\Install\Controller\IconController
Definition: IconController.php:31
‪TYPO3\CMS\Core\Package\PackageInterface
Definition: PackageInterface.php:21
‪TYPO3\CMS\Core\FormProtection\InstallToolFormProtection
Definition: InstallToolFormProtection.php:60
‪TYPO3\CMS\Install\Service\EnableFileService\checkInstallToolEnableFile
‪static bool checkInstallToolEnableFile()
Definition: EnableFileService.php:110
‪TYPO3\CMS\Install\Http\RequestHandler\checkEnableInstallToolFile
‪bool checkEnableInstallToolFile()
Definition: RequestHandler.php:259
‪TYPO3\CMS\Install\Service\SessionService\resetSession
‪resetSession()
Definition: SessionService.php:190
‪TYPO3\CMS\Install\Http
Definition: Application.php:2
‪TYPO3\CMS\Core\Http\RequestHandlerInterface
Definition: RequestHandlerInterface.php:28
‪TYPO3\CMS\Install\Service\EnableFileService\removeInstallToolEnableFile
‪static bool removeInstallToolEnableFile()
Definition: EnableFileService.php:75
‪TYPO3\CMS\Install\Http\RequestHandler\$controllers
‪array $controllers
Definition: RequestHandler.php:61
‪TYPO3\CMS\Install\Service\SessionService\startSession
‪string startSession()
Definition: SessionService.php:172
‪TYPO3\CMS\Install\Service\EnableFileService\installToolEnableFileExists
‪static bool installToolEnableFileExists()
Definition: EnableFileService.php:100
‪TYPO3\CMS\Install\Http\RequestHandler\checkSessionToken
‪bool checkSessionToken(ServerRequestInterface $request, SessionService $session)
Definition: RequestHandler.php:287
‪TYPO3\CMS\Install\Controller\LoginController
Definition: LoginController.php:30
‪TYPO3\CMS\Install\Service\SessionService\isExpired
‪bool isExpired()
Definition: SessionService.php:324
‪TYPO3\CMS\Core\Configuration\Features
Definition: Features.php:54
‪TYPO3\CMS\Install\Service\EnableFileService\isInstallToolEnableFilePermanent
‪static bool isInstallToolEnableFilePermanent()
Definition: EnableFileService.php:130
‪TYPO3\CMS\Install\Service\EnableFileService\isFirstInstallAllowed
‪static bool isFirstInstallAllowed()
Definition: EnableFileService.php:43
‪TYPO3\CMS\Install\Controller\LayoutController
Definition: LayoutController.php:36
‪TYPO3\CMS\Install\Http\RequestHandler\handleRequest
‪ResponseInterface handleRequest(ServerRequestInterface $request)
Definition: RequestHandler.php:85
‪TYPO3\CMS\Install\Http\RequestHandler\canHandleRequest
‪bool canHandleRequest(ServerRequestInterface $request)
Definition: RequestHandler.php:233
‪TYPO3\CMS\Install\Http\RequestHandler\checkSessionLifetime
‪bool checkSessionLifetime(SessionService $session)
Definition: RequestHandler.php:323
‪TYPO3\CMS\Core\Messaging\FlashMessage
Definition: FlashMessage.php:22
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory
Definition: FormProtectionFactory.php:45
‪TYPO3\CMS\Install\Http\RequestHandler
Definition: RequestHandler.php:54
‪TYPO3\CMS\Core\Http\JsonResponse
Definition: JsonResponse.php:25
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:39
‪TYPO3\CMS\Install\Http\RequestHandler\enforceReferrer
‪ResponseInterface null enforceReferrer(ServerRequestInterface $request)
Definition: RequestHandler.php:376
‪TYPO3\CMS\Install\Controller\MaintenanceController
Definition: MaintenanceController.php:46
‪TYPO3\CMS\Install\Controller\AbstractController
Definition: AbstractController.php:28
‪TYPO3\CMS\Install\Authentication\AuthenticationService
Definition: AuthenticationService.php:30
‪TYPO3\CMS\Install\Http\RequestHandler\recreatePackageStatesFileIfMissing
‪recreatePackageStatesFileIfMissing()
Definition: RequestHandler.php:350
‪TYPO3\CMS\Install\Controller\SettingsController
Definition: SettingsController.php:45
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Install\Http\RequestHandler\getPriority
‪int getPriority()
Definition: RequestHandler.php:249
‪TYPO3\CMS\Core\Messaging\FlashMessageQueue
Definition: FlashMessageQueue.php:25
‪TYPO3\CMS\Core\Core\Environment\getLegacyConfigPath
‪static string getLegacyConfigPath()
Definition: Environment.php:256
‪TYPO3\CMS\Install\Service\SessionService
Definition: SessionService.php:30
‪TYPO3\CMS\Install\Http\RequestHandler\checkIfEssentialConfigurationExists
‪bool checkIfEssentialConfigurationExists()
Definition: RequestHandler.php:339
‪TYPO3\CMS\Core\Messaging\AbstractMessage\ERROR
‪const ERROR
Definition: AbstractMessage.php:29
‪TYPO3\CMS\Install\Http\RequestHandler\handle
‪ResponseInterface handle(ServerRequestInterface $request)
Definition: RequestHandler.php:96
‪TYPO3\CMS\Core\Http\HtmlResponse
Definition: HtmlResponse.php:25