Skip to content
This repository has been archived by the owner on Feb 3, 2024. It is now read-only.
/ laravel-roles Public archive

Permissions and roles for Laravel

License

Notifications You must be signed in to change notification settings

Kerigard/laravel-roles

Repository files navigation

Laravel Roles

Build Status Total Downloads Latest Stable Version License

Permissions and roles for Laravel 9.20 and up.

Installation

Install package via composer:

composer require kerigard/laravel-roles

Publish the configuration and migration files using the vendor:publish artisan command:

php artisan vendor:publish --provider="Kerigard\LaravelRoles\RolesServiceProvider"

Customize the roles.php configuration file according to your requirements. After that run the migrations:

php artisan migrate

Usage

Connecting traits

To start using permission and role checking, your User model must use the Kerigard\LaravelRoles\Traits\HasRoles and Kerigard\LaravelRoles\Traits\HasPermissions traits:

use Kerigard\LaravelRoles\Traits\HasPermissions;
use Kerigard\LaravelRoles\Traits\HasRoles;

class User extends Authenticatable
{
    use HasPermissions;
    use HasRoles;
}

It is not necessary to connect both traits at the same time.

Creating roles and permissions

Create roles and permissions, after which create a relationship between them:

use Kerigard\LaravelRoles\Models\Permission;
use Kerigard\LaravelRoles\Models\Role;

$role = Role::create(['name' => 'Manager', 'slug' => 'manager']);
$permission = Permission::create(['name' => 'Edit articles', 'slug' => 'edit-articles']);
$role->attachPermission($permission);

You can override models through a config file.

Connect a role or permission to a user:

$user->attachRole(1);
$user->attachRole($adminRole);
$user->attachRole('super-admin');
$user->attachRole([1, $adminRole, 'manager']);

$user->attachPermission(1);
$user->attachPermission($editPostsPermission);
$user->attachPermission('edit-articles');
$user->attachPermission([1, $editPostsPermission, 'edit-articles']);

You can disable a role or permission for a user:

$user->detachRole(1);
$user->detachRole($adminRole);
$user->detachRole('super-admin');
$user->detachRole([1, $adminRole, 'manager']);
$user->detachAllRoles();

$user->detachPermission(1);
$user->detachPermission($editPostsPermission);
$user->detachPermission('edit-articles');
$user->detachPermission([1, $editPostsPermission, 'edit-articles']);
$user->detachAllPermissions();

Or just sync the specified roles or permissions. Any roles or permissions that are not listed will be disabled:

$user->syncRoles(1);
$user->syncRoles($adminRole);
$user->syncRoles('super-admin');
$user->syncRoles([1, $adminRole, 'manager']);

$user->syncPermissions(1);
$user->syncPermissions($editPostsPermission);
$user->syncPermissions('edit-articles');
$user->syncPermissions([1, $editPostsPermission, 'edit-articles']);

Use this method if you don't want old roles or permissions to be disabled when syncing:

$user->syncRolesWithoutDetaching($role);
$user->syncPermissionsWithoutDetaching($permission);

Permissions check

To check for permission, run:

$user->hasPermission('edit-articles');
$user->hasPermission(1);
$user->hasPermission($permission);

// has all permissions
$user->hasPermission(['edit-articles', 'register-articles']);
// has any permissions
$user->hasAnyPermission(['edit-articles', 'register-articles']);

$user->doesNotHasPermission($permission);
$user->doesNotHasAnyPermission(['edit-articles', 'register-articles']);

// or check that the role contains the permission
$role->hasPermission('edit-articles');

All permissions are registered with Laravel Gates, so you can use the can function:

$user->can('edit-articles');
$user->can(['edit-articles', 'register-articles']);
$user->canAny(['edit-articles', 'register-articles']);

In a controller, you can use the authorize function to throw an exception if the user doesn't have permissions:

class PostController extends Controller
{
    public function index()
    {
        $this->authorize('view-posts');

        return Post::all();
    }
}

Roles check

To check if a role exists, run:

$user->hasRole('manager');
$user->hasRole(1);
$user->hasRole($role);

// has all roles
$user->hasRole(['manager', 'admin']);
// kas any roles
$user->hasAnyRole(['manager', 'admin']);

$user->doesNotHasRole($role);
$user->doesNotHasAnyRole(['manager', 'admin']);

If you want to check the role in the controller and raise an exception if it is missing, then you need to replace the trait import in the app\Http\Controllers\Controller.php file:

// from
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
// to
use Kerigard\LaravelRoles\Traits\AuthorizesRequests;

After that, you can use the authorizeRole function in all controllers to check the role:

class PostController extends Controller
{
    public function index()
    {
        $this->authorizeRole('editor');

        return Post::all();
    }
}

Blade directives

You can use directives in blade files to write conditions conveniently:

@can('edit-articles')
    //
@endcan

@canany(['edit-articles', 'register-articles'])
    //
@endcanany

@is('manager')
    //
@endis

@isany(['manager', 'admin'])
    //
@endisany

Middlewares

In the app/Http/Kernel.php file, you can specify a middleware for checking roles and permissions:

protected $routeMiddleware = [
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'is' => \Kerigard\LaravelRoles\Middlewares\AuthorizeRole::class,
];

Then you can secure your routes:

Route::put('users', [UserController::class, 'update'])->middleware('can:edit-users');
// or
Route::put('users', [UserController::class, 'update'])->can('edit-users');

Route::get('users', [UserController::class, 'index'])->middleware('is:admin');
// or
Route::get('users', [UserController::class, 'index'])->is('admin');

Custom statuses

When throwing exceptions by default, Laravel returns a 403 error code with the message This action is unauthorized. You can specify your own error codes and messages for each role and permission:

Role::create([
    'name' => 'Admin',
    'slug' => 'admin',
    'status' => 404,
    'message' => 'Not found',
]);
Permission::create([
    'name' => 'Edit users',
    'slug' => 'edit-users',
    'status' => 404,
    'message' => 'Not found',
]);

Super admin

In the configuration, you can enable the super admin role. For users with this role, all permissions and role checks will be true.

Changelog

Please see the CHANGELOG for more information on what has changed recently.

License

MIT. Please see the LICENSE FILE for more information.