spatie/laravel-permission

[v5/v6] permission cache not cleared when giving permission

lk77 opened this issue · 6 comments

lk77 commented

The permission cache is not cleared when giving permissions with givePermissionTo,
it's due to this check :

if (is_a($this, get_class(app(PermissionRegistrar::class)->getRoleClass()))) {
    $this->forgetCachedPermissions();
}

it's always false,

we can test this in tinker :

is_a(User::first(), get_class(app(Spatie\Permission\PermissionRegistrar::class)->getRoleClass()))
[!] Aliasing 'User' to 'App\Models\User' for this Tinker session.
= false

Versions

  • spatie/laravel-permission: 5.11.1
  • illuminate/framework: 10.29.0
  • php: 8.1.11
  • mariadb: 10.9.4

To Reproduce

Simply call givePermissionTo and see that the cache is not cleared

Expected behavior

The cache is correctly cleared when giving permissions

it's seems to me that v6 has the same type of issue, the code has changed :

if (is_a($this, Role::class)) {
    $this->forgetCachedPermissions();
}

thanks.

is_a(User::first(), get_class(app(Spatie\Permission\PermissionRegistrar::class)->getRoleClass()))
[!] Aliasing 'User' to 'App\Models\User' for this Tinker session.
= false

It is not necessary to clear the cache when assigning permissions to an user, because this action does not change anything in the cache, the cache is only cleared when permissions are created/deleted/modified, or when permissions are assigned/removed to a role.

lk77 commented

@parallels999 it is, i have failing tests because of this issue, i had to manually clear the cache :

$user->givePermissionTo(['abc']);
app()->make(\Spatie\Permission\PermissionRegistrar::class)->forgetCachedPermissions();

i will try to dig deaper to understand why

It is an expected behavior, not an issue

$user->givePermissionTo(['abc']);
app()->make(\Spatie\Permission\PermissionRegistrar::class)->forgetCachedPermissions();

I don't see it necessary, you should do that in the seeder,

try this:

app()->make(\Spatie\Permission\PermissionRegistrar::class)->forgetCachedPermissions();
$user->givePermissionTo(['abc']);

It sure works the same

lk77 commented

There is an impact, because i can see the permissions of the user when calling getPermissions yet calling $user->can('mypermission') return false for some reason

Maybe

protected function getPackageProviders($app)

lk77 commented

the issue is solved now, and i cant reproduce it anymore, perhaps an issue with redis i don't know, but i could clearly call $user->getPermissionNames() and see my permissions while $user->can() was still returning false