Central management of Laravel authorization with database and user roles for Laravel 5.1, 5.2, and 5.3.
Ever thought about a way to put a policy or condition on every permission as a restriction, something like: allow authenticated user to modify posts Only if he is the post author or Only if he is in the same group as the author or Only if the post is not published ... etc
Not like other roles based packages, this package fills this gap by restricting user's role permission with a condition/policy, as it follows Attribute-Based Access Controll (ABAC) approach as Laravel authorize does.
Database tables will be installed to store abilities, user roles, permissions, and custom condition/policy per each permission you give.
AuzoTools package is required and will be installed, it provides several great tools that facilitates Laravel authorize management.
You can install the package via composer:
composer require kordy/auzo
This service provider must be installed.
// config/app.php
'providers' => [
...
Kordy\Auzo\AuzoServiceProvider::class,
Kordy\AuzoTools\AuzoToolsServiceProvider::class,
];
You can publish the migrations with:
php artisan vendor:publish --provider="Kordy\Auzo\AuzoServiceProvider" --tag="migrations"
After the migration has been published you can create the role- and permission-tables by running the migrations:
php artisan migrate
You can publish the config file with:
php artisan vendor:publish --provider="Kordy\Auzo\AuzoServiceProvider" --tag="config"
Finally, you have to add the HasRoleTrait
trait to the user's model where you want to assign roles to them.
// App\User.php
class User extends ...
{
use ..., Kordy\Auzo\Traits\HasRoleTrait;
...
You can replace or extend any model of the package through the configuration file, create your own class, use the model trait, modify any function, and just add the new class path in the config/auzo.php file.
config/auzo.php
contents:
/*
/*
|--------------------------------------------------------------------------
| Auzo Authorize Registrar
|--------------------------------------------------------------------------
|
| You may here add custom registrar where the Laravel Gate abilities are defined
|
*/
'registrar' => \Kordy\Auzo\Services\PermissionRegistrar::class,
/*
|--------------------------------------------------------------------------
| Auzo models paths
|--------------------------------------------------------------------------
|
| You may here add custom models paths to be used instead of models included
| with the package
|
*/
'models' => [
'user' => $user_model,
'ability' => \Kordy\Auzo\Models\Ability::class,
'policy' => \Kordy\Auzo\Models\Policy::class,
'permission' => \Kordy\Auzo\Models\Permission::class,
'role' => \Kordy\Auzo\Models\Role::class,
],
By default Laravel authorize abilities are defined statically through the service provider, this package gives more flexibility by creating them in the database and automatically defines them.
Manage abilities using AuzoAbility Facade:
AuzoAbility::create([
'name' => 'ability.name',
'label' => 'Abiliy Label',
'tag' => 'ability.tag'
]);
Manage abilities using auzo:ability
artisan command:
# create new ability
php artisan auzo:ability create 'ability.index' --label='Ability Index' --tag='ability'
# delete ability
php artisan auzo:ability delete 'ability.index'
Auzo approaches Role Based Access Control (RBAC) methodology, All users get their permissions "only" through their role, that is for better usability and scalability, and to maintain solid and non-conflict polices from different roles, "only" single role is allowed per user.
Manage roles using AuzoRole Facade:
$role = AuzoRole::create([
'name' => 'testRole',
'description' => 'test role description'
]);
Manage roles using auzo:role
artisan command:
# create new role
php artisan auzo:role create 'testRole' --description='testing role'
# delete role
php artisan auzo:role delete 'testRole'
Assign role to a user using hasRole
trait relationship:
// by role instance
$user->assignRole($role);
// or by role id
$user->assignRole(2);
// or by role name
$user->assignRole('testRole');
Manage user role assignment using auzo:user
artisan command:
# assign role to users
php artisan auzo:user assign '1,2,3' 'SomeRole'
# revoke role from users
php artisan auzo:user revoke '1,2,3' 'SomeRole'
You can define custom conditions or as we name it here "policies", policy is a custom function (that you have created somewhere) which defines some conditions that have to be met before granting the permission to a user.
example: grant a user permission if the user is the owner of the post.
// App\Post
public function owner($ability, $role, $user, $model) {
return $user->id == $model->usr_id;
}
see src/Services/AccessPolicies.php for more examples.
Manage policies through AuzoPolicy Facade:
$policy = AuzoPolicy::create([
'name' => 'Post Owner',
'method' => 'App\Post@owner',
]);
Manage policies using auzo:policy
artisan command:
# create new policy
php artisan auzo:policy create --name='Test Policy' --method='Controller@policy'
# delete policy by id
php artisan auzo:policy delete --id=1
Give role a permission to an ability:
// by ability instance
$role->givePermissionTo($ability);
// or by ability id
$role->givePermissionTo(3);
// or by array of abilities ids
$role->givePermissionTo([1,3]);
// or by ability name
$role->givePermissionTo('ability.name');
// remove permission by passing ability name
$role->removePermissionTo('ability.name');
Give role a permission to an ability restricted by policy:
$role->givePermissionTo($ability->name)
->addPolicy($policy1)
->addPolicy([$policy2->id => ['operator' => 'or']]);
Using auzo:permission
artisan command to manage permissions:
php artisan auzo:permission give 'testRole' 'ability.test,ability.test2' --policies='1,2:||'
if multiple policies applied, a default "AND" is applied between policies, unless you specified an operator at the time of adding policies to the permission.
This will use GenerateAbilities
from AuzoTools
to generate all abilities (by default matching route source scheme) for a model
and its fields, and saves them to the database abilities table.
Through the GeneratAbilitiesToDB class:
$generator = new Kordy\Auzo\Services\GenerateAbilitiesToDB();
// generate only model CRUD abilities
$generator->modelAbilities($model)->saveModelToDB();
// generate only fields CRUD abilities
$generator->fieldsAbilities($model)->saveFieldsToDB();
// generate both model and fields CRUD abilities
$generator->fullCrudAbilities($model)->saveToDB();
Through the artisan command
php artisan auzo:ability generate 'App\Post'
# or to generate only model abilities
php artisan auzo:ability generate 'App\Post' --option=model
# or to generate only fields abilities
php artisan auzo:ability generate 'App\Post' --option=fields
This will generate and save all abilities below to abilities table:
[
[
'name' => 'post.index',
'tag' => 'post',
],
[
'name' => 'post.create',
'tag' => 'post',
],
[
'name' => 'post.store',
'tag' => 'post',
],
[
'name' => 'post.show',
'tag' => 'post',
],
[
'name' => 'post.edit',
'tag' => 'post',
],
[
'name' => 'post.update',
'tag' => 'post',
],
[
'name' => 'post.destroy',
'tag' => 'post',
],
[
'name' => 'post.index.id',
'tag' => 'post.index',
],
[
'name' => 'post.create.id',
'tag' => 'post.create',
],
[
'name' => 'post.store.id',
'tag' => 'post.store',
],
[
'name' => 'post.show.id',
'tag' => 'post.show',
],
[
'name' => 'post.edit.id',
'tag' => 'post.edit',
],
[
'name' => 'post.update.id',
'tag' => 'post.update',
],
[
'name' => 'post.destroy.id',
'tag' => 'post.destroy',
],
[
'name' => 'post.index.name',
'tag' => 'post.index',
],
[
'name' => 'post.create.name',
'tag' => 'post.create',
],
[
'name' => 'post.store.name',
'tag' => 'post.store',
],
....
- Based on laravel-permission package which is considered the best alternative for this package if you need multiple roles and direct permissions for users.
- A lot of help from my friend balping
Please see CONTRIBUTING for details.
The MIT License (MIT). Please see License File for more information.