hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore', 'fornitore'])) { abort(403); } $ticket = $attachment->ticket; if (! $ticket) { abort(404); } if ($user->hasRole('fornitore')) { $this->authorizeSupplierAttachment($user, $attachment); } else { $allowedStabili = StabileContext::accessibleStabili($user) ->pluck('id') ->map(fn($value) => (int) $value) ->filter(fn(int $value) => $value > 0) ->values() ->all(); if ($allowedStabili === [] || ! in_array((int) $ticket->stabile_id, $allowedStabili, true)) { abort(403); } } $disk = Storage::disk('public'); $path = (string) $attachment->file_path; if (! $disk->exists($path)) { abort(404); } $absolutePath = $disk->path($path); $mime = $attachment->resolvedMimeType(); return response()->file($absolutePath, [ 'Content-Type' => $mime, 'Cache-Control' => 'private, max-age=300', 'Content-Disposition' => 'inline; filename="' . addslashes((string) ($attachment->original_file_name ?: basename($path))) . '"', ]); } protected function authorizeSupplierAttachment(User $user, TicketAttachment $attachment): void { $fornitoreIds = []; $currentSupplier = $this->resolveCurrentUserSupplier($user); if ($currentSupplier instanceof Fornitore) { $fornitoreIds[] = (int) $currentSupplier->id; } $dipendente = $this->resolveCollaboratoreForUser($user, $currentSupplier?->id); if ($dipendente instanceof FornitoreDipendente) { $fornitoreIds[] = (int) $dipendente->fornitore_id; if ((int) ($dipendente->fornitore_esterno_id ?? 0) > 0) { $fornitoreIds[] = (int) $dipendente->fornitore_esterno_id; } } $fornitoreIds = array_values(array_unique(array_filter($fornitoreIds))); abort_if($fornitoreIds === [], 403); $ticket = $attachment->ticket; abort_unless($ticket, 404); if (in_array((int) ($ticket->assegnato_a_fornitore_id ?? 0), $fornitoreIds, true)) { return; } $hasIntervento = $ticket->interventi() ->whereIn('fornitore_id', $fornitoreIds) ->exists(); abort_unless($hasIntervento, 403); } protected function resolveCurrentUserSupplier(User $user): ?Fornitore { $email = mb_strtolower(trim((string) $user->email)); if ($email === '') { return null; } return Fornitore::query() ->whereRaw('LOWER(email) = ?', [$email]) ->withCount(['ticketInterventi', 'dipendenti']) ->orderByDesc('ticket_interventi_count') ->orderByDesc('dipendenti_count') ->orderByDesc('id') ->first(); } protected function resolveCollaboratoreForUser(User $user, ?int $currentSupplierId = null): ?FornitoreDipendente { return FornitoreDipendente::query() ->where('attivo', true) ->where(function ($builder) use ($user, $currentSupplierId): void { $builder->where('user_id', (int) $user->id) ->orWhereRaw('LOWER(email) = ?', [mb_strtolower((string) $user->email)]); if (($currentSupplierId ?? 0) > 0) { $builder->orWhere('fornitore_esterno_id', (int) $currentSupplierId); } }) ->orderByRaw('CASE WHEN user_id = ? THEN 0 ELSE 1 END', [(int) $user->id]) ->orderByRaw('CASE WHEN fornitore_esterno_id IS NULL THEN 1 ELSE 0 END') ->orderByDesc('id') ->first(); } }