PM_Console/backend/app/Http/Middleware/EnsureResourceAccess.php

72 خطوط
3.0 KiB
PHP

<?php
namespace App\Http\Middleware;
use App\Models\BacklogItem;
use App\Models\Checklist;
use App\Models\Comment;
use App\Models\File;
use App\Models\Meeting;
use App\Models\MeetingActionItem;
use App\Models\Notification;
use App\Models\Project;
use App\Models\Sprint;
use App\Models\Subtask;
use App\Models\Task;
use App\Services\ResourceAccessService;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class EnsureResourceAccess
{
public function __construct(private readonly ResourceAccessService $access) {}
public function handle(Request $request, Closure $next): Response
{
$user = $request->user();
if (! $user) {
return response()->json(['success' => false, 'message' => 'Unauthenticated.'], 401);
}
$route = $request->route();
$checks = [
'project' => fn ($model) => $model instanceof Project && $this->access->canAccessProject($user, $model),
'task' => fn ($model) => $model instanceof Task && $this->access->canAccessTask($user, $model),
'sprint' => fn ($model) => $model instanceof Sprint && $this->access->canAccessSprint($user, $model),
'meeting' => fn ($model) => $model instanceof Meeting && $this->access->canAccessMeeting($user, $model),
'comment' => fn ($model) => $model instanceof Comment && $this->access->canAccessComment($user, $model),
'file' => fn ($model) => $model instanceof File && $this->access->canAccessFile($user, $model),
'backlogItem' => fn ($model) => $model instanceof BacklogItem
&& ($this->access->canSeeAll($user)
|| $model->created_by === $user->id
|| ($model->project_id !== null
&& $this->access->projects($user)->whereKey($model->project_id)->exists())),
'checklist' => fn ($model) => $model instanceof Checklist && $this->access->tasks($user)->whereKey($model->task_id)->exists(),
'subtask' => fn ($model) => $model instanceof Subtask && $this->access->tasks($user)->whereKey($model->task_id)->exists(),
'notification' => fn ($model) => $model instanceof Notification && $model->user_id === $user->id,
];
foreach ($checks as $parameter => $allowed) {
$model = $route?->parameter($parameter);
if ($model !== null && ! $allowed($model)) {
abort(403, 'شما به این منبع دسترسی ندارید.');
}
}
$actionItem = $route?->parameter('actionItem');
$meeting = $route?->parameter('meeting');
if ($actionItem instanceof MeetingActionItem) {
abort_unless(
$meeting instanceof Meeting
&& $actionItem->meeting_id === $meeting->id
&& $this->access->canAccessMeeting($user, $meeting),
403,
'این اقدام متعلق به جلسه انتخاب‌شده نیست.'
);
}
return $next($request);
}
}