AccessControl::isActive()   A
last analyzed

Complexity

Conditions 4
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
c 0
b 0
f 0
rs 10
cc 4
nc 2
nop 1
1
<?php
2
3
namespace yii2mod\rbac\filters;
4
5
use Yii;
6
use yii\base\Action;
7
use yii\base\Module;
8
use yii\helpers\ArrayHelper;
9
use yii\helpers\Url;
10
11
/**
12
 * Class AccessControl
13
 *
14
 * @package yii2mod\rbac\filters
15
 */
16
class AccessControl extends \yii\filters\AccessControl
17
{
18
    /**
19
     * @var array
20
     */
21
    public $params = [];
22
23
    /**
24
     * @var array list of actions that not need to check access
25
     */
26
    public $allowActions = [];
27
28
    /**
29
     * @inheritdoc
30
     */
31
    public function beforeAction($action): bool
32
    {
33
        $controller = $action->controller;
34
        $params = ArrayHelper::getValue($this->params, $action->id, []);
35
36
        if (Yii::$app->user->can('/' . $action->getUniqueId(), $params)) {
37
            return true;
38
        }
39
40
        do {
41
            if (Yii::$app->user->can('/' . ltrim($controller->getUniqueId() . '/*', '/'))) {
42
                return true;
43
            }
44
            $controller = $controller->module;
45
        } while ($controller !== null);
46
47
        return parent::beforeAction($action);
48
    }
49
50
    /**
51
     * @inheritdoc
52
     */
53
    protected function isActive($action): bool
54
    {
55
        if ($this->isErrorPage($action) || $this->isLoginPage($action) || $this->isAllowedAction($action)) {
56
            return false;
57
        }
58
59
        return parent::isActive($action);
60
    }
61
62
    /**
63
     * Returns a value indicating whether a current url equals `errorAction` property of the ErrorHandler component
64
     *
65
     * @param Action $action
66
     *
67
     * @return bool
68
     */
69
    private function isErrorPage(Action $action): bool
70
    {
71
        if ($action->getUniqueId() === Yii::$app->getErrorHandler()->errorAction) {
72
            return true;
73
        }
74
75
        return false;
76
    }
77
78
    /**
79
     * Returns a value indicating whether a current url equals `loginUrl` property of the User component
80
     *
81
     * @param Action $action
82
     *
83
     * @return bool
84
     */
85
    private function isLoginPage(Action $action): bool
86
    {
87
        $loginUrl = trim(Url::to(Yii::$app->user->loginUrl), '/');
88
89
        if (Yii::$app->user->isGuest && $action->getUniqueId() === $loginUrl) {
90
            return true;
91
        }
92
93
        return false;
94
    }
95
96
    /**
97
     * Returns a value indicating whether a current url exists in the `allowActions` list.
98
     *
99
     * @param Action $action
100
     *
101
     * @return bool
102
     */
103
    private function isAllowedAction(Action $action): bool
104
    {
105
        if ($this->owner instanceof Module) {
106
            $ownerId = $this->owner->getUniqueId();
107
            $id = $action->getUniqueId();
108
            if (!empty($ownerId) && strpos($id, $ownerId . '/') === 0) {
109
                $id = substr($id, strlen($ownerId) + 1);
110
            }
111
        } else {
112
            $id = $action->id;
113
        }
114
115
        foreach ($this->allowActions as $route) {
116
            if (substr($route, -1) === '*') {
117
                $route = rtrim($route, '*');
118
                if ($route === '' || strpos($id, $route) === 0) {
119
                    return true;
120
                }
121
            } else {
122
                if ($id === $route) {
123
                    return true;
124
                }
125
            }
126
        }
127
128
        return false;
129
    }
130
}
131