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