Passed
Push — develop ( c213cd...c14899 )
by Felipe
07:13
created

PrivilegesController::render()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 16
nc 4
nop 0
1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.48
5
 */
6
7
namespace PHPPgAdmin\Controller;
8
9
/**
10
 * PrivilegesController controller class.
11
 */
12
class PrivilegesController extends BaseController
13
{
14
    public $table_place      = 'privileges-privileges';
15
    public $controller_title = 'strprivileges';
16
17
    /**
18
     * Default method to render the controller according to the action parameter.
19
     */
20
    public function render()
21
    {
22
        $this->printHeader();
23
        $this->printBody();
24
25
        switch ($this->action) {
26
            case 'save':
27
                if (isset($_REQUEST['cancel'])) {
28
                    $this->doDefault();
29
                } else {
30
                    $this->doAlter($_REQUEST['mode']);
31
                }
32
33
                break;
34
            case 'alter':
35
                $this->formAlter($_REQUEST['mode']);
36
37
                break;
38
            default:
39
                $this->doDefault();
40
41
                break;
42
        }
43
44
        $this->printFooter();
45
    }
46
47
    /**
48
     * Show permissions on a database, namespace, relation, language or function.
49
     *
50
     * @param mixed $msg
51
     */
52
    public function doDefault($msg = '')
53
    {
54
        $data    = $this->misc->getDatabaseAccessor();
55
        $subject = $_REQUEST['subject'];
56
57
        $this->printTrail($subject);
58
59
        // @@@FIXME: This switch is just a temporary solution,
60
        // need a better way, maybe every type of object should
61
        // have a tab bar???
62
63
        if (in_array($subject, [
64
            'server',
65
            'database',
66
            'schema',
67
            'table',
68
            'column',
69
            'view',
70
        ], true)) {
71
            $this->printTabs($subject, 'privileges');
72
        } else {
73
            $this->printTitle($this->lang['strprivileges'], 'pg.privilege');
74
        }
75
76
        $this->printMsg($msg);
77
        if (!isset($data->privlist[$subject])) {
78
            $this->container->utils->halt('No privileges defined for subject '.$subject);
79
80
            return;
81
        }
82
83
        // Determine whether object should be ref'd by name or oid.
84
        if (isset($_REQUEST[$subject.'_oid'])) {
85
            $object = $_REQUEST[$subject.'_oid'];
86
        } else {
87
            $object = $_REQUEST[$subject];
88
        }
89
90
        // Get the privileges on the object, given its type
91
        if ('column' == $subject) {
92
            $privileges = $data->getPrivileges($object, 'column', $_REQUEST['table']);
93
        } else {
94
            $privileges = $data->getPrivileges($object, $subject);
95
        }
96
97
        if (sizeof($privileges) > 0) {
98
            echo "<table>\n";
99
            if ($data->hasRoles()) {
100
                echo "<tr><th class=\"data\">{$this->lang['strrole']}</th>";
101
            } else {
102
                echo "<tr><th class=\"data\">{$this->lang['strtype']}</th><th class=\"data\">{$this->lang['struser']}/{$this->lang['strgroup']}</th>";
103
            }
104
105
            foreach ($data->privlist[$subject] as $v2) {
106
                // Skip over ALL PRIVILEGES
107
                if ('ALL PRIVILEGES' == $v2) {
108
                    continue;
109
                }
110
111
                echo "<th class=\"data\">{$v2}</th>\n";
112
            }
113
            if ($data->hasGrantOption()) {
114
                echo "<th class=\"data\">{$this->lang['strgrantor']}</th>";
115
            }
116
            echo "</tr>\n";
117
118
            // Loop over privileges, outputting them
119
            $i = 0;
120
            foreach ($privileges as $v) {
121
                $id = (0 == ($i % 2) ? '1' : '2');
122
                echo "<tr class=\"data{$id}\">\n";
123
                if (!$data->hasRoles()) {
124
                    echo '<td>', $this->misc->printVal($v[0]), "</td>\n";
125
                }
126
127
                echo '<td>', $this->misc->printVal($v[1]), "</td>\n";
128
                foreach ($data->privlist[$subject] as $v2) {
129
                    // Skip over ALL PRIVILEGES
130
                    if ('ALL PRIVILEGES' == $v2) {
131
                        continue;
132
                    }
133
134
                    echo '<td>';
135
                    if (in_array($v2, $v[2], true)) {
136
                        echo $this->lang['stryes'];
137
                    } else {
138
                        echo $this->lang['strno'];
139
                    }
140
141
                    // If we have grant option for this, end mark
142
                    if ($data->hasGrantOption() && in_array($v2, $v[4], true)) {
143
                        echo $this->lang['strasterisk'];
144
                    }
145
146
                    echo "</td>\n";
147
                }
148
                if ($data->hasGrantOption()) {
149
                    echo '<td>', $this->misc->printVal($v[3]), "</td>\n";
150
                }
151
                echo "</tr>\n";
152
                ++$i;
153
            }
154
155
            echo '</table>';
156
        } else {
157
            echo "<p>{$this->lang['strnoprivileges']}</p>\n";
158
        }
159
        $this->printGrantLinks();
160
    }
161
162
    public function printGrantLinks()
163
    {
164
        $data    = $this->misc->getDatabaseAccessor();
165
        $subject = $_REQUEST['subject'];
166
        // Links for granting to a user or group
167
        switch ($subject) {
168
            case 'table':
169
            case 'view':
170
            case 'sequence':
171
            case 'function':
172
            case 'tablespace':
173
                $alllabel = "showall{$subject}s";
174
                $allurl   = "{$subject}s";
175
                $alltxt   = $this->lang["strshowall{$subject}s"];
176
177
                break;
178
            case 'schema':
179
                $alllabel = 'showallschemas';
180
                $allurl   = 'schemas';
181
                $alltxt   = $this->lang['strshowallschemas'];
182
183
                break;
184
            case 'database':
185
                $alllabel = 'showalldatabases';
186
                $allurl   = 'alldb';
187
                $alltxt   = $this->lang['strshowalldatabases'];
188
189
                break;
190
        }
191
192
        $object = $_REQUEST[$subject];
193
194
        if ('function' == $subject) {
195
            $objectoid = $_REQUEST[$subject.'_oid'];
196
            $urlvars   = [
197
                'action'         => 'alter',
198
                'server'         => $_REQUEST['server'],
199
                'database'       => $_REQUEST['database'],
200
                'schema'         => $_REQUEST['schema'],
201
                $subject         => $object,
202
                "{$subject}_oid" => $objectoid,
203
                'subject'        => $subject,
204
            ];
205
        } elseif ('column' == $subject) {
206
            $urlvars = [
207
                'action'   => 'alter',
208
                'server'   => $_REQUEST['server'],
209
                'database' => $_REQUEST['database'],
210
                'schema'   => $_REQUEST['schema'],
211
                $subject   => $object,
212
                'subject'  => $subject,
213
            ];
214
215
            if (isset($_REQUEST['table'])) {
216
                $urlvars['table'] = $_REQUEST['table'];
217
            } elseif (isset($_REQUEST['view'])) {
218
                $urlvars['view'] = $_REQUEST['view'];
219
            } else {
220
                $urlvars['matview'] = $_REQUEST['matview'];
221
            }
222
        } else {
223
            $urlvars = [
224
                'action'   => 'alter',
225
                'server'   => $_REQUEST['server'],
226
                'database' => $_REQUEST['database'],
227
                $subject   => $object,
228
                'subject'  => $subject,
229
            ];
230
            if (isset($_REQUEST['schema'])) {
231
                $urlvars['schema'] = $_REQUEST['schema'];
232
            }
233
        }
234
235
        $navlinks = [
236
            'grant'  => [
237
                'attr'    => [
238
                    'href' => [
239
                        'url'     => 'privileges',
240
                        'urlvars' => array_merge($urlvars, ['mode' => 'grant']),
241
                    ],
242
                ],
243
                'content' => $this->lang['strgrant'],
244
            ],
245
            'revoke' => [
246
                'attr'    => [
247
                    'href' => [
248
                        'url'     => 'privileges',
249
                        'urlvars' => array_merge($urlvars, ['mode' => 'revoke']),
250
                    ],
251
                ],
252
                'content' => $this->lang['strrevoke'],
253
            ],
254
        ];
255
256
        if (isset($allurl)) {
257
            $navlinks[$alllabel] = [
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $alllabel does not seem to be defined for all execution paths leading up to this point.
Loading history...
258
                'attr'    => [
259
                    'href' => [
260
                        'url'     => $allurl,
261
                        'urlvars' => [
262
                            'server'   => $_REQUEST['server'],
263
                            'database' => $_REQUEST['database'],
264
                        ],
265
                    ],
266
                ],
267
                'content' => $alltxt,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $alltxt does not seem to be defined for all execution paths leading up to this point.
Loading history...
268
            ];
269
            if (isset($_REQUEST['schema'])) {
270
                $navlinks[$alllabel]['attr']['href']['urlvars']['schema'] = $_REQUEST['schema'];
271
            }
272
        }
273
274
        $this->printNavLinks($navlinks, $this->table_place, get_defined_vars());
275
    }
276
277
    /**
278
     * Prints the form to grants permision on an object to a user.
279
     *
280
     * @param string $mode either grant or revoke
281
     * @param string $msg  The message
282
     */
283
    public function formAlter($mode, $msg = '')
284
    {
285
        $data = $this->misc->getDatabaseAccessor();
286
287
        $this->coalesceArr($_REQUEST, 'username', []);
288
289
        $this->coalesceArr($_REQUEST, 'groupname', []);
290
291
        $this->coalesceArr($_REQUEST, 'privilege', []);
292
293
        // Get users from the database
294
        $users = $data->getUsers();
295
        // Get groups from the database
296
        $groups = $data->getGroups();
297
298
        $this->printTrail($_REQUEST['subject']);
299
300
        switch ($mode) {
301
            case 'grant':
302
                $this->printTitle($this->lang['strgrant'], 'pg.privilege.grant');
303
304
                break;
305
            case 'revoke':
306
                $this->printTitle($this->lang['strrevoke'], 'pg.privilege.revoke');
307
308
                break;
309
        }
310
        $this->printMsg($msg);
311
312
        echo '<form action="'.\SUBFOLDER."/src/views/privileges\" method=\"post\">\n";
313
        echo "<table>\n";
314
        echo "<tr><th class=\"data left\">{$this->lang['strusers']}</th>\n";
315
        echo '<td class="data1"><select name="username[]" multiple="multiple" size="', min(6, $users->recordCount()), "\">\n";
316
        while (!$users->EOF) {
317
            $uname = htmlspecialchars($users->fields['usename']);
318
            echo "<option value=\"{$uname}\"",
319
            in_array($users->fields['usename'], $_REQUEST['username'], true) ? ' selected="selected"' : '', ">{$uname}</option>\n";
320
            $users->moveNext();
321
        }
322
        echo "</select></td></tr>\n";
323
        echo "<tr><th class=\"data left\">{$this->lang['strgroups']}</th>\n";
324
        echo "<td class=\"data1\">\n";
325
        echo '<input type="checkbox" id="public" name="public"', (isset($_REQUEST['public']) ? ' checked="checked"' : ''), " /><label for=\"public\">PUBLIC</label>\n";
326
        // Only show groups if there are groups!
327
        if ($groups->recordCount() > 0) {
328
            echo '<br /><select name="groupname[]" multiple="multiple" size="', min(6, $groups->recordCount()), "\">\n";
329
            while (!$groups->EOF) {
330
                $gname = htmlspecialchars($groups->fields['groname']);
331
                echo "<option value=\"{$gname}\"",
332
                in_array($groups->fields['groname'], $_REQUEST['groupname'], true) ? ' selected="selected"' : '', ">{$gname}</option>\n";
333
                $groups->moveNext();
334
            }
335
            echo "</select>\n";
336
        }
337
        echo "</td></tr>\n";
338
        echo "<tr><th class=\"data left required\">{$this->lang['strprivileges']}</th>\n";
339
        echo "<td class=\"data1\">\n";
340
        foreach ($data->privlist[$_REQUEST['subject']] as $v) {
341
            $v = htmlspecialchars($v);
342
            echo "<input type=\"checkbox\" id=\"privilege[${v}]\" name=\"privilege[${v}]\"",
343
            isset($_REQUEST['privilege'][$v]) ? ' checked="checked"' : '', " /><label for=\"privilege[${v}]\">{$v}</label><br />\n";
344
        }
345
        echo "</td></tr>\n";
346
        // Grant option
347
        if ($data->hasGrantOption()) {
348
            echo "<tr><th class=\"data left\">{$this->lang['stroptions']}</th>\n";
349
            echo "<td class=\"data1\">\n";
350
            if ('grant' == $mode) {
351
                echo '<input type="checkbox" id="grantoption" name="grantoption"',
352
                isset($_REQUEST['grantoption']) ? ' checked="checked"' : '', " /><label for=\"grantoption\">GRANT OPTION</label>\n";
353
            } elseif ('revoke' == $mode) {
354
                echo '<input type="checkbox" id="grantoption" name="grantoption"',
355
                isset($_REQUEST['grantoption']) ? ' checked="checked"' : '', " /><label for=\"grantoption\">GRANT OPTION FOR</label><br />\n";
356
                echo '<input type="checkbox" id="cascade" name="cascade"',
357
                isset($_REQUEST['cascade']) ? ' checked="checked"' : '', " /><label for=\"cascade\">CASCADE</label><br />\n";
358
            }
359
            echo "</td></tr>\n";
360
        }
361
        echo "</table>\n";
362
363
        echo "<p><input type=\"hidden\" name=\"action\" value=\"save\" />\n";
364
        echo '<input type="hidden" name="mode" value="', htmlspecialchars($mode), "\" />\n";
365
        echo '<input type="hidden" name="subject" value="', htmlspecialchars($_REQUEST['subject']), "\" />\n";
366
        if (isset($_REQUEST[$_REQUEST['subject'].'_oid'])) {
367
            echo '<input type="hidden" name="', htmlspecialchars($_REQUEST['subject'].'_oid'),
368
            '" value="', htmlspecialchars($_REQUEST[$_REQUEST['subject'].'_oid']), "\" />\n";
369
        }
370
371
        echo '<input type="hidden" name="', htmlspecialchars($_REQUEST['subject']),
372
        '" value="', htmlspecialchars($_REQUEST[$_REQUEST['subject']]), "\" />\n";
373
        if ('column' == $_REQUEST['subject']) {
374
            echo '<input type="hidden" name="table" value="',
375
            htmlspecialchars($_REQUEST['table']), "\" />\n";
376
        }
377
378
        echo $this->misc->form;
379
        if ('grant' == $mode) {
380
            echo "<input type=\"submit\" name=\"grant\" value=\"{$this->lang['strgrant']}\" />\n";
381
        } elseif ('revoke' == $mode) {
382
            echo "<input type=\"submit\" name=\"revoke\" value=\"{$this->lang['strrevoke']}\" />\n";
383
        }
384
385
        echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" /></p>";
386
        echo "</form>\n";
387
    }
388
389
    /**
390
     * Grant permissions on an object to a user.
391
     *
392
     * @param string $mode 'grant' or 'revoke'
393
     */
394
    public function doAlter($mode)
395
    {
396
        $data = $this->misc->getDatabaseAccessor();
397
398
        $this->coalesceArr($_REQUEST, 'username', []);
399
400
        $this->coalesceArr($_REQUEST, 'groupname', []);
401
402
        $this->coalesceArr($_REQUEST, 'privilege', []);
403
404
        // Determine whether object should be ref'd by name or oid.
405
        if (isset($_REQUEST[$_REQUEST['subject'].'_oid'])) {
406
            $object = $_REQUEST[$_REQUEST['subject'].'_oid'];
407
        } else {
408
            $object = $_REQUEST[$_REQUEST['subject']];
409
        }
410
411
        if (isset($_REQUEST['table'])) {
412
            $table = $_REQUEST['table'];
413
        } else {
414
            $table = null;
415
        }
416
417
        $status = $data->setPrivileges(
418
            ('grant' == $mode) ? 'GRANT' : 'REVOKE',
419
            $_REQUEST['subject'],
420
            $object,
421
            isset($_REQUEST['public']),
422
            $_REQUEST['username'],
423
            $_REQUEST['groupname'],
424
            array_keys($_REQUEST['privilege']),
425
            isset($_REQUEST['grantoption']),
426
            isset($_REQUEST['cascade']),
427
            $table
428
        );
429
430
        if (0 == $status) {
431
            $this->doDefault($this->lang['strgranted']);
432
        } elseif ($status == -3 || $status == -4) {
433
            $this->formAlter($_REQUEST['mode'], $this->lang['strgrantbad']);
434
        } else {
435
            $this->formAlter($_REQUEST['mode'], $this->lang['strgrantfailed']);
436
        }
437
    }
438
}
439