AuthController.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: Administrator
  5. * Date: 2017/10/9
  6. * Time: 1:21
  7. */
  8. namespace backend\controllers;
  9. use backend\models\PermissionForm;
  10. use backend\models\RoleForm;
  11. use backend\models\AuthItem;
  12. use backend\models\AuthItemChild;
  13. use yii\data\Pagination;
  14. use yii\filters\AccessControl;
  15. use yii\rbac\Item;
  16. /**
  17. * 权限管理
  18. * @package backend\controllers
  19. */
  20. class AuthController extends BaseController
  21. {
  22. public $layout = 'iframe';
  23. const PAGESIZE = 20;
  24. public function behaviors()
  25. {
  26. return [
  27. 'access' => [
  28. 'class' => AccessControl::className(),
  29. 'rules' => [
  30. [
  31. 'actions' => [],
  32. 'allow' => true,
  33. 'roles' => ['@'],
  34. ],
  35. ],
  36. ],
  37. ];
  38. }
  39. /**
  40. * 添加角色
  41. * @return string|\yii\web\Response
  42. */
  43. public function actionAddRoles()
  44. {
  45. if(\Yii::$app->request->isPost){
  46. $name = \Yii::$app->request->post('name');
  47. $description = \Yii::$app->request->post('description');
  48. if ((!empty($name)) && (!empty($description))) {
  49. self::createRole($name, $description);
  50. \Yii::$app->getSession()->setFlash('success', '创建角色成功!');
  51. return $this->redirect(['auth/roles']);
  52. } else {
  53. \Yii::$app->getSession()->setFlash('error', '创建角色失败!');
  54. // return $this->redirect(['auth/addroles']);
  55. }
  56. }
  57. return $this->render('addroles');
  58. }
  59. /**
  60. * 角色列表
  61. */
  62. public function actionRoles()
  63. {
  64. $model = AuthItem::find()->where(['type' => 1]);
  65. $pages = new Pagination(["totalCount" => $model->count(), "pageSize" => self::PAGESIZE]);
  66. $model = $model->offset($pages->offset)->limit($pages->pageSize)->all();
  67. return $this->render('roleslist', [
  68. 'model' => $model, 'pages' => $pages
  69. ]);
  70. }
  71. /**
  72. * 生成角色
  73. */
  74. private static function createRole($roles, $description)
  75. {
  76. $auth = \Yii::$app->authManager;
  77. $role = $auth->createRole($roles);
  78. $role->description = $description;
  79. return $auth->add($role);
  80. }
  81. /**
  82. * 删除角色
  83. * @return string
  84. */
  85. public function actionDelRoles()
  86. {
  87. $name = \Yii::$app->request->post('name');
  88. $authManager = \Yii::$app->authManager;
  89. $role = $authManager->getRole($name);
  90. if (!$role) {
  91. return json_encode([
  92. "status" => 2,
  93. "msg" => '角色不存在'
  94. ]);
  95. } else {
  96. $result = $authManager->getUserIdsByRole($name);
  97. if(empty($result)){
  98. if ($authManager->remove($role)) {
  99. return json_encode([
  100. "status" => 1,
  101. "msg" => '角色删除成功'
  102. ]);
  103. } else {
  104. return json_encode([
  105. "status" => 3,
  106. "msg" => '角色删除失败'
  107. ]);
  108. }
  109. }else{
  110. return json_encode([
  111. "status" => 0,
  112. "msg" => '该角色有与用户绑定,请先解绑再删除'
  113. ]);
  114. }
  115. }
  116. }
  117. /**
  118. * 修改角色
  119. * @param null $userid
  120. * @return string|\yii\web\Response
  121. */
  122. public function actionRoleUpdate($userid = NULL)
  123. {
  124. $name = \Yii::$app->request->get('name');
  125. $authManager = \Yii::$app->authManager;
  126. $role = $authManager->getRole($name);
  127. if (!$role) {
  128. \Yii::$app->getSession()->setFlash('error', '角色不存在!');
  129. return $this->redirect(['auth/roles']);
  130. }
  131. if (\Yii::$app->request->isPost) {
  132. $rolemodel = AuthItem::find()->where('type =:type and name = :name', [':type' => Item::TYPE_ROLE, ':name' => $name])->one();
  133. $rolemodel->description = \Yii::$app->request->post('RoleForm')['description'];
  134. if ($rolemodel->validate() && $rolemodel->save()) {
  135. \Yii::$app->getSession()->setFlash('success', '修改成功!');
  136. return $this->redirect(['auth/roles']);
  137. } else {
  138. \Yii::$app->getSession()->setFlash('error', '修改失败!');
  139. return $this->redirect(['auth/roles']);
  140. }
  141. } else {
  142. $model = new RoleForm();
  143. // //角色名称
  144. $model->name = $role->name;
  145. $model->description = $role->description;
  146. return $this->render('updateroles', [
  147. 'model' => $model,
  148. 'uid' => $userid
  149. ]);
  150. }
  151. }
  152. /**
  153. * 初始化权限
  154. * @return string
  155. */
  156. public function actionCreateAll(){
  157. $cont=\Yii::$app->request->post('cont','');
  158. $list = [];
  159. if(empty($cont)){
  160. $FileArray = $this->getControllers();
  161. foreach ($FileArray as $file){
  162. if($file != 'SiteController.php') { //过滤Site
  163. $method = $this->getMethodList('backend\\controllers\\' . strstr($file, '.', true));
  164. $list[] = $method;
  165. }
  166. }
  167. }else{
  168. $list[] = $this->getMethodList('backend\\controllers\\'.$cont);
  169. }
  170. $authManager =\Yii::$app->authManager;
  171. foreach ($list as $data){
  172. $name = $data['name'];
  173. $description= $data['comment'];
  174. foreach ($data['method'] as $method){
  175. $per = $authManager->getPermission($name.'::'.$method['name']);
  176. if(!$per){
  177. self::createPermission($data['name'] .'::'.$method['name'],$method['comment']);
  178. }
  179. }
  180. }
  181. return json_encode([
  182. "status" => 1,
  183. "msg" =>'创建成功'
  184. ]);
  185. }
  186. /**
  187. * 控制器列表
  188. * @return array
  189. */
  190. private function getControllers(){
  191. $Dir = \Yii::getAlias('@backend').'/controllers/';
  192. $fileArray = [];
  193. if( is_dir($Dir) ) {
  194. if (false != ($Handle = opendir($Dir))) {
  195. while (false != ($File = readdir($Handle))) {
  196. if ($File != '.' && $File != '..' && strpos($File, '.')) {
  197. $fileArray[] = $File;
  198. }
  199. }
  200. closedir($Handle);
  201. }
  202. }
  203. return $fileArray;
  204. }
  205. /**
  206. * 权限列表
  207. */
  208. public function actionPermission()
  209. {
  210. $keyword = \Yii::$app->request->get('keyword');
  211. $datas = AuthItem::find()->where(['type' => 2]);
  212. if(!empty($keyword)){
  213. $datas->andWhere('description like :keyword',[':keyword'=>'%'.$keyword.'%']);
  214. }
  215. $pages = new Pagination(["totalCount" => $datas->count(), "pageSize" => self::PAGESIZE]);
  216. $datas = $datas->offset($pages->offset)->limit($pages->pageSize)->all();
  217. return $this->render('permissionlist', [
  218. 'datas' => $datas, 'pages' => $pages
  219. ]);
  220. }
  221. /**
  222. * 创建权限
  223. * @return string
  224. */
  225. public function actionAddPermission()
  226. {
  227. $name = \Yii::$app->request->post('prename');
  228. $description = \Yii::$app->request->post('description');
  229. if ((!empty($name)) && (!empty($description))) {
  230. $authManager = \Yii::$app->authManager;
  231. $per = $authManager->getPermission($name);
  232. if ($per) {
  233. return json_encode([
  234. "status" => 3,
  235. "msg" => '该权限已创建'
  236. ]);
  237. } else {
  238. self::createPermission($name, $description);
  239. return json_encode([
  240. "status" => 1,
  241. "msg" => '创建成功'
  242. ]);
  243. }
  244. } else {
  245. return json_encode([
  246. "status" => 2,
  247. "msg" => '创建失败'
  248. ]);
  249. }
  250. }
  251. /**
  252. * 修改权限
  253. */
  254. public function actionUpdateper()
  255. {
  256. $cont = $this->getControllers();
  257. $name = \Yii::$app->request->get('name');
  258. $authManager = \Yii::$app->authManager;
  259. $per = $authManager->getPermission($name);
  260. if (!$per) {
  261. \Yii::$app->getSession()->setFlash('error', '修改失败,权限不存在!');
  262. return $this->redirect(['auth/permission']);
  263. }
  264. $model = new PermissionForm();
  265. $model->name = $per->name;
  266. $model->description = $per->description;
  267. // //权限表单
  268. // $model = new PermissionForm();
  269. // //权限名称
  270. // $model->name = $per->name;
  271. // //权限描述
  272. // $model->description = $per->description;
  273. // $contname = explode('::', $model->name);
  274. // if ($model->load(\Yii::$app->request->post())) {
  275. // $newname = \Yii::$app->request->post('PermissionForm')['name'];
  276. // if ($model->update($newname)) {
  277. // \Yii::$app->getSession()->setFlash('success', '修改成功!');
  278. // return $this->redirect(['auth/add-permission']);
  279. // } else {
  280. // \Yii::$app->getSession()->setFlash('error', '修改失败!');
  281. // return $this->redirect(['auth/add-permission']);
  282. // }
  283. //
  284. // } else {
  285. // return $this->render('updateper', [
  286. // 'model' => $model,
  287. // ]);
  288. // }
  289. if(\Yii::$app->request->isPost){
  290. //只修改权限名称
  291. $description = \Yii::$app->request->post('PermissionForm')['description'];
  292. $row = AuthItem::updateAll(['description'=>$description],['type'=>2,'name'=>$name]);
  293. if ($row) {
  294. \Yii::$app->getSession()->setFlash('success', '修改成功!');
  295. return $this->redirect(['auth/permission']);
  296. } else {
  297. \Yii::$app->getSession()->setFlash('error', '修改失败!');
  298. return $this->redirect(['auth/add-permission']);
  299. }
  300. }
  301. return $this->render('updateper', [
  302. 'model' => $model,
  303. ]);
  304. }
  305. /**
  306. * 删除权限
  307. */
  308. public function actionDelPermission()
  309. {
  310. $name = \Yii::$app->request->post('name');
  311. $authManager = \Yii::$app->authManager;
  312. $per = $authManager->getPermission($name);
  313. if (!$per) {
  314. return json_encode([
  315. "status" => 2,
  316. "msg" => '权限不存在'
  317. ]);
  318. } else {
  319. if ($authManager->remove($per)) {
  320. return json_encode([
  321. "status" => 0,
  322. "msg" => '权限删除成功'
  323. ]);
  324. } else {
  325. return json_encode([
  326. "status" => 3,
  327. "msg" => '权限删除失败'
  328. ]);
  329. }
  330. }
  331. }
  332. /**
  333. * 角色赋予权限
  334. * @param $name
  335. * @param $userid
  336. * @return string
  337. */
  338. public function actionRoleNode($name, $userid = NULL)
  339. {
  340. /**
  341. * 1.根据提交的数据,先删除当前角色下的当前模块下选择取消的角色权限关联
  342. * 2.新增提交过来的角色与权限管理
  343. */
  344. $authManager = \Yii::$app->authManager;
  345. $role = $authManager->getRole($name);
  346. if (!$role) {
  347. \Yii::$app->getSession()->setFlash('error', '角色不存在!');
  348. return $this->redirect(['auth/roles']);
  349. }
  350. if (\Yii::$app->request->isPost) {
  351. $nodes = \Yii::$app->request->post('permission');
  352. // $authManager->removeChildren($role);
  353. $nodeArray = [];
  354. if ($nodes) {
  355. foreach ($nodes as $v) {
  356. $node = $authManager->getPermission($v);
  357. if (!empty($node) && !$authManager->hasChild($role,$node)){
  358. $authManager->addChild($role, $node);
  359. };
  360. $nodeArray[] = $v;
  361. }
  362. }
  363. $roleNodes =
  364. //清除未选择中的权限绑定
  365. $datas = AuthItemChild::find()->where(['and',['parent'=>$name],['not in','child',$nodeArray]])->all();
  366. foreach($datas as $data){
  367. if(!in_array($data->child,$nodeArray)){
  368. $node = $authManager->getPermission($data->child);
  369. $authManager->removeChild($role,$node);
  370. }
  371. }
  372. if ($userid) {
  373. return $this->redirect(['auth/index']);
  374. } else {
  375. \Yii::$app->getSession()->setFlash('success', '成功添加权限!');
  376. return $this->redirect(['auth/roles']);
  377. }
  378. }
  379. $roleNodes = $authManager->getPermissionsByRole($name);
  380. $roleNodes = array_keys($roleNodes);
  381. $nodes = $authManager->getPermissions();
  382. $nodesList = [];
  383. foreach ($nodes as $node){
  384. $contname = strstr($node->name,'::',true);
  385. if(!isset($nodesList[$contname])){
  386. $class = new \ReflectionClass('backend\\controllers\\'.$contname);
  387. $nodesList[$contname]['name'] = $this->getComment($class);
  388. }
  389. $nodesList[$contname]['methods'][] = $node;
  390. }
  391. return $this->render('rolenode', [
  392. 'nodes' => $nodesList,
  393. 'roleNodes' => $roleNodes,
  394. 'name' => $name,
  395. 'uid' => $userid,
  396. ]);
  397. }
  398. /**
  399. * 用户赋予角色(单个)
  400. * @param $userid
  401. * @param $rolename
  402. * @return bool
  403. */
  404. public static function userRole($userid,$rolename){
  405. $auth = \Yii::$app->getAuthManager();
  406. $role = $auth->getRolesByUser($userid);
  407. if(!empty($role) && current($role)->name == $rolename){
  408. return true;
  409. }
  410. $role = $auth->getRole($rolename);
  411. if(empty($role)){
  412. return false;
  413. }
  414. $auth->revokeAll($userid); //清空绑定
  415. $auth->assign($role,$userid); //绑定
  416. return true;
  417. }
  418. // /**
  419. // * 用户赋予角色
  420. // */
  421. // public function actionRole()
  422. // {
  423. // //从用户跳转过来,目的获取用户id
  424. // $uid = \Yii::$app->request->get('uid');
  425. // $admin = User::find()->where(['id' => $uid])->one();
  426. // if (!$admin) {
  427. // \Yii::$app->getSession()->setFlash('error', '用户未找到!');
  428. // }
  429. // $authManager = \Yii::$app->authManager;
  430. // if (\Yii::$app->request->isPost) {
  431. // $roleNames = \Yii::$app->request->post('roles');
  432. // $authManager->revokeAll($uid);
  433. // if (!empty($roleNames) && is_array($roleNames)) {
  434. // foreach ($roleNames as $roleName) {
  435. // $role = $authManager->getRole($roleName);
  436. // if (!$role) {
  437. // continue;
  438. // }
  439. // $authManager->assign($role, $uid);
  440. // }
  441. // }
  442. // if ($roleNames) {
  443. // $admin->role = implode(',', $roleNames);
  444. // }
  445. //
  446. // if ($admin->update()) {
  447. // \Yii::$app->getSession()->setFlash('success', '更新成功!');
  448. // return $this->redirect(['auth/index']);
  449. // } else {
  450. // \Yii::$app->getSession()->setFlash('success', '更新失败!');
  451. // return $this->redirect(['auth/role', 'uid' => $uid]);
  452. // }
  453. // } else {
  454. // $userRoles = $authManager->getRolesByUser($uid);
  455. //
  456. // $roleNames = ArrayHelper::getColumn(ArrayHelper::toArray($userRoles), 'name');
  457. // $roles = $authManager->getRoles();
  458. // return $this->render('role', ['roles' => $roles, 'roleNames' => $roleNames, 'uid' => $uid]);
  459. // }
  460. // }
  461. /**
  462. * 权限验证
  463. * @param $level
  464. * @return bool
  465. */
  466. static function checkPermission($level)
  467. {
  468. $level = 1;
  469. $role = \Yii::$app->user->identity->role;
  470. if ($level <= $role) {
  471. return true;
  472. } else {
  473. return false;
  474. }
  475. }
  476. /**
  477. * 创建权限
  478. */
  479. static function createPermission($name, $description)
  480. {
  481. $auth = \Yii::$app->authManager;
  482. $createPost = $auth->createPermission($name);
  483. $createPost->description = $description;
  484. $auth->add($createPost);
  485. }
  486. /**
  487. * 获取类中可访问方法及注释
  488. * @param $classname
  489. * @return array
  490. */
  491. private function getMethodList($classname){
  492. $class = new \ReflectionClass($classname);
  493. $methods = $class->getMethods(\ReflectionMethod::IS_PUBLIC);
  494. $classMap = [];
  495. $classMap['name'] = $class->getShortName();
  496. $classMap['comment'] = $this->getComment($class);
  497. $classMap['method'] = [];
  498. foreach ($methods as $method){
  499. if(strlen($method->name) > 7 && substr($method->name,0,6) == 'action'){
  500. $temp['name'] = $method->getName();
  501. $temp['comment'] = $this->getComment($method);
  502. $classMap['method'][] = $temp;
  503. }
  504. }
  505. return $classMap;
  506. }
  507. /**
  508. * 提取注释
  509. * @param $reflection
  510. * @return string
  511. */
  512. private function getComment($reflection){
  513. $comment = strtr(trim(preg_replace('/^\s*\**( |\t)?/m', '', trim($reflection->getDocComment(), '/'))), "\r", '');
  514. if (preg_match('/^\s*@\w+/m', $comment, $matches, PREG_OFFSET_CAPTURE)) {
  515. $comment = trim(substr($comment, 0, $matches[0][1]));
  516. }
  517. return $comment;
  518. }
  519. }