‪TYPO3CMS  11.5
SwitchUserController.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\EventDispatcher\EventDispatcherInterface;
21 use Psr\Http\Message\ResponseFactoryInterface;
22 use Psr\Http\Message\ResponseInterface;
23 use Psr\Http\Message\ServerRequestInterface;
26 use TYPO3\CMS\Backend\Utility\BackendUtility;
33 
38 {
39  protected const ‪RECENT_USERS_LIMIT = 3;
40 
41  protected EventDispatcherInterface ‪$eventDispatcher;
43  protected ResponseFactoryInterface ‪$responseFactory;
45 
46  public function ‪__construct(
47  EventDispatcherInterface ‪$eventDispatcher,
49  ResponseFactoryInterface ‪$responseFactory
50  ) {
51  $this->eventDispatcher = ‪$eventDispatcher;
52  $this->uriBuilder = ‪$uriBuilder;
53  $this->responseFactory = ‪$responseFactory;
54  $this->sessionBackend = GeneralUtility::makeInstance(SessionManager::class)->getSessionBackend('BE');
55  }
56 
60  public function ‪switchUserAction(ServerRequestInterface $request): ResponseInterface
61  {
62  $currentUser = $this->‪getBackendUserAuthentication();
63  $targetUserId = (int)($request->getParsedBody()['targetUser'] ?? 0);
64 
65  if (!$targetUserId
66  || $targetUserId === (int)($currentUser->user[$currentUser->userid_column] ?? 0)
67  || !$currentUser->isAdmin()
68  || $currentUser->getOriginalUserIdWhenInSwitchUserMode() !== null
69  ) {
70  return $this->‪jsonResponse(['success' => false]);
71  }
72 
73  $targetUser = BackendUtility::getRecord('be_users', $targetUserId, '*', BackendUtility::BEenableFields('be_users'));
74  if ($targetUser === null) {
75  return $this->‪jsonResponse(['success' => false]);
76  }
77 
79  // Set backend user listing module as starting module if installed
80  $currentUser->uc['startModuleOnFirstLogin'] = 'system_BeuserTxBeuser';
81  }
82  $currentUser->uc['recentSwitchedToUsers'] = $this->‪generateListOfMostRecentSwitchedUsers($targetUserId);
83  $currentUser->writeUC();
84 
85  // Write user switch to log
86  $currentUser->writelog(‪Type::LOGIN, 2, 0, 1, 'User %s switched to user %s (be_users:%s)', [
87  $currentUser->user[$currentUser->username_column] ?? '',
88  $targetUser['username'] ?? '',
89  $targetUserId,
90  ]);
91 
92  $sessionObject = $currentUser->getSession();
93  $sessionObject->set('backuserid', (int)($currentUser->user[$currentUser->userid_column] ?? 0));
94  $sessionRecord = $sessionObject->toArray();
95  $sessionRecord['ses_userid'] = $targetUserId;
96  $this->sessionBackend->update($sessionObject->getIdentifier(), $sessionRecord);
97  // We must regenerate the internal session so the new ses_userid is present in the userObject
98  $currentUser->enforceNewSessionId();
99 
100  $event = new ‪SwitchUserEvent(
101  $currentUser->getSession()->getIdentifier(),
102  $targetUser,
103  (array)$currentUser->user
104  );
105  $this->eventDispatcher->dispatch($event);
106 
107  return $this->‪jsonResponse([
108  'success' => true,
109  'url' => $this->uriBuilder->buildUriFromRoute('main'),
110  ]);
111  }
112 
116  public function ‪exitSwitchUserAction(ServerRequestInterface $request): ResponseInterface
117  {
118  $currentUser = $this->‪getBackendUserAuthentication();
119 
120  if ($currentUser->getOriginalUserIdWhenInSwitchUserMode() === null) {
121  return $this->‪jsonResponse(['success' => false]);
122  }
123 
124  $sessionObject = $currentUser->getSession();
125  $originalUser = (int)$sessionObject->get('backuserid');
126  $sessionObject->set('backuserid', null);
127  $sessionRecord = $sessionObject->toArray();
128  $sessionRecord['ses_userid'] = $originalUser;
129  $this->sessionBackend->update($sessionObject->getIdentifier(), $sessionRecord);
130  // We must regenerate the internal session so the new ses_userid is present in the userObject
131  $currentUser->enforceNewSessionId();
132 
133  return $this->‪jsonResponse([
134  'success' => true,
135  'url' => $this->uriBuilder->buildUriFromRoute('main'),
136  ]);
137  }
138 
145  protected function ‪generateListOfMostRecentSwitchedUsers(int $targetUserUid): array
146  {
147  $latestUserUids = [];
148  $backendUser = $this->‪getBackendUserAuthentication();
149 
150  if (isset($backendUser->uc['recentSwitchedToUsers']) && is_array($backendUser->uc['recentSwitchedToUsers'])) {
151  $latestUserUids = $backendUser->uc['recentSwitchedToUsers'];
152  }
153 
154  // Remove potentially existing user in that list
155  $index = array_search($targetUserUid, $latestUserUids, true);
156  if ($index !== false) {
157  unset($latestUserUids[$index]);
158  }
159  array_unshift($latestUserUids, $targetUserUid);
160 
161  return array_slice($latestUserUids, 0, static::RECENT_USERS_LIMIT);
162  }
163 
164  protected function ‪jsonResponse(array $data): ResponseInterface
165  {
166  $response = $this->responseFactory
167  ->createResponse()
168  ->withAddedHeader('Content-Type', 'application/json; charset=utf-8');
169 
170  $response->getBody()->write(json_encode($data));
171  return $response;
172  }
173 
175  {
176  return ‪$GLOBALS['BE_USER'];
177  }
178 }
‪TYPO3\CMS\Backend\Controller\SwitchUserController\jsonResponse
‪jsonResponse(array $data)
Definition: SwitchUserController.php:164
‪TYPO3\CMS\Backend\Controller\SwitchUserController\$responseFactory
‪ResponseFactoryInterface $responseFactory
Definition: SwitchUserController.php:43
‪TYPO3\CMS\Core\SysLog\Type\LOGIN
‪const LOGIN
Definition: Type.php:36
‪TYPO3\CMS\Backend\Controller\SwitchUserController\generateListOfMostRecentSwitchedUsers
‪int[] generateListOfMostRecentSwitchedUsers(int $targetUserUid)
Definition: SwitchUserController.php:145
‪TYPO3\CMS\Core\Session\SessionManager
Definition: SessionManager.php:39
‪TYPO3\CMS\Backend\Controller\SwitchUserController\$sessionBackend
‪SessionBackendInterface $sessionBackend
Definition: SwitchUserController.php:44
‪TYPO3\CMS\Backend\Controller\SwitchUserController\$uriBuilder
‪UriBuilder $uriBuilder
Definition: SwitchUserController.php:42
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility
Definition: ExtensionManagementUtility.php:43
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:40
‪TYPO3\CMS\Core\Session\Backend\SessionBackendInterface
Definition: SessionBackendInterface.php:28
‪TYPO3\CMS\Backend\Controller\SwitchUserController\exitSwitchUserAction
‪exitSwitchUserAction(ServerRequestInterface $request)
Definition: SwitchUserController.php:116
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Backend\Controller\SwitchUserController\RECENT_USERS_LIMIT
‪const RECENT_USERS_LIMIT
Definition: SwitchUserController.php:39
‪TYPO3\CMS\Backend\Controller\SwitchUserController\getBackendUserAuthentication
‪getBackendUserAuthentication()
Definition: SwitchUserController.php:174
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Backend\Controller\SwitchUserController\__construct
‪__construct(EventDispatcherInterface $eventDispatcher, UriBuilder $uriBuilder, ResponseFactoryInterface $responseFactory)
Definition: SwitchUserController.php:46
‪TYPO3\CMS\Backend\Controller\SwitchUserController\$eventDispatcher
‪EventDispatcherInterface $eventDispatcher
Definition: SwitchUserController.php:41
‪TYPO3\CMS\Backend\Controller\SwitchUserController\switchUserAction
‪switchUserAction(ServerRequestInterface $request)
Definition: SwitchUserController.php:60
‪TYPO3\CMS\Backend\Controller\SwitchUserController
Definition: SwitchUserController.php:38
‪TYPO3\CMS\Backend\Authentication\Event\SwitchUserEvent
Definition: SwitchUserEvent.php:24
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\isLoaded
‪static bool isLoaded($key)
Definition: ExtensionManagementUtility.php:114
‪TYPO3\CMS\Backend\Controller
Definition: AboutController.php:16
‪TYPO3\CMS\Core\SysLog\Type
Definition: Type.php:28