Search by

alifcoder / permissions

alifcoder

A simple role and permission management package for Laravel.

Package info

github.com/alifcoder/permission

pkg:composer/alifcoder/permissions

Statistics

Installs: 268

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.1.1 2026-09-25 07:26 UTC

This package is auto-updated.

Last update: 2026-09-25 07:26:44 UTC


README

A simple, flexible role and permission management system for Laravel applications โ€” designed to support Gate::before, SUPER ADMIN logic, modular apps (nwidart/laravel-modules), and dynamic user model resolution.

โœจ Features

  • Role and permission management with pivot tables
  • SUPER ADMIN bypass support using Gate::before()
  • HasRolesTrait trait for easy user integration
  • Every role and permission check is answered from memory โ€” one query per user, per request
  • Automatic cache invalidation on every role/permission change
  • Dynamically configurable role and permission models (UUID or auto-increment keys)
  • Language file localization (EN, customizable)
  • Clean service provider with publishable config and migrations
  • Works with modular Laravel apps (like nwidart/laravel-modules)

๐Ÿ“ฆ Requirements

  • PHP >=8.2
  • Laravel ^11.0 || ^12.0 || ^13.0

๐Ÿš€ Installation

composer require alifcoder/permissions

Then publish the config, translations, and migrations:

php artisan vendor:publish --tag=permissions
php artisan migrate

This will publish:

  • lang/vendor/permissions
  • config/permission.php
  • database/migrations/xxxx_xx_xx_xxxxxx_create_permissions_table.php

โš™๏ธ Configuration

Inside config/permissions.php:

return [
    'models'        => [
        'role'       => \Alif\Permissions\Models\Role::class,
        'permission' => \Alif\Permissions\Models\Permission::class,
    ],

    // cache the roles and permissions of every user
    'cacheable'     => true,

    // cache store used by the package (null = default store)
    'cache_store'   => null,

    // lifetime in seconds of a cached entry (null = forever)
    'cache_ttl'     => null,

    // set to false when your primary keys are auto-incrementing integers
    'is_model_uuid' => true,

];

You can override the role and permission models here.

โš ๏ธ Caching requires a cache store that supports tags (redis, memcached, array). When the store is not taggable the package keeps working, it simply reads from the database.

๐Ÿงฌ Traits

In your User model, add the trait:

use Alif\Permissions\Traits\HasRolesTrait;

class User extends Authenticatable
{
    use HasRolesTrait;
}

๐Ÿ” Super Admin Access

Add this in your app (e.g., AuthServiceProvider) โ€” or it's auto-registered by the package:

Gate::before(function ($user) {
    // $user is null on guest checks
    return $user !== null && $user->isSuperAdmin() ? true : null;
});

This lets SUPER ADMIN users bypass all policy/gate checks, and the role / permission middleware.

๐Ÿง  Usage

Assign Roles & Permissions

$admin = Role::create(['name' => 'Admin', 's_code' => 'admin']);
$edit  = Permission::create(['name' => 'products.update']);

// role <-> permissions (these methods keep the cache in sync)
$admin->givePermissionTo($edit);           // model, id or name
$admin->syncPermissions(['products.update', 'products.read']);
$admin->revokePermissionTo('products.read');

// user <-> roles (these methods keep the cache in sync)
$user->assignRoles('admin');               // add, keeps the existing roles
$user->syncRoles([$admin, 'manager']);     // replace
$user->removeRole($admin->id);             // detach

Every method accepts a model, a primary key, a role name, a role s_code, or an array/collection of them.

โš ๏ธ $user->roles()->attach() / $role->permissions()->attach() bypass the package, so they leave a stale cache behind. Use the methods above, or call $user->forgetPermissionCache() / $role->forgetPermissionCache() yourself afterwards.

Check Roles & Permissions

$user->hasAllRoles('admin');                              // true
$user->hasAnyRole(['admin', 'manager']);                  // true
$user->hasAllPermissions(['products.update']);            // true
$user->hasAnyPermission('products.update');               // true
$user->isSuperAdmin();                                    // true or false

$user->roles;               // roles of the user, with their permissions (cached)
$user->permissions;         // unique permissions of all roles (cached)
$user->permissionNames();   // the same, as a plain array of names

All checks above are resolved in memory: the roles of a user are read once (from the cache when it is enabled, otherwise with a single query) and every following check reuses them.

Cache invalidation

The cache is dropped automatically when:

Change What is dropped
assignRoles(), syncRoles(), removeRole() the cache of that user
the user is deleted the cache of that user
givePermissionTo(), syncPermissions(), revokePermissionTo() the whole package cache
a role is updated, deleted or restored the whole package cache
a permission is updated or deleted the whole package cache

๐ŸŒ Localization

The package includes English (en) translations. To override or translate:

Then add resources/lang/vendor/permissions/{locale}/permissions.php.

๐Ÿง‘โ€๐Ÿ’ป Usage macro

Also you can use Route macro to check permissions and roles:

Route::put('/products/{product}', function () {
    // Your logic here
})->permission('products.update');

Route::put('/admin', function () {
    // Your logic here
})->role('admin');

// or the middleware aliases directly, an optional second argument selects the guard
Route::put('/admin', fn() => null)->middleware('role:admin|manager,web');

โš ๏ธ Several roles/permissions are checked with AND: role:admin|manager requires both roles.

๐Ÿงฉ Folder Structure

src/
โ”œโ”€โ”€ Models/
โ”‚   โ”œโ”€โ”€ Concerns/
โ”‚   โ”œโ”€โ”€ Role.php
โ”‚   โ””โ”€โ”€ Permission.php
โ”œโ”€โ”€ Traits/
โ”‚   โ””โ”€โ”€ HasRolesTrait.php
โ”œโ”€โ”€ Support/
โ”‚   โ””โ”€โ”€ PermissionCache.php
โ”œโ”€โ”€ Middleware/
โ”œโ”€โ”€ Macros/
โ”œโ”€โ”€ Exceptions/
โ”œโ”€โ”€ Helpers/
โ”œโ”€โ”€ Console/
โ”œโ”€โ”€ PermissionServiceProvider.php
config/
โ””โ”€โ”€ permissions.php
resources/
โ””โ”€โ”€ lang/en/permissions.php
database/
โ””โ”€โ”€ migrations/

๐Ÿงน Clear permission caches

Run this command to clear the permission cache:

php artisan permission:cache-clear

๐Ÿงน Uninstall (Clean Up)

Run this command before removing the package:

php artisan permission:uninstall

It rolls back the migration, deletes the published files and clears the cache. In production it asks for a confirmation, use --force to skip it.

๐Ÿงช Tests

composer install
composer test

The suite runs against orchestra/testbench with an in-memory SQLite database, and covers both UUID and auto-incrementing primary keys, the cache invalidation matrix, the middlewares and the console commands.

๐Ÿ“œ License

MIT ยฉ Shukhratjon Yuldashev

๐Ÿ™Œ Contributing

Pull requests and suggestions are welcome!