Passed
Pull Request — develop (#92)
by Felipe
04:25
created

src/controllers/PrivilegesController.php (2 issues)

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