User::checkAccessRoute()   A
last analyzed

Complexity

Conditions 4
Paths 5

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 19
rs 9.2
cc 4
eloc 13
nc 5
nop 3
1
<?php
2
3
namespace app\components;
4
5
/**
6
 * @link http://www.diemeisterei.de/
7
 *
8
 * @copyright Copyright (c) 2015 diemeisterei GmbH, Stuttgart
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
/**
15
 * Class User.
16
 *
17
 * Custom user class with additional checks and implementation of a 'root' user, who
18
 * has all permissions (`can()` always return true)
19
 */
20
class User extends \yii\web\User
21
{
22
    const PUBLIC_ROLE = 'Public';
23
24
    /**
25
     * Extended permission check with `Guest` role and `route`.
26
     *
27
     * @param string    $permissionName
28
     * @param array     $params
29
     * @param bool|true $allowCaching
30
     *
31
     * @return bool
32
     */
33
    public function can($permissionName, $params = [], $allowCaching = true)
34
    {
35
        switch (true) {
36
            case \Yii::$app->user->identity && \Yii::$app->user->identity->isAdmin:
37
                return true;
38
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
39
            case !empty($params['route']):
40
                \Yii::trace("Checking route permissions for '{$permissionName}'", __METHOD__);
41
                return $this->checkAccessRoute($permissionName, $params, $allowCaching);
42
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
43
            default:
44
                return parent::can($permissionName, $params, $allowCaching);
45
        }
46
    }
47
48
    /**
49
     * Checks permissions from guest role, when no user is logged in.
50
     *
51
     * @param $permissionName
52
     * @param $params
53
     * @param $allowCaching
54
     *
55
     * @return bool
56
     */
57
    private function canGuest($permissionName, $params, $allowCaching)
0 ignored issues
show
Unused Code introduced by
The parameter $params is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $allowCaching is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
58
    {
59
        $guestPermissions = $this->getAuthManager()->getPermissionsByRole(self::PUBLIC_ROLE);
60
61
        return array_key_exists($permissionName, $guestPermissions);
62
    }
63
64
    /**
65
     * Checks route permissions.
66
     *
67
     * Splits `permissionName` by underscore and match parts against more global rule
68
     * eg. a permission `app_site` will match, `app_site_foo`
69
     *
70
     * @param $permissionName
71
     * @param $params
72
     * @param $allowCaching
73
     *
74
     * @return bool
75
     */
76
    private function checkAccessRoute($permissionName, $params, $allowCaching)
77
    {
78
        $route = explode('_', $permissionName);
79
        $routePermission = '';
80
        foreach ($route as $part) {
81
            $routePermission .= $part;
82
            if (\Yii::$app->user->id) {
83
                $canRoute = parent::can($routePermission, $params, $allowCaching);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (can() instead of checkAccessRoute()). Are you sure this is correct? If so, you might want to change this to $this->can().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
84
            } else {
85
                $canRoute = $this->canGuest($routePermission, $params, $allowCaching);
86
            }
87
            if ($canRoute) {
88
                return true;
89
            }
90
            $routePermission .= '_';
91
        }
92
93
        return false;
94
    }
95
}
96