laravel-permission: [Bug? 4.3.0] Checking Permission via can() return PermissionDoesNotExists

Hi. First, thanks for this great packages. I’ve been using this packages since version 1.

I have user with Role ‘System Administrator’, and this roles has permission named ‘dashboard’, ‘logs’, etc. When I’m checking the user’s permission via can, it throws Spatie\Permission\Exceptions\PermissionDoesNotExist.

  • spatie/laravel-permission package version: 4.3.0
  • illuminate/framework package: v8.55.0

PHP version: 8.0.7 Database version: MySQL 8.0.25

This is not happening prior to version 4.3.0. We have traced this issue, and found that getPermissions on Spatie\Permission\PermissionRegistrar is the culprit here.

This is how we resolve this problem:

        $permissions = $this->permissions->$method(static function ($permission) use ($params) {
            foreach ($params as $attr => $value) {
                if ($permission->getAttribute($attr) == $value) {
                    return true;
                }
            }

            return false;
        });

I think the return value are swapped? If I swap the ‘true’ and ‘false’ value like above, it behaves normally, and I only get PermissionDoesNotExists exception only when I’m supplying it with wrong / invalid permission.

Thanks

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 35 (15 by maintainers)

Most upvoted comments

Hi @erikn69

Sorry for late reply. Found the problem, and it’s on our side. We are hiding the ‘guard_name’ in the extended model, so the permission cannot compare the guard_name with user’s guard. I’m sorry for taking your time for this, and thanks for the speedy response.

@syssi I’ve seen your code that you also extend the permission model. Maybe, just maybe, you hide the guard_name too?

@shadowbane Good catch! Indeed! We extended the permission model:

<?php

namespace App\Domains\UserManagement\Models;

use Spatie\Multitenancy\Models\Concerns\UsesLandlordConnection;

class Permission extends \Spatie\Permission\Models\Permission
{
    use UsesLandlordConnection;

    protected $visible = [
      'id', 
      'name',
    ];
}

This fixes the issue:

<?php

namespace App\Domains\UserManagement\Models;

use Spatie\Multitenancy\Models\Concerns\UsesLandlordConnection;

class Permission extends \Spatie\Permission\Models\Permission
{
    use UsesLandlordConnection;

    protected $visible = [
      'id', 
      'name',
      'guard_name',
    ];
}

Doesn’t help:

diff --git a/backend/database/seeders/RolesAndPermissionsSeeder.php b/backend/database/seeders/RolesAndPermissionsSeeder.php
index dda440db..5c010f5f 100644
--- a/backend/database/seeders/RolesAndPermissionsSeeder.php
+++ b/backend/database/seeders/RolesAndPermissionsSeeder.php
@@ -31,8 +31,11 @@ class RolesAndPermissionsSeeder extends Seeder
 
         foreach ($this->getPreparedRoles() as $roleName => $rolePermissions) {
             $role = Role::create(['name' => $roleName])->givePermissionTo($rolePermissions);
+            app()[PermissionRegistrar::class]->forgetCachedPermissions();
         }
 
+        app()[PermissionRegistrar::class]->forgetCachedPermissions();
+
         $this->generateConstFiles();
     }

The exception is the same at line 33.

I will provide the file later the day!

@syssi can you post your application code that is triggering the error?

Yeah, cleared the caches between every test. We will to check it thoroughly tomorrow.

Time: 00:00.205, Memory: 22.00 MB

OK (1 test, 3 assertions)

I’ve got same result on freshly cloned repo. Weird, in my other projects that also using this package, it also throwing the same error 😭

edit: other project behaves normally… I guess this bug is from our implementation…

Hi @erikn69

No, we’re using ‘backpack’ as the user’s default and only guard.