Issues (186)

includes/Pages/PageUserManagement.php (4 issues)

1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 * ACC Development Team. Please see team.json for a list of contributors.     *
5
 *                                                                            *
6
 * This is free and unencumbered software released into the public domain.    *
7
 * Please see LICENSE.md for the full licencing statement.                    *
8
 ******************************************************************************/
9
10
namespace Waca\Pages;
11
12
use Exception;
13
use PDO;
14
use Smarty\Exception as SmartyException;
15
use Waca\DataObjects\Domain;
16
use Waca\DataObjects\User;
17
use Waca\DataObjects\UserRole;
18
use Waca\Exceptions\ApplicationLogicException;
19
use Waca\Exceptions\OptimisticLockFailedException;
20
use Waca\Helpers\Logger;
21
use Waca\Helpers\OAuthUserHelper;
22
use Waca\Helpers\PreferenceManager;
23
use Waca\Helpers\SearchHelpers\UserSearchHelper;
24
use Waca\PdoDatabase;
25
use Waca\SessionAlert;
26
use Waca\Tasks\InternalPageBase;
27
use Waca\WebRequest;
28
29
/**
30
 * Class PageUserManagement
31
 * @package Waca\Pages
32
 */
33
class PageUserManagement extends InternalPageBase
34
{
35
    const OAUTH_STATE_NONE = 'none';
36
    const OAUTH_STATE_PARTIAL = 'partial';
37
    const OAUTH_STATE_FULL = 'full';
38
39
    // FIXME: domains
40
    /** @var string */
41
    private $adminMailingList = '[email protected]';
42
43
    private function getOAuthStatusMap(PdoDatabase $database): array
44
    {
45
        $oauthStatusQuery = $database->prepare(
46
            <<<SQL
47
    SELECT u.id,
48
           CASE
49
               WHEN SUM(IF(ot.type = :access, 1, 0)) OVER (PARTITION BY ot.user) > 0 THEN :full
50
               WHEN SUM(IF(ot.type = :request, 1, 0)) OVER (PARTITION BY ot.user) > 0 THEN :partial
51
               ELSE :none
52
           END AS status
53
    FROM user u 
54
    LEFT JOIN oauthtoken ot ON u.id = ot.user;
55
SQL
56
        );
57
58
        $oauthStatusQuery->execute([
59
            ':access' => OAuthUserHelper::TOKEN_ACCESS,
60
            ':request' => OAuthUserHelper::TOKEN_REQUEST,
61
            ':full' => self::OAUTH_STATE_FULL,
62
            ':partial' => self::OAUTH_STATE_PARTIAL,
63
            ':none' => self::OAUTH_STATE_NONE,
64
        ]);
65
        $oauthStatusRawData = $oauthStatusQuery->fetchAll(PDO::FETCH_ASSOC);
66
        $oauthStatusQuery->closeCursor();
67
        $oauthStatusMap = [];
68
69
        foreach ($oauthStatusRawData as $row) {
70
            $oauthStatusMap[(int)$row['id']] = $row['status'];
71
        }
72
73
        return $oauthStatusMap;
74
    }
75
76
    /**
77
     * Main function for this page, when no specific actions are called.
78
     */
79
    protected function main()
80
    {
81
        $this->setHtmlTitle('User Management');
82
83
        $database = $this->getDatabase();
84
        $currentUser = User::getCurrent($database);
85
86
        $userSearchRequest = WebRequest::getString('usersearch');
87
        if ($userSearchRequest !== null) {
88
            $searchedUser = User::getByUsername($userSearchRequest, $database);
89
            if ($searchedUser !== false) {
90
                $this->redirect('statistics/users', 'detail', ['user' => $searchedUser->getId()]);
91
                return;
92
            }
93
        }
94
95
        $this->assign('oauthStatusMap', $this->getOAuthStatusMap($database));
96
97
        if (WebRequest::getBoolean("showAll")) {
98
            $this->assign("showAll", true);
99
100
            $deactivatedUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_DEACTIVATED)->fetch();
101
            $this->assign('deactivatedUsers', $deactivatedUsers);
102
103
            UserSearchHelper::get($database)->getRoleMap($roleMap);
104
        }
105
        else {
106
            $this->assign("showAll", false);
107
            $this->assign('deactivatedUsers', array());
108
109
            UserSearchHelper::get($database)->statusIn(array('New', 'Active'))->getRoleMap($roleMap);
110
        }
111
112
        $newUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_NEW)->fetch();
113
        $normalUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_ACTIVE)->byRole('user')->fetch();
114
        $adminUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_ACTIVE)->byRole('admin')->fetch();
115
        $checkUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_ACTIVE)->byRole('checkuser')->fetch();
116
        $stewards = UserSearchHelper::get($database)->byStatus(User::STATUS_ACTIVE)->byRole('steward')->fetch();
117
        $toolRoots = UserSearchHelper::get($database)->byStatus(User::STATUS_ACTIVE)->byRole('toolRoot')->fetch();
118
        $this->assign('newUsers', $newUsers);
119
        $this->assign('normalUsers', $normalUsers);
120
        $this->assign('adminUsers', $adminUsers);
121
        $this->assign('checkUsers', $checkUsers);
122
        $this->assign('stewards', $stewards);
123
        $this->assign('toolRoots', $toolRoots);
124
125
        $this->assign('roles', $roleMap);
126
127
        $this->addJs("/api.php?action=users&all=true&targetVariable=typeaheaddata");
128
129
        $this->assign('canApprove', $this->barrierTest('approve', $currentUser));
130
        $this->assign('canDeactivate', $this->barrierTest('deactivate', $currentUser));
131
        $this->assign('canRename', $this->barrierTest('rename', $currentUser));
132
        $this->assign('canEditUser', $this->barrierTest('editUser', $currentUser));
133
        $this->assign('canEditRoles', $this->barrierTest('editRoles', $currentUser));
134
135
        // FIXME: domains!
136
        /** @var Domain $domain */
137
        $domain = Domain::getById(1, $this->getDatabase());
138
        $this->assign('mediawikiScriptPath', $domain->getWikiArticlePath());
139
140
        $this->setTemplate("usermanagement/main.tpl");
141
    }
142
143
    #region Access control
144
145
    /**
146
     * Action target for editing the roles assigned to a user
147
     *
148
     * @throws ApplicationLogicException
149
     * @throws SmartyException
150
     * @throws OptimisticLockFailedException
151
     * @throws Exception
152
     */
153
    protected function editRoles(): void
154
    {
155
        $this->setHtmlTitle('User Management');
156
        $database = $this->getDatabase();
157
        $domain = Domain::getCurrent($database);
158
        $userId = WebRequest::getInt('user');
159
160
        /** @var User|false $user */
161
        $user = User::getById($userId, $database);
162
163
        if ($user === false || $user->isCommunityUser()) {
164
            throw new ApplicationLogicException('Sorry, the user you are trying to edit could not be found.');
165
        }
166
167
        $roleData = $this->getRoleData(UserRole::getForUser($user->getId(), $database, $domain->getId()));
168
169
        // Dual-mode action
170
        if (WebRequest::wasPosted()) {
171
            $this->validateCSRFToken();
172
173
            $reason = WebRequest::postString('reason');
174
            if ($reason === false || trim($reason) === '') {
175
                throw new ApplicationLogicException('No reason specified for roles change');
176
            }
177
178
            /** @var UserRole[] $delete */
179
            $delete = array();
180
            /** @var string[] $add */
181
            $add = array();
182
183
            /** @var UserRole[] $globalDelete */
184
            $globalDelete = array();
185
            /** @var string[] $globalAdd */
186
            $globalAdd = array();
187
188
            foreach ($roleData as $name => $r) {
189
                if ($r['allowEdit'] !== 1) {
190
                    // not allowed, to touch this, so ignore it
191
                    continue;
192
                }
193
194
                $newValue = WebRequest::postBoolean('role-' . $name) ? 1 : 0;
195
                if ($newValue !== $r['active']) {
196
                    if ($newValue === 0) {
197
                        if ($r['globalOnly']) {
198
                            $globalDelete[] = $r['object'];
199
                        }
200
                        else {
201
                            $delete[] = $r['object'];
202
                        }
203
                    }
204
205
                    if ($newValue === 1) {
206
                        if ($r['globalOnly']) {
207
                            $globalAdd[] = $name;
208
                        }
209
                        else {
210
                            $add[] = $name;
211
                        }
212
                    }
213
                }
214
            }
215
216
            // Check there's something to do
217
            if ((count($add) + count($delete) + count($globalAdd) + count($globalDelete)) === 0) {
218
                $this->redirect('statistics/users', 'detail', array('user' => $user->getId()));
219
                SessionAlert::warning('No changes made to roles.');
220
221
                return;
222
            }
223
224
            $removed = array();
225
            $globalRemoved = array();
226
227
            foreach ($delete as $d) {
228
                $removed[] = $d->getRole();
229
                $d->delete();
230
            }
231
232
            foreach ($globalDelete as $d) {
233
                $globalRemoved[] = $d->getRole();
234
                $d->delete();
235
            }
236
237
            foreach ($add as $x) {
238
                $a = new UserRole();
239
                $a->setUser($user->getId());
240
                $a->setRole($x);
241
                $a->setDomain($domain->getId());
242
                $a->setDatabase($database);
243
                $a->save();
244
            }
245
246
            foreach ($globalAdd as $x) {
247
                $a = new UserRole();
248
                $a->setUser($user->getId());
249
                $a->setRole($x);
250
                $a->setDomain(null);
251
                $a->setDatabase($database);
252
                $a->save();
253
            }
254
255
            if ((count($add) + count($delete)) > 0) {
256
                Logger::userRolesEdited($database, $user, $reason, $add, $removed, $domain->getId());
257
            }
258
259
            if ((count($globalAdd) + count($globalDelete)) > 0) {
260
                Logger::userGlobalRolesEdited($database, $user, $reason, $globalAdd, $globalRemoved);
261
            }
262
263
            // dummy save for optimistic locking. If this fails, the entire txn will roll back.
264
            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
265
            $user->save();
266
267
            $this->getNotificationHelper()->userRolesEdited($user, $reason);
268
            SessionAlert::quick('Roles changed for user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
269
270
            $this->redirect('statistics/users', 'detail', array('user' => $user->getId()));
271
        }
272
        else {
273
            $this->assignCSRFToken();
274
            $this->setTemplate('usermanagement/roleedit.tpl');
275
            $this->assign('user', $user);
276
            $this->assign('roleData', $roleData);
277
        }
278
    }
279
280
    /**
281
     * Action target for deactivating users
282
     *
283
     * @throws ApplicationLogicException
284
     */
285
    protected function deactivate()
286
    {
287
        $this->setHtmlTitle('User Management');
288
289
        $database = $this->getDatabase();
290
291
        $userId = WebRequest::getInt('user');
292
293
        /** @var User $user */
294
        $user = User::getById($userId, $database);
295
296
        if ($user === false || $user->isCommunityUser()) {
297
            throw new ApplicationLogicException('Sorry, the user you are trying to deactivate could not be found.');
298
        }
299
300
        if ($user->isDeactivated()) {
301
            throw new ApplicationLogicException('Sorry, the user you are trying to deactivate is already deactivated.');
302
        }
303
304
        // Dual-mode action
305
        if (WebRequest::wasPosted()) {
306
            $this->validateCSRFToken();
307
            $reason = WebRequest::postString('reason');
308
309
            if ($reason === null || trim($reason) === '') {
310
                throw new ApplicationLogicException('No reason provided');
311
            }
312
313
            $user->setStatus(User::STATUS_DEACTIVATED);
314
            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
315
            $user->save();
316
            Logger::deactivatedUser($database, $user, $reason);
317
318
            $this->getNotificationHelper()->userDeactivated($user);
319
            SessionAlert::quick('Deactivated user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
320
321
            // send email
322
            $this->sendStatusChangeEmail(
323
                'Your WP:ACC account has been deactivated',
324
                'usermanagement/emails/deactivated.tpl',
325
                $reason,
326
                $user,
327
                User::getCurrent($database)->getUsername()
328
            );
329
330
            $this->redirect('userManagement');
331
332
            return;
333
        }
334
        else {
335
            $this->assignCSRFToken();
336
            $this->setTemplate('usermanagement/changelevel-reason.tpl');
337
            $this->assign('user', $user);
338
            $this->assign('status', User::STATUS_DEACTIVATED);
339
            $this->assign("showReason", true);
340
341
            if (WebRequest::getString('preload')) {
342
                $this->assign('preload', WebRequest::getString('preload'));
343
            }
344
        }
345
    }
346
347
    /**
348
     * Entry point for the approve action
349
     *
350
     * @throws ApplicationLogicException
351
     */
352
    protected function approve()
353
    {
354
        $this->setHtmlTitle('User Management');
355
356
        $database = $this->getDatabase();
357
358
        $userId = WebRequest::getInt('user');
359
        $user = User::getById($userId, $database);
360
361
        if ($user === false || $user->isCommunityUser()) {
362
            throw new ApplicationLogicException('Sorry, the user you are trying to approve could not be found.');
363
        }
364
365
        if ($user->isActive()) {
366
            throw new ApplicationLogicException('Sorry, the user you are trying to approve is already an active user.');
367
        }
368
369
        // Dual-mode action
370
        if (WebRequest::wasPosted()) {
371
            $this->validateCSRFToken();
372
            $user->setStatus(User::STATUS_ACTIVE);
373
            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
374
            $user->save();
375
            Logger::approvedUser($database, $user);
376
377
            $this->getNotificationHelper()->userApproved($user);
378
            SessionAlert::quick('Approved user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
379
380
            // send email
381
            $this->sendStatusChangeEmail(
382
                'Your WP:ACC account has been approved',
383
                'usermanagement/emails/approved.tpl',
384
                null,
385
                $user,
386
                User::getCurrent($database)->getUsername()
387
            );
388
389
            $this->redirect("userManagement");
390
391
            return;
392
        }
393
        else {
394
            $this->assignCSRFToken();
395
            $this->setTemplate("usermanagement/changelevel-reason.tpl");
396
            $this->assign("user", $user);
397
            $this->assign("status", "Active");
398
            $this->assign("showReason", false);
399
        }
400
    }
401
402
    #endregion
403
404
    #region Renaming / Editing
405
406
    /**
407
     * Entry point for the rename action
408
     *
409
     * @throws ApplicationLogicException
410
     */
411
    protected function rename()
412
    {
413
        $this->setHtmlTitle('User Management');
414
415
        $database = $this->getDatabase();
416
417
        $userId = WebRequest::getInt('user');
418
        $user = User::getById($userId, $database);
419
420
        if ($user === false || $user->isCommunityUser()) {
421
            throw new ApplicationLogicException('Sorry, the user you are trying to rename could not be found.');
422
        }
423
424
        // Dual-mode action
425
        if (WebRequest::wasPosted()) {
426
            $this->validateCSRFToken();
427
            $newUsername = WebRequest::postString('newname');
428
429
            if ($newUsername === null || trim($newUsername) === "") {
430
                throw new ApplicationLogicException('The new username cannot be empty');
431
            }
432
433
            if (User::getByUsername($newUsername, $database) != false) {
434
                throw new ApplicationLogicException('The new username already exists');
435
            }
436
437
            $oldUsername = $user->getUsername();
438
            $user->setUsername($newUsername);
439
            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
440
441
            $user->save();
442
443
            $logEntryData = serialize(array(
444
                'old' => $oldUsername,
445
                'new' => $newUsername,
446
            ));
447
448
            Logger::renamedUser($database, $user, $logEntryData);
449
450
            SessionAlert::quick("Changed User "
451
                . htmlentities($oldUsername, ENT_COMPAT, 'UTF-8')
452
                . " name to "
453
                . htmlentities($newUsername, ENT_COMPAT, 'UTF-8'));
454
455
            $this->getNotificationHelper()->userRenamed($user, $oldUsername);
456
457
            // send an email to the user.
458
            $this->assign('targetUsername', $user->getUsername());
459
            $this->assign('toolAdmin', User::getCurrent($database)->getUsername());
460
            $this->assign('oldUsername', $oldUsername);
461
            $this->assign('mailingList', $this->adminMailingList);
462
463
            // FIXME: domains!
464
            /** @var Domain $domain */
465
            $domain = Domain::getById(1, $database);
0 ignored issues
show
The assignment to $domain is dead and can be removed.
Loading history...
466
            $this->getEmailHelper()->sendMail(
467
                $this->adminMailingList,
468
                $user->getEmail(),
469
                'Your username on WP:ACC has been changed',
470
                $this->fetchTemplate('usermanagement/emails/renamed.tpl')
471
            );
472
473
            $this->redirect("userManagement");
474
475
            return;
476
        }
477
        else {
478
            $this->assignCSRFToken();
479
            $this->setTemplate('usermanagement/renameuser.tpl');
480
            $this->assign('user', $user);
481
        }
482
    }
483
484
    /**
485
     * Entry point for the edit action
486
     *
487
     * @throws ApplicationLogicException
488
     */
489
    protected function editUser()
490
    {
491
        $this->setHtmlTitle('User Management');
492
493
        $database = $this->getDatabase();
494
495
        $userId = WebRequest::getInt('user');
496
        $user = User::getById($userId, $database);
497
        $oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
498
499
        if ($user === false || $user->isCommunityUser()) {
500
            throw new ApplicationLogicException('Sorry, the user you are trying to edit could not be found.');
501
        }
502
503
        // FIXME: domains
504
        $prefs = new PreferenceManager($database, $user->getId(), 1);
505
506
        // Dual-mode action
507
        if (WebRequest::wasPosted()) {
508
            $this->validateCSRFToken();
509
            $newEmail = WebRequest::postEmail('user_email');
510
            $newOnWikiName = WebRequest::postString('user_onwikiname');
511
512
            if ($newEmail === null) {
513
                throw new ApplicationLogicException('Invalid email address');
514
            }
515
516
            if ($this->validateUnusedEmail($newEmail, $userId)) {
0 ignored issues
show
It seems like $userId can also be of type null; however, parameter $userId of Waca\Pages\PageUserManag...::validateUnusedEmail() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

516
            if ($this->validateUnusedEmail($newEmail, /** @scrutinizer ignore-type */ $userId)) {
Loading history...
517
                throw new ApplicationLogicException('The specified email address is already in use.');
518
            }
519
520
            if (!($oauth->isFullyLinked() || $oauth->isPartiallyLinked())) {
521
                if (trim($newOnWikiName) == "") {
0 ignored issues
show
It seems like $newOnWikiName can also be of type null; however, parameter $string of trim() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

521
                if (trim(/** @scrutinizer ignore-type */ $newOnWikiName) == "") {
Loading history...
522
                    throw new ApplicationLogicException('New on-wiki username cannot be blank');
523
                }
524
525
                $user->setOnWikiName($newOnWikiName);
526
            }
527
528
            $user->setEmail($newEmail);
529
530
            $prefs->setLocalPreference(PreferenceManager::PREF_CREATION_MODE, WebRequest::postInt('creationmode'));
531
532
            $prefs->setLocalPreference(PreferenceManager::ADMIN_PREF_PREVENT_REACTIVATION, WebRequest::postBoolean('preventReactivation'));
533
534
            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
535
536
            $user->save();
537
538
            Logger::userPreferencesChange($database, $user);
539
            $this->getNotificationHelper()->userPrefChange($user);
540
            SessionAlert::quick('Changes to user\'s preferences have been saved');
541
542
            $this->redirect("userManagement");
543
544
            return;
545
        }
546
        else {
547
            $this->assignCSRFToken();
548
            $oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(),
549
                $this->getSiteConfiguration());
550
            $this->setTemplate('usermanagement/edituser.tpl');
551
            $this->assign('user', $user);
552
            $this->assign('oauth', $oauth);
553
554
            $this->assign('preferredCreationMode', (int)$prefs->getPreference(PreferenceManager::PREF_CREATION_MODE));
555
            $this->assign('emailSignature', $prefs->getPreference(PreferenceManager::PREF_EMAIL_SIGNATURE));
556
557
            $this->assign('preventReactivation', $prefs->getPreference(PreferenceManager::ADMIN_PREF_PREVENT_REACTIVATION) ?? false);
558
559
            $this->assign('canManualCreate',
560
                $this->barrierTest(PreferenceManager::CREATION_MANUAL, $user, 'RequestCreation'));
561
            $this->assign('canOauthCreate',
562
                $this->barrierTest(PreferenceManager::CREATION_OAUTH, $user, 'RequestCreation'));
563
            $this->assign('canBotCreate',
564
                $this->barrierTest(PreferenceManager::CREATION_BOT, $user, 'RequestCreation'));
565
        }
566
    }
567
568
    #endregion
569
570
    private function validateUnusedEmail(string $email, int $userId) : bool {
571
        $query = 'SELECT COUNT(id) FROM user WHERE email = :email AND id <> :uid';
572
        $statement = $this->getDatabase()->prepare($query);
573
        $statement->execute(array(':email' => $email, ':uid' => $userId));
574
        $inUse = $statement->fetchColumn() > 0;
575
        $statement->closeCursor();
576
577
        return $inUse;
578
    }
579
580
    /**
581
     * Sends a status change email to the user.
582
     *
583
     * @param string      $subject           The subject of the email
584
     * @param string      $template          The smarty template to use
585
     * @param string|null $reason            The reason for performing the status change
586
     * @param User        $user              The user affected
587
     * @param string      $toolAdminUsername The tool admin's username who is making the edit
588
     */
589
    private function sendStatusChangeEmail($subject, $template, $reason, $user, $toolAdminUsername)
590
    {
591
        $this->assign('targetUsername', $user->getUsername());
592
        $this->assign('toolAdmin', $toolAdminUsername);
593
        $this->assign('actionReason', $reason);
594
        $this->assign('mailingList', $this->adminMailingList);
595
596
        // FIXME: domains!
597
        /** @var Domain $domain */
598
        $domain = Domain::getById(1, $this->getDatabase());
0 ignored issues
show
The assignment to $domain is dead and can be removed.
Loading history...
599
        $this->getEmailHelper()->sendMail(
600
            $this->adminMailingList,
601
            $user->getEmail(),
602
            $subject,
603
            $this->fetchTemplate($template)
604
        );
605
    }
606
607
    /**
608
     * @param UserRole[] $activeRoles
609
     *
610
     * @return array
611
     */
612
    private function getRoleData($activeRoles)
613
    {
614
        $availableRoles = $this->getSecurityManager()->getAvailableRoles();
615
616
        $currentUser = User::getCurrent($this->getDatabase());
617
        $this->getSecurityManager()->getActiveRoles($currentUser, $userRoles, $inactiveRoles);
618
619
        $initialValue = array('active' => 0, 'allowEdit' => 0, 'description' => '???', 'object' => null);
620
621
        $roleData = array();
622
        foreach ($availableRoles as $role => $data) {
623
            $intersection = array_intersect($data['editableBy'], $userRoles);
624
625
            $roleData[$role] = $initialValue;
626
            $roleData[$role]['allowEdit'] = count($intersection) > 0 ? 1 : 0;
627
            $roleData[$role]['description'] = $data['description'];
628
            $roleData[$role]['globalOnly'] = $data['globalOnly'];
629
        }
630
631
        foreach ($activeRoles as $role) {
632
            if (!isset($roleData[$role->getRole()])) {
633
                // This value is no longer available in the configuration, allow changing (aka removing) it.
634
                $roleData[$role->getRole()] = $initialValue;
635
                $roleData[$role->getRole()]['allowEdit'] = 1;
636
            }
637
638
            $roleData[$role->getRole()]['object'] = $role;
639
            $roleData[$role->getRole()]['active'] = 1;
640
        }
641
642
        return $roleData;
643
    }
644
}
645