Current state with latest updates
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Notifications\SecurityReportDangerNotification;
|
||||
use App\Services\SecurityReport\SecurityReportScanner;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
|
||||
final class SecurityReportScanCommand extends Command
|
||||
{
|
||||
protected $signature = 'security:scan
|
||||
{--notify : Send configured email notification when high or critical findings exist}
|
||||
{--triggered-by=artisan : Mark the scan source}
|
||||
{--user-id= : Associate the scan with a specific user id}';
|
||||
|
||||
protected $description = 'Run Composer and npm security audits and store a private admin report.';
|
||||
|
||||
public function handle(SecurityReportScanner $scanner): int
|
||||
{
|
||||
if (! (bool) config('security-report.enabled', true)) {
|
||||
$this->warn('Security report scanning is disabled.');
|
||||
|
||||
return self::INVALID;
|
||||
}
|
||||
|
||||
$this->info('Running security report scan...');
|
||||
|
||||
$report = $scanner->scan(
|
||||
(string) $this->option('triggered-by'),
|
||||
$this->option('user-id') !== null ? (int) $this->option('user-id') : null,
|
||||
);
|
||||
|
||||
if ($report->status === 'failed') {
|
||||
$this->error('Security scan failed: ' . (string) ($report->error_message ?? 'Unknown error'));
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$this->table(
|
||||
['Status', 'Critical', 'High', 'Medium', 'Low', 'Unknown', 'Composer outdated', 'npm outdated'],
|
||||
[[
|
||||
$report->status,
|
||||
$report->total_critical,
|
||||
$report->total_high,
|
||||
$report->total_medium,
|
||||
$report->total_low,
|
||||
$report->total_unknown,
|
||||
$report->composer_outdated_count,
|
||||
$report->npm_outdated_count,
|
||||
]],
|
||||
);
|
||||
|
||||
if ((bool) $this->option('notify') && $report->hasDangerFindings()) {
|
||||
$this->sendDangerNotification($report);
|
||||
$this->info('Danger notification sent.');
|
||||
}
|
||||
|
||||
if ($report->hasCriticalFindings() && (bool) config('security-report.fail_on.critical', false)) {
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
if ($report->hasHighFindings() && (bool) config('security-report.fail_on.high', false)) {
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
private function sendDangerNotification(\App\Models\SecurityReport $report): void
|
||||
{
|
||||
$email = trim((string) config('security-report.notify_email', ''));
|
||||
|
||||
if ($email === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
Notification::route('mail', $email)
|
||||
->notify(new SecurityReportDangerNotification($report));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user