Hi Andrei,
Personally I think the cleanest way would be inside the Controller. The setup() method gets called anyway (think of it as a constructor of sorts) so you can place general logic there, and it'll get applied for all operations. So something like this should work:
public function setup() {
//...
if (!backpack_user()->can('articles.create') {
CRUD::denyAccess('create');
}
if (!backpack_user()->can('articles.update') {
CRUD::denyAccess('update');
}
}
In the example above I've used the can() from spatie/laravel-permission and denyAccess() from Backpack.
Because it's called in the setup method, it will prevent the user from accessing all methods that correspond to those operations (ex: for the Create operation, both create() and store()).
Alternatively, if you need to do this across multiple CrudControllers, I recommend creating a trait, and using that trait across all your CrudControllers. Something like:
trait LimitAccessAccordingToUserPermissions {
protected function denyAccessIfNoPermission() {
$user = backpack_user();
$permission = $this->crud->entity_name.'.'.$this->crud->getCurrentOperation();
if (! $user->can($permission)) {
$this->crud->denyAccess($this->crud->getCurrentOperation());
}
}
}
Then you'll be able to use LimitAccessAccordingToUserPermissions; in all CrudControllers where you need it, and call $this->denyAccessIfNoPermission() in the setup() method. It'll be a little cleaner.
Of course, there are other alternatives like replacing Route::crud('articles', 'ArticleCrudController'); with the actual routes that that loads (you can see them in the operation traits), in order to use a can:articles.list middleware, but personally I think that'll be even messier, the routes file will get bloated pretty fast.
Hope it helps!