Roles and Permissions
Role-based access control (RBAC) using spatie/laravel-permission v6 with PHP enums for type-safe permission management.
Overview
Section titled “Overview”The system uses:
- PHP Enums for type-safe roles and permissions
- Spatie Permission package for RBAC infrastructure
- Wildcard permissions for admin full access
- FilamentPHP trait for automatic resource authorization
Quick Start
Section titled “Quick Start”Assign a Role
Section titled “Assign a Role”use App\Enums\Role;
$user->assignRole(Role::Admin->value);$user->assignRole(Role::DmcManager->value);Check Permissions
Section titled “Check Permissions”use App\Enums\Permission;
// Using enum (recommended)if ($user->can(Permission::ViewUser->value)) { // User can view users}
// Using stringif ($user->can('view_user')) { // User can view users}Check Role
Section titled “Check Role”use App\Enums\Role;
if ($user->hasRole(Role::Admin->value)) { // User is admin}Full system access via wildcard (*) permission.
| Property | Value |
|---|---|
| Slug | admin |
| Icon | heroicon-o-shield-check |
| Color | danger (red) |
| Scope | Global |
Capabilities: All permissions on all resources.
DMC Manager
Section titled “DMC Manager”Limited access to DMC-related resources only.
| Property | Value |
|---|---|
| Slug | dmc-manager |
| Icon | heroicon-o-building-office-2 |
| Color | info (blue) |
| Scope | DMC-scoped |
Capabilities:
- Full CRUD on DMCs
- Full CRUD on Offers
- Full CRUD on Travel Products
Restrictions (no access to):
- Users, Activity Logs
- Markets, Market Products
- Flight Search, Flight Bookings
- Hotels, Airports
- Clients, Passengers
Permission Structure
Section titled “Permission Structure”Naming Convention
Section titled “Naming Convention”{action}_{resource}Actions: view, create, update, delete
Examples:
view_user- View user recordscreate_dmc- Create new DMCupdate_offer- Update offersdelete_travel_product- Delete travel products
Available Permissions (48 total)
Section titled “Available Permissions (48 total)”| Resource | View | Create | Update | Delete |
|---|---|---|---|---|
| User | view_user | create_user | update_user | delete_user |
| Client | view_client | create_client | update_client | delete_client |
| Hotel | view_hotel | create_hotel | update_hotel | delete_hotel |
| Airport | view_airport | create_airport | update_airport | delete_airport |
| Market | view_market | create_market | update_market | delete_market |
| DMC | view_dmc | create_dmc | update_dmc | delete_dmc |
| Offer | view_offer | create_offer | update_offer | delete_offer |
| Travel Product | view_travel_product | create_travel_product | update_travel_product | delete_travel_product |
FilamentPHP Integration
Section titled “FilamentPHP Integration”HasResourcePermissions Trait
Section titled “HasResourcePermissions Trait”Add to Filament resources for automatic permission checks:
use App\Filament\Traits\HasResourcePermissions;
class UserResource extends Resource{ use HasResourcePermissions;
// Resource implementation...}The trait automatically:
- Derives permission prefix from model name (
User->user,FlightBooking->flight_booking) - Hides navigation for unauthorized resources
- Checks
view,create,update,deletepermissions
Adding New Permissions
Section titled “Adding New Permissions”1. Add to Permission Enum
Section titled “1. Add to Permission Enum”enum Permission: string{ // ... existing permissions
// New resource (4 permissions) case ViewInvoice = 'view_invoice'; case CreateInvoice = 'create_invoice'; case UpdateInvoice = 'update_invoice'; case DeleteInvoice = 'delete_invoice';}2. Update Role Permissions (if needed)
Section titled “2. Update Role Permissions (if needed)”// If DMC Managers should access the new resourcepublic static function dmcManagerPermissions(): array{ return [ // ... existing permissions self::ViewInvoice, self::CreateInvoice, self::UpdateInvoice, self::DeleteInvoice, ];}3. Run Seeder
Section titled “3. Run Seeder”./vendor/bin/sail artisan db:seed --class=RolesAndPermissionsSeederWriting Policies
Section titled “Writing Policies”Use Permission enum for type-safe policy checks:
use App\Enums\Permission;use App\Models\User;
class InvoicePolicy{ public function viewAny(User $user): bool { return $user->can(Permission::ViewInvoice->value); }
public function create(User $user): bool { return $user->can(Permission::CreateInvoice->value); }
public function update(User $user, Invoice $invoice): bool { return $user->can(Permission::UpdateInvoice->value); }
public function delete(User $user, Invoice $invoice): bool { return $user->can(Permission::DeleteInvoice->value); }}Cache Management
Section titled “Cache Management”Spatie Permission caches roles and permissions. Clear cache after changes:
./vendor/bin/sail artisan permission:cache-resetTroubleshooting
Section titled “Troubleshooting”User Can’t Access Resource
Section titled “User Can’t Access Resource”-
Check user has correct role:
$user->getRoleNames(); // ['admin'] or ['dmc-manager'] -
Check role has permission:
$user->getAllPermissions()->pluck('name'); -
Clear permission cache:
Terminal window ./vendor/bin/sail artisan permission:cache-reset
Navigation Not Showing
Section titled “Navigation Not Showing”Ensure resource uses HasResourcePermissions trait:
class DMCResource extends Resource{ use HasResourcePermissions;}| File | Purpose |
|---|---|
app/Enums/Permission.php | Permission enum with 48 CRUD permissions |
app/Enums/Role.php | Role enum with Admin and DmcManager |
app/Filament/Traits/HasResourcePermissions.php | Filament authorization trait |
database/seeders/RolesAndPermissionsSeeder.php | Seeds roles and permissions |