Squareetlabs/LaravelSimplePermissions

A comprehensive and flexible Laravel package for advanced permission management. This package provides a robust system for managing roles, permissions, groups, and entity-specific abilities.
Core Functionality:
-
Role-Based Access Control (RBAC): Define custom roles with specific permission sets. Roles can be assigned to users to manage access levels efficiently.
-
Permission System: Implement fine-grained permissions using a code-based system (e.g., `posts.create`, `users.edit`). Permissions are global entities that can be assigned to roles and groups. Supports wildcard permissions for flexible access patterns.
-
Group Management: Organize users into groups. Groups can have their own permission sets, allowing for efficient permission management when multiple users need the same access level.
-
Entity-Specific Abilities: Grant or deny permissions for specific model instances (e.g., allowing a user to edit a particular post but not others). This provides the most granular level of access control.
-
Caching & Performance: Intelligent caching system to optimize permission checks, reducing database queries and improving application performance.
-
Audit Logging: Optional comprehensive audit trail that logs all permission-related actions including role assignments and permission changes.
-
Laravel Integration: Seamlessly integrates with Laravel's built-in authorization system, including Policies, Blade directives, and middleware for route protection.
Key Features
-
? Roles & Permissions: Flexible role system with granular permissions
-
? Groups: Organize users into groups with shared permissions
-
? Abilities: Entity-specific permissions for individual models
-
? Smart Caching: Caching system to optimize permission checks
-
? Audit Logging: Complete action logging (optional)
-
? Blade Directives: Blade directives for permission checks in views
-
? Policies: Integration with Laravel's Policy system
-
? Middleware: Middleware for route protection
-
? Artisan Commands: CLI tools for management
-
? Events: Event system for permission changes (RoleAssigned, RoleRemoved, AbilityGranted, AbilityRevoked)
-
? Validation: Automatic validation of permission codes
-
? Performance: Optimized queries with eager loading
Requirements
-
PHP >= 8.1
-
Laravel 8.x, 9.x, 10.x, 11.x or 12.x
Installation
1. Install the Package
composer require squareetlabs/laravel-simple-permissions
2. Publish Configuration and Migrations
php artisan vendor:publish --provider="Squareetlabs\LaravelSimplePermissions\SimplePermissionsServiceProvider"
This will publish:
- config/simple-permissions.php - Configuration file
- Database migrations
3. Configure the User Model
Add the HasPermissions trait to your User model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Squareetlabs\LaravelSimplePermissions\Traits\HasPermissions;
class User extends Model
{
use HasPermissions;
// ... rest of your code
}
4. Run Migrations
> ?? IMPORTANT: Always do backups before running migrations.
php artisan migrate
> [!NOTE]
> If you wish to use custom foreign keys and table names, modify config/simple-permissions.php before running migrations.
5. Optional Configuration
Enable Caching
To improve performance, enable caching in .env:
SIMPLE_PERMISSIONS_CACHE_ENABLED=true
SIMPLE_PERMISSIONS_CACHE_DRIVER=redis
SIMPLE_PERMISSIONS_CACHE_TTL=3600
Enable Audit Logging
To log all permission actions:
SIMPLE_PERMISSIONS_AUDIT_ENABLED=true
SIMPLE_PERMISSIONS_AUDIT_LOG_CHANNEL=stack
Configuration
The configuration file config/simple-permissions.php contains all options:
Custom Models
'models' => [
'user' => App\Models\User::class,
// ... other models
],
Cache
'cache' => [
'enabled' => env('SIMPLE_PERMISSIONS_CACHE_ENABLED', true),
'driver' => env('SIMPLE_PERMISSIONS_CACHE_DRIVER', 'redis'),
'ttl' => env('SIMPLE_PERMISSIONS_CACHE_TTL', 3600),
'prefix' => 'simple_permissions',
'tags' => true,
],
Basic Usage
Creating Roles and Permissions
use Squareetlabs\LaravelSimplePermissions\Support\Facades\SimplePermissions;
// Create permissions
$viewPost = SimplePermissions::model('permission')::create(['code' => 'posts.view', 'name' => 'View Posts']);
$createPost = SimplePermissions::model('permission')::create(['code' => 'posts.create', 'name' => 'Create Posts']);
// Create role
$adminRole = SimplePermissions::model('role')::create(['code' => 'admin', 'name' => 'Administrator']);
// Assign permissions to role
$adminRole->permissions()->attach([$viewPost->id, $createPost->id]);
Assigning Roles to Users
// Assign role to user
$user->assignRole('admin');
// Remove role from user
$user->removeRole('admin');
// Sync roles (replaces all existing roles)
$user->syncRoles(['admin', 'editor']);
Checking Permissions
// Check if user has a permission (direct or via role/group)
if ($user->hasPermission('posts.create')) {
// User can create posts
}
// Check if user has a role
if ($user->hasRole('admin')) {
// User is admin
}
// Check specific ability on an entity
if ($user->hasAbility('edit', $post)) {
// User can edit this specific post
}
Users
The HasPermissions trait provides the following methods:
// Check if user has a role (or roles)
// $require = true: all roles are required
// $require = false: at least one of the roles
$user->hasRole('admin', $require = false)
$user->hasRole(['admin', 'editor'], $require = false)
// Check if user has a permission (or permissions)
// $require = true: all permissions are required
// $require = false: at least one of the permissions
$user->hasPermission('posts.create', $require = false)
$user->hasPermission(['posts.create', 'posts.edit'], $require = false)
// Check if user has an ability on an entity
$user->hasAbility('posts.edit', $post)
// Allow ability for user on an entity
$user->allowAbility('posts.edit', $post)
// Forbid ability for user on an entity
$user->forbidAbility('posts.edit', $post)
// Remove ability from user
$user->removeAbility('posts.edit', $post)
Roles & Permissions
Wildcard Permissions
You can use wildcards for permissions:
-
`posts.*` - All permissions starting with `posts.`
-
`*` - All permissions (if enabled in config)
Checking Permissions
// Check multiple permissions (OR)
if ($user->hasPermission(['posts.create', 'posts.edit'], false)) {
// User can create OR edit posts
}
// Check multiple permissions (AND)
if ($user->hasPermission(['posts.create', 'posts.edit'], true)) {
// User can create AND edit posts
}
Abilities
Abilities allow specific permissions for individual entities.
Creating and Assigning Abilities
You can use helper methods for easier ability management:
// Allow user to edit a specific post
$user->allowAbility('posts.edit', $post);
// Forbid user to edit a specific post
$user->forbidAbility('posts.edit', $post);
// Remove ability from user
$user->removeAbility('posts.edit', $post);
Or use the direct approach:
use Squareetlabs\LaravelSimplePermissions\Support\Facades\SimplePermissions;
// Create a permission first
$permission = SimplePermissions::model('permission')::create(['code' => 'posts.edit']);
// Create an ability for a specific entity
$ability = SimplePermissions::model('ability')::create([
'permission_id' => $permission->id,
'title' => 'Edit Post #1',
'entity_id' => $post->id,
'entity_type' => get_class($post),
]);
// Allow user to edit a specific post
$ability->users()->attach($user, ['forbidden' => false]);
// Forbid user to edit a specific post
$ability->users()->attach($user, ['forbidden' => true]);
// Remove ability from user
$ability->users()->detach($user);
Checking an Ability
if ($user->hasAbility('posts.edit', $post)) {
// User can edit this specific post
}
Groups
Groups allow organizing users with shared permissions.
Creating and Managing Groups
use Squareetlabs\LaravelSimplePermissions\Support\Facades\SimplePermissions;
// Create group
$group = SimplePermissions::model('group')::create(['code' => 'moderators', 'name' => 'Moderators']);
// Assign permissions to group
$permission = SimplePermissions::model('permission')::where('code', 'posts.moderate')->first();
$group->permissions()->attach($permission);
// Add users to group
$group->users()->attach($user);
// Remove users from group
$group->users()->detach($user);
Middleware
The package provides middleware for route protection.
Usage in Routes
// Check role
Route::middleware(['role:admin'])->group(function () {
Route::get('/admin', [AdminController::class, 'index']);
});
// Check permission
Route::middleware(['permission:posts.create'])->group(function () {
Route::post('/posts', [PostController::class, 'store']);
});
// Check ability
// Format: ability:action,entity_class,route_parameter_name
Route::middleware(['ability:edit,App\Models\Post,post_id'])->group(function () {
Route::put('/posts/{post_id}', [PostController::class, 'update']);
});
OR Operations
// User must have admin OR root
Route::middleware(['role:admin|root'])->group(function () {
// ...
});
Blade Directives
The package includes Blade directives for permission checks in views:
{{-- Check role --}}
@role('admin')
<button>Admin Panel</button>
@endrole
{{-- Check permission --}}
@permission('posts.create')
<a href="{{ route('posts.create') }}">New Post</a>
@endpermission
{{-- Check ability --}}
@ability('edit', $post)
<button>Edit Post</button>
@endability
Policies
The package integrates with Laravel's Policy system.
Generate a Policy
php artisan permissions:policy PostPolicy --model=Post
Using the Policy
// In a controller
if ($user->can('view', $post)) {
// User can view the post
}
// In a view
@can('update', $post)
<button>Edit</button>
@endcan
Events
The package dispatches events when permissions change, allowing you to hook into these actions:
Available Events
-
`RoleAssigned`: Dispatched when a role is assigned to a user
-
`RoleRemoved`: Dispatched when a role is removed from a user
-
`AbilityGranted`: Dispatched when an ability is granted to a user
-
`AbilityRevoked`: Dispatched when an ability is revoked from a user
Listening to Events
use Squareetlabs\LaravelSimplePermissions\Events\RoleAssigned;
use Squareetlabs\LaravelSimplePermissions\Events\AbilityGranted;
// In your EventServiceProvider
protected $listen = [
RoleAssigned::class => [
// Your listeners here
],
AbilityGranted::class => [
// Your listeners here
],
];
Example Listener
use Squareetlabs\LaravelSimplePermissions\Events\RoleAssigned;
class LogRoleAssignment
{
public function handle(RoleAssigned $event)
{
// Log the role assignment
Log::info("User {$event->user->id} was assigned role {$event->role->code}");
}
}
Artisan Commands
The package includes several useful commands:
Management
// List all roles
php artisan permissions:roles
// Show role details
php artisan permissions:show-role {role}
// List all permissions
php artisan permissions:list
// Sync permissions from configuration
php artisan permissions:sync
// Export permissions
php artisan permissions:export --format=json
// Import permissions
php artisan permissions:import --file=permissions.json
// Clear permissions cache
php artisan permissions:clear-cache
// Generate a policy
php artisan permissions:policy PostPolicy --model=Post