fix(服务器资源): 修复角色继承权限下资源不可见问题

资源列表筛选增加对角色继承权限的解析,合并用户直连权限与继承权限后再计算可见资源。
This commit is contained in:
Boen_Shi 2026-04-29 14:24:32 +08:00
parent 57f8f4492d
commit acba3c9f62
2 changed files with 35 additions and 1 deletions

1
.gitignore vendored
View File

@ -29,3 +29,4 @@ AGENTS.md
CLAUDE.md CLAUDE.md
.mcp.json .mcp.json
boost.json boost.json
LOG.md

View File

@ -16,6 +16,7 @@ use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\Client\RequestException; use Illuminate\Http\Client\RequestException;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Http;
use Illuminate\Validation\ValidationException; use Illuminate\Validation\ValidationException;
use Spatie\Permission\Models\Permission; use Spatie\Permission\Models\Permission;
@ -38,7 +39,7 @@ class ServerResourceController extends Controller
$user = auth('api')->user(); $user = auth('api')->user();
if ($user && ! $user->can('platform.servers.view')) { if ($user && ! $user->can('platform.servers.view')) {
$resourceIds = $user->serverResources() $pivotResourceIds = $user->serverResources()
->where(function ($pivotQuery) { ->where(function ($pivotQuery) {
$pivotQuery->where('can_ssh', true) $pivotQuery->where('can_ssh', true)
->orWhere('can_sftp', true) ->orWhere('can_sftp', true)
@ -47,6 +48,13 @@ class ServerResourceController extends Controller
->pluck('server_resources.id') ->pluck('server_resources.id')
->values(); ->values();
$permissionResourceIds = $this->resolveResourceIdsFromPermissions($user);
$resourceIds = $pivotResourceIds
->merge($permissionResourceIds)
->map(fn ($id): int => (int) $id)
->unique()
->values();
$parentIds = ServerResource::query() $parentIds = ServerResource::query()
->whereIn('id', $resourceIds) ->whereIn('id', $resourceIds)
->pluck('parent_id') ->pluck('parent_id')
@ -61,6 +69,31 @@ class ServerResourceController extends Controller
return response()->json(['code' => 0, 'message' => 'ok', 'data' => $query->paginate(500)]); return response()->json(['code' => 0, 'message' => 'ok', 'data' => $query->paginate(500)]);
} }
private function resolveResourceIdsFromPermissions(User $user): Collection
{
$allPermissions = $user->getAllPermissions();
if ($allPermissions->contains(fn (Permission $permission): bool => $permission->name === 'resource.servers.use')) {
return ServerResource::query()
->whereNotNull('parent_id')
->pluck('id')
->values();
}
$resourceIds = collect();
foreach ($allPermissions as $permission) {
if (! str_starts_with((string) $permission->name, 'resource.servers.use.')) {
continue;
}
$description = (string) ($permission->description ?? '');
if (preg_match('/资源ID[:]\s*(\d+)/u', $description, $matches) === 1) {
$resourceIds->push((int) $matches[1]);
}
}
return $resourceIds->unique()->values();
}
#[Apidoc\Title('创建资源'), Apidoc\Method('POST'), Apidoc\Url('/servers')] #[Apidoc\Title('创建资源'), Apidoc\Method('POST'), Apidoc\Url('/servers')]
public function store(StoreServerResourceRequest $request): JsonResponse public function store(StoreServerResourceRequest $request): JsonResponse
{ {