eventDispatcher = $eventDispatcher; $this->uriBuilder = $uriBuilder; $this->responseFactory = $responseFactory; $this->sessionBackend = $sessionManager->getSessionBackend('BE'); } /** * Handle switching current user to the requested target user */ public function switchUserAction(ServerRequestInterface $request): ResponseInterface { $currentUser = $this->getBackendUserAuthentication(); $targetUserId = (int)($request->getParsedBody()['targetUser'] ?? 0); if (!$targetUserId || !$currentUser->isAdmin() || $targetUserId === $currentUser->getUserId() || $currentUser->getOriginalUserIdWhenInSwitchUserMode() !== null ) { return $this->jsonResponse(['success' => false]); } $targetUser = BackendUtility::getRecord('be_users', $targetUserId, '*', BackendUtility::BEenableFields('be_users')); if ($targetUser === null) { return $this->jsonResponse(['success' => false]); } if (ExtensionManagementUtility::isLoaded('beuser')) { // Set backend user listing module as starting module if installed $currentUser->uc['startModuleOnFirstLogin'] = 'backend_user_management'; } $currentUser->uc['recentSwitchedToUsers'] = $this->generateListOfMostRecentSwitchedUsers($targetUserId); $currentUser->writeUC(); // Write user switch to log $currentUser->writelog(Type::LOGIN, 2, 0, null, 'User %s switched to user %s (be_users:%s)', [ $currentUser->getUserName() ?? '', $targetUser['username'] ?? '', $targetUserId, ]); $sessionObject = $currentUser->getSession(); $sessionObject->set('backuserid', $currentUser->getUserId() ?? 0); $sessionRecord = $sessionObject->toArray(); $sessionRecord['ses_userid'] = $targetUserId; $this->sessionBackend->update($sessionObject->getIdentifier(), $sessionRecord); // We must regenerate the internal session so the new ses_userid is present in the userObject $currentUser->enforceNewSessionId(); $event = new SwitchUserEvent( $currentUser->getSession()->getIdentifier(), $targetUser, (array)$currentUser->user ); $this->eventDispatcher->dispatch($event); return $this->jsonResponse([ 'success' => true, 'url' => (string)$this->uriBuilder->buildUriFromRoute('main'), ]); } /** * Handle exiting the switch user mode */ public function exitSwitchUserAction(ServerRequestInterface $request): ResponseInterface { $currentUser = $this->getBackendUserAuthentication(); if ($currentUser->getOriginalUserIdWhenInSwitchUserMode() === null) { return $this->jsonResponse(['success' => false]); } $sessionObject = $currentUser->getSession(); $originalUser = (int)$sessionObject->get('backuserid'); $sessionObject->set('backuserid', null); $sessionRecord = $sessionObject->toArray(); $sessionRecord['ses_userid'] = $originalUser; $this->sessionBackend->update($sessionObject->getIdentifier(), $sessionRecord); // We must regenerate the internal session so the new ses_userid is present in the userObject $currentUser->enforceNewSessionId(); return $this->jsonResponse([ 'success' => true, 'url' => (string)$this->uriBuilder->buildUriFromRoute('main'), ]); } /** * Generates a list of users to whom where switched in the past. This is limited by RECENT_USERS_LIMIT. * * @return int[] */ protected function generateListOfMostRecentSwitchedUsers(int $targetUserUid): array { $latestUserUids = []; $backendUser = $this->getBackendUserAuthentication(); if (isset($backendUser->uc['recentSwitchedToUsers']) && is_array($backendUser->uc['recentSwitchedToUsers'])) { $latestUserUids = $backendUser->uc['recentSwitchedToUsers']; } // Remove potentially existing user in that list $index = array_search($targetUserUid, $latestUserUids, true); if ($index !== false) { unset($latestUserUids[$index]); } array_unshift($latestUserUids, $targetUserUid); return array_slice($latestUserUids, 0, static::RECENT_USERS_LIMIT); } protected function jsonResponse(array $data): ResponseInterface { $response = $this->responseFactory ->createResponse() ->withAddedHeader('Content-Type', 'application/json; charset=utf-8'); $response->getBody()->write(json_encode($data)); return $response; } protected function getBackendUserAuthentication(): BackendUserAuthentication { return $GLOBALS['BE_USER']; } }