Laravel 13 + Filament 5 admin panel and REST API for a non-profit developer collective, backed by the Pireon OAuth identity server. The public site is a separate, server-rendered application consuming /api/public/v1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
55 lines
1.7 KiB
PHP
55 lines
1.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Database\Seeders;
|
|
|
|
use App\Support\Permissions;
|
|
use Illuminate\Database\Seeder;
|
|
use Spatie\Permission\Models\Permission;
|
|
use Spatie\Permission\Models\Role;
|
|
use Spatie\Permission\PermissionRegistrar;
|
|
|
|
/**
|
|
* Brings the database in line with App\Support\Permissions.
|
|
*
|
|
* Idempotent: safe to re-run after every deploy. Permissions removed from the
|
|
* catalogue are deleted, so a permission that no longer exists in code cannot
|
|
* keep granting access.
|
|
*/
|
|
class RolePermissionSeeder extends Seeder
|
|
{
|
|
public function run(): void
|
|
{
|
|
app(PermissionRegistrar::class)->forgetCachedPermissions();
|
|
|
|
$catalogue = Permissions::all();
|
|
|
|
foreach ($catalogue as $name) {
|
|
Permission::findOrCreate($name, 'web');
|
|
}
|
|
|
|
// Drop permissions that were retired from the catalogue, along with
|
|
// their role and user assignments.
|
|
Permission::query()->whereNotIn('name', $catalogue)->delete();
|
|
|
|
foreach (Permissions::roleDefinitions() as $roleName => $permissions) {
|
|
$role = Role::findOrCreate($roleName, 'web');
|
|
|
|
// syncPermissions is what makes this idempotent: the role ends up
|
|
// with exactly the definition in code, no more and no less.
|
|
// super_admin gets an empty set on purpose — its power comes from
|
|
// the Gate::before hook in AuthServiceProvider.
|
|
$role->syncPermissions($permissions);
|
|
}
|
|
|
|
app(PermissionRegistrar::class)->forgetCachedPermissions();
|
|
|
|
$this->command?->info(sprintf(
|
|
'Synced %d permissions across %d roles.',
|
|
count($catalogue),
|
|
count(Permissions::roleDefinitions()),
|
|
));
|
|
}
|
|
}
|