Control.php 2.83 KB
<?php

namespace app\ht\exts\rbac;

use Yii;
use yii\web\ForbiddenHttpException;
use yii\base\ActionFilter;
use yii\db\Query;
use common\models\SysUser as SysUserModel;
use function is_array;
use function trim;

class Control extends ActionFilter
{

    public $allowActions = [];

    /**
     * @inheritdoc
     */
    public function beforeAction($action)
    {
        $actionId = $action->getUniqueId();
        $user = Yii::$app->getUser();

        if ($this->checkRoute($actionId, $user)) {
            return true;
        }

        $this->denyAccess($user);
    }

    /**
     * 拒绝当前用户的访问.
     * @param  User $user the current user
     * @throws ForbiddenHttpException if the user is already logged in.
     */
    protected function denyAccess($user)
    {
        if ($user->getIsGuest()) {
            $user->loginRequired();
        } else {
            throw new ForbiddenHttpException('您没有权限访问此页面');
        }
    }

    /**
     * Check access route for user.
     * @param string|array $route
     * @param array $param
     * @param User $user
     * @return boolean
     */
    protected function checkRoute($route,  $user = null)
    {
        if ($user === null) {
            $user = Yii::$app->getUser();
        }

        $routes = $this->getAllRoutes();

        if (isset($routes[$route])) {
            $perms = $routes[$route];
            foreach ($perms as $perm) {
                if ($user->can($perm)) {
                    return true;
                }
            }

        }
        return false;
    }

    /**
     * @inheritdoc
     */
    protected function isActive($action)
    {
        // 对site/error无效
        $uniqueId = $action->getUniqueId();
        if ($uniqueId === Yii::$app->getErrorHandler()->errorAction) {
            return false;
        }

        // 对调试等路由无效
        foreach ($this->allowActions as $route) {
            if ($route == $uniqueId) {
                return false;
            }
        }

        // 对登陆页面无效
        $user = Yii::$app->getUser();
        if ($user->getIsGuest() && is_array($user->loginUrl) && isset($user->loginUrl[0]) && $uniqueId === trim($user->loginUrl[0], '/')) {;
            return false;
        }

        // 对超级管理员无效
        if ($user->id == SysUserModel::ROOT_ID) {
            return false;
        }

        return true;
    }

    protected function getAllRoutes()
    {
        static $routes = [];

        if (!empty($routes)) {
            return $routes;
        }

        $routeQuery = new Query();
        $routeQuery->select(['auth_perms_routes.*']);
        $routeQuery->from('auth_perms_routes');
        $result = $routeQuery->all();
        $routes = [];
        foreach($result as $r) {
            $routes[$r['route']][] = $r['perm_id'];
        }

        return $routes;
    }
}