Skip to main content
  1. All Posts/

nova-permissions

Tools PHP

Laravel Nova Grouped Permissions (RBAC)



Add Permissions based authorization for your Nova installation via Role-Based Access Control (RBAC). Roles are defined in the database whereas Permissions are defined in the code base. It allows you to group your Permissions into Groups and attach it to Users.

Nova 4
v3.x

<= Nova 3
v2.x

If you like this package, show some love by starring the repo. 🙏
This package is inspired by SilvaniteBrandenburg as it has clear separation of concerns.

Roles are defined in the Database

and

Permissions are defined in the Codebase

As a result, you won’t see any Permissions resource. The Roles resource will get the permissions from the Gates defined in your code.

  • Laravel Nova Grouped Permissions (RBAC)

    • Installation
    • Permissions with Groups

    •   <li>
          <a rel="nofollow noopener" target="_blank" href="#usage">Usage</a></p> <ul dir="auto">
            <li>
              <a rel="nofollow noopener" target="_blank" href="#create-a-model-policy">Create a Model Policy</a>
            </li>
          </ul>
        </li>
        
        <li>
          <a rel="nofollow noopener" target="_blank" href="#customization">Customization</a></p> <ul dir="auto">
            <li>
              <a rel="nofollow noopener" target="_blank" href="#use-your-own-resources">Use your own Resources</a>
            </li>
          </ul>
        </li>
        
        <li>
          <a rel="nofollow noopener" target="_blank" href="#support">Support</a>
        </li>
        <li>
          <a rel="nofollow noopener" target="_blank" href="#credits">Credits</a>
        </li>
        <li>
          <a rel="nofollow noopener" target="_blank" href="#license">License</a>
        </li>
      </ul>
      

    Installation

    You can install the package in to a Laravel app that uses Nova via composer:

    composer require pktharindu/nova-permissions

    Publish the Configuration with the following command:

    php artisan vendor:publish --provider="PktharinduNovaPermissionsToolServiceProvider" --tag="config"

    Configuration file includes some dummy permissions for your refference. Feel free to remove them and add your own permissions.

    // in config/nova-permissions.php
    
    <?php
    
    return [
        /*
        |--------------------------------------------------------------------------
        | User model class
        |--------------------------------------------------------------------------
        */
    
        'user_model' => 'AppUser',
    
        /*
        |--------------------------------------------------------------------------
        | Nova User resource tool class
        |--------------------------------------------------------------------------
        */
    
        'user_resource' => 'AppNovaUser',
    
        /*
        |--------------------------------------------------------------------------
        | The group associated with the resource
        |--------------------------------------------------------------------------
        */
    
        'role_resource_group' => 'Other',
    
        /*
        |--------------------------------------------------------------------------
        | Database 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.
        */
    
        'table_names' => [
            'roles' => 'roles',
    
            'role_permission' => 'role_permission',
    
            'role_user' => 'role_user',
            
            'users' => 'users',
        ],
    
        /*
        |--------------------------------------------------------------------------
        | Application Permissions
        |--------------------------------------------------------------------------
        */
    
        'permissions' => [
            'view users' => [
                'display_name' => 'View users',
                'description'  => 'Can view users',
                'group'        => 'User',
            ],
    
            'create users' => [
                'display_name' => 'Create users',
                'description'  => 'Can create users',
                'group'        => 'User',
            ],
    
            // ...
        ],
    ];

    Publish the Migration with the following command:

    php artisan vendor:publish --provider="PktharinduNovaPermissionsToolServiceProvider" --tag="migrations"

    Migrate the Database:

    php artisan migrate

    Next up, you must register the tool with Nova. This is typically done in the tools method of the NovaServiceProvider.

    // in app/Providers/NovaServiceProvider.php
    
    public function tools()
    {
        return [
            // ...
            new PktharinduNovaPermissionsNovaPermissions(),
        ];
    }

    Create a new policy:

    php artisan make:policy RolePolicy --model=PktharinduNovaPermissionsRole

    After that, register the RolePolicy along with any other policies you may have and define the gates in the boot method of the AuthServiceProvider like below.

    // in app/Providers/AuthServiceProvider.php
    
    use IlluminateSupportFacadesGate;
    use PktharinduNovaPermissionsTraitsValidatesPermissions;
    use IlluminateFoundationSupportProvidersAuthServiceProvider as ServiceProvider;
    
    class AuthServiceProvider extends ServiceProvider
    {
        use ValidatesPermissions;
    
        protected $policies = [
            PktharinduNovaPermissionsRole::class => AppPoliciesRolePolicy::class,
        ];
    
        public function boot()
        {
            $this->registerPolicies();
    
            foreach (config('nova-permissions.permissions') as $key => $permissions) {
                Gate::define($key, function (User $user) use ($key) {
                    if ($this->nobodyHasAccess($key)) {
                        return true;
                    }
    
                    return $user->hasPermissionTo($key);
                });
            }
        }
    }

    Then, use HasRoles Traits in your User model.

    // in app/User.php
    
    use IlluminateNotificationsNotifiable;
    use PktharinduNovaPermissionsTraitsHasRoles;
    use IlluminateFoundationAuthUser as Authenticatable;
    
    class User extends Authenticatable
    {
        use HasRoles,
            Notifiable;
    
        // ...
    }

    Finally, add BelongsToMany fields to you app/Nova/User resource:

    use LaravelNovaFieldsBelongsToMany;
    
    public function fields(Request $request)
    {
        return [
            // ...
            BelongsToMany::make('Roles', 'roles', PktharinduNovaPermissionsNovaRole::class),
        ];
    }

    A new resource called Roles will appear in your Nova app after installing this package.

    Permissions with Groups

    Index View

    Detail View

    Edit View

    Usage

    Create a Model Policy

    To check permissions, you can create Model Policies that works with Laravel Nova.

    Note: This package doesn’t come with any Model Policies built-in. The dummy permissions defined in the config are for your reference only. For each Nova Resource including the Role and User resources, that you want to authorize user actions against, you need to create a Model Policy. Please refer to the Laravel Docs and Laravel Nova Docs for additional information.

    For Example: Create a new Post Policy with php artisan make:policy PostPolicy with the following code:

    <?php
    
    namespace AppPolicies;
    
    use AppPost;
    use AppUser;
    use IlluminateAuthAccessHandlesAuthorization;
    
    class PostPolicy
    {
        use HandlesAuthorization;
    
        public function view(User $user, Post $post)
        {
            if ($user->hasPermissionTo('view own posts')) {
                return $user->id === $post->user_id;
            }
    
            return $user->hasPermissionTo('view posts');
        }
    
        public function create(User $user)
        {
            return $user->hasAnyPermission(['manage posts', 'manage own posts']);
        }
    
        public function update(User $user, Post $post)
        {
            if ($user->hasPermissionTo('manage own posts')) {
                return $user->id == $post->user_id;
            }
            return $user->hasPermissionTo('manage posts');
        }
    
        public function delete(User $user, Post $post)
        {
            if ($user->hasPermissionTo('manage own posts')) {
                return $user->id === $post->user_id;
            }
    
            return $user->hasPermissionTo('manage posts');
        }
    }

    It should now work as exptected. Just create a Role, modify its Permissions and the Policy should take care of the rest.

    Note: Don’t forget to add your Policy to your $policies in AppProvidersAuthServiceProvider and define the permissions in confignova-permissions.php.

    hasPermissionTo() method determine if any of the assigned roles to this user have a specific permission.

    hasAnyPermission() method determine if the model has any of the given permissions.

    hasAllPermissions() method determine if the model has all of the given permissions.

    view own posts is superior to view posts and allows the User to only view his own posts.

    manage own posts is superior to manage posts and allows the User to only manage his own posts.

    Customization

    Use your…