‪TYPO3CMS  11.5
BackendModuleController.php
Go to the documentation of this file.
1 <?php
2 
3 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 
19 
20 use Psr\Http\Message\ResponseInterface;
21 use Psr\Http\Message\ServerRequestInterface;
36 use TYPO3\CMS\Install\Service\SessionService;
37 
49 {
50  protected const ‪FLAG_CONFIRMATION_REQUEST = 1;
51  protected const ‪FLAG_INSTALL_TOOL_PASSWORD = 2;
52  protected const ‪ALLOWED_ACTIONS = ['maintenance', 'settings', 'upgrade', 'environment'];
53 
57  protected ‪$sessionService;
58 
61 
62  public function ‪__construct(
65  ) {
66  $this->uriBuilder = ‪$uriBuilder;
67  $this->moduleTemplateFactory = ‪$moduleTemplateFactory;
68  }
69 
77  public function ‪backendUserConfirmationAction(ServerRequestInterface $request): ResponseInterface
78  {
79  $flags = (int)($request->getQueryParams()['flags'] ?? 0);
80  $targetController = (string)($request->getQueryParams()['targetController'] ?? '');
81  $targetHash = (string)($request->getQueryParams()['targetHash'] ?? '');
82  $expectedTargetHash = GeneralUtility::hmac($targetController, BackendModuleController::class);
83  $flagInstallToolPassword = (bool)($flags & self::FLAG_INSTALL_TOOL_PASSWORD);
84  $flagInvalidPassword = false;
85 
86  if (!in_array($targetController, self::ALLOWED_ACTIONS, true)
87  || !hash_equals($expectedTargetHash, $targetHash)) {
88  return new ‪HtmlResponse('', 403);
89  }
90  if ($flags & self::FLAG_CONFIRMATION_REQUEST) {
91  if ($flagInstallToolPassword && $this->‪verifyInstallToolPassword($request)) {
92  return $this->‪setAuthorizedAndRedirect($targetController);
93  }
94  if (!$flagInstallToolPassword && $this->‪verifyBackendUserPassword($request)) {
95  return $this->‪setAuthorizedAndRedirect($targetController);
96  }
97  $flagInvalidPassword = true;
98  }
99 
100  $view = GeneralUtility::makeInstance(StandaloneView::class);
101  $view->getTemplatePaths()->setTemplatePathAndFilename(
103  'install',
104  'Resources/Private/Templates/BackendModule/BackendUserConfirmation.html'
105  )
106  );
107  $view->assignMultiple([
108  'flagInvalidPassword' => $flagInvalidPassword,
109  'flagInstallToolPassword' => $flagInstallToolPassword,
110  'languageFileReference' => 'LLL:EXT:install/Resources/Private/Language/BackendModule.xlf',
111  'passwordModeUri' => $this->‪getBackendUserConfirmationUri([
112  'targetController' => $targetController,
113  'targetHash' => $targetHash,
114  // current flags, unset FLAG_CONFIRMATION_REQUEST, toggle FLAG_INSTALL_TOOL_PASSWORD
115  'flags' => $flags & ~self::FLAG_CONFIRMATION_REQUEST ^ self::FLAG_INSTALL_TOOL_PASSWORD,
116  ]),
117  'verifyUri' => $this->‪getBackendUserConfirmationUri([
118  'targetController' => $targetController,
119  'targetHash' => $targetHash,
120  // current flags, add FLAG_CONFIRMATION_REQUEST
121  'flags' => $flags | self::FLAG_CONFIRMATION_REQUEST,
122  ]),
123  ]);
124 
125  $moduleTemplate = $this->moduleTemplateFactory->create($request);
126  $moduleTemplate->setModuleName('tools_tools' . $targetController);
127  $moduleTemplate->setContent($view->render());
128  return new HtmlResponse($moduleTemplate->renderContent());
129  }
130 
136  public function ‪maintenanceAction(): ResponseInterface
137  {
138  return $this->‪getBackendUserConfirmationRedirect('maintenance')
139  ?? $this->‪setAuthorizedAndRedirect('maintenance');
140  }
141 
147  public function ‪settingsAction(): ResponseInterface
148  {
149  return $this->‪getBackendUserConfirmationRedirect('settings')
150  ?? $this->‪setAuthorizedAndRedirect('settings');
151  }
152 
158  public function ‪upgradeAction(): ResponseInterface
159  {
160  return $this->‪getBackendUserConfirmationRedirect('upgrade')
161  ?? $this->‪setAuthorizedAndRedirect('upgrade');
162  }
163 
169  public function ‪environmentAction(): ResponseInterface
170  {
171  return $this->‪getBackendUserConfirmationRedirect('environment')
172  ?? $this->‪setAuthorizedAndRedirect('environment');
173  }
174 
181  protected function ‪getBackendUserConfirmationRedirect(string $targetController): ?ResponseInterface
182  {
183  if ($this->‪getSessionService()->isAuthorizedBackendUserSession()) {
184  return null;
185  }
186  if (‪Environment::getContext()->isDevelopment()) {
187  return null;
188  }
189  $redirectUri = $this->‪getBackendUserConfirmationUri([
190  'targetController' => $targetController,
191  'targetHash' => GeneralUtility::hmac($targetController, BackendModuleController::class),
192  ]);
193  return new RedirectResponse((string)$redirectUri, 403);
194  }
195 
196  protected function ‪getBackendUserConfirmationUri(array $parameters): ‪Uri
197  {
198  return $this->uriBuilder->buildUriFromRoute(
199  'install.backend-user-confirmation',
200  $parameters
201  );
202  }
203 
211  protected function ‪setAuthorizedAndRedirect(string $controller): ResponseInterface
212  {
213  $userSession = $this->‪getBackendUser()->getSession();
214  $this->‪getSessionService()->setAuthorizedBackendSession($userSession);
215  $redirectLocation = ‪PathUtility::getAbsoluteWebPath('install.php?install[controller]=' . $controller . '&install[context]=backend');
216  return new ‪RedirectResponse($redirectLocation, 303);
217  }
218 
225  protected function ‪verifyInstallToolPassword(ServerRequestInterface $request): bool
226  {
227  $parsedBody = $request->getParsedBody();
228  $password = $parsedBody['confirmationPassword'] ?? null;
229  $installToolPassword = ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword'] ?? null;
230  if (!is_string($password) || empty($installToolPassword)) {
231  return false;
232  }
233 
234  try {
235  $hashFactory = GeneralUtility::makeInstance(PasswordHashFactory::class);
236  $hashInstance = $hashFactory->get($installToolPassword, 'BE');
237  return $hashInstance->checkPassword($password, $installToolPassword);
238  } catch (InvalidPasswordHashException $exception) {
239  return false;
240  }
241  }
242 
250  protected function ‪verifyBackendUserPassword(ServerRequestInterface $request): bool
251  {
252  $parsedBody = $request->getParsedBody();
253  $password = $parsedBody['confirmationPassword'] ?? null;
254  if (!is_string($password)) {
255  return false;
256  }
257 
258  // clone current backend user object to avoid
259  // possible side effects for the real instance
260  $backendUser = clone $this->‪getBackendUser();
261  $loginData = [
262  'status' => 'sudo-mode',
263  'origin' => BackendModuleController::class,
264  'uname' => $backendUser->user['username'],
265  'uident' => $password,
266  ];
267  // currently there is no dedicated API to perform authentication
268  // that's why this process partially has to be simulated here
269  $loginData = $backendUser->‪processLoginData($loginData);
270  $authInfo = $backendUser->‪getAuthInfoArray();
271 
272  $authenticated = false;
274  foreach ($this->getAuthServices($backendUser, $loginData, $authInfo) as ‪$service) {
275  $ret = (int)‪$service->authUser($backendUser->user);
276  if ($ret <= 0) {
277  return false;
278  }
279  if ($ret >= 200) {
280  return true;
281  }
282  if ($ret < 100) {
283  $authenticated = true;
284  continue;
285  }
286  }
287  return $authenticated;
288  }
289 
298  protected function getAuthServices(BackendUserAuthentication $backendUser, array $loginData, array $authInfo): \Generator
299  {
300  $serviceChain = [];
301  $subType = 'authUserBE';
302  while (‪$service = GeneralUtility::makeInstanceService('auth', $subType, $serviceChain)) {
303  $serviceChain[] = ‪$service->getServiceKey();
304  if (!is_object(‪$service)) {
305  break;
306  }
307  ‪$service->initAuth($subType, $loginData, $authInfo, $backendUser);
308  yield ‪$service;
309  }
310  }
311 
312  protected function ‪getBackendUser(): ‪BackendUserAuthentication
313  {
314  return ‪$GLOBALS['BE_USER'];
315  }
316 
323  protected function ‪getSessionService(): SessionService
324  {
325  if ($this->sessionService === null) {
326  $this->sessionService = new SessionService();
327  $this->sessionService->startSession();
328  }
330  }
331 }
‪TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory
Definition: PasswordHashFactory.php:27
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:25
‪TYPO3\CMS\Install\Controller\BackendModuleController\ALLOWED_ACTIONS
‪const ALLOWED_ACTIONS
Definition: BackendModuleController.php:52
‪TYPO3\CMS\Install\Controller\BackendModuleController\getBackendUserConfirmationUri
‪getBackendUserConfirmationUri(array $parameters)
Definition: BackendModuleController.php:195
‪TYPO3\CMS\Backend\Template\ModuleTemplateFactory
Definition: ModuleTemplateFactory.php:29
‪TYPO3\CMS\Install\Controller\BackendModuleController\verifyBackendUserPassword
‪bool verifyBackendUserPassword(ServerRequestInterface $request)
Definition: BackendModuleController.php:249
‪TYPO3\CMS\Install\Controller\BackendModuleController\maintenanceAction
‪ResponseInterface maintenanceAction()
Definition: BackendModuleController.php:135
‪TYPO3\CMS\Install\Controller\BackendModuleController\$moduleTemplateFactory
‪ModuleTemplateFactory $moduleTemplateFactory
Definition: BackendModuleController.php:59
‪TYPO3\CMS\Core\Crypto\PasswordHashing\InvalidPasswordHashException
Definition: InvalidPasswordHashException.php:25
‪TYPO3\CMS\Install\Controller\BackendModuleController\$uriBuilder
‪UriBuilder $uriBuilder
Definition: BackendModuleController.php:58
‪TYPO3\CMS\Core\Authentication\AbstractUserAuthentication\getAuthInfoArray
‪array getAuthInfoArray()
Definition: AbstractUserAuthentication.php:1207
‪TYPO3\CMS\Install\Controller\BackendModuleController\__construct
‪__construct(UriBuilder $uriBuilder, ModuleTemplateFactory $moduleTemplateFactory)
Definition: BackendModuleController.php:61
‪TYPO3\CMS\Core\Authentication\AbstractAuthenticationService
Definition: AbstractAuthenticationService.php:30
‪TYPO3\CMS\Install\Controller\BackendModuleController\upgradeAction
‪ResponseInterface upgradeAction()
Definition: BackendModuleController.php:157
‪TYPO3\CMS\Install\Controller\BackendModuleController\settingsAction
‪ResponseInterface settingsAction()
Definition: BackendModuleController.php:146
‪TYPO3\CMS\Install\Controller\BackendModuleController\getBackendUser
‪getBackendUser()
Definition: BackendModuleController.php:311
‪TYPO3\CMS\Install\Controller\BackendModuleController\backendUserConfirmationAction
‪ResponseInterface backendUserConfirmationAction(ServerRequestInterface $request)
Definition: BackendModuleController.php:76
‪TYPO3\CMS\Core\Authentication\AbstractUserAuthentication\processLoginData
‪array processLoginData($loginData)
Definition: AbstractUserAuthentication.php:1148
‪TYPO3\CMS\Core\Http\Uri
Definition: Uri.php:29
‪TYPO3\CMS\Core\Core\Environment\getContext
‪static ApplicationContext getContext()
Definition: Environment.php:141
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility
Definition: ExtensionManagementUtility.php:43
‪TYPO3\CMS\Install\Controller\BackendModuleController\getSessionService
‪SessionService getSessionService()
Definition: BackendModuleController.php:322
‪TYPO3\CMS\Install\Controller\BackendModuleController\FLAG_CONFIRMATION_REQUEST
‪const FLAG_CONFIRMATION_REQUEST
Definition: BackendModuleController.php:50
‪TYPO3\CMS\Install\Controller
Definition: AbstractController.php:18
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:40
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Install\Controller\BackendModuleController\verifyInstallToolPassword
‪bool verifyInstallToolPassword(ServerRequestInterface $request)
Definition: BackendModuleController.php:224
‪TYPO3\CMS\Core\Http\RedirectResponse
Definition: RedirectResponse.php:28
‪TYPO3\CMS\Install\Controller\BackendModuleController\getBackendUserConfirmationRedirect
‪ResponseInterface null getBackendUserConfirmationRedirect(string $targetController)
Definition: BackendModuleController.php:180
‪TYPO3\CMS\Install\Controller\BackendModuleController\$service
‪yield $service
Definition: BackendModuleController.php:307
‪TYPO3\CMS\Install\Controller\BackendModuleController\FLAG_INSTALL_TOOL_PASSWORD
‪const FLAG_INSTALL_TOOL_PASSWORD
Definition: BackendModuleController.php:51
‪TYPO3\CMS\Install\Controller\BackendModuleController\$sessionService
‪SessionService $sessionService
Definition: BackendModuleController.php:56
‪TYPO3\CMS\Fluid\View\StandaloneView
Definition: StandaloneView.php:31
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:43
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\extPath
‪static string extPath($key, $script='')
Definition: ExtensionManagementUtility.php:142
‪TYPO3\CMS\Core\Utility\PathUtility\getAbsoluteWebPath
‪static string getAbsoluteWebPath($targetPath, bool $prefixWithSitePath=true)
Definition: PathUtility.php:51
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Install\Controller\BackendModuleController\environmentAction
‪ResponseInterface environmentAction()
Definition: BackendModuleController.php:168
‪TYPO3\CMS\Install\Controller\BackendModuleController\setAuthorizedAndRedirect
‪ResponseInterface setAuthorizedAndRedirect(string $controller)
Definition: BackendModuleController.php:210
‪TYPO3\CMS\Core\Http\HtmlResponse
Definition: HtmlResponse.php:26
‪TYPO3\CMS\Install\Controller\BackendModuleController
Definition: BackendModuleController.php:49