Added jobs, controllers, and PDF generation logic for management report runtime as defined in Spec 379. Includes artifact migrations, payload builders, and testing coverage. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #450
104 lines
3.9 KiB
PHP
104 lines
3.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\ManagedEnvironment;
|
|
use App\Models\ReviewPack;
|
|
use App\Models\StoredReport;
|
|
use App\Models\User;
|
|
use App\Services\Audit\WorkspaceAuditLogger;
|
|
use App\Support\Audit\AuditActionId;
|
|
use App\Support\Auth\Capabilities;
|
|
use App\Support\ReviewPackStatus;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|
|
|
class ManagementReportPdfDownloadController extends Controller
|
|
{
|
|
public function __invoke(Request $request, StoredReport $storedReport): StreamedResponse
|
|
{
|
|
$storedReport->loadMissing(['tenant.workspace', 'sourceReviewPack.environmentReview']);
|
|
|
|
$user = $request->user();
|
|
$tenant = $storedReport->tenant;
|
|
$reviewPack = $storedReport->sourceReviewPack;
|
|
|
|
if (! $user instanceof User || ! $tenant instanceof ManagedEnvironment || ! $reviewPack instanceof ReviewPack) {
|
|
throw new NotFoundHttpException;
|
|
}
|
|
|
|
if (! $storedReport->isReadyManagementPdf()) {
|
|
throw new NotFoundHttpException;
|
|
}
|
|
|
|
if ((int) $storedReport->managed_environment_id !== (int) $tenant->getKey()
|
|
|| (int) $reviewPack->managed_environment_id !== (int) $tenant->getKey()
|
|
) {
|
|
throw new NotFoundHttpException;
|
|
}
|
|
|
|
if ($reviewPack->status !== ReviewPackStatus::Ready->value || ($reviewPack->expires_at !== null && $reviewPack->expires_at->isPast())) {
|
|
throw new NotFoundHttpException;
|
|
}
|
|
|
|
$review = $reviewPack->environmentReview;
|
|
|
|
if (! $review || (int) ($review->current_export_review_pack_id ?? 0) !== (int) $reviewPack->getKey()) {
|
|
throw new NotFoundHttpException;
|
|
}
|
|
|
|
if (! $user->canAccessTenant($tenant)) {
|
|
throw new NotFoundHttpException;
|
|
}
|
|
|
|
if (! $user->can(Capabilities::REVIEW_PACK_VIEW, $tenant)) {
|
|
abort(403);
|
|
}
|
|
|
|
$disk = Storage::disk((string) $storedReport->file_disk);
|
|
|
|
if (! $disk->exists((string) $storedReport->file_path)) {
|
|
throw new NotFoundHttpException;
|
|
}
|
|
|
|
app(WorkspaceAuditLogger::class)->log(
|
|
workspace: $tenant->workspace,
|
|
action: AuditActionId::ManagementReportPdfDownloaded,
|
|
context: [
|
|
'metadata' => [
|
|
'stored_report_id' => (int) $storedReport->getKey(),
|
|
'review_pack_id' => (int) $reviewPack->getKey(),
|
|
'environment_review_id' => $storedReport->source_environment_review_id !== null
|
|
? (int) $storedReport->source_environment_review_id
|
|
: null,
|
|
'source_surface' => (string) $request->query('source_surface', 'review_pack'),
|
|
'profile' => (string) $storedReport->profile,
|
|
],
|
|
],
|
|
actor: $user,
|
|
resourceType: 'stored_report',
|
|
resourceId: (string) $storedReport->getKey(),
|
|
targetLabel: sprintf('Management report PDF #%d', (int) $storedReport->getKey()),
|
|
tenant: $tenant,
|
|
operationRunId: $storedReport->operation_run_id,
|
|
);
|
|
|
|
return $disk->download((string) $storedReport->file_path, $this->filename($storedReport, $tenant), [
|
|
'Content-Type' => 'application/pdf',
|
|
'X-Management-Report-PDF-SHA256' => $storedReport->sha256 ?? '',
|
|
]);
|
|
}
|
|
|
|
private function filename(StoredReport $storedReport, ManagedEnvironment $tenant): string
|
|
{
|
|
$tenantSlug = preg_replace('/[^A-Za-z0-9._-]+/', '-', (string) ($tenant->external_id ?: $tenant->name)) ?: 'environment';
|
|
$date = $storedReport->generated_at?->format('Y-m-d') ?? now()->format('Y-m-d');
|
|
|
|
return sprintf('management-report-%s-%s.pdf', trim($tenantSlug, '-') ?: 'environment', $date);
|
|
}
|
|
}
|