Resource policies / can

The filament base resource has the static can method, which looks like:
public static function can(string $action, ?Model $record = null): bool
{
if (static::shouldIgnorePolicies()) {
return true;
}

$policy = Gate::getPolicyFor($model = static::getModel());
$user = Filament::auth()->user();

if ($policy === null) {
return true;
}

if (! method_exists($policy, $action)) {
return true;
}

return Gate::forUser($user)->check($action, $record ?? $model);
}
public static function can(string $action, ?Model $record = null): bool
{
if (static::shouldIgnorePolicies()) {
return true;
}

$policy = Gate::getPolicyFor($model = static::getModel());
$user = Filament::auth()->user();

if ($policy === null) {
return true;
}

if (! method_exists($policy, $action)) {
return true;
}

return Gate::forUser($user)->check($action, $record ?? $model);
}
I don't get the point from the last row. When already having the $policy and making sure, there is a method $action, why not just
return $policy->$action($user, $record ?? $model)
return $policy->$action($user, $record ?? $model)
or what is the difference? In my current case, "my" line returns true, while Gate::forUser($user)->check($action, $record ?? $model) returns false. Is it possible, that it ignores the used guard?
13 Replies
Dan Harrin
Dan Harrin2y ago
because the gate allows policy overrides etc wdym by "ignores the used guard" i think its bad practice to call policy methods directly when theres a Laravel method to do it for us
bernhard
bernhardOP2y ago
Thanks for explanation, But then I don't get it, why my user doesn't have access to my resource. This is the Policy:
class ArticlePolicy
{
use HandlesAuthorization;

/**
* Determine whether the user can view any models.
*
* @param \App\Models\User $user
* @return \Illuminate\Auth\Access\Response|bool
*/
public function viewAny(User $user)
{
return $user->can('view_any_article');
}
...
class ArticlePolicy
{
use HandlesAuthorization;

/**
* Determine whether the user can view any models.
*
* @param \App\Models\User $user
* @return \Illuminate\Auth\Access\Response|bool
*/
public function viewAny(User $user)
{
return $user->can('view_any_article');
}
...
to test it, I tried it (directly in the canmethod of the resource class):
dd(
$policy->$action($user, $record ?? $model),
Gate::forUser($user)->check($action, $record ?? $model)
);
dd(
$policy->$action($user, $record ?? $model),
Gate::forUser($user)->check($action, $record ?? $model)
);
first returns true, second false
Dan Harrin
Dan Harrin2y ago
is your policy registered?
bernhard
bernhardOP2y ago
protected $policies = [
Article::class => ArticlePolicy::class
];
protected $policies = [
Article::class => ArticlePolicy::class
];
Inside AuthSeriveProvider
Dan Harrin
Dan Harrin2y ago
not sure then but it must be a laravel issue, right? you should debug inside the check() method in /vendor
bernhard
bernhardOP2y ago
yeah, I tried that already:
public function check($abilities, $arguments = [])
{
return collect($abilities)->every(
fn ($ability) => dump($ability, $arguments) && $this->inspect($ability, $arguments)->allowed()
);
}
public function check($abilities, $arguments = [])
{
return collect($abilities)->every(
fn ($ability) => dump($ability, $arguments) && $this->inspect($ability, $arguments)->allowed()
);
}
but I understand, that you cant give "support" for such issues. Just thought it is a stupid mistake from myself 😄
Dan Harrin
Dan Harrin2y ago
whats use_filament
bernhard
bernhardOP2y ago
a permission I check inside public function canAccessFilament(): bool but this is ok, its true
Dan Harrin
Dan Harrin2y ago
if you just return true from viewAny directly what happens
bernhard
bernhardOP2y ago
which viewAny?
Dan Harrin
Dan Harrin2y ago
the one that calls the other gate method in your policy
bernhard
bernhardOP2y ago
it looks like it is never called, dd in the ArticlePolicy doesn't get printed To resolve the mystery: I am once again stupid. I had this in my AuthServiceProvider:
Gate::before(function ($user, $ability) {
return $user->isRoot();
});
Gate::before(function ($user, $ability) {
return $user->isRoot();
});
And since this is (for this user) alway false,..... Thanks for your time
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Want results from more Discord servers?
Add your server