Policy to allow admins to edit models in the admin panel
I am using the following code inside the policy class for the Duel model to prevent users from editing the model unless they are the opponent. However I want admins to be able to edit the model inside the filament panel.
/**
* Determine whether the user can update the model.
*/
public function update(User $user, Duel $duel): bool
{
\Log::info("Filament Auth Check: " . Filament::auth()->check());
\Log::info("User is Admin: " . $user->hasRole('admin'));
if (Filament::auth()->check() && $user->hasRole('admin')) {
return true;
}
return $user->id === $duel->opponent->user->id;
}
After debugging my code I get the following output:
[2025-02-07 19:23:01] local.INFO: Filament Auth Check: 1
[2025-02-07 19:23:01] local.INFO: User is Admin: 1
I noticed Filament::auth()->check() is always returning true, even if the admin panel isn't being accessed.
I even tried this variation:
/**
* Determine whether the user can update the model.
*/
public function update(User $user, Duel $duel): bool
{
\Log::info("Filament Auth Check: " . Filament::auth()->check());
\Log::info("User is Admin: " . $user->hasRole('admin'));
if (Filament::auth()->check() && $user->hasRole('admin')) {
if (request()->routeIs('filament.resources.models.edit')) {
return true;
}
}
return $user->id === $duel->opponent->user->id;
}
The issue is the filament check code always return false and admins can't edit the model inside the admin panel.
I then tried simplifying my check but, nope that didn't work either.
public function update(User $user, Duel $duel): bool
{
\Log::info("User is admin: " . $user->hasRole('admin'));
\Log::info("Route: " . request()->route()->uri());
if (request()->routeIs('filament.resources.models.edit') && $user->hasRole('admin')) {
return true;
}
if ($user->id === $duel->opponent->user->id) {
return true;
}
return false;
}
Log:
[2025-02-09 22:18:39] local.INFO: User is admin: 1
[2025-02-09 22:18:39] local.INFO: Route: admin/duels
[2025-02-09 22:18:49] local.INFO: User is admin: 1
[2025-02-09 22:18:49] local.INFO: Route: admin/duels/{record}/edit
Hi,
It looks like Filament::auth()->check()
is always returning true because Filament maintains its own authentication state, even outside the admin panel. Instead, try using Filament::getCurrentPanel()
to check if the request is actually coming from Filament.
Update your policy to:
public function update(User $user, Duel $duel): bool
{
if (Filament::getCurrentPanel() && $user->hasRole('admin')) {
return true;
}
return $user->id === $duel->opponent->user->id;
}
Let me know if this helps!