-
Notifications
You must be signed in to change notification settings - Fork 2
2. Roles
Deadbolt doesn't have support for roles in the traditional sense. It does provide something called Permission Groups, which was our attempt a making roles simple, but they're not really the same as roles. If you want to use proper roles with Deadbolt, then you'll need to implement them yourself. However, doing so is actually easier than you might think.
There are two Deadbolt features that make this possible:
- you can manipulate and test the permissions on a collection of users at the same time,
- Deadbolt doesn't care what model you give it, as long as there is a
permissions
array available.
For this to work, you need to be using at least Deadbolt v0.3.
Here's a simple example of how this could be done:
Create a Role
model along with a migration table:
php ./artisan make:model Role -m
Update the create_roles_table
migration so that it includes a permissions
column. You'll assign permissions to the roles in your application instead of directly to your users.
Schema::create('roles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('description')->nullable();
$table->string('permissions')->nullable();
$table->timestamps();
});
You won't need a permissions
column on your users table as we'll be assigning permissions to the roles we create. Users will then have roles instead of permissions.
you'll also need to create a pivot table:
Schema::create('role_user', function (Blueprint $table) {
$table->unsignedBigInteger('role_id');
$table->unsignedBigInteger('user_id');
$table->foreign('role_id')->references('id')->on('roles');
$table->foreign('user_id')->references('id')->on('users');
});
Now update your Role
model and add the users
relationship method:
class Role
{
public function users()
{
return $this->belongsToMany(User::class);
}
}
Do the same on the User
model, adding the roles
relationship method:
class User
{
public function roles()
{
return $this->belongsToMany(Role::class);
}
}
Now when you need to add permissions to a role, Deadbolt can be used in the same way. Instead of passing in an instance of your User
model, you'll passing in a Role
instance. For example, lets create a Writer
role:
$role = Role::create([
'name' => 'writer',
'description' => 'Writer',
]);
Deadbolt::user($role)->give('articles.create', 'articles.create', 'articles.delete')->save();
Now you have a role named writer
that has three permissions. You can easily assign this role to your users:
$user->roles()->attach($role->id);
You really shouldn't test your users abilities by testing for roles. Rather, users should still have permissions. But in this example, your users don't actually have permissions directly. However, since Deadbolt doesn't require a user, and can manage permissions on any model, we can pass the roles collection from one of our users to the Deadbolt::users()
method (note that it's users
and not user
).
So In your policy class you can test if a user has a permission by first passing the roles collection from the user instead of the user itself, and then using the anyHave
method to check if any of the roles have the specified permission. Like this:
public function create(User $user)
{
return Deadbolt::users($user->roles)->anyHave('articles.create');
}
Deadbolt itself does not manage your roles, only the permissions on the roles. To give users abilities, you would need to assign roles to users yourself.