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.
		
		
		
		
		
			
		
			
				
					
					
						
							185 lines
						
					
					
						
							5.2 KiB
						
					
					
				
			
		
		
	
	
							185 lines
						
					
					
						
							5.2 KiB
						
					
					
				<?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; | 
						|
	/** | 
						|
	 * @var array list of roles that this rule applies to. Two special roles are recognized, and | 
						|
	 * they are checked via [[User::isGuest]]: | 
						|
	 * | 
						|
	 * - `?`: matches a guest user (not authenticated yet) | 
						|
	 * - `@`: matches an authenticated user | 
						|
	 * | 
						|
	 * 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. | 
						|
	 */ | 
						|
	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->getMethod()) | 
						|
			&& $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) | 
						|
	{ | 
						|
		return empty($this->controllers) || in_array($controller->uniqueId, $this->controllers, true); | 
						|
	} | 
						|
 | 
						|
	/** | 
						|
	 * @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) { | 
						|
			if ($role === '?' && $user->getIsGuest()) { | 
						|
				return true; | 
						|
			} elseif ($role === '@' && !$user->getIsGuest()) { | 
						|
				return true; | 
						|
			} elseif ($user->checkAccess($role)) { | 
						|
				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); | 
						|
	} | 
						|
}
 | 
						|
 |