Completed
Push — 2.1 ( eea58f...782246 )
by Dmitry
19:35 queued 13:59
created

AccessControl   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 86
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 10
c 1
b 0
f 0
lcom 1
cbo 5
dl 0
loc 86
ccs 0
cts 29
cp 0
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
C beforeAction() 0 29 8
A denyAccess() 0 8 2
1
<?php
2
/**
3
 * @link http://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license http://www.yiiframework.com/license/
6
 */
7
8
namespace yii\filters;
9
10
use Yii;
11
use yii\base\Action;
12
use yii\base\ActionFilter;
13
use yii\di\Instance;
14
use yii\web\ForbiddenHttpException;
15
use yii\web\User;
16
17
/**
18
 * AccessControl provides simple access control based on a set of rules.
19
 *
20
 * AccessControl is an action filter. It will check its [[rules]] to find
21
 * the first rule that matches the current context variables (such as user IP address, user role).
22
 * The matching rule will dictate whether to allow or deny the access to the requested controller
23
 * action. If no rule matches, the access will be denied.
24
 *
25
 * To use AccessControl, declare it in the `behaviors()` method of your controller class.
26
 * For example, the following declarations will allow authenticated users to access the "create"
27
 * and "update" actions and deny all other users from accessing these two actions.
28
 *
29
 * ```php
30
 * public function behaviors()
31
 * {
32
 *     return [
33
 *         'access' => [
34
 *             'class' => \yii\filters\AccessControl::class,
35
 *             'only' => ['create', 'update'],
36
 *             'rules' => [
37
 *                 // deny all POST requests
38
 *                 [
39
 *                     'allow' => false,
40
 *                     'verbs' => ['POST']
41
 *                 ],
42
 *                 // allow authenticated users
43
 *                 [
44
 *                     'allow' => true,
45
 *                     'roles' => ['@'],
46
 *                 ],
47
 *                 // everything else is denied
48
 *             ],
49
 *         ],
50
 *     ];
51
 * }
52
 * ```
53
 *
54
 * @author Qiang Xue <[email protected]>
55
 * @since 2.0
56
 */
57
class AccessControl extends ActionFilter
58
{
59
    /**
60
     * @var User|array|string the user object representing the authentication status or the ID of the user application component.
61
     * Starting from version 2.0.2, this can also be a configuration array for creating the object.
62
     */
63
    public $user = 'user';
64
    /**
65
     * @var callable a callback that will be called if the access should be denied
66
     * to the current user. If not set, [[denyAccess()]] will be called.
67
     *
68
     * The signature of the callback should be as follows:
69
     *
70
     * ```php
71
     * function ($rule, $action)
72
     * ```
73
     *
74
     * where `$rule` is the rule that denies the user, and `$action` is the current [[Action|action]] object.
75
     * `$rule` can be `null` if access is denied because none of the rules matched.
76
     */
77
    public $denyCallback;
78
    /**
79
     * @var array the default configuration of access rules. Individual rule configurations
80
     * specified via [[rules]] will take precedence when the same property of the rule is configured.
81
     */
82
    public $ruleConfig = ['class' => AccessRule::class];
83
    /**
84
     * @var array a list of access rule objects or configuration arrays for creating the rule objects.
85
     * If a rule is specified via a configuration array, it will be merged with [[ruleConfig]] first
86
     * before it is used for creating the rule object.
87
     * @see ruleConfig
88
     */
89
    public $rules = [];
90
91
    /**
92
     * This method is invoked right before an action is to be executed (after all possible filters.)
93
     * You may override this method to do last-minute preparation for the action.
94
     * @param Action $action the action to be executed.
95
     * @return boolean whether the action should continue to be executed.
96
     */
97
    public function beforeAction($action)
98
    {
99
        $user = $this->user = Instance::ensure($this->user, User::class);
100
        $request = Yii::$app->getRequest();
101
        /* @var $rule AccessRule */
102
        foreach ($this->rules as $key => $rule) {
103
            if (!is_object($rule)) {
104
                $rule = $this->rules[$key] = Yii::createObject(array_merge($this->ruleConfig, $rule));
105
            }
106
            if ($allow = $rule->allows($action, $user, $request)) {
107
                return true;
108
            } elseif ($allow === false) {
109
                if (isset($rule->denyCallback)) {
110
                    call_user_func($rule->denyCallback, $rule, $action);
111
                } elseif ($this->denyCallback !== null) {
112
                    call_user_func($this->denyCallback, $rule, $action);
113
                } else {
114
                    $this->denyAccess($user);
115
                }
116
                return false;
117
            }
118
        }
119
        if ($this->denyCallback !== null) {
120
            call_user_func($this->denyCallback, null, $action);
121
        } else {
122
            $this->denyAccess($user);
123
        }
124
        return false;
125
    }
126
127
    /**
128
     * Denies the access of the user.
129
     * The default implementation will redirect the user to the login page if he is a guest;
130
     * if the user is already logged, a 403 HTTP exception will be thrown.
131
     * @param User $user the current user
132
     * @throws ForbiddenHttpException if the user is already logged in.
133
     */
134
    protected function denyAccess($user)
135
    {
136
        if ($user->getIsGuest()) {
137
            $user->loginRequired();
138
        } else {
139
            throw new ForbiddenHttpException(Yii::t('yii', 'You are not allowed to perform this action.'));
140
        }
141
    }
142
}
143