Manager.php 13.8 KB
Newer Older
1 2 3 4 5 6 7
<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

8
namespace yii\rbac;
9 10 11

use Yii;
use yii\base\Component;
12
use yii\base\InvalidParamException;
13 14

/**
15 16 17 18 19 20 21 22 23
 * Manager is the base class for authorization manager classes.
 *
 * Manager extends [[Component]] and implements some methods
 * that are common among authorization manager classes.
 *
 * Manager together with its concrete child classes implement the Role-Based
 * Access Control (RBAC).
 *
 * The main idea is that permissions are organized as a hierarchy of
Qiang Xue committed
24
 * [[Item]] authorization items. Items on higher level inherit the permissions
25 26 27 28 29 30 31
 * represented by items on lower level. And roles are simply top-level authorization items
 * that may be assigned to individual users. A user is said to have a permission
 * to do something if the corresponding authorization item is inherited by one of his roles.
 *
 * Using authorization manager consists of two aspects. First, the authorization hierarchy
 * and assignments have to be established. Manager and its child classes
 * provides APIs to accomplish this task. Developers may need to develop some GUI
32
 * so that it is more intuitive to end-users. Second, developers call [[Manager::checkAccess()]]
33 34 35
 * at appropriate places in the application code to check if the current user
 * has the needed permission for an operation.
 *
36 37 38
 * @property Item[] $operations Operations (name => AuthItem). This property is read-only.
 * @property Item[] $roles Roles (name => AuthItem). This property is read-only.
 * @property Item[] $tasks Tasks (name => AuthItem). This property is read-only.
39 40 41 42 43
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @author Alexander Kochetov <creocoder@gmail.com>
 * @since 2.0
 */
44
abstract class Manager extends Component
45
{
46 47 48 49
    /**
     * @var boolean Enable error reporting for bizRules.
     */
    public $showErrors = false;
50

51 52 53 54 55 56 57 58 59 60 61
    /**
     * @var array list of role names that are assigned to all users implicitly.
     * These roles do not need to be explicitly assigned to any user.
     * When calling [[checkAccess()]], these roles will be checked first.
     * For performance reason, you should minimize the number of such roles.
     * A typical usage of such roles is to define an 'authenticated' role and associate
     * it with a biz rule which checks if the current user is authenticated.
     * And then declare 'authenticated' in this property so that it can be applied to
     * every authenticated user.
     */
    public $defaultRoles = [];
62

63 64 65
    /**
     * Creates a role.
     * This is a shortcut method to [[Manager::createItem()]].
66 67 68 69 70
     * @param string $name the item name
     * @param string $description the item description.
     * @param string $bizRule the business rule associated with this item
     * @param mixed $data additional data to be passed when evaluating the business rule
     * @return Item the authorization item
71 72 73 74 75
     */
    public function createRole($name, $description = '', $bizRule = null, $data = null)
    {
        return $this->createItem($name, Item::TYPE_ROLE, $description, $bizRule, $data);
    }
76

77 78 79
    /**
     * Creates a task.
     * This is a shortcut method to [[Manager::createItem()]].
80 81 82 83 84
     * @param string $name the item name
     * @param string $description the item description.
     * @param string $bizRule the business rule associated with this item
     * @param mixed $data additional data to be passed when evaluating the business rule
     * @return Item the authorization item
85 86 87 88 89
     */
    public function createTask($name, $description = '', $bizRule = null, $data = null)
    {
        return $this->createItem($name, Item::TYPE_TASK, $description, $bizRule, $data);
    }
90

91 92 93
    /**
     * Creates an operation.
     * This is a shortcut method to [[Manager::createItem()]].
94 95 96 97 98
     * @param string $name the item name
     * @param string $description the item description.
     * @param string $bizRule the business rule associated with this item
     * @param mixed $data additional data to be passed when evaluating the business rule
     * @return Item the authorization item
99 100 101 102 103
     */
    public function createOperation($name, $description = '', $bizRule = null, $data = null)
    {
        return $this->createItem($name, Item::TYPE_OPERATION, $description, $bizRule, $data);
    }
104

105 106 107
    /**
     * Returns roles.
     * This is a shortcut method to [[Manager::getItems()]].
108 109
     * @param mixed $userId the user ID. If not null, only the roles directly assigned to the user
     * will be returned. Otherwise, all roles will be returned.
110 111 112 113 114 115
     * @return Item[] roles (name => AuthItem)
     */
    public function getRoles($userId = null)
    {
        return $this->getItems($userId, Item::TYPE_ROLE);
    }
116

117 118 119
    /**
     * Returns tasks.
     * This is a shortcut method to [[Manager::getItems()]].
120 121
     * @param mixed $userId the user ID. If not null, only the tasks directly assigned to the user
     * will be returned. Otherwise, all tasks will be returned.
122 123 124 125 126 127
     * @return Item[] tasks (name => AuthItem)
     */
    public function getTasks($userId = null)
    {
        return $this->getItems($userId, Item::TYPE_TASK);
    }
128

129 130 131
    /**
     * Returns operations.
     * This is a shortcut method to [[Manager::getItems()]].
132 133
     * @param mixed $userId the user ID. If not null, only the operations directly assigned to the user
     * will be returned. Otherwise, all operations will be returned.
134 135 136 137 138 139
     * @return Item[] operations (name => AuthItem)
     */
    public function getOperations($userId = null)
    {
        return $this->getItems($userId, Item::TYPE_OPERATION);
    }
140

141 142
    /**
     * Executes the specified business rule.
143 144 145
     * @param string $bizRule the business rule to be executed.
     * @param array $params parameters passed to [[Manager::checkAccess()]].
     * @param mixed $data additional data associated with the authorization item or assignment.
146
     * @return boolean whether the business rule returns true.
147
     * If the business rule is empty, it will still return true.
148 149 150 151 152
     */
    public function executeBizRule($bizRule, $params, $data)
    {
        return $bizRule === '' || $bizRule === null || ($this->showErrors ? eval($bizRule) != 0 : @eval($bizRule) != 0);
    }
153

154 155
    /**
     * Checks the item types to make sure a child can be added to a parent.
156 157
     * @param integer $parentType parent item type
     * @param integer $childType child item type
158 159 160 161 162 163 164 165 166
     * @throws InvalidParamException if the item cannot be added as a child due to its incompatible type.
     */
    protected function checkItemChildType($parentType, $childType)
    {
        static $types = ['operation', 'task', 'role'];
        if ($parentType < $childType) {
            throw new InvalidParamException("Cannot add an item of type '{$types[$childType]}' to an item of type '{$types[$parentType]}'.");
        }
    }
167

168 169
    /**
     * Performs access check for the specified user.
170 171 172 173 174
     * @param mixed $userId the user ID. This should be either an integer or a string representing
     * the unique identifier of a user. See [[\yii\web\User::id]].
     * @param string $itemName the name of the operation that we are checking access to
     * @param array $params name-value pairs that would be passed to biz rules associated
     * with the tasks and roles assigned to the user.
175 176 177
     * @return boolean whether the operations can be performed by the user.
     */
    abstract public function checkAccess($userId, $itemName, $params = []);
178

179 180 181 182 183 184
    /**
     * Creates an authorization item.
     * An authorization item represents an action permission (e.g. creating a post).
     * It has three types: operation, task and role.
     * Authorization items form a hierarchy. Higher level items inheirt permissions representing
     * by lower level items.
185 186 187 188 189 190
     * @param string $name the item name. This must be a unique identifier.
     * @param integer $type the item type (0: operation, 1: task, 2: role).
     * @param string $description description of the item
     * @param string $bizRule business rule associated with the item. This is a piece of
     * PHP code that will be executed when [[checkAccess()]] is called for the item.
     * @param mixed $data additional data associated with the item.
191
     * @throws \yii\base\Exception if an item with the same name already exists
192
     * @return Item the authorization item
193 194 195 196
     */
    abstract public function createItem($name, $type, $description = '', $bizRule = null, $data = null);
    /**
     * Removes the specified authorization item.
197
     * @param string $name the name of the item to be removed
198 199 200 201 202
     * @return boolean whether the item exists in the storage and has been removed
     */
    abstract public function removeItem($name);
    /**
     * Returns the authorization items of the specific type and user.
203 204 205 206 207
     * @param mixed $userId the user ID. Defaults to null, meaning returning all items even if
     * they are not assigned to a user.
     * @param integer $type the item type (0: operation, 1: task, 2: role). Defaults to null,
     * meaning returning all items regardless of their type.
     * @return Item[] the authorization items of the specific type.
208 209 210 211
     */
    abstract public function getItems($userId = null, $type = null);
    /**
     * Returns the authorization item with the specified name.
212 213
     * @param string $name the name of the item
     * @return Item the authorization item. Null if the item cannot be found.
214 215 216 217
     */
    abstract public function getItem($name);
    /**
     * Saves an authorization item to persistent storage.
218
     * @param Item $item the item to be saved.
219 220 221
     * @param string $oldName the old item name. If null, it means the item name is not changed.
     */
    abstract public function saveItem($item, $oldName = null);
222

223 224
    /**
     * Adds an item as a child of another item.
225 226
     * @param string $itemName the parent item name
     * @param string $childName the child item name
227 228 229 230 231 232
     * @throws \yii\base\Exception if either parent or child doesn't exist or if a loop has been detected.
     */
    abstract public function addItemChild($itemName, $childName);
    /**
     * Removes a child from its parent.
     * Note, the child item is not deleted. Only the parent-child relationship is removed.
233 234
     * @param string $itemName the parent item name
     * @param string $childName the child item name
235 236 237 238 239
     * @return boolean whether the removal is successful
     */
    abstract public function removeItemChild($itemName, $childName);
    /**
     * Returns a value indicating whether a child exists within a parent.
240 241
     * @param string $itemName the parent item name
     * @param string $childName the child item name
242 243 244 245 246
     * @return boolean whether the child exists
     */
    abstract public function hasItemChild($itemName, $childName);
    /**
     * Returns the children of the specified item.
247 248
     * @param mixed $itemName the parent item name. This can be either a string or an array.
     * The latter represents a list of item names.
249 250 251
     * @return Item[] all child items of the parent
     */
    abstract public function getItemChildren($itemName);
252

253 254
    /**
     * Assigns an authorization item to a user.
255 256 257 258 259 260
     * @param mixed $userId the user ID (see [[\yii\web\User::id]])
     * @param string $itemName the item name
     * @param string $bizRule the business rule to be executed when [[checkAccess()]] is called
     * for this particular authorization item.
     * @param mixed $data additional data associated with this assignment
     * @return Assignment the authorization assignment information.
261 262 263 264 265
     * @throws \yii\base\Exception if the item does not exist or if the item has already been assigned to the user
     */
    abstract public function assign($userId, $itemName, $bizRule = null, $data = null);
    /**
     * Revokes an authorization assignment from a user.
266 267
     * @param mixed $userId the user ID (see [[\yii\web\User::id]])
     * @param string $itemName the item name
268 269 270 271 272
     * @return boolean whether removal is successful
     */
    abstract public function revoke($userId, $itemName);
    /**
     * Revokes all authorization assignments from a user.
273
     * @param mixed $userId the user ID (see [[\yii\web\User::id]])
274 275 276 277 278
     * @return boolean whether removal is successful
     */
    abstract public function revokeAll($userId);
    /**
     * Returns a value indicating whether the item has been assigned to the user.
279 280
     * @param mixed $userId the user ID (see [[\yii\web\User::id]])
     * @param string $itemName the item name
281 282 283 284 285
     * @return boolean whether the item has been assigned to the user.
     */
    abstract public function isAssigned($userId, $itemName);
    /**
     * Returns the item assignment information.
286 287
     * @param mixed $userId the user ID (see [[\yii\web\User::id]])
     * @param string $itemName the item name
288
     * @return Assignment the item assignment information. Null is returned if
289
     * the item is not assigned to the user.
290 291 292 293
     */
    abstract public function getAssignment($userId, $itemName);
    /**
     * Returns the item assignments for the specified user.
294
     * @param mixed $userId the user ID (see [[\yii\web\User::id]])
295
     * @return Item[] the item assignment information for the user. An empty array will be
296
     * returned if there is no item assigned to the user.
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
     */
    abstract public function getAssignments($userId);
    /**
     * Saves the changes to an authorization assignment.
     * @param Assignment $assignment the assignment that has been changed.
     */
    abstract public function saveAssignment($assignment);
    /**
     * Removes all authorization data.
     */
    abstract public function clearAll();
    /**
     * Removes all authorization assignments.
     */
    abstract public function clearAssignments();
    /**
     * Saves authorization data into persistent storage.
     * If any change is made to the authorization data, please make
     * sure you call this method to save the changed data into persistent storage.
     */
    abstract public function save();
318
}