Home > Enterprise >  Laravel Spatie permissions how to define set of permission for each user based upon role?
Laravel Spatie permissions how to define set of permission for each user based upon role?

Time:10-24

I have 4 types of users using my system, 1. superadmin 2. superadmin team, 3. admin and 4th. admin team members, as I'm using spatie for roles and permissions, I have set of modules (permissions)which are common for all types of users and there is other set of modules(permissions) which is only for superadmin like payment methods etc. Now, once seeding my database for permission should I have have to seed all once? ['contacts','email','bids'] with web guard (however I'm bit confuse about exact usage of guards and how it works), so admin can assign permissions to his team only from these allowed permissions however, for superadmin should I create other set of permission with superadmin guard? I would like to know what's best practice. Use Case: Superadmin firstly login to the system and will decide which permission should have to be given to admin from his list. 2. Admin login to the system and will assign which set of permission will be given to his team but admin won't be able to see list of permissions which superadmin have. I hope I would have cleared my point please let me know appropriate way for its implementation.

CodePudding user response:

I suppose you are using one model i.e. User and assign permissions directly to users. Here is my approach So, what you can do is, you can first create a role and give appropriate permission to a role and then assign that role to a user.

First, Assign permissions to a role

$role->syncPermissions(['permission-1', 'permission-2', '...']);

Now, sync the role with a user

$user->assignRole('writer');

// Or, you can also assign multiple roles
$user->assignRole('writer', 'admin');

These are the built-in spatie middleware you can write in app/Http/Kernel.php

protected $routeMiddleware = [
    // ...
    'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
    'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
    'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class,
];

Now, you can use the 'role' middleware in the routes to protect like,

// for superadmin
Route::group(['middleware' => ['role:superadmin']], function () {
    //
});

// for admin
Route::group(['middleware' => ['role:admin']], function () {
    //
});

// Or with multiple roles
Route::group(['middleware' => ['role:superadmin|admin']], function () 
{
    //
});

...

So, now you need to get permissions for a specific role i.e. superadmin or admin. Here is what you can do,

// get all permissions associated with a role
$role->permissions;

// get specific columns of permissions
$role->permissions->pluck('name');

Also, you can get user roles in this way

auth()->user()->roles;

// Or get only role names
auth()->user()->getRoleNames();

// Or check if user has a specific role
auth()->user()->hasRole('admin')

One More Thing, for superadmin you don't need to get permissions from the role you can get all the permissions directly. And because the superadmin can have access to the whole system then you can bypass the permissions check for the superadmin by doing this,

use Illuminate\Support\Facades\Gate;

class AuthServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $this->registerPolicies();

        // Implicitly grant "Super Admin" role all permissions
        // This works in the app by using gate-related functions like 
        // auth()->user->can() and @can()
        Gate::before(function ($user, $ability) {
            return $user->hasRole('superadmin') ? true : null;
        });
    }
}

I hope it may help you :)

  • Related