123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- <?php
- /**
- * @link http://www.yiiframework.com/
- * @copyright Copyright (c) 2008 Yii Software LLC
- * @license http://www.yiiframework.com/license/
- */
- namespace yii\web;
- use Yii;
- use yii\base\Action;
- use yii\base\ActionFilter;
- /**
- * AccessControl provides simple access control based on a set of rules.
- *
- * AccessControl is an action filter. It will check its [[rules]] to find
- * the first rule that matches the current context variables (such as user IP address, user role).
- * The matching rule will dictate whether to allow or deny the access to the requested controller
- * action. If no rule matches, the access will be denied.
- *
- * To use AccessControl, declare it in the `behaviors()` method of your controller class.
- * For example, the following declarations will allow authenticated users to access the "create"
- * and "update" actions and deny all other users from accessing these two actions.
- *
- * ~~~
- * public function behaviors()
- * {
- * return [
- * 'access' => [
- * 'class' => \yii\web\AccessControl::className(),
- * 'only' => ['create', 'update'],
- * 'rules' => [
- * // deny all POST requests
- * [
- * 'allow' => false,
- * 'verbs' => ['POST']
- * ],
- * // allow authenticated users
- * [
- * 'allow' => true,
- * 'roles' => ['@'],
- * ],
- * // everything else is denied
- * ],
- * ],
- * ];
- * }
- * ~~~
- *
- * @author Qiang Xue <[email protected]>
- * @since 2.0
- */
- class AccessControl extends ActionFilter
- {
- /**
- * @var callback a callback that will be called if the access should be denied
- * to the current user. If not set, [[denyAccess()]] will be called.
- *
- * 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;
- /**
- * @var array the default configuration of access rules. Individual rule configurations
- * specified via [[rules]] will take precedence when the same property of the rule is configured.
- */
- public $ruleConfig = ['class' => 'yii\web\AccessRule'];
- /**
- * @var array a list of access rule objects or configuration arrays for creating the rule objects.
- * If a rule is specified via a configuration array, it will be merged with [[ruleConfig]] first
- * before it is used for creating the rule object.
- * @see ruleConfig
- */
- public $rules = [];
- /**
- * Initializes the [[rules]] array by instantiating rule objects from configurations.
- */
- public function init()
- {
- parent::init();
- foreach ($this->rules as $i => $rule) {
- if (is_array($rule)) {
- $this->rules[$i] = Yii::createObject(array_merge($this->ruleConfig, $rule));
- }
- }
- }
- /**
- * This method is invoked right before an action is to be executed (after all possible filters.)
- * You may override this method to do last-minute preparation for the action.
- * @param Action $action the action to be executed.
- * @return boolean whether the action should continue to be executed.
- */
- public function beforeAction($action)
- {
- $user = Yii::$app->getUser();
- $request = Yii::$app->getRequest();
- /** @var AccessRule $rule */
- foreach ($this->rules as $rule) {
- if ($allow = $rule->allows($action, $user, $request)) {
- return true;
- } elseif ($allow === false) {
- if (isset($rule->denyCallback)) {
- call_user_func($rule->denyCallback, $rule, $action);
- } elseif (isset($this->denyCallback)) {
- call_user_func($this->denyCallback, $rule, $action);
- } else {
- $this->denyAccess($user);
- }
- return false;
- }
- }
- if (isset($this->denyCallback)) {
- call_user_func($this->denyCallback, $rule, $action);
- } else {
- $this->denyAccess($user);
- }
- return false;
- }
- /**
- * Denies the access of the user.
- * The default implementation will redirect the user to the login page if he is a guest;
- * if the user is already logged, a 403 HTTP exception will be thrown.
- * @param User $user the current user
- * @throws AccessDeniedHttpException if the user is already logged in.
- */
- protected function denyAccess($user)
- {
- if ($user->getIsGuest()) {
- $user->loginRequired();
- } else {
- throw new AccessDeniedHttpException(Yii::t('yii', 'You are not allowed to perform this action.'));
- }
- }
- }
|