Completed
Pull Request — 2.1 (#15718)
by Alex
17:00
created

BaseManager   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 264
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 8

Test Coverage

Coverage 78.56%

Importance

Changes 0
Metric Value
wmc 35
lcom 2
cbo 8
dl 0
loc 264
rs 9
c 0
b 0
f 0
ccs 55
cts 70
cp 0.7856

22 Methods

Rating   Name   Duplication   Size   Complexity  
getItem() 0 1 ?
getItems() 0 1 ?
addItem() 0 1 ?
addRule() 0 1 ?
removeItem() 0 1 ?
removeRule() 0 1 ?
updateItem() 0 1 ?
updateRule() 0 1 ?
A createRole() 0 6 1
A createPermission() 0 6 1
B add() 0 16 5
A remove() 0 10 3
B update() 0 16 5
A getRole() 0 5 3
A getPermission() 0 5 3
A getRoles() 0 4 1
A setDefaultRoles() 0 14 4
A getDefaultRoles() 0 4 1
A getDefaultRoleInstances() 0 9 2
A getPermissions() 0 4 1
A executeRule() 0 12 3
A hasNoAssignments() 0 4 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\rbac;
9
10
use yii\base\Component;
11
use yii\base\InvalidArgumentException;
12
use yii\base\InvalidConfigException;
13
14
/**
15
 * BaseManager is a base class implementing [[ManagerInterface]] for RBAC management.
16
 *
17
 * For more details and usage information on DbManager, see the [guide article on security authorization](guide:security-authorization).
18
 *
19
 * @property Role[] $defaultRoleInstances Default roles. The array is indexed by the role names. This property
20
 * is read-only.
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 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 264
    public function createRole($name)
104
    {
105 264
        $role = new Role();
106 264
        $role->name = $name;
107 264
        return $role;
108
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113 263
    public function createPermission($name)
114
    {
115 263
        $permission = new Permission();
116 263
        $permission->name = $name;
117 263
        return $permission;
118
    }
119
120
    /**
121
     * {@inheritdoc}
122
     */
123 276
    public function add($object)
124
    {
125 276
        if ($object instanceof Item) {
126 270
            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 270
            return $this->addItem($object);
133 179
        } elseif ($object instanceof Rule) {
134 179
            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;
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;
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 array|\Closure $roles either array of roles or a callable returning it
203
     * @since 2.0.14
204
     */
205 268
    public function setDefaultRoles($roles)
206
    {
207 268
        if (is_array($roles)) {
208 268
            $this->defaultRoles = $roles;
209
        } elseif (is_callable($roles)) {
210
            $roles = $roles();
211
            if (!is_array($roles)) {
212
                throw new InvalidArgumentException('Default roles closure must return an array');
213
            }
214
            $this->defaultRoles = $roles;
215
        } else {
216
            throw new InvalidArgumentException('Default roles must be either an array or a callable');
217
        }
218 268
    }
219
220
    /**
221
     * Get default roles.
222
     * @return array default roles
223
     * @since 2.0.14
224
     */
225
    public function getDefaultRoles()
226
    {
227
        return $this->defaultRoles;
228
    }
229
230
    /**
231
     * Returns defaultRoles as array of Role objects.
232
     * @since 2.0.12
233
     * @return Role[] default roles. The array is indexed by the role names
234
     */
235 22
    public function getDefaultRoleInstances()
236
    {
237 22
        $result = [];
238 22
        foreach ($this->defaultRoles as $roleName) {
239 22
            $result[$roleName] = $this->createRole($roleName);
240
        }
241
242 22
        return $result;
243
    }
244
245
    /**
246
     * {@inheritdoc}
247
     */
248 18
    public function getPermissions()
249
    {
250 18
        return $this->getItems(Item::TYPE_PERMISSION);
251
    }
252
253
    /**
254
     * Executes the rule associated with the specified auth item.
255
     *
256
     * If the item does not specify a rule, this method will return true. Otherwise, it will
257
     * return the value of [[Rule::execute()]].
258
     *
259
     * @param string|int $user the user ID. This should be either an integer or a string representing
260
     * the unique identifier of a user. See [[\yii\web\User::id]].
261
     * @param Item $item the auth item that needs to execute its rule
262
     * @param array $params parameters passed to [[CheckAccessInterface::checkAccess()]] and will be passed to the rule
263
     * @return bool the return value of [[Rule::execute()]]. If the auth item does not specify a rule, true will be returned.
264
     * @throws InvalidConfigException if the auth item has an invalid rule.
265
     */
266 47
    protected function executeRule($user, $item, $params)
267
    {
268 47
        if ($item->ruleName === null) {
269 47
            return true;
270
        }
271 38
        $rule = $this->getRule($item->ruleName);
272 38
        if ($rule instanceof Rule) {
273 38
            return $rule->execute($user, $item, $params);
274
        }
275
276
        throw new InvalidConfigException("Rule not found: {$item->ruleName}");
277
    }
278
279
    /**
280
     * Checks whether array of $assignments is empty and [[defaultRoles]] property is empty as well.
281
     *
282
     * @param Assignment[] $assignments array of user's assignments
283
     * @return bool whether array of $assignments is empty and [[defaultRoles]] property is empty as well
284
     * @since 2.0.11
285
     */
286 55
    protected function hasNoAssignments(array $assignments)
287
    {
288 55
        return empty($assignments) && empty($this->defaultRoles);
289
    }
290
}
291