generated from liutk/owl-admin-base
路由权限校验
parent
90bd0711cf
commit
1af4a4952c
|
|
@ -0,0 +1,96 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Admin\Middleware;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Slowlyo\OwlAdmin\Admin;
|
||||||
|
use Slowlyo\OwlAdmin\Support\Cores\Permission;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
|
class CheckPermission
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var array<int, string>
|
||||||
|
*/
|
||||||
|
protected $exceptPaths = [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array<int, string>
|
||||||
|
*/
|
||||||
|
protected $exceptRoutes = [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle an incoming request.
|
||||||
|
*
|
||||||
|
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||||
|
*/
|
||||||
|
public function handle(Request $request, Closure $next): Response
|
||||||
|
{
|
||||||
|
if ($this->inExceptArray($request) || $this->checkRoutePermission($request)) {
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Admin::response()->fail(__('admin.unauthorized'));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function checkRoutePermission(Request $request): bool
|
||||||
|
{
|
||||||
|
if (is_null($user = Admin::user())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ability = $this->normalizeRouteAbility(
|
||||||
|
$original = $request->route()->getName()
|
||||||
|
);
|
||||||
|
|
||||||
|
return collect($ability)
|
||||||
|
->when($ability !== $original, fn (Collection $collection) => $collection->push($original))
|
||||||
|
->contains(fn ($ability) => $user->can($ability));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function normalizeRouteAbility(string $ability)
|
||||||
|
{
|
||||||
|
foreach ($this->resourceAbilityMap() as $method => $map) {
|
||||||
|
if (str_ends_with($ability, ".{$method}")) {
|
||||||
|
return preg_replace("/(.*)\.{$method}$/", '${1}.'.$map, $ability);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ability;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function resourceAbilityMap(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'index' => 'list',
|
||||||
|
'show' => 'view',
|
||||||
|
'store' => 'create',
|
||||||
|
'edit' => 'update',
|
||||||
|
'destroy' => 'delete',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function inExceptArray(Request $request): bool
|
||||||
|
{
|
||||||
|
if (in_array($request->route()->getName(), $this->exceptRoutes)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$permission = Admin::permission();
|
||||||
|
|
||||||
|
return $request->is(
|
||||||
|
collect($this->exceptPaths)
|
||||||
|
->when(Admin::permission(), fn (Collection $collection, Permission $permission) => $collection->merge($permission->authExcept)->merge($permission->permissionExcept))
|
||||||
|
->map(function ($path) {
|
||||||
|
$path = trim((string) config('admin.route.prefix'), '/').'/'.trim((string) $path, '/');
|
||||||
|
return ltrim($path, '/');
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,11 +9,74 @@ use Slowlyo\OwlAdmin\Models\AdminUser as Model;
|
||||||
|
|
||||||
class AdminUser extends Model
|
class AdminUser extends Model
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
protected $allAbilities;
|
||||||
|
|
||||||
public function roles(): BelongsToMany
|
public function roles(): BelongsToMany
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(Admin::adminRoleModel(), 'admin_role_users', 'user_id', 'role_id')->withTimestamps();
|
return $this->belongsToMany(Admin::adminRoleModel(), 'admin_role_users', 'user_id', 'role_id')->withTimestamps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取此用户的全部能力
|
||||||
|
*/
|
||||||
|
public function allAbilities(): Collection
|
||||||
|
{
|
||||||
|
if ($this->allAbilities) {
|
||||||
|
return $this->allAbilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
$model = Admin::adminPermissionModel();
|
||||||
|
$allPermissions = $model::all(['id', 'parent_id', 'slug'])->keyBy('id');
|
||||||
|
|
||||||
|
/** @var \Illuminate\Database\Eloquent\Collection 此用户的所有角色的权限集合 */
|
||||||
|
$rolePermissions = $this->roles
|
||||||
|
->pluck('permissions')
|
||||||
|
->flatten()
|
||||||
|
->keyBy('id');
|
||||||
|
|
||||||
|
$abilities = $rolePermissions->map(fn ($permission) => $permission->slug);
|
||||||
|
|
||||||
|
foreach ($rolePermissions as $rolePermission) {
|
||||||
|
if (is_null($rolePermission->parent_id) || $abilities->has($rolePermission->parent_id)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parent = $allPermissions->get($rolePermission->parent_id);
|
||||||
|
|
||||||
|
while ($parent) {
|
||||||
|
$abilities->put($parent->id, $parent->slug);
|
||||||
|
|
||||||
|
if (is_null($parent->parent_id)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parent = $allPermissions->get($parent->parent_id);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($allPermissions, $rolePermissions);
|
||||||
|
|
||||||
|
return $this->allAbilities = $abilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function can($abilities, $arguments = []): bool
|
||||||
|
{
|
||||||
|
if (empty($abilities)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->isAdministrator()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return collect($abilities)->every(
|
||||||
|
fn ($ability) => $this->allAbilities()->contains($ability)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function allMenus(): Collection
|
public function allMenus(): Collection
|
||||||
{
|
{
|
||||||
$model = Admin::adminMenuModel();
|
$model = Admin::adminMenuModel();
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,13 @@ return [
|
||||||
'prefix' => 'admin-api',
|
'prefix' => 'admin-api',
|
||||||
'domain' => null,
|
'domain' => null,
|
||||||
'namespace' => 'App\\Admin\\Controllers',
|
'namespace' => 'App\\Admin\\Controllers',
|
||||||
'middleware' => ['admin'],
|
'middleware' => [
|
||||||
|
'admin.auth',
|
||||||
|
'admin.bootstrap',
|
||||||
|
\App\Admin\Middleware\CheckPermission::class,
|
||||||
|
'sanctum',
|
||||||
|
'substitute',
|
||||||
|
],
|
||||||
// 不包含额外路由, 配置后, 不会追加新增/详情/编辑页面路由
|
// 不包含额外路由, 配置后, 不会追加新增/详情/编辑页面路由
|
||||||
'without_extra_routes' => [
|
'without_extra_routes' => [
|
||||||
'/dashboard',
|
'/dashboard',
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue