From 8acbcc92793b46396ccd037fcc7d5f3958759a01 Mon Sep 17 00:00:00 2001 From: linyaostalker <602604991@qq.com> Date: Mon, 16 Dec 2019 20:13:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=80=E5=8F=91=E8=8E=B7=E5=8F=96=E6=8C=87?= =?UTF-8?q?=E5=AE=9Aapplication=E7=9A=84=E6=9D=83=E9=99=90=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/controllers/ConfigController.php | 76 ----------- backend/logic/PermissionManager.php | 163 +++++++++++++++++++++++ backend/views/config/index.php | 27 ---- console/controllers/MenuController.php | 35 +++++ 4 files changed, 198 insertions(+), 103 deletions(-) delete mode 100755 backend/controllers/ConfigController.php create mode 100644 backend/logic/PermissionManager.php delete mode 100755 backend/views/config/index.php create mode 100644 console/controllers/MenuController.php diff --git a/backend/controllers/ConfigController.php b/backend/controllers/ConfigController.php deleted file mode 100755 index 53da01f..0000000 --- a/backend/controllers/ConfigController.php +++ /dev/null @@ -1,76 +0,0 @@ - [ - 'class' => VerbFilter::className(), - 'actions' => [ - 'delete' => ['POST'], - ], - ], - ]; - } - - /** - * Lists all Category models. - * @return mixed - */ - public function actionIndex() - { - return $this->render('index'); - } - - - /** - * Updates an existing Category model. - * If update is successful, the browser will be redirected to the 'view' page. - * @param integer $id - * @return mixed - * @throws NotFoundHttpException if the model cannot be found - */ - public function actionUpdate($id) - { - $model = $this->findModel($id); - - if ($model->load(Yii::$app->request->post()) && $model->save()) { - return $this->redirect('index'); - } - - return $this->render('update', [ - 'model' => $model, - ]); - } - - /** - * Finds the Category model based on its primary key value. - * If the model is not found, a 404 HTTP exception will be thrown. - * @param integer $id - * @return Category the loaded model - * @throws NotFoundHttpException if the model cannot be found - */ - protected function findModel($id) - { - if (($model = Category::findOne($id)) !== null) { - return $model; - } - - throw new NotFoundHttpException('The requested page does not exist.'); - } -} diff --git a/backend/logic/PermissionManager.php b/backend/logic/PermissionManager.php new file mode 100644 index 0000000..e1a80b0 --- /dev/null +++ b/backend/logic/PermissionManager.php @@ -0,0 +1,163 @@ + [ + * 'class' => 'xxx\xxx\xxx', + * 'id' => '{actionDescribe}' + * ] + * @return array 返回已匹配到的权限。返回例子:[["{controllerDescribe}"=>["{actionDescribe}"=>"action route"]]] + * @throws yii\base\InvalidConfigException + * @throws ReflectionException + */ + public static function getAppPermission() + { + $permission = []; + $permission = self::getControllersAndActions($permission); //获取该app的所有controller权限 + $permission = self::getModuleControllerAndAction($permission); //获取该app引用module的所有controller权限 + return $permission; + } + + /** + * 获取app下controller已标记的action方法权限 + * 这个方法先是获取该app下controller的路径,控制器的命名空间,然后匹配该路径下面的所有控制器文件 + * 截取控制器文件的控制器基础名称,转换为相应url规则名称,拼接为相应类名 + * 根据控制器id,通过[[Module::createControllerByID]]方法实例化该控制器,最后通过[[PermissionManager::constructingPermissionArray]]获取所有已标记的权限 + * @param array $permission 权限数组 + * @return array 权限数组 + * @throws yii\base\InvalidConfigException + * @throws ReflectionException + */ + private static function getControllersAndActions($permission = []) + { + $dir = Yii::$app->getControllerPath(); + $nameSpace = Yii::$app->controllerNamespace . "\\"; + $fileList = glob($dir."/*Controller.php"); + foreach ($fileList as $file) { + $baseName = substr(basename($file), 0, -14); + + //根据路由规则转换控制器名称 + $name = strtolower(preg_replace('/(?createControllerByID($id); + $permission = self::constructingPermissionArray($controller, $className, $permission); + } + return $permission; + } + + /** + * 获取该app下关联module的已标记controller的权限 + * 这个方法通过[[Module::getModules]]获取该app下关联的module并循环 + * 去除gii和debug,通过[[Module::getModule]]获取子类module,获取命名空间,文件位置,然后匹配该路径下面的所有控制器文件 + * 截取控制器文件的控制器基础名称,转换为相应url规则名称,拼接为相应类名 + * 通过[[BaseYii::createObject]]实例化,最后通过[[PermissionManager::constructingPermissionArray]]获取所有已标记的权限 + * @param array $permission 权限数组 + * @return array 权限数组 + * @throws yii\base\InvalidConfigException + * @throws ReflectionException + */ + private static function getModuleControllerAndAction($permission = []) + { + foreach (Yii::$app->getModules() as $id => $child) { + if(in_array($id, ['gii', 'debug'])) { + continue; + } + $module = Yii::$app->getModule($id); + $nameSpace = $module->controllerNamespace."\\"; + $dir = $module->controllerPath; + $fileList = glob($dir."/*Controller.php"); + foreach ($fileList as $file) { + $baseName = substr(basename($file), 0, -14); + $name = strtolower(preg_replace('/(?id.'/'.ltrim(str_replace(' ', '-', $name), '-'); + $className = $nameSpace . $baseName . 'Controller'; + $controller = Yii::createObject($className, [$id, $module]); + $permission = self::constructingPermissionArray($controller, $className, $permission); + } + } + return $permission; + } + + /** + * 构建权限数组 + * 根据类名,使用ReflectionClass方法获取该类的信息 + * 通过该类的注释,判断是否存在DESCRIBE标记,以此判断是否要记录该类的权限 + * 若存在标记,则通过[[PermissionManager::getActionsInController]]获取actions里面的方法权限数组,通过[[PermissionManager::getActionInController]]获取该类下面的action方法权限数组 + * @param $controllerObject + * @param $className + * @param array $permission 权限数组 + * @return array 权限数组 + * @throws ReflectionException + */ + private static function constructingPermissionArray($controllerObject, $className, $permission = []) + { + $prefix = '/'.$controllerObject->id.'/'; + $reflection = new ReflectionClass($className); //通过ReflectionClass方法获取该类的所有信息,包括参数方法等 + $controllerComment = $reflection->getDocComment(); + $controllerPregRes = preg_match("/(?<=DESCRIBE ).*?(?= DESCRIBE)/", $controllerComment, $controllerDescribe); + if ($controllerPregRes) { + $permission = self::getActionsInController($controllerObject, $controllerDescribe, $prefix, $permission); + $permission = self::getActionInController($reflection, $prefix, $controllerDescribe, $permission); + } + return $permission; + } + + /** + * 获取控制器类中actions的方法权限 + * 根据实例化的控制器类,获取actions的方法并且循环,方法存在id这个参数,则记录 + * 最后放回权限数组 + * @param $controllerObject + * @param $controllerDescribe + * @param $prefix + * @param array $permission 权限数组 + * @return array 权限数组 + */ + private static function getActionsInController($controllerObject, $controllerDescribe, $prefix, $permission = []) + { + foreach ($controllerObject->actions() as $id => $item) { + if (isset($item['id'])) { + $permission[$controllerDescribe[0]][$item['id']] = $prefix . $id; + } + } + return $permission; + } + + /** + * 获取控制器类中的action方法权限 + * 获取所有的action方法,若注释中存在ACTION标记,则记录 + * @param $controllerObject + * @param $prefix + * @param $controllerDescribe + * @param array $permission 权限数组 + * @return array 权限数组 + */ + private static function getActionInController($controllerObject, $prefix, $controllerDescribe, $permission = []) + { + foreach ($controllerObject->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { + //action的注释 + $actionComment = $method->getDocComment(); + $actionPregRes = preg_match("/(?<=ACTION ).*?(?= ACTION)/", $actionComment, $actionDescribe); + if ($actionPregRes) { + $actionName = $method->getName(); + if ($actionName != 'actions' && strpos($actionName, 'action') === 0) { + $name = strtolower(preg_replace('/(? - -配置页 diff --git a/console/controllers/MenuController.php b/console/controllers/MenuController.php new file mode 100644 index 0000000..5e95ebf --- /dev/null +++ b/console/controllers/MenuController.php @@ -0,0 +1,35 @@ +security->generateRandomString(8); + $security = Yii::createObject("yii\base\Security"); + $n = 0; + for ($i = 1; $i < 1000; $i++) { + //$key = $security->generateRandomString(8); + $key = rand(10000000, 99999999); + //$key = strtolower($key); + //$key = str_replace(['_', '-'], 'a', $key); + $ret[$key] += 1; + } + + $this->stdout("duplicate data:\n", Console::FG_RED); + foreach ($ret as $k => $v) { + if ($v > 1) { + echo "$k $v\n"; + } + } + } +}