BaseManager::remove()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3.0416

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 1
dl 0
loc 9
ccs 5
cts 6
cp 0.8333
crap 3.0416
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @link https://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license https://www.yiiframework.com/license/
6
 */
7
8
namespace yii\rbac;
9
10
use yii\base\Component;
11
use yii\base\InvalidArgumentException;
12
use yii\base\InvalidConfigException;
13
use yii\base\InvalidValueException;
14
15
/**
16
 * BaseManager is a base class implementing [[ManagerInterface]] for RBAC management.
17
 *
18
 * For more details and usage information on DbManager, see the [guide article on security authorization](guide:security-authorization).
19
 *
20
 * @property-read Role[] $defaultRoleInstances Default roles. The array is indexed by the role names.
21
 * @property string[] $defaultRoles Default roles. Note that the type of this property differs in getter and
22
 * setter. See [[getDefaultRoles()]] and [[setDefaultRoles()]] for details.
23
 *
24
 * @author Qiang Xue <[email protected]>
25
 * @since 2.0
26
 */
27
abstract class BaseManager extends Component implements ManagerInterface
28
{
29
    /**
30
     * @var array a list of role names that are assigned to every user automatically without calling [[assign()]].
31
     * Note that these roles are applied to users, regardless of their state of authentication.
32
     */
33
    protected $defaultRoles = [];
34
35
36
    /**
37
     * Returns the named auth item.
38
     * @param string $name the auth item name.
39
     * @return Item|null the auth item corresponding to the specified name. Null is returned if no such item.
40
     */
41
    abstract protected function getItem($name);
42
43
    /**
44
     * Returns the items of the specified type.
45
     * @param int $type the auth item type (either [[Item::TYPE_ROLE]] or [[Item::TYPE_PERMISSION]]
46
     * @return Item[] the auth items of the specified type.
47
     */
48
    abstract protected function getItems($type);
49
50
    /**
51
     * Adds an auth item to the RBAC system.
52
     * @param Item $item the item to add
53
     * @return bool whether the auth item is successfully added to the system
54
     * @throws \Exception if data validation or saving fails (such as the name of the role or permission is not unique)
55
     */
56
    abstract protected function addItem($item);
57
58
    /**
59
     * Adds a rule to the RBAC system.
60
     * @param Rule $rule the rule to add
61
     * @return bool whether the rule is successfully added to the system
62
     * @throws \Exception if data validation or saving fails (such as the name of the rule is not unique)
63
     */
64
    abstract protected function addRule($rule);
65
66
    /**
67
     * Removes an auth item from the RBAC system.
68
     * @param Item $item the item to remove
69
     * @return bool whether the role or permission is successfully removed
70
     * @throws \Exception if data validation or saving fails (such as the name of the role or permission is not unique)
71
     */
72
    abstract protected function removeItem($item);
73
74
    /**
75
     * Removes a rule from the RBAC system.
76
     * @param Rule $rule the rule to remove
77
     * @return bool whether the rule is successfully removed
78
     * @throws \Exception if data validation or saving fails (such as the name of the rule is not unique)
79
     */
80
    abstract protected function removeRule($rule);
81
82
    /**
83
     * Updates an auth item in the RBAC system.
84
     * @param string $name the name of the item being updated
85
     * @param Item $item the updated item
86
     * @return bool whether the auth item is successfully updated
87
     * @throws \Exception if data validation or saving fails (such as the name of the role or permission is not unique)
88
     */
89
    abstract protected function updateItem($name, $item);
90
91
    /**
92
     * Updates a rule to the RBAC system.
93
     * @param string $name the name of the rule being updated
94
     * @param Rule $rule the updated rule
95
     * @return bool whether the rule is successfully updated
96
     * @throws \Exception if data validation or saving fails (such as the name of the rule is not unique)
97
     */
98
    abstract protected function updateRule($name, $rule);
99
100
    /**
101
     * {@inheritdoc}
102
     */
103 270
    public function createRole($name)
104
    {
105 270
        $role = new Role();
106 270
        $role->name = $name;
107 270
        return $role;
108
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113 266
    public function createPermission($name)
114
    {
115 266
        $permission = new Permission();
116 266
        $permission->name = $name;
117 266
        return $permission;
118
    }
119
120
    /**
121
     * {@inheritdoc}
122
     */
123 284
    public function add($object)
124
    {
125 284
        if ($object instanceof Item) {
126 278
            if ($object->ruleName && $this->getRule($object->ruleName) === null) {
127 12
                $rule = \Yii::createObject($object->ruleName);
128 12
                $rule->name = $object->ruleName;
129 12
                $this->addRule($rule);
130
            }
131
132 278
            return $this->addItem($object);
133 180
        } elseif ($object instanceof Rule) {
134 180
            return $this->addRule($object);
135
        }
136
137
        throw new InvalidArgumentException('Adding unsupported object type.');
138
    }
139
140
    /**
141
     * {@inheritdoc}
142
     */
143 7
    public function remove($object)
144
    {
145 7
        if ($object instanceof Item) {
146 7
            return $this->removeItem($object);
147 6
        } elseif ($object instanceof Rule) {
148 6
            return $this->removeRule($object);
149
        }
150
151
        throw new InvalidArgumentException('Removing unsupported object type.');
152
    }
153
154
    /**
155
     * {@inheritdoc}
156
     */
157 22
    public function update($name, $object)
158
    {
159 22
        if ($object instanceof Item) {
160 22
            if ($object->ruleName && $this->getRule($object->ruleName) === null) {
161
                $rule = \Yii::createObject($object->ruleName);
162
                $rule->name = $object->ruleName;
163
                $this->addRule($rule);
164
            }
165
166 22
            return $this->updateItem($name, $object);
167 6
        } elseif ($object instanceof Rule) {
168 6
            return $this->updateRule($name, $object);
169
        }
170
171
        throw new InvalidArgumentException('Updating unsupported object type.');
172
    }
173
174
    /**
175
     * {@inheritdoc}
176
     */
177 62
    public function getRole($name)
178
    {
179 62
        $item = $this->getItem($name);
180 62
        return $item instanceof Item && $item->type == Item::TYPE_ROLE ? $item : null;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $item instanceof ...YPE_ROLE ? $item : null also could return the type yii\rbac\Item which includes types incompatible with the return type mandated by yii\rbac\ManagerInterface::getRole() of null|yii\rbac\Role. Consider adding a type-check to rule them out.
Loading history...
181
    }
182
183
    /**
184
     * {@inheritdoc}
185
     */
186 27
    public function getPermission($name)
187
    {
188 27
        $item = $this->getItem($name);
189 27
        return $item instanceof Item && $item->type == Item::TYPE_PERMISSION ? $item : null;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $item instanceof ...RMISSION ? $item : null also could return the type yii\rbac\Item which includes types incompatible with the return type mandated by yii\rbac\ManagerInterface::getPermission() of null|yii\rbac\Permission. Consider adding a type-check to rule them out.
Loading history...
190
    }
191
192
    /**
193
     * {@inheritdoc}
194
     */
195 24
    public function getRoles()
196
    {
197 24
        return $this->getItems(Item::TYPE_ROLE);
198
    }
199
200
    /**
201
     * Set default roles
202
     * @param string[]|\Closure $roles either array of roles or a callable returning it
203
     * @throws InvalidArgumentException when $roles is neither array nor Closure
204
     * @throws InvalidValueException when Closure return is not an array
205
     * @since 2.0.14
206
     */
207 285
    public function setDefaultRoles($roles)
208
    {
209 285
        if (is_array($roles)) {
210 285
            $this->defaultRoles = $roles;
211 12
        } elseif ($roles instanceof \Closure) {
0 ignored issues
show
introduced by
$roles is always a sub-type of Closure.
Loading history...
212 6
            $roles = call_user_func($roles);
213 6
            if (!is_array($roles)) {
214 6
                throw new InvalidValueException('Default roles closure must return an array');
215
            }
216
            $this->defaultRoles = $roles;
217
        } else {
218 6
            throw new InvalidArgumentException('Default roles must be either an array or a callable');
219
        }
220
    }
221
222
    /**
223
     * Get default roles
224
     * @return string[] default roles
225
     * @since 2.0.14
226
     */
227
    public function getDefaultRoles()
228
    {
229
        return $this->defaultRoles;
230
    }
231
232
    /**
233
     * Returns defaultRoles as array of Role objects.
234
     * @since 2.0.12
235
     * @return Role[] default roles. The array is indexed by the role names
236
     */
237 27
    public function getDefaultRoleInstances()
238
    {
239 27
        $result = [];
240 27
        foreach ($this->defaultRoles as $roleName) {
241 27
            $result[$roleName] = $this->createRole($roleName);
242
        }
243
244 27
        return $result;
245
    }
246
247
    /**
248
     * {@inheritdoc}
249
     */
250 18
    public function getPermissions()
251
    {
252 18
        return $this->getItems(Item::TYPE_PERMISSION);
253
    }
254
255
    /**
256
     * Executes the rule associated with the specified auth item.
257
     *
258
     * If the item does not specify a rule, this method will return true. Otherwise, it will
259
     * return the value of [[Rule::execute()]].
260
     *
261
     * @param string|int $user the user ID. This should be either an integer or a string representing
262
     * the unique identifier of a user. See [[\yii\web\User::id]].
263
     * @param Item $item the auth item that needs to execute its rule
264
     * @param array $params parameters passed to [[CheckAccessInterface::checkAccess()]] and will be passed to the rule
265
     * @return bool the return value of [[Rule::execute()]]. If the auth item does not specify a rule, true will be returned.
266
     * @throws InvalidConfigException if the auth item has an invalid rule.
267
     */
268 50
    protected function executeRule($user, $item, $params)
269
    {
270 50
        if ($item->ruleName === null) {
271 50
            return true;
272
        }
273 39
        $rule = $this->getRule($item->ruleName);
274 39
        if ($rule instanceof Rule) {
275 39
            return $rule->execute($user, $item, $params);
276
        }
277
278
        throw new InvalidConfigException("Rule not found: {$item->ruleName}");
279
    }
280
281
    /**
282
     * Checks whether array of $assignments is empty and [[defaultRoles]] property is empty as well.
283
     *
284
     * @param Assignment[] $assignments array of user's assignments
285
     * @return bool whether array of $assignments is empty and [[defaultRoles]] property is empty as well
286
     * @since 2.0.11
287
     */
288 58
    protected function hasNoAssignments(array $assignments)
289
    {
290 58
        return empty($assignments) && empty($this->defaultRoles);
291
    }
292
}
293