Manager.php 13 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 50 51 52 53 54 55 56 57 58 59 60
{
	/**
	 * @var boolean Enable error reporting for bizRules.
	 */
	public $showErrors = false;

	/**
	 * @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.
	 */
Alexander Makarov committed
61
	public $defaultRoles = [];
62 63 64

	/**
	 * Creates a role.
65
	 * This is a shortcut method to [[Manager::createItem()]].
66 67 68 69
	 * @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
70
	 * @return Item the authorization item
71 72 73
	 */
	public function createRole($name, $description = '', $bizRule = null, $data = null)
	{
74
		return $this->createItem($name, Item::TYPE_ROLE, $description, $bizRule, $data);
75 76 77 78
	}

	/**
	 * Creates a task.
79
	 * This is a shortcut method to [[Manager::createItem()]].
80 81 82 83
	 * @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
84
	 * @return Item the authorization item
85 86 87
	 */
	public function createTask($name, $description = '', $bizRule = null, $data = null)
	{
88
		return $this->createItem($name, Item::TYPE_TASK, $description, $bizRule, $data);
89 90 91 92
	}

	/**
	 * Creates an operation.
93
	 * This is a shortcut method to [[Manager::createItem()]].
94 95 96 97
	 * @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
98
	 * @return Item the authorization item
99 100 101
	 */
	public function createOperation($name, $description = '', $bizRule = null, $data = null)
	{
102
		return $this->createItem($name, Item::TYPE_OPERATION, $description, $bizRule, $data);
103 104 105 106
	}

	/**
	 * Returns roles.
107
	 * 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.
resurtm committed
110
	 * @return Item[] roles (name => AuthItem)
111 112 113
	 */
	public function getRoles($userId = null)
	{
114
		return $this->getItems($userId, Item::TYPE_ROLE);
115 116 117 118
	}

	/**
	 * Returns tasks.
119
	 * 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.
resurtm committed
122
	 * @return Item[] tasks (name => AuthItem)
123 124 125
	 */
	public function getTasks($userId = null)
	{
126
		return $this->getItems($userId, Item::TYPE_TASK);
127 128 129 130
	}

	/**
	 * Returns operations.
131
	 * 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.
resurtm committed
134
	 * @return Item[] operations (name => AuthItem)
135 136 137
	 */
	public function getOperations($userId = null)
	{
138
		return $this->getItems($userId, Item::TYPE_OPERATION);
139 140 141 142 143
	}

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

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

	/**
	 * Performs access check for the specified user.
	 * @param mixed $userId the user ID. This should be either an integer or a string representing
171
	 * the unique identifier of a user. See [[\yii\web\User::id]].
172 173 174 175 176
	 * @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.
	 * @return boolean whether the operations can be performed by the user.
	 */
Alexander Makarov committed
177
	abstract public function checkAccess($userId, $itemName, $params = []);
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254

	/**
	 * 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.
	 * @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.
	 * @throws \yii\base\Exception if an item with the same name already exists
	 * @return Item the authorization item
	 */
	abstract public function createItem($name, $type, $description = '', $bizRule = null, $data = null);
	/**
	 * Removes the specified authorization item.
	 * @param string $name the name of the item to be removed
	 * @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.
	 * @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.
	 */
	abstract public function getItems($userId = null, $type = null);
	/**
	 * Returns the authorization item with the specified name.
	 * @param string $name the name of the item
	 * @return Item the authorization item. Null if the item cannot be found.
	 */
	abstract public function getItem($name);
	/**
	 * Saves an authorization item to persistent storage.
	 * @param Item $item the item to be saved.
	 * @param string $oldName the old item name. If null, it means the item name is not changed.
	 */
	abstract public function saveItem($item, $oldName = null);

	/**
	 * Adds an item as a child of another item.
	 * @param string $itemName the parent item name
	 * @param string $childName the child item name
	 * @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.
	 * @param string $itemName the parent item name
	 * @param string $childName the child item name
	 * @return boolean whether the removal is successful
	 */
	abstract public function removeItemChild($itemName, $childName);
	/**
	 * Returns a value indicating whether a child exists within a parent.
	 * @param string $itemName the parent item name
	 * @param string $childName the child item name
	 * @return boolean whether the child exists
	 */
	abstract public function hasItemChild($itemName, $childName);
	/**
	 * Returns the children of the specified item.
	 * @param mixed $itemName the parent item name. This can be either a string or an array.
	 * The latter represents a list of item names.
	 * @return Item[] all child items of the parent
	 */
	abstract public function getItemChildren($itemName);

	/**
	 * Assigns an authorization item to a user.
255
	 * @param mixed $userId the user ID (see [[\yii\web\User::id]])
256 257 258 259 260 261 262 263 264 265
	 * @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.
	 * @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
	 * @param mixed $userId the user ID (see [[\yii\web\User::id]])
267 268 269 270
	 * @param string $itemName the item name
	 * @return boolean whether removal is successful
	 */
	abstract public function revoke($userId, $itemName);
271 272
	/**
	 * Revokes all authorization assignments from a user.
273
	 * @param mixed $userId the user ID (see [[\yii\web\User::id]])
274 275 276
	 * @return boolean whether removal is successful
	 */
	abstract public function revokeAll($userId);
277 278
	/**
	 * Returns a value indicating whether the item has been assigned to the user.
279
	 * @param mixed $userId the user ID (see [[\yii\web\User::id]])
280 281 282 283 284 285
	 * @param string $itemName the item name
	 * @return boolean whether the item has been assigned to the user.
	 */
	abstract public function isAssigned($userId, $itemName);
	/**
	 * Returns the item assignment information.
286
	 * @param mixed $userId the user ID (see [[\yii\web\User::id]])
287 288 289 290 291 292 293
	 * @param string $itemName the item name
	 * @return Assignment the item assignment information. Null is returned if
	 * the item is not assigned to the user.
	 */
	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 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
	 * @return Item[] the item assignment information for the user. An empty array will be
	 * returned if there is no item assigned to the user.
	 */
	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
}