Central management of Laravel authorization with database and user roles for Laravel 5.1, 5.2, and 5.3., (*1)
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, (*2)
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., (*3)
Database tables will be installed to store abilities, user roles,
permissions, and custom condition/policy per each permission you give., (*4)
AuzoTools package is
required and will be installed, it provides several great tools
that facilitates Laravel authorize management., (*5)
What you can do with this package:
- Manage Abilities
- Manage Roles
- Manage Conditions/Policies
- Manage Permissions
- Generate abilities
Installation
You can install the package via composer:
``` bash
composer require kordy/auzo, (*6)
This service provider must be installed.
```php
// config/app.php
'providers' => [
...
Kordy\Auzo\AuzoServiceProvider::class,
Kordy\AuzoTools\AuzoToolsServiceProvider::class,
];
You can publish the migrations with:, (*7)
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:, (*8)
php artisan migrate
You can publish the config file with:, (*9)
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., (*10)
// App\User.php
class User extends ...
{
use ..., Kordy\Auzo\Traits\HasRoleTrait;
...
Customization
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., (*11)
config/auzo.php
contents:, (*12)
/*
/*
|--------------------------------------------------------------------------
| 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,
],
Usage
Abilities
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., (*13)
Manage abilities using AuzoAbility Facade:, (*14)
AuzoAbility::create([
'name' => 'ability.name',
'label' => 'Abiliy Label',
'tag' => 'ability.tag'
]);
Manage abilities using auzo:ability
artisan command:, (*15)
# create new ability
php artisan auzo:ability create 'ability.index' --label='Ability Index' --tag='ability'
# delete ability
php artisan auzo:ability delete 'ability.index'
Roles
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., (*16)
Manage roles using AuzoRole Facade:, (*17)
$role = AuzoRole::create([
'name' => 'testRole',
'description' => 'test role description'
]);
Manage roles using auzo:role
artisan command:, (*18)
# 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:, (*19)
// 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:, (*20)
# 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'
Policies
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., (*21)
example: grant a user permission if the user is the owner of the post., (*22)
// App\Post
public function owner($ability, $role, $user, $model) {
return $user->id == $model->usr_id;
}
see src/Services/AccessPolicies.php for more examples., (*23)
Manage policies through AuzoPolicy Facade:, (*24)
$policy = AuzoPolicy::create([
'name' => 'Post Owner',
'method' => 'App\Post@owner',
]);
Manage policies using auzo:policy
artisan command:, (*25)
# 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
Permissions
Give role a permission to an ability:, (*26)
// 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:, (*27)
$role->givePermissionTo($ability->name)
->addPolicy($policy1)
->addPolicy([$policy2->id => ['operator' => 'or']]);
Using auzo:permission
artisan command to manage permissions:, (*28)
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., (*29)
Generate abilities
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., (*30)
Through the GeneratAbilitiesToDB class:, (*31)
$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, (*32)
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:, (*33)
[
[
'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',
],
....
Credits
- 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
Contributing
Please see CONTRIBUTING for details., (*34)
License
The MIT License (MIT). Please see License File for more information., (*35)