lky
lky

Reputation: 1129

Laravel - Issues setting up Spatie Permissons - Roles Relationship Returns NULL

I have a laravel application that current has two sql db connections, the default 'mysql' connection and another 'master' connection.

The default contains data for the application where the master connection contains the users, roles and permisson.

I can confirm that the users are assigned to roles as the master connection is currently used for another application where the roles and permissions are assigned.

I am attempting to create an admin login, which would authenicate users from the master connection. I've created a serpate auth guard and middleware for this. However I need to only let certain user roles login.

I have updated my login POST so that it

if (!$user->hasAnyRole(['administrator', 'manager', 'senior_manager', 'operations_manager', 'head_office_operations', 'hr'])) {
   throw new \Exception('Invalid user role');
}

The issue that I am having is that the hasAnyRole() method just returns an empty collection. Although there is definitely roles assigned.

My User Model:

<?php

namespace App\Models\Master;

use App\Traits\Encryptable;
use Spatie\Permission\Traits\HasRoles;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\SoftDeletes;

class User extends Authenticatable
{
    use Encryptable, HasRoles, HasFactory, Notifiable, SoftDeletes;

    protected $connection = 'app_master';
    protected $table = 'users';

   [...]

}

I have created a Role and Permisson Model that both extend the relevant spatie model:

class Role extends \Spatie\Permission\Models\Role

class Permission extends \Spatie\Permission\Models\Permission

And included:

protected $connection = 'app_master';
protected $table = 'permissions';

etc..

Updated permission.php configuration to:

<?php

return [

    'models' => [

        /*
         * When using the "HasPermissions" trait from this package, we need to know which
         * Eloquent model should be used to retrieve your permissions. Of course, it
         * is often just the "Permission" model but you may use whatever you like.
         *
         * The model you want to use as a Permission model needs to implement the
         * `Spatie\Permission\Contracts\Permission` contract.
         */

//        'permission' => Spatie\Permission\Models\Permission::class,
        'permission' => App\Models\Master\Permission::class,

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * Eloquent model should be used to retrieve your roles. Of course, it
         * is often just the "Role" model but you may use whatever you like.
         *
         * The model you want to use as a Role model needs to implement the
         * `Spatie\Permission\Contracts\Role` contract.
         */

//        'role' => Spatie\Permission\Models\Role::class,
        'role' => App\Models\Master\Role::class,

    ],

    'table_names' => [

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * table should be used to retrieve your roles. We have chosen a basic
         * default value but you may easily change it to any table you like.
         */

        'roles' => 'roles',

        /*
         * When using the "HasPermissions" trait from this package, we need to know which
         * table should be used to retrieve your permissions. We have chosen a basic
         * default value but you may easily change it to any table you like.
         */

        'permissions' => 'permissions',

        /*
         * When using the "HasPermissions" trait from this package, we need to know which
         * table should be used to retrieve your models permissions. We have chosen a
         * basic default value but you may easily change it to any table you like.
         */

        'model_has_permissions' => 'model_has_permissions',

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * table should be used to retrieve your models roles. We have chosen a
         * basic default value but you may easily change it to any table you like.
         */

        'model_has_roles' => 'model_has_roles',

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * table should be used to retrieve your roles permissions. We have chosen a
         * basic default value but you may easily change it to any table you like.
         */

        'role_has_permissions' => 'role_has_permissions',
    ],

    'column_names' => [

        /*
         * Change this if you want to name the related model primary key other than
         * `model_id`.
         *
         * For example, this would be nice if your primary keys are all UUIDs. In
         * that case, name this `model_uuid`.
         */

        'model_morph_key' => 'model_id',
    ],

    /*
     * When set to true, the required permission names are added to the exception
     * message. This could be considered an information leak in some contexts, so
     * the default setting is false here for optimum safety.
     */

    'display_permission_in_exception' => false,

    /*
     * When set to true, the required role names are added to the exception
     * message. This could be considered an information leak in some contexts, so
     * the default setting is false here for optimum safety.
     */

    'display_role_in_exception' => false,

    /*
     * By default wildcard permission lookups are disabled.
     */

    'enable_wildcard_permission' => false,

    'cache' => [

        /*
         * By default all permissions are cached for 24 hours to speed up performance.
         * When permissions or roles are updated the cache is flushed automatically.
         */

        'expiration_time' => \DateInterval::createFromDateString('24 hours'),

        /*
         * The cache key used to store all permissions.
         */

        'key' => 'spatie.permission.cache',

        /*
         * When checking for a permission against a model by passing a Permission
         * instance to the check, this key determines what attribute on the
         * Permissions model is used to cache against.
         *
         * Ideally, this should match your preferred way of checking permissions, eg:
         * `$user->can('view-posts')` would be 'name'.
         */

        'model_key' => 'name',

        /*
         * You may optionally indicate a specific cache driver to use for permission and
         * role caching using any of the `store` drivers listed in the cache.php config
         * file. Using 'default' here means to use the `default` set in cache.php.
         */

        'store' => 'default',
    ],
];

I've tried updating the model and updating the tables to 'roles' => 'app_master.roles' to try reference the table name but it doesn't seem to set up the relationship correct from the HasRoles Trait?

Same issue when using default permisson.php configuration.

What am I doing wrong to be able to get the relationship to work correctly and return back the correct user roles and permissons that are defined in the master connection??

Any help would be much appreciated.

Upvotes: 0

Views: 2045

Answers (1)

Charlie
Charlie

Reputation: 427

Try to reset permission cache after you add role to user.

Command: php artisan permission:cache-reset.

Not sure which spatie version you are using and how you add roles, but if you are not using spatie supplied methods to add role or spatie lower than v4.4.0, spatie won't auto rebuild permission cache, it might cause the issue.

Upvotes: 0

Related Questions