A comprehensive and advanced permission management system for Laravel applications. This package provides a robust role-based access control (RBAC) system with support for wildcard permissions, blade directives, Artisan commands, and a fluent API.
users).admin.*, admin*, *admin, *admin*) for flexible route matching.@hasRole, @hasPermission).PermissionManager facade.pm, pm:role:admin|editor).composer require HosseinHezami/laravel-permission-manager
config/app.php:'providers' => [
// ...
HosseinHezami\PermissionManager\PermissionManagerServiceProvider::class,
],
'aliases' => [
// ...
'PermissionManager' => HosseinHezami\PermissionManager\Facades\PermissionManager::class,
],
php artisan vendor:publish --provider="HosseinHezami\PermissionManager\PermissionManagerServiceProvider" --tag="config"
php artisan vendor:publish --provider="HosseinHezami\PermissionManager\PermissionManagerServiceProvider" --tag="migrations"
php artisan migrate
PermissionTrait trait to your User model:namespace App\Models;
use HosseinHezami\PermissionManager\Traits\PermissionTrait;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use PermissionTrait;
}
To run the install command which sets up the configuration and optionally adds the trait to your User model:
# Install the permission manager package with default settings
php artisan permission-manager:install
# Install and automatically run the migrations for permission tables
php artisan permission-manager:install --migrate
# Install, run migrations and force overwrite existing files if any
php artisan permission-manager:install --migrate --force
# Install with custom User model path to automatically add the PermissionTrait trait
php artisan permission-manager:install --user-model=/path/to/User.php
After publishing the configuration file, you can customize the package behavior in config/permission-manager.php:
return [
'models' => [
'role' => \HosseinHezami\PermissionManager\Models\Role::class,
'permission' => \HosseinHezami\PermissionManager\Models\Permission::class,
'user' => \App\Models\User::class,
],
'tables' => [
'roles' => 'roles',
'permissions' => 'permissions',
'role_permissions' => 'role_permissions',
'user_roles' => 'user_roles',
],
'cache_duration' => 60, // Cache permissions for 60 minutes
'log_denials' => false, // Log permission/role denials
'wildcards' => true, // Enable wildcard support
];
The package includes the following database migrations:
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug')->unique();
$table->text('description')->nullable();
$table->timestamps();
});
Schema::create('permissions', function (Blueprint $table) {
$table->id();
$table->string('route')->unique();
$table->timestamps();
});
Schema::create('role_permissions', function (Blueprint $table) {
$table->unsignedBigInteger('role_id');
$table->unsignedBigInteger('permission_id');
$table->primary(['role_id','permission_id']);
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade');
$table->timestamps();
});
Schema::create('user_roles', function (Blueprint $table) {
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('role_id');
$table->primary(['user_id','role_id']);
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->timestamps();
});
Check for roles in your Blade templates:
<!-- string|array -->
@hasRole('admin')
<!-- Content for admins only -->
@endhasRole
@hasPermission('users.edit')
<!-- Content for users with edit permission -->
@endhasPermission
Protect your routes with middleware:
// ->middleware('pm');
Route::get('/admin', [AdminController::class, 'index'])
->middleware('pm:role:admin|manager');
Route::get('/posts', [PostController::class, 'create'])
->middleware('pm:permission:posts|post.create');
The package provides several Artisan commands for managing roles and permissions:
# List all roles
php artisan roles:list
# List all permissions
php artisan permissions:list
# Create a new role
php artisan role:create admin "Administrator" "Has full system access"
# Update a role
php artisan role:update admin --name="Super Admin" --description="Updated description"
# Delete a role
php artisan role:delete admin
# Create permissions
php artisan permission:create "users.*"
php artisan permission:create "users.create,users.edit"
# Delete permissions
php artisan permission:delete "users.edit"
php artisan permission:delete "users.create,users.edit"
# Sync routes with permissions table
php artisan permission:sync-routes
# Assign permissions to a role
php artisan role:assign-permission admin "users.*"
php artisan role:assign-permission admin "users.create,users.edit"
# Revoke permissions from a role
php artisan role:revoke-permission admin "users.edit"
# Export roles to a JSON file
php artisan role:export roles.json
# Import roles from a JSON file
php artisan role:import roles.json
# Assign roles to a user
php artisan user:assign-role 1 admin
php artisan user:assign-role 1 "admin,editor"
# Revoke roles from a user
php artisan user:revoke-role 1 admin
Use the facade for programmatic management:
use HosseinHezami\PermissionManager\Facades\PermissionManager;
// Get all roles
$roles = PermissionManager::roles()->list();
// Get all permissions
$permissions = PermissionManager::permissions()->list();
// Sync routes with permissions
PermissionManager::permissions()->sync();
// Create permissions
PermissionManager::permissions()->create('users.create');
PermissionManager::permissions()->create(['users.create', 'users.edit']);
// Delete permissions
PermissionManager::permissions()->delete('users.create');
PermissionManager::permissions()->delete(['users.create', 'users.edit']);
// Create a role
PermissionManager::roles()->create([
'slug' => 'admin',
'name' => 'Administrator',
'description' => 'Has full system access'
]);
// Role operations
PermissionManager::role('admin')->assignPermission('users.edit');
PermissionManager::role('admin')->revokePermission('users.edit');
PermissionManager::role('admin')->update(['name' => 'Super Admin']);
PermissionManager::role('admin')->delete();
// User operations
PermissionManager::user($userId)->assignRole(['admin', 'editor']);
PermissionManager::user($userId)->revokeRole('admin');
$roles = PermissionManager::user($userId)->roles();
$permissions = PermissionManager::user($userId)->permissions();
$hasRole = PermissionManager::user($userId)->hasRole('admin');
$hasPermission = PermissionManager::user($userId)->hasPermission('users.edit');
The package supports wildcard permissions for flexible route matching:
// Match all routes starting with 'admin'
'admin.*'
// Match all routes ending with '.admin'
'*.admin'
// Match all routes containing 'admin'
'*admin*'
The PermissionTrait trait adds these methods to your User model:
// Get all roles
$user->roles;
// Get all permissions (including through roles)
$user->permissions();
// Assign a role
$user->assignRole('admin');
// Revoke a role
$user->revokeRole('admin');
// Check if user has a role
$user->hasRole('admin');
// Check if user has a permission
$user->hasPermission('users.edit');
The package includes custom exceptions for better error handling:
PermissionAlreadyExistsPermissionDoesNotExistRoleAlreadyExistsRoleDoesNotExistUnauthorizedExceptionPlease see CONTRIBUTING for details.
The MIT License (MIT). Please see License File for more information.
If you have any questions or issues, please email hossein.hezami@gmail.com instead of using the issue tracker.