diff --git a/app/Admin/Middleware/Permissions.php b/app/Admin/Middleware/Permissions.php new file mode 100644 index 00000000..868e0787 --- /dev/null +++ b/app/Admin/Middleware/Permissions.php @@ -0,0 +1,86 @@ +route()->getName(); + $user = Admin::user(); + + if (!$this->shouldPassThrough($request) //路由是否是白名单 + && !$user?->hasPermission($routeName)//是否有权限 + ) { + if (Helper::isAjaxRequest()) { + abort(403, trans('admin.deny')); + } + + admin_exit( + Content::make()->withError(trans('admin.deny')) + ); + } + return $next($request); + } + + /** + * @param \Illuminate\Http\Request $request + * + * @return bool + */ + protected function isApiRoute($request) + { + return $request->routeIs(admin_api_route_name('*')); + } + + /** + * Determine if the request has a URI that should pass through verification. + * + * @param \Illuminate\Http\Request $request + * + * @return bool + */ + public function shouldPassThrough($request) + { + if ($this->isApiRoute($request) || Authenticate::shouldPassThrough($request)) { + return true; + } + + $excepts = array_merge( + (array) config('admin.permission.except', []), + Admin::context()->getArray('permission.except') + ); + + foreach ($excepts as $except) { + if ($request->routeIs($except) || $request->routeIs(admin_route_name($except))) { + return true; + } + + $except = admin_base_path($except); + + if ($except !== '/') { + $except = trim($except, '/'); + } + + if (Helper::matchRequestPath($except)) { + return true; + } + } + + return false; + } +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 490e98fe..f535dc1e 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -63,5 +63,6 @@ class Kernel extends HttpKernel 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, + 'admin.permissions' => \App\Admin\Middleware\Permissions::class, ]; } diff --git a/app/Models/Admin/Administrator.php b/app/Models/Admin/Administrator.php index 79d98099..f65fa52a 100644 --- a/app/Models/Admin/Administrator.php +++ b/app/Models/Admin/Administrator.php @@ -6,4 +6,57 @@ use Dcat\Admin\Models\Administrator as DcatAdministrator; class Administrator extends DcatAdministrator { + public function hasPermission(String $slug): bool + { + //判断是否是超级管理员 + if ($this->isAdministrator()) { + return true; + } + + $userPermissions = $this->getCachePermissions(); + + //获取缓存权限 + if (!$userPermissions) {//未获取到则刷新 + $userPermissions = $this->refreshCachePermissions(); + } + + //判断是否有权限 + if (in_array($slug, $userPermissions)) { + return true; + } + return false; + } + + /** + * 更新缓存权限:重新获取,并存入缓存 + * + * @return array|null + */ + public function refreshCachePermissions(): ?array + { + //获取角色权限 + $permissions = []; + foreach ($this->roles()->get() as $role) { + if ($role->name !== 'Administrator') { + foreach ($role->permissions as $permission) { + $permissions[] = $permission->slug; + } + } + } + + //缓存权限 + session(['user_permissions' => $permissions]); + + return $permissions; + } + + /** + * 获取缓存权限 + * + * @return array|null + */ + public function getCachePermissions(): ?array + { + return session('user_permissions'); + } } diff --git a/config/admin.php b/config/admin.php index 800052f5..4a62443f 100644 --- a/config/admin.php +++ b/config/admin.php @@ -71,7 +71,7 @@ return [ 'namespace' => 'App\\Admin\\Controllers', - 'middleware' => ['web', 'admin'], + 'middleware' => ['web', 'admin.auth', 'admin.pjax', 'admin.bootstrap', 'admin.session', 'admin.upload', 'admin.permissions'], 'enable_session_middleware' => false, ], @@ -222,6 +222,7 @@ return [ 'auth/login', 'auth/logout', 'auth/setting', + 'dcat-api*', ], ], diff --git a/database/seeders/AdminPermissionSeeder.php b/database/seeders/AdminPermissionSeeder.php new file mode 100644 index 00000000..84f64e51 --- /dev/null +++ b/database/seeders/AdminPermissionSeeder.php @@ -0,0 +1,107 @@ + [ + // 'name' => '测试权限', + // 'curd' => true, //true默认全部,false为不需要, ['index']为仅需要的 + // 'children' => [ + // 'show' => [ + // 'name' => '详情', + // ], + // ], + // ], + ]; + try { + DB::begintransaction(); + $this->createPermissionData($permissions); + DB::commit(); + } catch (\Exception $e) { + Log::error('权限录入:'.$e->getMessage()); + DB::rollBack(); + } + } + + /** + * 插入权限 + * + * @param array $permissions + * @param string $key + * @param integer $pId + */ + public function createPermissionData(array $permissions, string $key = '', int $pId = 0) + { + $curdArr = [ + 'index'=>[ + 'name' => '列表', + ], + 'create'=>[ + 'name' => '新增', + ], + 'store' =>[ + 'name' => '保存', + ], + 'edit' =>[ + 'name' => '修改', + ], + 'update'=>[ + 'name' => '更新', + ], + 'destroy'=>[ + 'name' => '删除', + ], + 'show'=>[ + 'name' => '详情', + ], + ]; + foreach ($permissions as $slug => $permission) { + //是否已存在该权限 + $slugKey = 'dcat.admin.'.($key ? $key.'.'.$slug : $slug); + if (!$pper = Permission::where('slug', $slugKey)->first()) { + $pper = Permission::create([ + 'name' => $permission['name'], + 'slug' => $slugKey, + 'parent_id' => $pId, + ]); + } else { + $pper->update([ + 'name' => $permission['name'], + ]); + } + + if (!isset($permission['children'])) { + $permission['children'] = []; + } + //判断是否默认插入curd权限 + if (isset($permission['curd']) && $permission['curd']) { + if (is_array($permission['curd'])) { + foreach ($permission['curd'] as $value) { + $permission['children'][$value] = $curdArr[$value]; + } + } else { + $permission['children'] = array_merge($curdArr, $permission['children']); + } + } + if (count($permission['children']) > 0) { + $this->createPermissionData($permission['children'], $key ? $key.'.'.$slug : $slug, $pper->id); + } + } + } +}