Completed
Push — master ( 3db01f...893ee2 )
by
unknown
24:16 queued 05:55
created

BackendUserController::initializeView()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace TYPO3\CMS\Beuser\Controller;
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
18
use TYPO3\CMS\Backend\Authentication\Event\SwitchUserEvent;
19
use TYPO3\CMS\Beuser\Domain\Repository\BackendUserGroupRepository;
20
use TYPO3\CMS\Beuser\Domain\Repository\BackendUserRepository;
21
use TYPO3\CMS\Beuser\Domain\Repository\BackendUserSessionRepository;
22
use TYPO3\CMS\Beuser\Service\ModuleDataStorageService;
23
use TYPO3\CMS\Beuser\Service\UserInformationService;
24
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
25
use TYPO3\CMS\Core\Session\Backend\SessionBackendInterface;
26
use TYPO3\CMS\Core\Session\SessionManager;
27
use TYPO3\CMS\Core\Utility\GeneralUtility;
28
use TYPO3\CMS\Core\Utility\HttpUtility;
29
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
30
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
31
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
32
33
/**
34
 * Backend module user administration controller
35
 * @internal This class is a TYPO3 Backend implementation and is not considered part of the Public TYPO3 API.
36
 */
37
class BackendUserController extends ActionController
38
{
39
    /**
40
     * @var int
41
     */
42
    const RECENT_USERS_LIMIT = 3;
43
44
    /**
45
     * @var \TYPO3\CMS\Beuser\Domain\Model\ModuleData
46
     */
47
    protected $moduleData;
48
49
    /**
50
     * @var ModuleDataStorageService
51
     */
52
    protected $moduleDataStorageService;
53
54
    /**
55
     * @var BackendUserRepository
56
     */
57
    protected $backendUserRepository;
58
59
    /**
60
     * @var BackendUserGroupRepository
61
     */
62
    protected $backendUserGroupRepository;
63
64
    /**
65
     * @var BackendUserSessionRepository
66
     */
67
    protected $backendUserSessionRepository;
68
69
    /**
70
     * @var UserInformationService
71
     */
72
    protected $userInformationService;
73
74
    public function __construct(
75
        ModuleDataStorageService $moduleDataStorageService,
76
        BackendUserRepository $backendUserRepository,
77
        BackendUserGroupRepository $backendUserGroupRepository,
78
        BackendUserSessionRepository $backendUserSessionRepository,
79
        UserInformationService $userInformationService
80
    ) {
81
        $this->moduleDataStorageService = $moduleDataStorageService;
82
        $this->backendUserRepository = $backendUserRepository;
83
        $this->backendUserGroupRepository = $backendUserGroupRepository;
84
        $this->backendUserSessionRepository = $backendUserSessionRepository;
85
        $this->userInformationService = $userInformationService;
86
    }
87
88
    /**
89
     * Load and persist module data
90
     *
91
     * @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request
92
     * @param \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response
93
     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
94
     */
95
    public function processRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request, \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response)
96
    {
97
        $this->moduleData = $this->moduleDataStorageService->loadModuleData();
98
        // We "finally" persist the module data.
99
        try {
100
            parent::processRequest($request, $response);
101
            $this->moduleDataStorageService->persistModuleData($this->moduleData);
102
        } catch (\TYPO3\CMS\Extbase\Mvc\Exception\StopActionException $e) {
103
            $this->moduleDataStorageService->persistModuleData($this->moduleData);
104
            throw $e;
105
        }
106
    }
107
108
    /**
109
     * Assign default variables to view
110
     * @param ViewInterface $view
111
     */
112
    protected function initializeView(ViewInterface $view)
113
    {
114
        $view->assignMultiple([
115
            'shortcutLabel' => 'backendUsers',
116
            'dateFormat' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'],
117
            'timeFormat' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'],
118
        ]);
119
    }
120
121
    /**
122
     * Displays all BackendUsers
123
     * - Switch session to different user
124
     *
125
     * @param \TYPO3\CMS\Beuser\Domain\Model\Demand $demand
126
     */
127
    public function indexAction(\TYPO3\CMS\Beuser\Domain\Model\Demand $demand = null)
128
    {
129
        if ($demand === null) {
130
            $demand = $this->moduleData->getDemand();
131
        } else {
132
            $this->moduleData->setDemand($demand);
133
        }
134
        // Switch user until logout
135
        $switchUser = (int)GeneralUtility::_GP('SwitchUser');
136
        if ($switchUser > 0) {
137
            $this->switchUser($switchUser);
138
        }
139
        $compareUserList = $this->moduleData->getCompareUserList();
140
141
        $this->view->assignMultiple([
142
            'onlineBackendUsers' => $this->getOnlineBackendUsers(),
143
            'demand' => $demand,
144
            'backendUsers' => $this->backendUserRepository->findDemanded($demand),
145
            'backendUserGroups' => array_merge([''], $this->backendUserGroupRepository->findAll()->toArray()),
146
            'compareUserUidList' => array_combine($compareUserList, $compareUserList),
147
            'currentUserUid' => $this->getBackendUserAuthentication()->user['uid'],
148
            'compareUserList' => !empty($compareUserList) ? $this->backendUserRepository->findByUidList($compareUserList) : '',
149
        ]);
150
    }
151
152
    /**
153
     * Views all currently logged in BackendUsers and their sessions
154
     */
155
    public function onlineAction()
156
    {
157
        $onlineUsersAndSessions = [];
158
        $onlineUsers = $this->backendUserRepository->findOnline();
159
        foreach ($onlineUsers as $onlineUser) {
160
            $onlineUsersAndSessions[] = [
161
                'backendUser' => $onlineUser,
162
                'sessions' => $this->backendUserSessionRepository->findByBackendUser($onlineUser)
163
            ];
164
        }
165
166
        $this->view->assignMultiple([
167
            'shortcutLabel' => 'onlineUsers',
168
            'onlineUsersAndSessions' => $onlineUsersAndSessions,
169
            'currentSessionId' => $this->getBackendUserAuthentication()->user['ses_id'],
170
        ]);
171
    }
172
173
    /**
174
     * @param int $uid
175
     */
176
    public function showAction(int $uid = 0): void
177
    {
178
        $data = $this->userInformationService->get($uid);
179
        $this->view->assignMultiple([
180
            'shortcutLabel' => 'showUser',
181
            'data' => $data
182
        ]);
183
    }
184
185
    /**
186
     * Compare backend users from demand
187
     */
188
    public function compareAction()
189
    {
190
        $compareUserList = $this->moduleData->getCompareUserList();
191
        if (empty($compareUserList)) {
192
            $this->redirect('index');
193
        }
194
195
        $compareData = [];
196
        foreach ($compareUserList as $uid) {
197
            $compareData[] =  $this->userInformationService->get($uid);
198
        }
199
200
        $this->view->assignMultiple([
201
            'shortcutLabel' => 'compareUsers',
202
            'compareUserList' => $compareData,
203
            'onlineBackendUsers' => $this->getOnlineBackendUsers()
204
        ]);
205
    }
206
207
    /**
208
     * Attaches one backend user to the compare list
209
     *
210
     * @param int $uid
211
     */
212
    public function addToCompareListAction($uid)
213
    {
214
        $this->moduleData->attachUidCompareUser($uid);
215
        $this->moduleDataStorageService->persistModuleData($this->moduleData);
216
        $this->forward('index');
217
    }
218
219
    /**
220
     * Removes given backend user to the compare list
221
     *
222
     * @param int $uid
223
     */
224
    public function removeFromCompareListAction($uid)
225
    {
226
        $this->moduleData->detachUidCompareUser($uid);
227
        $this->moduleDataStorageService->persistModuleData($this->moduleData);
228
        $this->forward('index');
229
    }
230
231
    /**
232
     * Terminate BackendUser session and logout corresponding client
233
     * Redirects to onlineAction with message
234
     *
235
     * @param \TYPO3\CMS\Beuser\Domain\Model\BackendUser $backendUser
236
     * @param string $sessionId
237
     */
238
    protected function terminateBackendUserSessionAction(\TYPO3\CMS\Beuser\Domain\Model\BackendUser $backendUser, $sessionId)
0 ignored issues
show
Unused Code introduced by
The parameter $backendUser is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

238
    protected function terminateBackendUserSessionAction(/** @scrutinizer ignore-unused */ \TYPO3\CMS\Beuser\Domain\Model\BackendUser $backendUser, $sessionId)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
239
    {
240
        $sessionBackend = $this->getSessionBackend();
241
        $success = $sessionBackend->remove($sessionId);
242
243
        if ($success) {
244
            $this->addFlashMessage(LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:terminateSessionSuccess', 'beuser'));
245
        }
246
        $this->forward('online');
247
    }
248
249
    /**
250
     * Switches to a given user (SU-mode) and then redirects to the start page of the backend to refresh the navigation etc.
251
     *
252
     * @param string $switchUser BE-user record that will be switched to
253
     */
254
    protected function switchUser($switchUser)
255
    {
256
        $targetUser = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecord('be_users', $switchUser);
0 ignored issues
show
Bug introduced by
$switchUser of type string is incompatible with the type integer expected by parameter $uid of TYPO3\CMS\Backend\Utilit...endUtility::getRecord(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

256
        $targetUser = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecord('be_users', /** @scrutinizer ignore-type */ $switchUser);
Loading history...
257
        if (is_array($targetUser) && $this->getBackendUserAuthentication()->isAdmin()) {
258
            // Set backend user listing module as starting module for switchback
259
            $this->getBackendUserAuthentication()->uc['startModuleOnFirstLogin'] = 'system_BeuserTxBeuser';
260
            $this->getBackendUserAuthentication()->uc['recentSwitchedToUsers'] = $this->generateListOfMostRecentSwitchedUsers($targetUser['uid']);
261
            $this->getBackendUserAuthentication()->writeUC();
262
263
            // User switch   written to log
264
            $this->getBackendUserAuthentication()->writelog(
265
                255,
266
                2,
267
                0,
268
                1,
269
                'User %s switched to user %s (be_users:%s)',
270
                [
271
                    $this->getBackendUserAuthentication()->user['username'],
272
                    $targetUser['username'],
273
                    $targetUser['uid'],
274
                ]
275
            );
276
277
            $sessionBackend = $this->getSessionBackend();
278
            $sessionBackend->update(
279
                $this->getBackendUserAuthentication()->getSessionId(),
280
                [
281
                    'ses_userid' => (int)$targetUser['uid'],
282
                    'ses_backuserid' => (int)$this->getBackendUserAuthentication()->user['uid']
283
                ]
284
            );
285
286
            $event = new SwitchUserEvent(
287
                $this->getBackendUserAuthentication()->getSessionId(),
288
                $targetUser,
289
                $this->getBackendUserAuthentication()->user
290
            );
291
            $this->eventDispatcher->dispatch($event);
292
293
            $redirectUrl = 'index.php' . ($GLOBALS['TYPO3_CONF_VARS']['BE']['interfaces'] ? '' : '?commandLI=1');
294
            HttpUtility::redirect($redirectUrl);
295
        }
296
    }
297
298
    /**
299
     * Generates a list of users to whom where switched in the past. This is limited by RECENT_USERS_LIMIT.
300
     *
301
     * @param int $targetUserUid
302
     * @return int[]
303
     */
304
    protected function generateListOfMostRecentSwitchedUsers(int $targetUserUid): array
305
    {
306
        $latestUserUids = [];
307
        $backendUser = $this->getBackendUserAuthentication();
308
309
        if (isset($backendUser->uc['recentSwitchedToUsers']) && is_array($backendUser->uc['recentSwitchedToUsers'])) {
310
            $latestUserUids = $backendUser->uc['recentSwitchedToUsers'];
311
        }
312
313
        // Remove potentially existing user in that list
314
        $index = array_search($targetUserUid, $latestUserUids, true);
315
        if ($index !== false) {
316
            unset($latestUserUids[$index]);
317
        }
318
319
        array_unshift($latestUserUids, $targetUserUid);
320
        $latestUserUids = array_slice($latestUserUids, 0, static::RECENT_USERS_LIMIT);
321
322
        return $latestUserUids;
323
    }
324
325
    /**
326
     * @return BackendUserAuthentication
327
     */
328
    protected function getBackendUserAuthentication(): BackendUserAuthentication
329
    {
330
        return $GLOBALS['BE_USER'];
331
    }
332
333
    /**
334
     * @return SessionBackendInterface
335
     */
336
    protected function getSessionBackend()
337
    {
338
        $loginType = $this->getBackendUserAuthentication()->getLoginType();
339
        return GeneralUtility::makeInstance(SessionManager::class)->getSessionBackend($loginType);
340
    }
341
342
    /**
343
     * Create an array with the uids of online users as the keys
344
     * [
345
     *   1 => true,
346
     *   5 => true
347
     * ]
348
     * @return array
349
     */
350
    protected function getOnlineBackendUsers(): array
351
    {
352
        $onlineUsers = $this->backendUserSessionRepository->findAllActive();
353
        $onlineBackendUsers = [];
354
        if (is_array($onlineUsers)) {
0 ignored issues
show
introduced by
The condition is_array($onlineUsers) is always true.
Loading history...
355
            foreach ($onlineUsers as $onlineUser) {
356
                $onlineBackendUsers[$onlineUser['ses_userid']] = true;
357
            }
358
        }
359
        return $onlineBackendUsers;
360
    }
361
}
362