evo-mark / evo-laravel-rbac
Role-Based Access Control for Laravel
Requires
Requires (Dev)
- orchestra/testbench: *
- pestphp/pest: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
README
<a href="https://packagist.org/packages/evo-mark/evo-laravel-rbac"><img src="https://img.shields.io/packagist/dt/evo-mark/evo-laravel-rbac" alt="Total Downloads"></a>
<a href="https://packagist.org/packages/evo-mark/evo-laravel-rbac"><img src="https://img.shields.io/packagist/l/evo-mark/evo-laravel-rbac" alt="License"></a>
Evo Laravel RBAC
Built on top of Spatie's Laravel Permission package and forked from Binary Cats' Laravel RBAC package, Evo Laravel RBAC (Role-Based Access Control) is an easy solution for keeping all of your roles and permissions up-to-date without grappling with hundreds of seeders. Simply declare your roles, and which permissions belong to that role and Evo Laravel RBAC will handle the rest.
Installation
You can install the package via composer:
composer require evo-mark/evo-laravel-rbac
Publishing
You can publish the config file with:
php artisan vendor:publish --tag="rbac-config"
This is the contents of the published config file:
return [
/*
|--------------------------------------------------------------------------
| Role base access reset control
|--------------------------------------------------------------------------
|
| When running rbac:reset those commands will be executed in sequence
|
*/
'jobs' => [
\EvoMark\EvoLaravelRbac\Jobs\FlushPermissionCache::class,
\EvoMark\EvoLaravelRbac\Jobs\ResetPermissions::class,
\EvoMark\EvoLaravelRbac\Jobs\SyncDefinedRoles::class,
],
/*
|--------------------------------------------------------------------------
| Role base access ability set
|--------------------------------------------------------------------------
|
| Place your ability files in this folder, and they will be auto discovered
|
*/
'abilities_path' => app()->path('Authorisation/Abilities'),
/*
|--------------------------------------------------------------------------
| Roles
|--------------------------------------------------------------------------
|
| Roles are immutable by users. Any roles in here will be auto-discovered
|
*/
'roles_path' => app()->path('Authorisation/Roles'),
];
You can publish the stub files with:
php artisan vendor:publish --tag="rbac-stubs"
Usage
php artisan rbac:reset
In a simple setup we usually have two basic parts of an RBAC: a permission and a role. Permissions are usually grouped by functional or business logic domain and a Role encapsulates them for a specific guard.
Abilities
To avoid collision with spatie/laravel-permission we are going to use BackedEnum Ability enums to hold out enumerated permissions:
You can read more on using enums as permissions at the official docs.
To create an Ability:
php artisan make:ability PostAbility
This will generate a PostAbility in App\Authorisation\Abilities:
namespace App\Authorisation\Abilities;
enum PostAbility: string
{
case ViewPost = 'view post';
case CreatePost = 'create post';
case UpdatePost = 'update post';
case DeletePost = 'delete post';
}
Default stub contains fairly standard CRUD enumeration, generated using the name of the ability. Feel free to publish the stubs and adjust as needed.
Ability Guards
By default, abilities will be assigned to your default auth guard as well as any additional role guards that use them.
If you wish, you can override this either at the Ability enum class level, or by the individual permission:
namespace App\Authorisation\Abilities;
use EvoMark\EvoLaravelRbac\Attributes\Guards;
#[Guards('admin')]
enum PostAbility: string
{
// Permission created only against 'admin' guard
case ViewPost = 'view post';
// Permission created only against 'admin' guard
case CreatePost = 'create post';
// Permission created only against 'admin' guard
case UpdatePost = 'update post';
// Permission created against 'admin' and 'web' guards
#[Guards(['admin', 'web'])]
case DeletePost = 'delete post';
}
Roles
A Role offers a mechanism to simplify the definition of all permissions needed for a given role.
To create an EditorRole run:
php artisan make:role EditorRole
This will generate an EditorRole within App\Authorisation\Roles:
use EvoMark\EvoLaravelRbac\Role;
class EditorRole extends Role
{
/** @var array|string[] */
protected array $guards = [
'web'
];
/**
* List of enumerated permissions for the `web` guard
*
* @return array
*/
public function web(): array
{
return [];
}
}
This class contains a (now testable!) configuration definition for the role and its web guard. Pretty neat!
We can now adjust it like so:
namespace App\Authorisation\Roles;
use App\Authorisation\Abilities\PostAbility;
use EvoMark\EvoLaravelRbac\Role;
class EditorRole extends Role
{
/** @var array|string[] */
protected array $guards = [
'web'
];
/**
* List of enumerated permissions for the `web` guard
*
* @return array
*/
public function web(): array
{
return [
PostAbility::CreatePost,
PostAbility::UpdatePost,
PostAbility::ViewPost,
];
}
}
Now you are confident a specific role has specific permissions!
Super Admins
A super-admin is a special type of role which automatically grants a user all available permissions in an application.
Based on the Spatie example, this package provides an attribute which can be added to any role to make it a super-admin role.
namespace App\Authorisation\Roles;
use EvoMark\EvoLaravelRbac\Role;
use EvoMark\EvoLaravelRbac\Attributes\SuperAdmin;
#[SuperAdmin()]
class GodRole extends Role
{
// ...
}
You don't need to fill in any abilities for a super-admin, they automatically pass all checks.
Application Integration
We suggest adding the script to post-autoload-dump of your composer.json to make sure the RBAC is reset on every composer dump:
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan rbac:reset"
],
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Security
If you discover any security related issues, please email github@evomark.co.uk instead of using issue tracker.
Credits
License
The Apache-2.0 Licence. Please see Licence File for more information.