You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					186 lines
				
				5.2 KiB
			
		
		
			
		
	
	
					186 lines
				
				5.2 KiB
			| 
											13 years ago
										 | <?php
 | ||
|  | /**
 | ||
|  |  * @link http://www.yiiframework.com/
 | ||
|  |  * @copyright Copyright (c) 2008 Yii Software LLC
 | ||
|  |  * @license http://www.yiiframework.com/license/
 | ||
|  |  */
 | ||
|  | 
 | ||
|  | namespace yii\web;
 | ||
|  | 
 | ||
|  | use yii\base\Component;
 | ||
|  | use yii\base\Action;
 | ||
|  | 
 | ||
|  | /**
 | ||
|  |  *
 | ||
|  |  * @author Qiang Xue <qiang.xue@gmail.com>
 | ||
|  |  * @since 2.0
 | ||
|  |  */
 | ||
|  | class AccessRule extends Component
 | ||
|  | {
 | ||
|  | 	/**
 | ||
|  | 	 * @var boolean whether this is an 'allow' rule or 'deny' rule.
 | ||
|  | 	 */
 | ||
|  | 	public $allow;
 | ||
|  | 	/**
 | ||
|  | 	 * @var array list of action IDs that this rule applies to. The comparison is case-sensitive.
 | ||
|  | 	 * If not set or empty, it means this rule applies to all actions.
 | ||
|  | 	 */
 | ||
|  | 	public $actions;
 | ||
|  | 	/**
 | ||
|  | 	 * @var array list of controller IDs that this rule applies to. The comparison is case-sensitive.
 | ||
|  | 	 * If not set or empty, it means this rule applies to all controllers.
 | ||
|  | 	 */
 | ||
|  | 	public $controllers;
 | ||
|  | 	/**
 | ||
| 
											13 years ago
										 | 	 * @var array list of roles that this rule applies to. Two special roles are recognized, and
 | ||
|  | 	 * they are checked via [[User::isGuest]]:
 | ||
| 
											13 years ago
										 | 	 *
 | ||
|  | 	 * - `?`: matches a guest user (not authenticated yet)
 | ||
|  | 	 * - `@`: matches an authenticated user
 | ||
|  | 	 *
 | ||
| 
											13 years ago
										 | 	 * Using additional role names requires RBAC (Role-Based Access Control), and
 | ||
|  | 	 * [[User::hasAccess()]] will be called.
 | ||
|  | 	 *
 | ||
|  | 	 * If this property is not set or empty, it means this rule applies to all roles.
 | ||
| 
											13 years ago
										 | 	 */
 | ||
|  | 	public $roles;
 | ||
|  | 	/**
 | ||
|  | 	 * @var array list of user IP addresses that this rule applies to. An IP address
 | ||
|  | 	 * can contain the wildcard `*` at the end so that it matches IP addresses with the same prefix.
 | ||
|  | 	 * For example, '192.168.*' matches all IP addresses in the segment '192.168.'.
 | ||
|  | 	 * If not set or empty, it means this rule applies to all IP addresses.
 | ||
|  | 	 * @see Request::userIP
 | ||
|  | 	 */
 | ||
|  | 	public $ips;
 | ||
|  | 	/**
 | ||
|  | 	 * @var array list of request methods (e.g. `GET`, `POST`) that this rule applies to.
 | ||
|  | 	 * The request methods must be specified in uppercase.
 | ||
|  | 	 * If not set or empty, it means this rule applies to all request methods.
 | ||
|  | 	 * @see Request::requestMethod
 | ||
|  | 	 */
 | ||
|  | 	public $verbs;
 | ||
|  | 	/**
 | ||
|  | 	 * @var callback a callback that will be called to determine if the rule should be applied.
 | ||
|  | 	 * The signature of the callback should be as follows:
 | ||
|  | 	 *
 | ||
|  | 	 * ~~~
 | ||
|  | 	 * function ($rule, $action)
 | ||
|  | 	 * ~~~
 | ||
|  | 	 *
 | ||
|  | 	 * where `$rule` is this rule, and `$action` is the current [[Action|action]] object.
 | ||
|  | 	 * The callback should return a boolean value indicating whether this rule should be applied.
 | ||
|  | 	 */
 | ||
|  | 	public $matchCallback;
 | ||
|  | 	/**
 | ||
|  | 	 * @var callback a callback that will be called if this rule determines the access to
 | ||
|  | 	 * the current action should be denied. If not set, the behavior will be determined by
 | ||
|  | 	 * [[AccessControl]].
 | ||
|  | 	 *
 | ||
|  | 	 * The signature of the callback should be as follows:
 | ||
|  | 	 *
 | ||
|  | 	 * ~~~
 | ||
|  | 	 * function ($rule, $action)
 | ||
|  | 	 * ~~~
 | ||
|  | 	 *
 | ||
|  | 	 * where `$rule` is this rule, and `$action` is the current [[Action|action]] object.
 | ||
|  | 	 */
 | ||
|  | 	public $denyCallback;
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * Checks whether the Web user is allowed to perform the specified action.
 | ||
|  | 	 * @param Action $action the action to be performed
 | ||
|  | 	 * @param User $user the user object
 | ||
|  | 	 * @param Request $request
 | ||
|  | 	 * @return boolean|null true if the user is allowed, false if the user is denied, null if the rule does not apply to the user
 | ||
|  | 	 */
 | ||
|  | 	public function allows($action, $user, $request)
 | ||
|  | 	{
 | ||
|  | 		if ($this->matchAction($action)
 | ||
|  | 			&& $this->matchRole($user)
 | ||
|  | 			&& $this->matchIP($request->getUserIP())
 | ||
|  | 			&& $this->matchVerb($request->getRequestMethod())
 | ||
|  | 			&& $this->matchController($action->controller)
 | ||
|  | 			&& $this->matchCustom($action)
 | ||
|  | 		) {
 | ||
|  | 			return $this->allow ? true : false;
 | ||
|  | 		} else {
 | ||
|  | 			return null;
 | ||
|  | 		}
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * @param Action $action the action
 | ||
|  | 	 * @return boolean whether the rule applies to the action
 | ||
|  | 	 */
 | ||
|  | 	protected function matchAction($action)
 | ||
|  | 	{
 | ||
|  | 		return empty($this->actions) || in_array($action->id, $this->actions, true);
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * @param Controller $controller the controller
 | ||
|  | 	 * @return boolean whether the rule applies to the controller
 | ||
|  | 	 */
 | ||
|  | 	protected function matchController($controller)
 | ||
|  | 	{
 | ||
| 
											13 years ago
										 | 		return empty($this->controllers) || in_array($controller->uniqueId, $this->controllers, true);
 | ||
| 
											13 years ago
										 | 	}
 | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * @param User $user the user object
 | ||
|  | 	 * @return boolean whether the rule applies to the role
 | ||
|  | 	 */
 | ||
|  | 	protected function matchRole($user)
 | ||
|  | 	{
 | ||
|  | 		if (empty($this->roles)) {
 | ||
|  | 			return true;
 | ||
|  | 		}
 | ||
|  | 		foreach ($this->roles as $role) {
 | ||
| 
											13 years ago
										 | 			if ($role === '?' && $user->getIsGuest()) {
 | ||
|  | 				return true;
 | ||
|  | 			} elseif ($role === '@' && !$user->getIsGuest()) {
 | ||
|  | 				return true;
 | ||
| 
											13 years ago
										 | 			} elseif ($user->checkAccess($role)) {
 | ||
| 
											13 years ago
										 | 				return true;
 | ||
|  | 			}
 | ||
|  | 		}
 | ||
|  | 		return false;
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * @param string $ip the IP address
 | ||
|  | 	 * @return boolean whether the rule applies to the IP address
 | ||
|  | 	 */
 | ||
|  | 	protected function matchIP($ip)
 | ||
|  | 	{
 | ||
|  | 		if (empty($this->ips)) {
 | ||
|  | 			return true;
 | ||
|  | 		}
 | ||
|  | 		foreach ($this->ips as $rule) {
 | ||
|  | 			if ($rule === '*' || $rule === $ip || (($pos = strpos($rule, '*')) !== false && !strncmp($ip, $rule, $pos))) {
 | ||
|  | 				return true;
 | ||
|  | 			}
 | ||
|  | 		}
 | ||
|  | 		return false;
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * @param string $verb the request method
 | ||
|  | 	 * @return boolean whether the rule applies to the request
 | ||
|  | 	 */
 | ||
|  | 	protected function matchVerb($verb)
 | ||
|  | 	{
 | ||
|  | 		return empty($this->verbs) || in_array($verb, $this->verbs, true);
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * @param Action $action the action to be performed
 | ||
|  | 	 * @return boolean whether the rule should be applied
 | ||
|  | 	 */
 | ||
|  | 	protected function matchCustom($action)
 | ||
|  | 	{
 | ||
|  | 		return empty($this->matchCallback) || call_user_func($this->matchCallback, $this, $action);
 | ||
|  | 	}
 | ||
| 
											13 years ago
										 | }
 |