From 3244e40634234ae66fe9fe08c63c5276502f5052 Mon Sep 17 00:00:00 2001 From: "sweep-ai[bot]" <128439645+sweep-ai[bot]@users.noreply.github.com> Date: Tue, 24 Dec 2024 23:28:23 +0000 Subject: [PATCH] Enhance Role Management and Permissions System --- app/Filament/Resources/RoleResource.php | 48 +++++++++++++------ app/Models/Role.php | 18 +++++++ database/seeders/RolesSeeder.php | 62 ++++++++++++------------- 3 files changed, 83 insertions(+), 45 deletions(-) diff --git a/app/Filament/Resources/RoleResource.php b/app/Filament/Resources/RoleResource.php index 6e0f67ff..dd9786ca 100644 --- a/app/Filament/Resources/RoleResource.php +++ b/app/Filament/Resources/RoleResource.php @@ -12,28 +12,36 @@ use Filament\Tables\Table; use Filament\Forms\Components\TextInput; use Filament\Forms\Components\Select; +use Filament\Forms\Components\Card; use Filament\Tables\Columns\TextColumn; +use Filament\Tables\Actions\DeleteAction; +use Illuminate\Support\Collection; class RoleResource extends Resource { protected static ?string $model = Role::class; - protected static ?string $navigationIcon = 'heroicon-o-shield-check'; - protected static ?string $navigationGroup = 'Administration'; + protected static ?int $navigationSort = 2; public static function form(Form $form): Form { return $form ->schema([ - TextInput::make('name') - ->required() - ->unique(ignoreRecord: true), - Select::make('permissions') - ->multiple() - ->relationship('permissions', 'name') - ->preload() - ->searchable(), + Card::make() + ->schema([ + TextInput::make('name') + ->required() + ->unique(ignoreRecord: true) + ->helperText('The name of the role (e.g., editor, manager)'), + Select::make('permissions') + ->multiple() + ->relationship('permissions', 'name') + ->preload() + ->searchable() + ->helperText('Select the permissions for this role') + ->required(), + ]) ]); } @@ -41,19 +49,33 @@ public static function table(Table $table): Table { return $table ->columns([ - TextColumn::make('name'), + TextColumn::make('id')->sortable(), + TextColumn::make('name')->sortable()->searchable(), TextColumn::make('permissions.name') ->listWithLineBreaks() ->bulleted(), + TextColumn::make('created_at') + ->dateTime() + ->sortable(), ]) ->filters([]) ->actions([ Tables\Actions\EditAction::make(), - Tables\Actions\DeleteAction::make(), + Tables\Actions\DeleteAction::make() + ->before(function (DeleteAction $action, Role $record) { + if ($record->name === 'super_admin') { + $action->cancel(); + } + }), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ - Tables\Actions\DeleteBulkAction::make(), + Tables\Actions\DeleteBulkAction::make() + ->before(function ($action, Collection $records) { + if ($records->contains('name', 'super_admin')) { + $action->cancel(); + } + }), ]), ]); } diff --git a/app/Models/Role.php b/app/Models/Role.php index 445e5b43..0ff16d9d 100644 --- a/app/Models/Role.php +++ b/app/Models/Role.php @@ -8,8 +8,26 @@ class Role extends SpatieRole { + protected $fillable = ['name', 'guard_name']; + public function team(): BelongsTo { return $this->belongsTo(Team::class); } + + public function hasPermissionTo($permission): bool + { + return $this->permissions()->where('name', $permission)->exists(); + } + + public static function defaultRoles(): array + { + return [ + 'super_admin' => 'Full access to all features', + 'admin' => 'Administrative access with some restrictions', + 'staff' => 'Standard staff access', + 'client' => 'Client access with limited permissions', + 'free' => 'Basic access for free users' + ]; + } } diff --git a/database/seeders/RolesSeeder.php b/database/seeders/RolesSeeder.php index 253e17572..5d123655 100644 --- a/database/seeders/RolesSeeder.php +++ b/database/seeders/RolesSeeder.php @@ -8,42 +8,40 @@ class RolesSeeder extends Seeder { - /** - * Run the database seeds. - */ public function run(): void { - // Create roles - $superAdmin = Role::firstOrCreate(['name' => 'super_admin']); - $admin = Role::firstOrCreate(['name' => 'admin']); - $staff = Role::firstOrCreate(['name' => 'staff']); - $client = Role::firstOrCreate(['name' => 'client']); - $free = Role::firstOrCreate(['name' => 'free']); + // Create base permissions + $permissions = [ + // User management + 'view_users', 'create_users', 'edit_users', 'delete_users', + // Role management + 'view_roles', 'create_roles', 'edit_roles', 'delete_roles', + // Permission management + 'view_permissions', 'assign_permissions', + // Team management + 'view_teams', 'create_teams', 'edit_teams', 'delete_teams', + // Billing + 'view_billing', 'manage_billing', + // Settings + 'view_settings', 'manage_settings', + ]; - // Get all permissions - $permissions = Permission::all(); + foreach ($permissions as $permission) { + Permission::firstOrCreate(['name' => $permission]); + } - // Assign permissions to roles - $superAdmin->syncPermissions($permissions); - - $adminPermissions = $permissions->filter(function ($permission) { - return !str_contains($permission->name, ['role', 'permission']); - }); - $admin->syncPermissions($adminPermissions); + // Create roles and assign permissions + $roles = [ + 'super_admin' => $permissions, + 'admin' => array_filter($permissions, fn($p) => !str_contains($p, ['roles', 'permissions'])), + 'staff' => array_filter($permissions, fn($p) => str_contains($p, ['view', 'create', 'edit'])), + 'client' => array_filter($permissions, fn($p) => str_contains($p, ['view'])), + 'free' => ['view_billing'] + ]; - $staffPermissions = $permissions->filter(function ($permission) { - return str_contains($permission->name, ['view', 'create', 'update']); - }); - $staff->syncPermissions($staffPermissions); - - $clientPermissions = $permissions->filter(function ($permission) { - return str_contains($permission->name, ['view']); - }); - $client->syncPermissions($clientPermissions); - - $freePermissions = $permissions->filter(function ($permission) { - return str_contains($permission->name, ['view']); - }); - $free->syncPermissions($freePermissions); + foreach ($roles as $roleName => $rolePermissions) { + $role = Role::firstOrCreate(['name' => $roleName]); + $role->syncPermissions($rolePermissions); + } } }