Passed
Push — develop ( c2019a...2cab77 )
by Felipe
04:50
created

RolesController   F

Complexity

Total Complexity 111

Size/Duplication

Total Lines 847
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 111
dl 0
loc 847
rs 1.263
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
B doDefault() 0 112 3
B doAccount() 0 53 5
C render() 0 67 15
A doDrop() 0 23 3
D doProperties() 0 113 16
B doSaveCreate() 0 34 4
D doCreate() 0 99 13
A _populateMemberof() 0 12 4
F _adjustPostVars() 0 33 10
A _populateMembers() 0 12 4
A _populateAdminmembers() 0 12 4
B doChangePassword() 0 42 5
B doSaveAlter() 0 26 6
D doAlter() 0 113 19

How to fix   Complexity   

Complex Class

Complex classes like RolesController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use RolesController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.48
5
 */
6
7
namespace PHPPgAdmin\Controller;
8
9
use PHPPgAdmin\Decorators\Decorator;
10
11
/**
12
 * Base controller class.
13
 *
14
 * @package PHPPgAdmin
15
 */
16
class RolesController extends BaseController
17
{
18
    public $controller_title = 'strroles';
19
20
    /**
21
     * Default method to render the controller according to the action parameter.
22
     */
23
    public function render()
24
    {
25
        $this->printHeader();
26
        $this->printBody();
27
28
        switch ($this->action) {
29
            case 'create':
30
                $this->doCreate();
31
32
                break;
33
            case 'save_create':
34
                if (isset($_POST['create'])) {
35
                    $this->doSaveCreate();
36
                } else {
37
                    $this->doDefault();
38
                }
39
40
                break;
41
            case 'alter':
42
                $this->doAlter();
43
44
                break;
45
            case 'save_alter':
46
                if (isset($_POST['alter'])) {
47
                    $this->doSaveAlter();
48
                } else {
49
                    $this->doDefault();
50
                }
51
52
                break;
53
            case 'confirm_drop':
54
                $this->doDrop(true);
55
56
                break;
57
            case 'drop':
58
                if (isset($_POST['drop'])) {
59
                    $this->doDrop(false);
60
                } else {
61
                    $this->doDefault();
62
                }
63
64
                break;
65
            case 'properties':
66
                $this->doProperties();
67
68
                break;
69
            case 'confchangepassword':
70
                $this->doChangePassword(true);
71
72
                break;
73
            case 'changepassword':
74
                if (isset($_REQUEST['ok'])) {
75
                    $this->doChangePassword(false);
76
                } else {
77
                    $this->doAccount();
78
                }
79
80
                break;
81
            case 'account':
82
                $this->doAccount();
83
84
                break;
85
            default:
86
                $this->doDefault();
87
        }
88
89
        $this->printFooter();
90
    }
91
92
    /**
93
     * Show default list of roles in the database.
94
     *
95
     * @param mixed $msg
96
     */
97
    public function doDefault($msg = '')
98
    {
99
        $data = $this->misc->getDatabaseAccessor();
100
101
        $lang                = $this->lang;
102
        $renderRoleConnLimit = function ($val) use ($lang) {
103
            return '-1' == $val ? $lang['strnolimit'] : htmlspecialchars($val);
104
        };
105
106
        $renderRoleExpires = function ($val) use ($lang) {
107
            return 'infinity' == $val ? $lang['strnever'] : htmlspecialchars($val);
108
        };
109
110
        $this->printTrail('server');
111
        $this->printTabs('server', 'roles');
112
        $this->printMsg($msg);
113
114
        $roles = $data->getRoles();
115
116
        $columns = [
117
            'role'       => [
118
                'title' => $this->lang['strrole'],
119
                'field' => Decorator::field('rolname'),
120
                'url'   => \SUBFOLDER."/redirect/role?action=properties&amp;{$this->misc->href}&amp;",
121
                'vars'  => ['rolename' => 'rolname'],
122
            ],
123
            'superuser'  => [
124
                'title' => $this->lang['strsuper'],
125
                'field' => Decorator::field('rolsuper'),
126
                'type'  => 'yesno',
127
            ],
128
            'createdb'   => [
129
                'title' => $this->lang['strcreatedb'],
130
                'field' => Decorator::field('rolcreatedb'),
131
                'type'  => 'yesno',
132
            ],
133
            'createrole' => [
134
                'title' => $this->lang['strcancreaterole'],
135
                'field' => Decorator::field('rolcreaterole'),
136
                'type'  => 'yesno',
137
            ],
138
            'inherits'   => [
139
                'title' => $this->lang['strinheritsprivs'],
140
                'field' => Decorator::field('rolinherit'),
141
                'type'  => 'yesno',
142
            ],
143
            'canloging'  => [
144
                'title' => $this->lang['strcanlogin'],
145
                'field' => Decorator::field('rolcanlogin'),
146
                'type'  => 'yesno',
147
            ],
148
            'connlimit'  => [
149
                'title'  => $this->lang['strconnlimit'],
150
                'field'  => Decorator::field('rolconnlimit'),
151
                'type'   => 'callback',
152
                'params' => ['function' => $renderRoleConnLimit],
153
            ],
154
            'expires'    => [
155
                'title'  => $this->lang['strexpires'],
156
                'field'  => Decorator::field('rolvaliduntil'),
157
                'type'   => 'callback',
158
                'params' => ['function' => $renderRoleExpires, 'null' => $this->lang['strnever']],
159
            ],
160
            'actions'    => [
161
                'title' => $this->lang['stractions'],
162
            ],
163
        ];
164
165
        $actions = [
166
            'alter' => [
167
                'content' => $this->lang['stralter'],
168
                'attr'    => [
169
                    'href' => [
170
                        'url'     => 'roles',
171
                        'urlvars' => [
172
                            'action'   => 'alter',
173
                            'rolename' => Decorator::field('rolname'),
174
                        ],
175
                    ],
176
                ],
177
            ],
178
            'drop'  => [
179
                'content' => $this->lang['strdrop'],
180
                'attr'    => [
181
                    'href' => [
182
                        'url'     => 'roles',
183
                        'urlvars' => [
184
                            'action'   => 'confirm_drop',
185
                            'rolename' => Decorator::field('rolname'),
186
                        ],
187
                    ],
188
                ],
189
            ],
190
        ];
191
192
        echo $this->printTable($roles, $columns, $actions, 'roles-roles', $this->lang['strnoroles']);
193
194
        $navlinks = [
195
            'create' => [
196
                'attr'    => [
197
                    'href' => [
198
                        'url'     => 'roles',
199
                        'urlvars' => [
200
                            'action' => 'create',
201
                            'server' => $_REQUEST['server'],
202
                        ],
203
                    ],
204
                ],
205
                'content' => $this->lang['strcreaterole'],
206
            ],
207
        ];
208
        $this->printNavLinks($navlinks, 'roles-roles', get_defined_vars());
209
    }
210
211
    /**
212
     * Displays a screen for create a new role.
213
     *
214
     * @param mixed $msg
215
     */
216
    public function doCreate($msg = '')
217
    {
218
        $data = $this->misc->getDatabaseAccessor();
219
220
        $this->coalesceArr($_POST, 'formRolename', '');
221
222
        $this->coalesceArr($_POST, 'formPassword', '');
223
224
        $this->coalesceArr($_POST, 'formConfirm', '');
225
226
        $this->coalesceArr($_POST, 'formConnLimit', '');
227
228
        $this->coalesceArr($_POST, 'formExpires', '');
229
230
        $this->coalesceArr($_POST, 'memberof', []);
231
232
        $this->coalesceArr($_POST, 'members', []);
233
234
        $this->coalesceArr($_POST, 'adminmembers', []);
235
236
        $this->printTrail('role');
237
        $this->printTitle($this->lang['strcreaterole'], 'pg.role.create');
238
        $this->printMsg($msg);
239
240
        echo '<form action="'.\SUBFOLDER.'/src/views/roles" method="post">'.PHP_EOL;
241
        echo '<table>'.PHP_EOL;
242
        echo "\t<tr>\n\t\t<th class=\"data left required\" style=\"width: 130px\">{$this->lang['strname']}</th>".PHP_EOL;
243
        echo "\t\t<td class=\"data1\"><input size=\"15\" maxlength=\"{$data->_maxNameLen}\" name=\"formRolename\" value=\"", htmlspecialchars($_POST['formRolename']), "\" /></td>\n\t</tr>".PHP_EOL;
244
        echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['strpassword']}</th>".PHP_EOL;
245
        echo "\t\t<td class=\"data1\"><input size=\"15\" type=\"password\" name=\"formPassword\" value=\"", htmlspecialchars($_POST['formPassword']), "\" /></td>\n\t</tr>".PHP_EOL;
246
        echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['strconfirm']}</th>".PHP_EOL;
247
        echo "\t\t<td class=\"data1\"><input size=\"15\" type=\"password\" name=\"formConfirm\" value=\"", htmlspecialchars($_POST['formConfirm']), "\" /></td>\n\t</tr>".PHP_EOL;
248
        echo "\t<tr>\n\t\t<th class=\"data left\"><label for=\"formSuper\">{$this->lang['strsuper']}</label></th>".PHP_EOL;
249
        echo "\t\t<td class=\"data1\"><input type=\"checkbox\" id=\"formSuper\" name=\"formSuper\"",
250
        (isset($_POST['formSuper'])) ? ' checked="checked"' : '', " /></td>\n\t</tr>".PHP_EOL;
251
        echo "\t<tr>\n\t\t<th class=\"data left\"><label for=\"formCreateDB\">{$this->lang['strcreatedb']}</label></th>".PHP_EOL;
252
        echo "\t\t<td class=\"data1\"><input type=\"checkbox\" id=\"formCreateDB\" name=\"formCreateDB\"",
253
        (isset($_POST['formCreateDB'])) ? ' checked="checked"' : '', " /></td>\n\t</tr>".PHP_EOL;
254
        echo "\t<tr>\n\t\t<th class=\"data left\"><label for=\"formCreateRole\">{$this->lang['strcancreaterole']}</label></th>".PHP_EOL;
255
        echo "\t\t<td class=\"data1\"><input type=\"checkbox\" id=\"formCreateRole\" name=\"formCreateRole\"",
256
        (isset($_POST['formCreateRole'])) ? ' checked="checked"' : '', " /></td>\n\t</tr>".PHP_EOL;
257
        echo "\t<tr>\n\t\t<th class=\"data left\"><label for=\"formInherits\">{$this->lang['strinheritsprivs']}</label></th>".PHP_EOL;
258
        echo "\t\t<td class=\"data1\"><input type=\"checkbox\" id=\"formInherits\" name=\"formInherits\"",
259
        (isset($_POST['formInherits'])) ? ' checked="checked"' : '', " /></td>\n\t</tr>".PHP_EOL;
260
        echo "\t<tr>\n\t\t<th class=\"data left\"><label for=\"formCanLogin\">{$this->lang['strcanlogin']}</label></th>".PHP_EOL;
261
        echo "\t\t<td class=\"data1\"><input type=\"checkbox\" id=\"formCanLogin\" name=\"formCanLogin\"",
262
        (isset($_POST['formCanLogin'])) ? ' checked="checked"' : '', " /></td>\n\t</tr>".PHP_EOL;
263
        echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['strconnlimit']}</th>".PHP_EOL;
264
        echo "\t\t<td class=\"data1\"><input size=\"4\" name=\"formConnLimit\" value=\"", htmlspecialchars($_POST['formConnLimit']), "\" /></td>\n\t</tr>".PHP_EOL;
265
        echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['strexpires']}</th>".PHP_EOL;
266
        echo "\t\t<td class=\"data1\"><input size=\"23\" name=\"formExpires\" value=\"", htmlspecialchars($_POST['formExpires']), "\" /></td>\n\t</tr>".PHP_EOL;
267
268
        $roles = $data->getRoles();
269
        if ($roles->recordCount() > 0) {
270
            echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['strmemberof']}</th>".PHP_EOL;
271
            echo "\t\t<td class=\"data\">".PHP_EOL;
272
            echo "\t\t\t<select name=\"memberof[]\" multiple=\"multiple\" size=\"", min(20, $roles->recordCount()), '">'.PHP_EOL;
273
            while (!$roles->EOF) {
274
                $rolename = $roles->fields['rolname'];
275
                echo "\t\t\t\t<option value=\"{$rolename}\"",
276
                (in_array($rolename, $_POST['memberof'], true) ? ' selected="selected"' : ''), '>', $this->misc->printVal($rolename), '</option>'.PHP_EOL;
277
                $roles->moveNext();
278
            }
279
            echo "\t\t\t</select>".PHP_EOL;
280
            echo "\t\t</td>\n\t</tr>".PHP_EOL;
281
282
            $roles->moveFirst();
283
            echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['strmembers']}</th>".PHP_EOL;
284
            echo "\t\t<td class=\"data\">".PHP_EOL;
285
            echo "\t\t\t<select name=\"members[]\" multiple=\"multiple\" size=\"", min(20, $roles->recordCount()), '">'.PHP_EOL;
286
            while (!$roles->EOF) {
287
                $rolename = $roles->fields['rolname'];
288
                echo "\t\t\t\t<option value=\"{$rolename}\"",
289
                (in_array($rolename, $_POST['members'], true) ? ' selected="selected"' : ''), '>', $this->misc->printVal($rolename), '</option>'.PHP_EOL;
290
                $roles->moveNext();
291
            }
292
            echo "\t\t\t</select>".PHP_EOL;
293
            echo "\t\t</td>\n\t</tr>".PHP_EOL;
294
295
            $roles->moveFirst();
296
            echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['stradminmembers']}</th>".PHP_EOL;
297
            echo "\t\t<td class=\"data\">".PHP_EOL;
298
            echo "\t\t\t<select name=\"adminmembers[]\" multiple=\"multiple\" size=\"", min(20, $roles->recordCount()), '">'.PHP_EOL;
299
            while (!$roles->EOF) {
300
                $rolename = $roles->fields['rolname'];
301
                echo "\t\t\t\t<option value=\"{$rolename}\"",
302
                (in_array($rolename, $_POST['adminmembers'], true) ? ' selected="selected"' : ''), '>', $this->misc->printVal($rolename), '</option>'.PHP_EOL;
303
                $roles->moveNext();
304
            }
305
            echo "\t\t\t</select>".PHP_EOL;
306
            echo "\t\t</td>\n\t</tr>".PHP_EOL;
307
        }
308
309
        echo '</table>'.PHP_EOL;
310
        echo '<p><input type="hidden" name="action" value="save_create" />'.PHP_EOL;
311
        echo $this->misc->form;
312
        echo "<input type=\"submit\" name=\"create\" value=\"{$this->lang['strcreate']}\" />".PHP_EOL;
313
        echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" /></p>".PHP_EOL;
314
        echo '</form>'.PHP_EOL;
315
    }
316
317
    /**
318
     * Actually creates the new role in the database.
319
     */
320
    public function doSaveCreate()
321
    {
322
        $data = $this->misc->getDatabaseAccessor();
323
324
        $this->coalesceArr($_POST, 'memberof', []);
325
326
        $this->coalesceArr($_POST, 'members', []);
327
328
        $this->coalesceArr($_POST, 'adminmembers', []);
329
330
        // Check data
331
        if ('' == $_POST['formRolename']) {
332
            $this->doCreate($this->lang['strroleneedsname']);
333
        } elseif ($_POST['formPassword'] != $_POST['formConfirm']) {
334
            $this->doCreate($this->lang['strpasswordconfirm']);
335
        } else {
336
            $status = $data->createRole(
337
                $_POST['formRolename'],
338
                $_POST['formPassword'],
339
                isset($_POST['formSuper']),
340
                isset($_POST['formCreateDB']),
341
                isset($_POST['formCreateRole']),
342
                isset($_POST['formInherits']),
343
                isset($_POST['formCanLogin']),
344
                $_POST['formConnLimit'],
345
                $_POST['formExpires'],
346
                $_POST['memberof'],
347
                $_POST['members'],
348
                $_POST['adminmembers']
349
            );
350
            if (0 == $status) {
351
                $this->doDefault($this->lang['strrolecreated']);
352
            } else {
353
                $this->doCreate($this->lang['strrolecreatedbad']);
354
            }
355
        }
356
    }
357
358
    /**
359
     * Adjusts the content of the $_POST superglobal according to role data.
360
     *
361
     * @param \PHPPgAdmin\ADORecordSet $roledata  The roledata
362
     * @param bool                     $canRename Indicates if role can be renamed
363
     */
364
    private function _adjustPostVars($roledata, $canRename)
365
    {
366
        if (isset($_POST['formExpires'])) {
367
            return;
368
        }
369
370
        if ($canRename) {
371
            $_POST['formNewRoleName'] = $roledata->fields['rolname'];
372
        }
373
374
        if ($roledata->fields['rolsuper']) {
375
            $_POST['formSuper'] = '';
376
        }
377
378
        if ($roledata->fields['rolcreatedb']) {
379
            $_POST['formCreateDB'] = '';
380
        }
381
382
        if ($roledata->fields['rolcreaterole']) {
383
            $_POST['formCreateRole'] = '';
384
        }
385
386
        if ($roledata->fields['rolinherit']) {
387
            $_POST['formInherits'] = '';
388
        }
389
390
        if ($roledata->fields['rolcanlogin']) {
391
            $_POST['formCanLogin'] = '';
392
        }
393
394
        $_POST['formConnLimit'] = '-1' == $roledata->fields['rolconnlimit'] ? '' : $roledata->fields['rolconnlimit'];
395
        $_POST['formExpires']   = 'infinity' == $roledata->fields['rolvaliduntil'] ? '' : $roledata->fields['rolvaliduntil'];
396
        $_POST['formPassword']  = '';
397
    }
398
399
    private function _populateMemberof($data)
400
    {
401
        if (!isset($_POST['memberof'])) {
402
            $memberof = $data->getMemberOf($_REQUEST['rolename']);
403
            if ($memberof->recordCount() > 0) {
404
                $i = 0;
405
                while (!$memberof->EOF) {
406
                    $_POST['memberof'][$i++] = $memberof->fields['rolname'];
407
                    $memberof->moveNext();
408
                }
409
            } else {
410
                $_POST['memberof'] = [];
411
            }
412
        }
413
    }
414
415
    private function _populateMembers($data)
416
    {
417
        if (!isset($_POST['members'])) {
418
            $members = $data->getMembers($_REQUEST['rolename']);
419
            if ($members->recordCount() > 0) {
420
                $i = 0;
421
                while (!$members->EOF) {
422
                    $_POST['members'][$i++] = $members->fields['rolname'];
423
                    $members->moveNext();
424
                }
425
            } else {
426
                $_POST['members'] = [];
427
            }
428
        }
429
    }
430
431
    private function _populateAdminmembers($data)
432
    {
433
        if (!isset($_POST['adminmembers'])) {
434
            $adminmembers = $data->getMembers($_REQUEST['rolename'], 't');
435
            if ($adminmembers->recordCount() > 0) {
436
                $i = 0;
437
                while (!$adminmembers->EOF) {
438
                    $_POST['adminmembers'][$i++] = $adminmembers->fields['rolname'];
439
                    $adminmembers->moveNext();
440
                }
441
            } else {
442
                $_POST['adminmembers'] = [];
443
            }
444
        }
445
    }
446
447
    /**
448
     * Function to allow alter a role.
449
     *
450
     * @param mixed $msg
451
     */
452
    public function doAlter($msg = '')
453
    {
454
        $data = $this->misc->getDatabaseAccessor();
455
456
        $this->printTrail('role');
457
        $this->printTitle($this->lang['stralter'], 'pg.role.alter');
458
        $this->printMsg($msg);
459
460
        $roledata = $data->getRole($_REQUEST['rolename']);
461
462
        if ($roledata->recordCount() <= 0) {
463
            echo "<p>{$this->lang['strnodata']}</p>".PHP_EOL;
464
465
            return;
466
        }
467
        $server_info                       = $this->misc->getServerInfo();
468
        $canRename                         = $data->hasUserRename() && ($_REQUEST['rolename'] != $server_info['username']);
469
        $roledata->fields['rolsuper']      = $data->phpBool($roledata->fields['rolsuper']);
470
        $roledata->fields['rolcreatedb']   = $data->phpBool($roledata->fields['rolcreatedb']);
471
        $roledata->fields['rolcreaterole'] = $data->phpBool($roledata->fields['rolcreaterole']);
472
        $roledata->fields['rolinherit']    = $data->phpBool($roledata->fields['rolinherit']);
473
        $roledata->fields['rolcanlogin']   = $data->phpBool($roledata->fields['rolcanlogin']);
474
475
        $this->_adjustPostVars($roledata, $canRename);
476
477
        echo '<form action="'.\SUBFOLDER.'/src/views/roles" method="post">'.PHP_EOL;
478
        echo '<table>'.PHP_EOL;
479
        echo "\t<tr>\n\t\t<th class=\"data left\" style=\"width: 130px\">{$this->lang['strname']}</th>".PHP_EOL;
480
        echo "\t\t<td class=\"data1\">", ($canRename ? "<input name=\"formNewRoleName\" size=\"15\" maxlength=\"{$data->_maxNameLen}\" value=\"".htmlspecialchars($_POST['formNewRoleName']).'" />' : $this->misc->printVal($roledata->fields['rolname'])), "</td>\n\t</tr>".PHP_EOL;
481
        echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['strpassword']}</th>".PHP_EOL;
482
        echo "\t\t<td class=\"data1\"><input type=\"password\" size=\"15\" name=\"formPassword\" value=\"", htmlspecialchars($_POST['formPassword']), "\" /></td>\n\t</tr>".PHP_EOL;
483
        echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['strconfirm']}</th>".PHP_EOL;
484
        echo "\t\t<td class=\"data1\"><input type=\"password\" size=\"15\" name=\"formConfirm\" value=\"\" /></td>\n\t</tr>".PHP_EOL;
485
        echo "\t<tr>\n\t\t<th class=\"data left\"><label for=\"formSuper\">{$this->lang['strsuper']}</label></th>".PHP_EOL;
486
        echo "\t\t<td class=\"data1\"><input type=\"checkbox\" id=\"formSuper\" name=\"formSuper\"",
487
        (isset($_POST['formSuper'])) ? ' checked="checked"' : '', " /></td>\n\t</tr>".PHP_EOL;
488
        echo "\t<tr>\n\t\t<th class=\"data left\"><label for=\"formCreateDB\">{$this->lang['strcreatedb']}</label></th>".PHP_EOL;
489
        echo "\t\t<td class=\"data1\"><input type=\"checkbox\" id=\"formCreateDB\" name=\"formCreateDB\"",
490
        (isset($_POST['formCreateDB'])) ? ' checked="checked"' : '', " /></td>\n\t</tr>".PHP_EOL;
491
        echo "\t<tr>\n\t\t<th class=\"data left\"><label for=\"formCreateRole\">{$this->lang['strcancreaterole']}</label></th>".PHP_EOL;
492
        echo "\t\t<td class=\"data1\"><input type=\"checkbox\" id=\"formCreateRole\" name=\"formCreateRole\"",
493
        (isset($_POST['formCreateRole'])) ? ' checked="checked"' : '', " /></td>\n\t</tr>".PHP_EOL;
494
        echo "\t<tr>\n\t\t<th class=\"data left\"><label for=\"formInherits\">{$this->lang['strinheritsprivs']}</label></th>".PHP_EOL;
495
        echo "\t\t<td class=\"data1\"><input type=\"checkbox\" id=\"formInherits\" name=\"formInherits\"",
496
        (isset($_POST['formInherits'])) ? ' checked="checked"' : '', " /></td>\n\t</tr>".PHP_EOL;
497
        echo "\t<tr>\n\t\t<th class=\"data left\"><label for=\"formCanLogin\">{$this->lang['strcanlogin']}</label></th>".PHP_EOL;
498
        echo "\t\t<td class=\"data1\"><input type=\"checkbox\" id=\"formCanLogin\" name=\"formCanLogin\"",
499
        (isset($_POST['formCanLogin'])) ? ' checked="checked"' : '', " /></td>\n\t</tr>".PHP_EOL;
500
        echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['strconnlimit']}</th>".PHP_EOL;
501
        echo "\t\t<td class=\"data1\"><input size=\"4\" name=\"formConnLimit\" value=\"", htmlspecialchars($_POST['formConnLimit']), "\" /></td>\n\t</tr>".PHP_EOL;
502
        echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['strexpires']}</th>".PHP_EOL;
503
        echo "\t\t<td class=\"data1\"><input size=\"23\" name=\"formExpires\" value=\"", htmlspecialchars($_POST['formExpires']), "\" /></td>\n\t</tr>".PHP_EOL;
504
505
        $this->_populateMemberof($data);
506
        $memberofold = implode(',', $_POST['memberof']);
507
508
        $this->_populateMembers($data);
509
        $membersold = implode(',', $_POST['members']);
510
511
        $this->_populateAdminmembers($data);
512
        $adminmembersold = implode(',', $_POST['adminmembers']);
513
514
        $roles = $data->getRoles($_REQUEST['rolename']);
515
        if ($roles->recordCount() > 0) {
516
            echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['strmemberof']}</th>".PHP_EOL;
517
            echo "\t\t<td class=\"data\">".PHP_EOL;
518
            echo "\t\t\t<select name=\"memberof[]\" multiple=\"multiple\" size=\"", min(20, $roles->recordCount()), '">'.PHP_EOL;
519
            while (!$roles->EOF) {
520
                $rolename = $roles->fields['rolname'];
521
                echo "\t\t\t\t<option value=\"{$rolename}\"",
522
                (in_array($rolename, $_POST['memberof'], true) ? ' selected="selected"' : ''), '>', $this->misc->printVal($rolename), '</option>'.PHP_EOL;
523
                $roles->moveNext();
524
            }
525
            echo "\t\t\t</select>".PHP_EOL;
526
            echo "\t\t</td>\n\t</tr>".PHP_EOL;
527
528
            $roles->moveFirst();
529
            echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['strmembers']}</th>".PHP_EOL;
530
            echo "\t\t<td class=\"data\">".PHP_EOL;
531
            echo "\t\t\t<select name=\"members[]\" multiple=\"multiple\" size=\"", min(20, $roles->recordCount()), '">'.PHP_EOL;
532
            while (!$roles->EOF) {
533
                $rolename = $roles->fields['rolname'];
534
                echo "\t\t\t\t<option value=\"{$rolename}\"",
535
                (in_array($rolename, $_POST['members'], true) ? ' selected="selected"' : ''), '>', $this->misc->printVal($rolename), '</option>'.PHP_EOL;
536
                $roles->moveNext();
537
            }
538
            echo "\t\t\t</select>".PHP_EOL;
539
            echo "\t\t</td>\n\t</tr>".PHP_EOL;
540
541
            $roles->moveFirst();
542
            echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['stradminmembers']}</th>".PHP_EOL;
543
            echo "\t\t<td class=\"data\">".PHP_EOL;
544
            echo "\t\t\t<select name=\"adminmembers[]\" multiple=\"multiple\" size=\"", min(20, $roles->recordCount()), '">'.PHP_EOL;
545
            while (!$roles->EOF) {
546
                $rolename = $roles->fields['rolname'];
547
                echo "\t\t\t\t<option value=\"{$rolename}\"",
548
                (in_array($rolename, $_POST['adminmembers'], true) ? ' selected="selected"' : ''), '>', $this->misc->printVal($rolename), '</option>'.PHP_EOL;
549
                $roles->moveNext();
550
            }
551
            echo "\t\t\t</select>".PHP_EOL;
552
            echo "\t\t</td>\n\t</tr>".PHP_EOL;
553
        }
554
        echo '</table>'.PHP_EOL;
555
556
        echo '<p><input type="hidden" name="action" value="save_alter" />'.PHP_EOL;
557
        echo '<input type="hidden" name="rolename" value="', htmlspecialchars($_REQUEST['rolename']), '" />'.PHP_EOL;
558
        echo '<input type="hidden" name="memberofold" value="', isset($_POST['memberofold']) ? $_POST['memberofold'] : htmlspecialchars($memberofold), '" />'.PHP_EOL;
559
        echo '<input type="hidden" name="membersold" value="', isset($_POST['membersold']) ? $_POST['membersold'] : htmlspecialchars($membersold), '" />'.PHP_EOL;
560
        echo '<input type="hidden" name="adminmembersold" value="', isset($_POST['adminmembersold']) ? $_POST['adminmembersold'] : htmlspecialchars($adminmembersold), '" />'.PHP_EOL;
561
        echo $this->misc->form;
562
        echo "<input type=\"submit\" name=\"alter\" value=\"{$this->lang['stralter']}\" />".PHP_EOL;
563
        echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" /></p>".PHP_EOL;
564
        echo '</form>'.PHP_EOL;
565
    }
566
567
    /**
568
     * Function to save after editing a role.
569
     */
570
    public function doSaveAlter()
571
    {
572
        $data = $this->misc->getDatabaseAccessor();
573
574
        $this->coalesceArr($_POST, 'memberof', []);
575
576
        $this->coalesceArr($_POST, 'members', []);
577
578
        $this->coalesceArr($_POST, 'adminmembers', []);
579
580
        // Check name and password
581
        if (isset($_POST['formNewRoleName']) && '' == $_POST['formNewRoleName']) {
582
            $this->doAlter($this->lang['strroleneedsname']);
583
        } elseif ($_POST['formPassword'] != $_POST['formConfirm']) {
584
            $this->doAlter($this->lang['strpasswordconfirm']);
585
        } else {
586
            if (isset($_POST['formNewRoleName'])) {
587
                $status = $data->setRenameRole($_POST['rolename'], $_POST['formPassword'], isset($_POST['formSuper']), isset($_POST['formCreateDB']), isset($_POST['formCreateRole']), isset($_POST['formInherits']), isset($_POST['formCanLogin']), $_POST['formConnLimit'], $_POST['formExpires'], $_POST['memberof'], $_POST['members'], $_POST['adminmembers'], $_POST['memberofold'], $_POST['membersold'], $_POST['adminmembersold'], $_POST['formNewRoleName']);
588
            } else {
589
                $status = $data->setRole($_POST['rolename'], $_POST['formPassword'], isset($_POST['formSuper']), isset($_POST['formCreateDB']), isset($_POST['formCreateRole']), isset($_POST['formInherits']), isset($_POST['formCanLogin']), $_POST['formConnLimit'], $_POST['formExpires'], $_POST['memberof'], $_POST['members'], $_POST['adminmembers'], $_POST['memberofold'], $_POST['membersold'], $_POST['adminmembersold']);
590
            }
591
592
            if (0 == $status) {
593
                $this->doDefault($this->lang['strrolealtered']);
594
            } else {
595
                $this->doAlter($this->lang['strrolealteredbad']);
596
            }
597
        }
598
    }
599
600
    /**
601
     * Show confirmation of drop a role and perform actual drop.
602
     *
603
     * @param mixed $confirm
604
     */
605
    public function doDrop($confirm)
606
    {
607
        $data = $this->misc->getDatabaseAccessor();
608
609
        if ($confirm) {
610
            $this->printTrail('role');
611
            $this->printTitle($this->lang['strdroprole'], 'pg.role.drop');
612
613
            echo '<p>', sprintf($this->lang['strconfdroprole'], $this->misc->printVal($_REQUEST['rolename'])), '</p>'.PHP_EOL;
614
615
            echo '<form action="'.\SUBFOLDER.'/src/views/roles" method="post">'.PHP_EOL;
616
            echo '<p><input type="hidden" name="action" value="drop" />'.PHP_EOL;
617
            echo '<input type="hidden" name="rolename" value="', htmlspecialchars($_REQUEST['rolename']), '" />'.PHP_EOL;
618
            echo $this->misc->form;
619
            echo "<input type=\"submit\" name=\"drop\" value=\"{$this->lang['strdrop']}\" />".PHP_EOL;
620
            echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" /></p>".PHP_EOL;
621
            echo '</form>'.PHP_EOL;
622
        } else {
623
            $status = $data->dropRole($_REQUEST['rolename']);
624
            if (0 == $status) {
625
                $this->doDefault($this->lang['strroledropped']);
626
            } else {
627
                $this->doDefault($this->lang['strroledroppedbad']);
628
            }
629
        }
630
    }
631
632
    /**
633
     * Show the properties of a role.
634
     *
635
     * @param mixed $msg
636
     */
637
    public function doProperties($msg = '')
638
    {
639
        $data = $this->misc->getDatabaseAccessor();
640
641
        $this->printTrail('role');
642
        $this->printTitle($this->lang['strproperties'], 'pg.role');
643
        $this->printMsg($msg);
644
645
        $roledata = $data->getRole($_REQUEST['rolename']);
646
        if ($roledata->recordCount() > 0) {
647
            $roledata->fields['rolsuper']      = $data->phpBool($roledata->fields['rolsuper']);
648
            $roledata->fields['rolcreatedb']   = $data->phpBool($roledata->fields['rolcreatedb']);
649
            $roledata->fields['rolcreaterole'] = $data->phpBool($roledata->fields['rolcreaterole']);
650
            $roledata->fields['rolinherit']    = $data->phpBool($roledata->fields['rolinherit']);
651
            $roledata->fields['rolcanlogin']   = $data->phpBool($roledata->fields['rolcanlogin']);
652
653
            echo '<table>'.PHP_EOL;
654
            echo "\t<tr>\n\t\t<th class=\"data\" style=\"width: 130px\">Description</th>".PHP_EOL;
655
            echo "\t\t<th class=\"data\" style=\"width: 120\">Value</th>\n\t</tr>".PHP_EOL;
656
            echo "\t<tr>\n\t\t<td class=\"data1\">{$this->lang['strname']}</td>".PHP_EOL;
657
            echo "\t\t<td class=\"data1\">", htmlspecialchars($_REQUEST['rolename']), "</td>\n\t</tr>".PHP_EOL;
658
            echo "\t<tr>\n\t\t<td class=\"data2\">{$this->lang['strsuper']}</td>".PHP_EOL;
659
            echo "\t\t<td class=\"data2\">", (($roledata->fields['rolsuper']) ? $this->lang['stryes'] : $this->lang['strno']), "</td>\n\t</tr>".PHP_EOL;
660
            echo "\t<tr>\n\t\t<td class=\"data1\">{$this->lang['strcreatedb']}</td>".PHP_EOL;
661
            echo "\t\t<td class=\"data1\">", (($roledata->fields['rolcreatedb']) ? $this->lang['stryes'] : $this->lang['strno']), '</td>'.PHP_EOL;
662
            echo "\t<tr>\n\t\t<td class=\"data2\">{$this->lang['strcancreaterole']}</td>".PHP_EOL;
663
            echo "\t\t<td class=\"data2\">", (($roledata->fields['rolcreaterole']) ? $this->lang['stryes'] : $this->lang['strno']), '</td>'.PHP_EOL;
664
            echo "\t<tr>\n\t\t<td class=\"data1\">{$this->lang['strinheritsprivs']}</td>".PHP_EOL;
665
            echo "\t\t<td class=\"data1\">", (($roledata->fields['rolinherit']) ? $this->lang['stryes'] : $this->lang['strno']), '</td>'.PHP_EOL;
666
            echo "\t<tr>\n\t\t<td class=\"data2\">{$this->lang['strcanlogin']}</td>".PHP_EOL;
667
            echo "\t\t<td class=\"data2\">", (($roledata->fields['rolcanlogin']) ? $this->lang['stryes'] : $this->lang['strno']), '</td>'.PHP_EOL;
668
            echo "\t<tr>\n\t\t<td class=\"data1\">{$this->lang['strconnlimit']}</td>".PHP_EOL;
669
            echo "\t\t<td class=\"data1\">", ('-1' == $roledata->fields['rolconnlimit'] ? $this->lang['strnolimit'] : $this->misc->printVal($roledata->fields['rolconnlimit'])), '</td>'.PHP_EOL;
670
            echo "\t<tr>\n\t\t<td class=\"data2\">{$this->lang['strexpires']}</td>".PHP_EOL;
671
            echo "\t\t<td class=\"data2\">", ('infinity' == $roledata->fields['rolvaliduntil'] || is_null($roledata->fields['rolvaliduntil']) ? $this->lang['strnever'] : $this->misc->printVal($roledata->fields['rolvaliduntil'])), '</td>'.PHP_EOL;
672
            echo "\t<tr>\n\t\t<td class=\"data1\">{$this->lang['strsessiondefaults']}</td>".PHP_EOL;
673
            echo "\t\t<td class=\"data1\">", $this->misc->printVal($roledata->fields['rolconfig']), '</td>'.PHP_EOL;
674
            echo "\t<tr>\n\t\t<td class=\"data2\">{$this->lang['strmemberof']}</td>".PHP_EOL;
675
            echo "\t\t<td class=\"data2\">";
676
            $memberof = $data->getMemberOf($_REQUEST['rolename']);
677
            if ($memberof->recordCount() > 0) {
678
                while (!$memberof->EOF) {
679
                    echo $this->misc->printVal($memberof->fields['rolname']), '<br />'.PHP_EOL;
680
                    $memberof->moveNext();
681
                }
682
            }
683
            echo "</td>\n\t</tr>".PHP_EOL;
684
            echo "\t<tr>\n\t\t<td class=\"data1\">{$this->lang['strmembers']}</td>".PHP_EOL;
685
            echo "\t\t<td class=\"data1\">";
686
            $members = $data->getMembers($_REQUEST['rolename']);
687
            if ($members->recordCount() > 0) {
688
                while (!$members->EOF) {
689
                    echo $this->misc->printVal($members->fields['rolname']), '<br />'.PHP_EOL;
690
                    $members->moveNext();
691
                }
692
            }
693
            echo "</td>\n\t</tr>".PHP_EOL;
694
            echo "\t<tr>\n\t\t<td class=\"data2\">{$this->lang['stradminmembers']}</td>".PHP_EOL;
695
            echo "\t\t<td class=\"data2\">";
696
            $adminmembers = $data->getMembers($_REQUEST['rolename'], 't');
697
            if ($adminmembers->recordCount() > 0) {
698
                while (!$adminmembers->EOF) {
699
                    echo $this->misc->printVal($adminmembers->fields['rolname']), '<br />'.PHP_EOL;
700
                    $adminmembers->moveNext();
701
                }
702
            }
703
            echo "</td>\n\t</tr>".PHP_EOL;
704
            echo '</table>'.PHP_EOL;
705
        } else {
706
            echo "<p>{$this->lang['strnodata']}</p>".PHP_EOL;
707
        }
708
709
        $navlinks = [
710
            'showall' => [
711
                'attr'    => [
712
                    'href' => [
713
                        'url'     => 'roles',
714
                        'urlvars' => [
715
                            'server' => $_REQUEST['server'],
716
                        ],
717
                    ],
718
                ],
719
                'content' => $this->lang['strshowallroles'],
720
            ],
721
            'alter'   => [
722
                'attr'    => [
723
                    'href' => [
724
                        'url'     => 'roles',
725
                        'urlvars' => [
726
                            'action'   => 'alter',
727
                            'server'   => $_REQUEST['server'],
728
                            'rolename' => $_REQUEST['rolename'],
729
                        ],
730
                    ],
731
                ],
732
                'content' => $this->lang['stralter'],
733
            ],
734
            'drop'    => [
735
                'attr'    => [
736
                    'href' => [
737
                        'url'     => 'roles',
738
                        'urlvars' => [
739
                            'action'   => 'confirm_drop',
740
                            'server'   => $_REQUEST['server'],
741
                            'rolename' => $_REQUEST['rolename'],
742
                        ],
743
                    ],
744
                ],
745
                'content' => $this->lang['strdrop'],
746
            ],
747
        ];
748
749
        $this->printNavLinks($navlinks, 'roles-properties', get_defined_vars());
750
    }
751
752
    /**
753
     * If a role is not a superuser role, then we have an 'account management'
754
     * page for change his password, etc.  We don't prevent them from
755
     * messing with the URL to gain access to other role admin stuff, because
756
     * the PostgreSQL permissions will prevent them changing anything anyway.
757
     *
758
     * @param mixed $msg
759
     */
760
    public function doAccount($msg = '')
761
    {
762
        $data = $this->misc->getDatabaseAccessor();
763
764
        $server_info = $this->misc->getServerInfo();
765
766
        $roledata             = $data->getRole($server_info['username']);
767
        $_REQUEST['rolename'] = $server_info['username'];
768
769
        $this->printTrail('role');
770
        $this->printTabs('server', 'account');
771
        $this->printMsg($msg);
772
773
        if ($roledata->recordCount() > 0) {
774
            $roledata->fields['rolsuper']      = $data->phpBool($roledata->fields['rolsuper']);
775
            $roledata->fields['rolcreatedb']   = $data->phpBool($roledata->fields['rolcreatedb']);
776
            $roledata->fields['rolcreaterole'] = $data->phpBool($roledata->fields['rolcreaterole']);
777
            $roledata->fields['rolinherit']    = $data->phpBool($roledata->fields['rolinherit']);
778
            echo '<table>'.PHP_EOL;
779
            echo "\t<tr>\n\t\t<th class=\"data\">{$this->lang['strname']}</th>".PHP_EOL;
780
            echo "\t\t<th class=\"data\">{$this->lang['strsuper']}</th>".PHP_EOL;
781
            echo "\t\t<th class=\"data\">{$this->lang['strcreatedb']}</th>".PHP_EOL;
782
            echo "\t\t<th class=\"data\">{$this->lang['strcancreaterole']}</th>".PHP_EOL;
783
            echo "\t\t<th class=\"data\">{$this->lang['strinheritsprivs']}</th>".PHP_EOL;
784
            echo "\t\t<th class=\"data\">{$this->lang['strconnlimit']}</th>".PHP_EOL;
785
            echo "\t\t<th class=\"data\">{$this->lang['strexpires']}</th>".PHP_EOL;
786
            echo "\t\t<th class=\"data\">{$this->lang['strsessiondefaults']}</th>".PHP_EOL;
787
            echo "\t</tr>".PHP_EOL;
788
            echo "\t<tr>\n\t\t<td class=\"data1\">", $this->misc->printVal($roledata->fields['rolname']), '</td>'.PHP_EOL;
789
            echo "\t\t<td class=\"data1\">", $this->misc->printVal($roledata->fields['rolsuper'], 'yesno'), '</td>'.PHP_EOL;
790
            echo "\t\t<td class=\"data1\">", $this->misc->printVal($roledata->fields['rolcreatedb'], 'yesno'), '</td>'.PHP_EOL;
791
            echo "\t\t<td class=\"data1\">", $this->misc->printVal($roledata->fields['rolcreaterole'], 'yesno'), '</td>'.PHP_EOL;
792
            echo "\t\t<td class=\"data1\">", $this->misc->printVal($roledata->fields['rolinherit'], 'yesno'), '</td>'.PHP_EOL;
793
            echo "\t\t<td class=\"data1\">", ('-1' == $roledata->fields['rolconnlimit'] ? $this->lang['strnolimit'] : $this->misc->printVal($roledata->fields['rolconnlimit'])), '</td>'.PHP_EOL;
794
            echo "\t\t<td class=\"data1\">", ('infinity' == $roledata->fields['rolvaliduntil'] || is_null($roledata->fields['rolvaliduntil']) ? $this->lang['strnever'] : $this->misc->printVal($roledata->fields['rolvaliduntil'])), '</td>'.PHP_EOL;
795
            echo "\t\t<td class=\"data1\">", $this->misc->printVal($roledata->fields['rolconfig']), '</td>'.PHP_EOL;
796
            echo "\t</tr>\n</table>".PHP_EOL;
797
        } else {
798
            echo "<p>{$this->lang['strnodata']}</p>".PHP_EOL;
799
        }
800
801
        $this->printNavLinks(['changepassword' => [
802
            'attr'    => [
803
                'href' => [
804
                    'url'     => 'roles',
805
                    'urlvars' => [
806
                        'action' => 'confchangepassword',
807
                        'server' => $_REQUEST['server'],
808
                    ],
809
                ],
810
            ],
811
            'content' => $this->lang['strchangepassword'],
812
        ]], 'roles-account', get_defined_vars());
813
    }
814
815
    /**
816
     * Show confirmation of change password and actually change password.
817
     *
818
     * @param mixed $confirm
819
     * @param mixed $msg
820
     */
821
    public function doChangePassword($confirm, $msg = '')
822
    {
823
        $data = $this->misc->getDatabaseAccessor();
824
825
        $server_info = $this->misc->getServerInfo();
826
827
        if ($confirm) {
828
            $_REQUEST['rolename'] = $server_info['username'];
829
            $this->printTrail('role');
830
            $this->printTitle($this->lang['strchangepassword'], 'pg.role.alter');
831
            $this->printMsg($msg);
832
833
            $this->coalesceArr($_POST, 'password', '');
834
835
            $this->coalesceArr($_POST, 'confirm', '');
836
837
            echo '<form action="'.\SUBFOLDER.'/src/views/roles" method="post">'.PHP_EOL;
838
            echo '<table>'.PHP_EOL;
839
            echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strpassword']}</th>".PHP_EOL;
840
            echo "\t\t<td><input type=\"password\" name=\"password\" size=\"32\" value=\"",
841
            htmlspecialchars($_POST['password']), "\" /></td>\n\t</tr>".PHP_EOL;
842
            echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strconfirm']}</th>".PHP_EOL;
843
            echo "\t\t<td><input type=\"password\" name=\"confirm\" size=\"32\" value=\"\" /></td>\n\t</tr>".PHP_EOL;
844
            echo '</table>'.PHP_EOL;
845
            echo '<p><input type="hidden" name="action" value="changepassword" />'.PHP_EOL;
846
            echo $this->misc->form;
847
            echo "<input type=\"submit\" name=\"ok\" value=\"{$this->lang['strok']}\" />".PHP_EOL;
848
            echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" />".PHP_EOL;
849
            echo '</p></form>'.PHP_EOL;
850
        } else {
851
            // Check that password is minimum length
852
            if (strlen($_POST['password']) < $this->conf['min_password_length']) {
853
                $this->doChangePassword(true, $this->lang['strpasswordshort']);
854
            } elseif ($_POST['password'] != $_POST['confirm']) {
855
                // Check that password matches confirmation password
856
                $this->doChangePassword(true, $this->lang['strpasswordconfirm']);
857
            } else {
858
                $status = $data->changePassword($server_info['username'], $_POST['password']);
859
                if (0 == $status) {
860
                    $this->doAccount($this->lang['strpasswordchanged']);
861
                } else {
862
                    $this->doAccount($this->lang['strpasswordchangedbad']);
863
                }
864
            }
865
        }
866
    }
867
}
868