I am working on a blogging application in Laravel 8.
The application gives the users rights by assigning them roles. Every role has a set of permissions. There is a many-to-many relationship between roles and permissions.
In the user-rights view, I output each user's permissions successfully:
@foreach ($user->role->permissions as $permission)
<span >{{ $permission->slug }}</span>
@endforeach
The goal
I am trying to restrict access to the Site settings section of the application, like this:
// Settings routes
Route::group(['prefix' => 'settings', 'middleware' => ['checkUserPermissions:edit-settings']], function() {
Route::get('/', [SettingsController::class, 'index'])->name('dashboard.settings');
});
For this purpose, I have created the checkUserPermissions middleware:
class CheckUserPermissions
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
// Permissions checker
public function hasPermissionTo($permission) {
return in_array($permission, Auth::user()->role->permissions->toArray());
}
public function handle(Request $request, Closure $next, ...$permissions)
{
// Check user permissions
foreach ($permissions as $permission) {
if (!$this->hasPermissionTo($permission)) {
$permission_label = join(' ', explode('-', $permission));
return redirect()->back()->with('error', 'You do not have permission to ' . $permission_label);
}
}
return $next($request);
}
}
The problem
Although the super admin does have the permission to edit settings, dd(in_array($permission, Auth::user()->role->permissions->toArray()))
returns false.
That means that the restriction(s) apply when they should not.
NOTE
dd(Auth::user()->role->permissions->toArray())
returns:
Questions
- What causes this bug?
- What is the easiest fix?
CodePudding user response:
In your custom middleware, you need to compare the permission to the slugs
return in_array($permission, Auth::user()->role->permissions()->pluck('slug')->toArray());