Test Failed
Branch develop (db5506)
by Felipe
03:46
created

PrivilegesController::render()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 29
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 21
nc 4
nop 0
dl 0
loc 29
rs 8.5806
c 0
b 0
f 0
1
<?php
2
3
namespace PHPPgAdmin\Controller;
4
5
/**
6
 * PrivilegesController controller class
7
 */
8
class PrivilegesController extends BaseController
9
{
10
    public $_name       = 'PrivilegesController';
11
    public $table_place = 'privileges-privileges';
12
13
    public function render()
0 ignored issues
show
Coding Style introduced by
render uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
14
    {
15
        $conf   = $this->conf;
0 ignored issues
show
Unused Code introduced by
The assignment to $conf is dead and can be removed.
Loading history...
16
        $misc   = $this->misc;
17
        $lang   = $this->lang;
18
        $action = $this->action;
19
        $data   = $misc->getDatabaseAccessor();
0 ignored issues
show
Unused Code introduced by
The assignment to $data is dead and can be removed.
Loading history...
20
21
        $this->printHeader($lang['strprivileges']);
22
        $this->printBody();
23
24
        switch ($action) {
25
            case 'save':
26
                if (isset($_REQUEST['cancel'])) {
27
                    $this->doDefault();
28
                } else {
29
                    $this->doAlter(false, $_REQUEST['mode']);
30
                }
31
32
                break;
33
            case 'alter':
34
                $this->doAlter(true, $_REQUEST['mode']);
35
                break;
36
            default:
37
                $this->doDefault();
38
                break;
39
        }
40
41
        $this->printFooter();
42
    }
43
44
    /**
45
     * Show permissions on a database, namespace, relation, language or function
46
     */
47
    public function doDefault($msg = '')
0 ignored issues
show
Coding Style introduced by
doDefault uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
48
    {
49
        $conf     = $this->conf;
50
        $misc     = $this->misc;
51
        $lang     = $this->lang;
52
        $action   = $this->action;
53
        $data     = $misc->getDatabaseAccessor();
54
        $database = $misc->getDatabase();
55
56
        $this->printTrail($_REQUEST['subject']);
57
58
        # @@@FIXME: This switch is just a temporary solution,
59
        # need a better way, maybe every type of object should
60
        # have a tab bar???
61
        switch ($_REQUEST['subject']) {
62
            case 'server':
63
            case 'database':
64
            case 'schema':
65
            case 'table':
66
            case 'column':
67
            case 'view':
68
                $this->printTabs($_REQUEST['subject'], 'privileges');
69
                break;
70
            default:
71
                $this->printTitle($lang['strprivileges'], 'pg.privilege');
72
        }
73
        $this->printMsg($msg);
74
75
        // Determine whether object should be ref'd by name or oid.
76 View Code Duplication
        if (isset($_REQUEST[$_REQUEST['subject'] . '_oid'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
77
            $object = $_REQUEST[$_REQUEST['subject'] . '_oid'];
78
        } else {
79
            $object = $_REQUEST[$_REQUEST['subject']];
80
        }
81
82
        // Get the privileges on the object, given its type
83
        if ($_REQUEST['subject'] == 'column') {
84
            $privileges = $data->getPrivileges($object, 'column', $_REQUEST['table']);
85
        } else {
86
            $privileges = $data->getPrivileges($object, $_REQUEST['subject']);
87
        }
88
89
        if (sizeof($privileges) > 0) {
90
            echo "<table>\n";
91
            if ($data->hasRoles()) {
92
                echo "<tr><th class=\"data\">{$lang['strrole']}</th>";
93
            } else {
94
                echo "<tr><th class=\"data\">{$lang['strtype']}</th><th class=\"data\">{$lang['struser']}/{$lang['strgroup']}</th>";
95
            }
96
97
            foreach ($data->privlist[$_REQUEST['subject']] as $v2) {
98
                // Skip over ALL PRIVILEGES
99
                if ($v2 == 'ALL PRIVILEGES') {
100
                    continue;
101
                }
102
103
                echo "<th class=\"data\">{$v2}</th>\n";
104
            }
105
            if ($data->hasGrantOption()) {
106
                echo "<th class=\"data\">{$lang['strgrantor']}</th>";
107
            }
108
            echo "</tr>\n";
109
110
            // Loop over privileges, outputting them
111
            $i = 0;
112
            foreach ($privileges as $v) {
113
                $id = (($i % 2) == 0 ? '1' : '2');
114
                echo "<tr class=\"data{$id}\">\n";
115
                if (!$data->hasRoles()) {
116
                    echo '<td>', $misc->printVal($v[0]), "</td>\n";
117
                }
118
119
                echo '<td>', $misc->printVal($v[1]), "</td>\n";
120
                foreach ($data->privlist[$_REQUEST['subject']] as $v2) {
121
                    // Skip over ALL PRIVILEGES
122
                    if ($v2 == 'ALL PRIVILEGES') {
123
                        continue;
124
                    }
125
126
                    echo '<td>';
127
                    if (in_array($v2, $v[2])) {
128
                        echo $lang['stryes'];
129
                    } else {
130
                        echo $lang['strno'];
131
                    }
132
133
                    // If we have grant option for this, end mark
134
                    if ($data->hasGrantOption() && in_array($v2, $v[4])) {
135
                        echo $lang['strasterisk'];
136
                    }
137
138
                    echo "</td>\n";
139
                }
140
                if ($data->hasGrantOption()) {
141
                    echo '<td>', $misc->printVal($v[3]), "</td>\n";
142
                }
143
                echo "</tr>\n";
144
                $i++;
145
            }
146
147
            echo '</table>';
148
        } else {
149
            echo "<p>{$lang['strnoprivileges']}</p>\n";
150
        }
151
152
        // Links for granting to a user or group
153
        switch ($_REQUEST['subject']) {
154
            case 'table':
155
            case 'view':
156
            case 'sequence':
157
            case 'function':
158
            case 'tablespace':
159
                $alllabel = "showall{$_REQUEST['subject']}s";
160
                $allurl   = "{$_REQUEST['subject']}s.php";
161
                $alltxt   = $lang["strshowall{$_REQUEST['subject']}s"];
162
                break;
163
            case 'schema':
164
                $alllabel = 'showallschemas';
165
                $allurl   = 'schemas.php';
166
                $alltxt   = $lang['strshowallschemas'];
167
                break;
168
            case 'database':
169
                $alllabel = 'showalldatabases';
170
                $allurl   = 'alldb.php';
171
                $alltxt   = $lang['strshowalldatabases'];
172
                break;
173
        }
174
175
        $subject = $_REQUEST['subject'];
176
        $object  = $_REQUEST[$_REQUEST['subject']];
177
178
        if ($_REQUEST['subject'] == 'function') {
179
            $objectoid = $_REQUEST[$_REQUEST['subject'] . '_oid'];
180
            $urlvars   = [
181
                'action'         => 'alter',
182
                'server'         => $_REQUEST['server'],
183
                'database'       => $_REQUEST['database'],
184
                'schema'         => $_REQUEST['schema'],
185
                $subject         => $object,
186
                "{$subject}_oid" => $objectoid,
187
                'subject'        => $subject,
188
            ];
189
        } elseif ($_REQUEST['subject'] == 'column') {
190
            $urlvars = [
191
                'action'   => 'alter',
192
                'server'   => $_REQUEST['server'],
193
                'database' => $_REQUEST['database'],
194
                'schema'   => $_REQUEST['schema'],
195
                $subject   => $object,
196
                'subject'  => $subject,
197
            ];
198
199
            if (isset($_REQUEST['table'])) {
200
                $urlvars['table'] = $_REQUEST['table'];
201
            } else {
202
                $urlvars['view'] = $_REQUEST['view'];
203
            }
204
        } else {
205
            $urlvars = [
206
                'action'   => 'alter',
207
                'server'   => $_REQUEST['server'],
208
                'database' => $_REQUEST['database'],
209
                $subject   => $object,
210
                'subject'  => $subject,
211
            ];
212
            if (isset($_REQUEST['schema'])) {
213
                $urlvars['schema'] = $_REQUEST['schema'];
214
            }
215
        }
216
217
        $navlinks = [
218
            'grant'  => [
219
                'attr'    => [
220
                    'href' => [
221
                        'url'     => 'privileges.php',
222
                        'urlvars' => array_merge($urlvars, ['mode' => 'grant']),
223
                    ],
224
                ],
225
                'content' => $lang['strgrant'],
226
            ],
227
            'revoke' => [
228
                'attr'    => [
229
                    'href' => [
230
                        'url'     => 'privileges.php',
231
                        'urlvars' => array_merge($urlvars, ['mode' => 'revoke']),
232
                    ],
233
                ],
234
                'content' => $lang['strrevoke'],
235
            ],
236
        ];
237
238
        if (isset($allurl)) {
239
            $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...
240
                'attr'    => [
241
                    'href' => [
242
                        'url'     => $allurl,
243
                        'urlvars' => [
244
                            'server'   => $_REQUEST['server'],
245
                            'database' => $_REQUEST['database'],
246
                        ],
247
                    ],
248
                ],
249
                '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...
250
            ];
251
            if (isset($_REQUEST['schema'])) {
252
                $navlinks[$alllabel]['attr']['href']['urlvars']['schema'] = $_REQUEST['schema'];
253
            }
254
        }
255
256
        $this->printNavLinks($navlinks, $this->table_place, get_defined_vars());
257
    }
258
259
    /**
260
     * Grant permissions on an object to a user
261
     * @param $confirm To show entry screen
262
     * @param $mode 'grant' or 'revoke'
263
     * @param $msg (optional) A message to show
264
     */
0 ignored issues
show
Documentation Bug introduced by
The doc comment 'grant' at position 0 could not be parsed: Unknown type name ''grant'' at position 0 in 'grant'.
Loading history...
265
    public function doAlter($confirm, $mode, $msg = '')
0 ignored issues
show
Coding Style introduced by
doAlter uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
266
    {
267
        $conf   = $this->conf;
0 ignored issues
show
Unused Code introduced by
The assignment to $conf is dead and can be removed.
Loading history...
268
        $misc   = $this->misc;
269
        $lang   = $this->lang;
270
        $action = $this->action;
0 ignored issues
show
Unused Code introduced by
The assignment to $action is dead and can be removed.
Loading history...
271
        $data   = $misc->getDatabaseAccessor();
272
273
        if (!isset($_REQUEST['username'])) {
274
            $_REQUEST['username'] = [];
275
        }
276
277
        if (!isset($_REQUEST['groupname'])) {
278
            $_REQUEST['groupname'] = [];
279
        }
280
281
        if (!isset($_REQUEST['privilege'])) {
282
            $_REQUEST['privilege'] = [];
283
        }
284
285
        if ($confirm) {
286
            // Get users from the database
287
            $users = $data->getUsers();
288
            // Get groups from the database
289
            $groups = $data->getGroups();
290
291
            $this->printTrail($_REQUEST['subject']);
292
293
            switch ($mode) {
294
                case 'grant':
295
                    $this->printTitle($lang['strgrant'], 'pg.privilege.grant');
296
                    break;
297
                case 'revoke':
298
                    $this->printTitle($lang['strrevoke'], 'pg.privilege.revoke');
299
                    break;
300
            }
301
            $this->printMsg($msg);
302
303
            echo '<form action="' . SUBFOLDER . "/src/views/privileges.php\" method=\"post\">\n";
304
            echo "<table>\n";
305
            echo "<tr><th class=\"data left\">{$lang['strusers']}</th>\n";
306
            echo '<td class="data1"><select name="username[]" multiple="multiple" size="', min(6, $users->recordCount()), "\">\n";
307
            while (!$users->EOF) {
308
                $uname = htmlspecialchars($users->fields['usename']);
309
                echo "<option value=\"{$uname}\"",
310
                in_array($users->fields['usename'], $_REQUEST['username']) ? ' selected="selected"' : '', ">{$uname}</option>\n";
311
                $users->moveNext();
312
            }
313
            echo "</select></td></tr>\n";
314
            echo "<tr><th class=\"data left\">{$lang['strgroups']}</th>\n";
315
            echo "<td class=\"data1\">\n";
316
            echo '<input type="checkbox" id="public" name="public"', (isset($_REQUEST['public']) ? ' checked="checked"' : ''), " /><label for=\"public\">PUBLIC</label>\n";
317
            // Only show groups if there are groups!
318 View Code Duplication
            if ($groups->recordCount() > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
319
                echo '<br /><select name="groupname[]" multiple="multiple" size="', min(6, $groups->recordCount()), "\">\n";
320
                while (!$groups->EOF) {
321
                    $gname = htmlspecialchars($groups->fields['groname']);
322
                    echo "<option value=\"{$gname}\"",
323
                    in_array($groups->fields['groname'], $_REQUEST['groupname']) ? ' selected="selected"' : '', ">{$gname}</option>\n";
324
                    $groups->moveNext();
325
                }
326
                echo "</select>\n";
327
            }
328
            echo "</td></tr>\n";
329
            echo "<tr><th class=\"data left required\">{$lang['strprivileges']}</th>\n";
330
            echo "<td class=\"data1\">\n";
331
            foreach ($data->privlist[$_REQUEST['subject']] as $v) {
332
                $v = htmlspecialchars($v);
333
                echo "<input type=\"checkbox\" id=\"privilege[$v]\" name=\"privilege[$v]\"",
334
                isset($_REQUEST['privilege'][$v]) ? ' checked="checked"' : '', " /><label for=\"privilege[$v]\">{$v}</label><br />\n";
335
            }
336
            echo "</td></tr>\n";
337
            // Grant option
338
            if ($data->hasGrantOption()) {
339
                echo "<tr><th class=\"data left\">{$lang['stroptions']}</th>\n";
340
                echo "<td class=\"data1\">\n";
341
                if ($mode == 'grant') {
342
                    echo '<input type="checkbox" id="grantoption" name="grantoption"',
343
                    isset($_REQUEST['grantoption']) ? ' checked="checked"' : '', " /><label for=\"grantoption\">GRANT OPTION</label>\n";
344
                } elseif ($mode == 'revoke') {
345
                    echo '<input type="checkbox" id="grantoption" name="grantoption"',
346
                    isset($_REQUEST['grantoption']) ? ' checked="checked"' : '', " /><label for=\"grantoption\">GRANT OPTION FOR</label><br />\n";
347
                    echo '<input type="checkbox" id="cascade" name="cascade"',
348
                    isset($_REQUEST['cascade']) ? ' checked="checked"' : '', " /><label for=\"cascade\">CASCADE</label><br />\n";
349
                }
350
                echo "</td></tr>\n";
351
            }
352
            echo "</table>\n";
353
354
            echo "<p><input type=\"hidden\" name=\"action\" value=\"save\" />\n";
355
            echo '<input type="hidden" name="mode" value="', htmlspecialchars($mode), "\" />\n";
356
            echo '<input type="hidden" name="subject" value="', htmlspecialchars($_REQUEST['subject']), "\" />\n";
357
            if (isset($_REQUEST[$_REQUEST['subject'] . '_oid'])) {
358
                echo '<input type="hidden" name="', htmlspecialchars($_REQUEST['subject'] . '_oid'),
359
                '" value="', htmlspecialchars($_REQUEST[$_REQUEST['subject'] . '_oid']), "\" />\n";
360
            }
361
362
            echo '<input type="hidden" name="', htmlspecialchars($_REQUEST['subject']),
363
            '" value="', htmlspecialchars($_REQUEST[$_REQUEST['subject']]), "\" />\n";
364
            if ($_REQUEST['subject'] == 'column') {
365
                echo '<input type="hidden" name="table" value="',
366
                htmlspecialchars($_REQUEST['table']), "\" />\n";
367
            }
368
369
            echo $misc->form;
370
            if ($mode == 'grant') {
371
                echo "<input type=\"submit\" name=\"grant\" value=\"{$lang['strgrant']}\" />\n";
372
            } elseif ($mode == 'revoke') {
373
                echo "<input type=\"submit\" name=\"revoke\" value=\"{$lang['strrevoke']}\" />\n";
374
            }
375
376
            echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>";
377
            echo "</form>\n";
378
        } else {
379
            // Determine whether object should be ref'd by name or oid.
380 View Code Duplication
            if (isset($_REQUEST[$_REQUEST['subject'] . '_oid'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
381
                $object = $_REQUEST[$_REQUEST['subject'] . '_oid'];
382
            } else {
383
                $object = $_REQUEST[$_REQUEST['subject']];
384
            }
385
386
            if (isset($_REQUEST['table'])) {
387
                $table = $_REQUEST['table'];
388
            } else {
389
                $table = null;
390
            }
391
392
            $status = $data->setPrivileges(($mode == 'grant') ? 'GRANT' : 'REVOKE', $_REQUEST['subject'], $object,
393
                isset($_REQUEST['public']), $_REQUEST['username'], $_REQUEST['groupname'], array_keys($_REQUEST['privilege']),
394
                isset($_REQUEST['grantoption']), isset($_REQUEST['cascade']), $table);
395
396
            if ($status == 0) {
397
                $this->doDefault($lang['strgranted']);
398
            } elseif ($status == -3 || $status == -4) {
399
                $this->doAlter(true, $_REQUEST['mode'], $lang['strgrantbad']);
400
            } else {
401
                $this->doAlter(true, $_REQUEST['mode'], $lang['strgrantfailed']);
402
            }
403
        }
404
    }
405
}
406