feat: add app and database modules
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Routing\Router;
|
||||
use Illuminate\Support\Collection;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
|
||||
class AuditPermissions extends Command
|
||||
{
|
||||
protected $signature = 'permissions:audit
|
||||
{--fix : Create missing permissions in the database}
|
||||
{--json : Output results as JSON}';
|
||||
|
||||
protected $description = 'Compare route middleware permissions against the database and report gaps';
|
||||
|
||||
public function __construct(private Router $router)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$routePerms = $this->collectRoutePermissions();
|
||||
$dbPerms = Permission::pluck('name')->map(fn ($n) => strtolower($n))->toArray();
|
||||
|
||||
$missing = $routePerms->filter(fn ($p) => ! in_array(strtolower($p), $dbPerms))->values();
|
||||
$orphaned = collect($dbPerms)->filter(fn ($p) => ! $routePerms->map(fn ($r) => strtolower($r))->contains($p))->values();
|
||||
|
||||
if ($this->option('json')) {
|
||||
$this->line(json_encode(compact('missing', 'orphaned'), JSON_PRETTY_PRINT));
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
$this->info('=== Permission Audit ===');
|
||||
$this->newLine();
|
||||
|
||||
if ($missing->isEmpty()) {
|
||||
$this->line('<fg=green>✓ All route permissions exist in database.</>');
|
||||
} else {
|
||||
$this->warn("Missing in database ({$missing->count()} permissions used in routes but not in DB):");
|
||||
$missing->each(fn ($p) => $this->line(" - {$p}"));
|
||||
|
||||
if ($this->option('fix')) {
|
||||
$missing->each(fn ($p) => Permission::findOrCreate($p, 'web'));
|
||||
$this->info("Created {$missing->count()} missing permission(s).");
|
||||
}
|
||||
}
|
||||
|
||||
$this->newLine();
|
||||
|
||||
if ($orphaned->isEmpty()) {
|
||||
$this->line('<fg=green>✓ No orphaned permissions in database.</>');
|
||||
} else {
|
||||
$this->warn("Orphaned in database ({$orphaned->count()} permissions in DB but not used in any route):");
|
||||
$orphaned->each(fn ($p) => $this->line(" - {$p}"));
|
||||
}
|
||||
|
||||
return $missing->isEmpty() ? self::SUCCESS : self::FAILURE;
|
||||
}
|
||||
|
||||
private function collectRoutePermissions(): Collection
|
||||
{
|
||||
$permissions = collect();
|
||||
|
||||
foreach ($this->router->getRoutes() as $route) {
|
||||
$middleware = $route->gatherMiddleware();
|
||||
|
||||
foreach ($middleware as $mw) {
|
||||
if (is_string($mw) && str_starts_with($mw, 'permission:')) {
|
||||
$perm = trim(str_replace('permission:', '', $mw));
|
||||
$permissions->push($perm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $permissions->unique()->sort()->values();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user