‪TYPO3CMS  11.5
MfaAjaxController.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;
32 
39 {
40  private const ‪ALLOWED_ACTIONS = ['deactivate'];
41 
43 
45  {
46  $this->mfaProviderRegistry = ‪$mfaProviderRegistry;
47  }
48 
52  public function ‪handleRequest(ServerRequestInterface $request): ResponseInterface
53  {
54  $action = (string)($request->getQueryParams()['action'] ?? $request->getParsedBody()['action'] ?? '');
55 
56  if (!in_array($action, self::ALLOWED_ACTIONS, true)) {
57  return new ‪JsonResponse($this->‪getResponseData(false, $this->‪getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_mfa.xlf:ajax.invalidRequest')));
58  }
59 
60  $userId = (int)($request->getParsedBody()['userId'] ?? 0);
61  $tableName = (string)($request->getParsedBody()['tableName'] ?? '');
62 
63  if (!$userId || !in_array($tableName, ['be_users', 'fe_users'], true)) {
64  return new ‪JsonResponse($this->‪getResponseData(false, $this->‪getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_mfa.xlf:ajax.invalidRequest')));
65  }
66 
67  $user = $this->‪initializeUser($userId, $tableName);
68 
69  if (!$this->‪isAllowedToPerformAction($action, $user)) {
70  return new ‪JsonResponse($this->‪getResponseData(false, $this->‪getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_mfa.xlf:ajax.insufficientPermissions')));
71  }
72 
73  return new ‪JsonResponse($this->{$action . 'Action'}($request, $user));
74  }
75 
81  protected function ‪deactivateAction(ServerRequestInterface $request, ‪AbstractUserAuthentication $user): array
82  {
83  $lang = $this->‪getLanguageService();
84  $userName = (string)($user->user[$user->username_column] ?? '');
85  $providerToDeactivate = (string)($request->getParsedBody()['provider'] ?? '');
86 
87  if ($providerToDeactivate === '') {
88  // In case no provider is given, try to deactivate all active providers
89  $providersToDeactivate = $this->mfaProviderRegistry->getActiveProviders($user);
90  if ($providersToDeactivate === []) {
91  return $this->‪getResponseData(
92  false,
93  $lang->sL('LLL:EXT:backend/Resources/Private/Language/locallang_mfa.xlf:ajax.deactivate.providersNotDeactivated'),
94  $user
95  );
96  }
97  foreach ($providersToDeactivate as $identifier => $provider) {
98  $propertyManager = ‪MfaProviderPropertyManager::create($provider, $user);
99  if (!$provider->deactivate($request, $propertyManager)) {
100  return $this->‪getResponseData(
101  false,
102  sprintf($lang->sL('LLL:EXT:backend/Resources/Private/Language/locallang_mfa.xlf:ajax.deactivate.providerNotDeactivated'), $lang->sL($provider->getTitle())),
103  $user
104  );
105  }
106  }
107  return $this->‪getResponseData(
108  true,
109  sprintf($lang->sL('LLL:EXT:backend/Resources/Private/Language/locallang_mfa.xlf:ajax.deactivate.providersDeactivated'), $userName),
110  $user
111  );
112  }
113 
114  if (!$this->mfaProviderRegistry->hasProvider($providerToDeactivate)) {
115  return $this->‪getResponseData(
116  false,
117  sprintf($lang->sL('LLL:EXT:backend/Resources/Private/Language/locallang_mfa.xlf:ajax.deactivate.providerNotFound'), $providerToDeactivate),
118  $user
119  );
120  }
121 
122  $provider = $this->mfaProviderRegistry->getProvider($providerToDeactivate);
123  $propertyManager = ‪MfaProviderPropertyManager::create($provider, $user);
124 
125  if (!$provider->isActive($propertyManager) || !$provider->deactivate($request, $propertyManager)) {
126  return $this->‪getResponseData(
127  false,
128  sprintf($lang->sL('LLL:EXT:backend/Resources/Private/Language/locallang_mfa.xlf:ajax.deactivate.providerNotDeactivated'), $lang->sL($provider->getTitle())),
129  $user
130  );
131  }
132 
133  return $this->‪getResponseData(
134  true,
135  sprintf($lang->sL('LLL:EXT:backend/Resources/Private/Language/locallang_mfa.xlf:ajax.deactivate.providerDeactivated'), $lang->sL($provider->getTitle()), $userName),
136  $user
137  );
138  }
139 
143  protected function ‪initializeUser(int $userId, string $tableName): ‪AbstractUserAuthentication
144  {
145  $user = $tableName === 'be_users'
146  ? GeneralUtility::makeInstance(BackendUserAuthentication::class)
147  : GeneralUtility::makeInstance(FrontendUserAuthentication::class);
148 
149  $user->enablecolumns = ['deleted' => true];
150  $user->setBeUserByUid($userId);
151 
152  return $user;
153  }
154 
158  protected function ‪getResponseData(bool $success, string $message, ?‪AbstractUserAuthentication $user = null): array
159  {
160  $payload = [
161  'success' => $success,
162  'status' => (new ‪FlashMessageQueue('backend'))->enqueue(
163  new ‪FlashMessage(
164  $message,
165  $this->‪getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_mfa.xlf:ajax.' . ($success ? 'success' : 'error'))
166  )
167  ),
168  ];
169 
170  if ($user !== null) {
171  $payload['remaining'] = count($this->mfaProviderRegistry->getActiveProviders($user));
172  }
173 
174  return $payload;
175  }
176 
181  protected function ‪isAllowedToPerformAction(string $action, ‪AbstractUserAuthentication $user): bool
182  {
183  if ($action === 'deactivate') {
184  $currentBackendUser = $this->‪getBackendUser();
185  // Only admins are allowed to deactivate providers
186  if (!$currentBackendUser->isAdmin()) {
187  return false;
188  }
189  // Providers from system maintainers can only be deactivated by system maintainers.
190  // This check is however only be necessary if the target is a backend user.
191  if ($user instanceof ‪BackendUserAuthentication) {
192  $systemMaintainers = array_map('intval', ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['systemMaintainers'] ?? []);
193  $isTargetUserSystemMaintainer = $user->isAdmin() && in_array((int)$user->user[$user->userid_column], $systemMaintainers, true);
194  if ($isTargetUserSystemMaintainer && !$this->‪getBackendUser()->isSystemMaintainer()) {
195  return false;
196  }
197  }
198  return true;
199  }
200 
201  return false;
202  }
203 
205  {
206  return ‪$GLOBALS['BE_USER'];
207  }
208 
210  {
211  return ‪$GLOBALS['LANG'];
212  }
213 }
‪TYPO3\CMS\Backend\Controller\MfaAjaxController\isAllowedToPerformAction
‪isAllowedToPerformAction(string $action, AbstractUserAuthentication $user)
Definition: MfaAjaxController.php:181
‪TYPO3\CMS\Backend\Controller\MfaAjaxController\deactivateAction
‪deactivateAction(ServerRequestInterface $request, AbstractUserAuthentication $user)
Definition: MfaAjaxController.php:81
‪TYPO3\CMS\Backend\Controller\MfaAjaxController\__construct
‪__construct(MfaProviderRegistry $mfaProviderRegistry)
Definition: MfaAjaxController.php:44
‪TYPO3\CMS\Backend\Controller\MfaAjaxController\initializeUser
‪initializeUser(int $userId, string $tableName)
Definition: MfaAjaxController.php:143
‪TYPO3\CMS\Backend\Controller\MfaAjaxController
Definition: MfaAjaxController.php:39
‪TYPO3\CMS\Backend\Controller\MfaAjaxController\getBackendUser
‪getBackendUser()
Definition: MfaAjaxController.php:204
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager
Definition: MfaProviderPropertyManager.php:33
‪TYPO3\CMS\Core\Messaging\FlashMessage
Definition: FlashMessage.php:26
‪TYPO3\CMS\Backend\Controller\MfaAjaxController\$mfaProviderRegistry
‪MfaProviderRegistry $mfaProviderRegistry
Definition: MfaAjaxController.php:42
‪TYPO3\CMS\Core\Http\JsonResponse
Definition: JsonResponse.php:28
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager\create
‪static MfaProviderPropertyManager create(MfaProviderManifestInterface $provider, AbstractUserAuthentication $user)
Definition: MfaProviderPropertyManager.php:224
‪TYPO3\CMS\Backend\Controller\MfaAjaxController\getLanguageService
‪getLanguageService()
Definition: MfaAjaxController.php:209
‪TYPO3\CMS\Backend\Controller\MfaAjaxController\handleRequest
‪handleRequest(ServerRequestInterface $request)
Definition: MfaAjaxController.php:52
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:42
‪TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication
Definition: FrontendUserAuthentication.php:32
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Backend\Controller\MfaAjaxController\ALLOWED_ACTIONS
‪const ALLOWED_ACTIONS
Definition: MfaAjaxController.php:40
‪TYPO3\CMS\Core\Messaging\FlashMessageQueue
Definition: FlashMessageQueue.php:29
‪TYPO3\CMS\Backend\Controller
Definition: AboutController.php:16
‪TYPO3\CMS\Backend\Controller\MfaAjaxController\getResponseData
‪getResponseData(bool $success, string $message, ?AbstractUserAuthentication $user=null)
Definition: MfaAjaxController.php:158
‪TYPO3\CMS\Core\Authentication\AbstractUserAuthentication
Definition: AbstractUserAuthentication.php:56
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderRegistry
Definition: MfaProviderRegistry.php:28