Skip to content

ACL - Access Control List

The Access Control List (ACL) Module allows you to define authorization rules to access resources in your application.

Under the hood, the Modular ACL System provides an Interface integrated with Spatie's Laravel-permission package, which is used to handle the permissions and roles for the logged-in users in your application.

You can create roles for your users, like admin and marketing. Create permissions that represent the actions that your users can perform, like create, edit, delete, and view resources. And finally, you can assign permissions to roles, and assign roles to the users of the application.

In cases where you need granular control over user permissions, you can also assign permissions directly to users, and this will override the permissions that the user has through the roles.

The ACL System will require updates in two parts of your application:

1 - The sidebar navigation menu (and other links to resources in your application) to show or hide the menu items based on the permissions of the logged user.

2 - The Laravel routes, to allow or deny access to the routes based on the permissions of the logged user.

In this manner, the ACL operates on two different layers; the first one disables the links to protected resources in your application's interface. The second one, denies access to the routes of the protected resources, even if the user tries to directly access the route in the browser.

Disabling Resources in the Sidebar Navigation Menu

The Sidebar Navigation Menu is generated automatically by the resources/js/Components/AppMenu.vue component, which is configured in the resources/js/Configs/menu.js file.

A clean install of Modular will set the resources/js/Configs/menu.js file with the following content:

js
import { ZiggyVue } from "/vendor/tightenco/ziggy/dist/vue.m";

export default {
  // main navigation - side menu
  items: [
    {
      label: "Dashboard",
      permission: "Main Menu: Dashboard",
      icon: "ri-dashboard-line",
      link: route("dashboard.index"),
    },

    {
      label: "Access Control List",
      permission: "Main Menu: Access Control List",
      children: [
        {
          label: "Users",
          permission: "Main Menu: Access Control List: Users - List",
          icon: "ri-user-line",
          link: route("user.index"),
        },
        {
          label: "Permissions",
          permission: "Main Menu: Access Control List: Permissions - List",
          icon: "ri-shield-keyhole-line",
          link: route("aclPermission.index"),
        },
        {
          label: "Roles",
          permission: "Main Menu: Access Control List: Roles - List",
          icon: "ri-account-box-line",
          link: route("aclRole.index"),
        },
      ],
    },
  ],
};

This is translated by the AppMenu.vue component to the following sidebar menu:

Sidebar Menu

The permission property of each menu item is the permission that the user must have to see the menu item in the sidebar menu.

You should always maintain a 1:1 relationship between the menu items and the ACL permissions created for your application (listed in alphabetical order):

ACL Permissions

Now you can create a new role and assign the permissions to it. In this example, the admin role will have access to the app Dashboard but will not manage users resources.

ACL Permissions

The last step is to assign the admin role to a user. Now, the user will be able to access the Dashboard, but will not see the Users menu item in the sidebar menu.

ACL User

During the development lifecycle of your application, you'll likely need to manage links and buttons that are outside the AppMenu.vue. To apply this ACL feature to these links and buttons, you can utilize the can() method from the resources/js/Composables/useAuthCan.js file:

vue
<template>
  <button v-if="can('Main Menu: Access Control List: Users - Create')">
    Add User
  </button>
</template>

<script setup>
import useAuthCan from "@/Composables/useAuthCan";

const { can } = useAuthCan();
</script>

Protecting Routes

Following the instructions from the previous section will disable the links to the protected resources in the sidebar menu and other parts (buttons and links) of your application. However, users can still access the routes directly in the browser.

To ensure the ACL Module protects the routes of your application, you must apply the ACL protection method can() to your routes:

php
<?php

use Illuminate\Support\Facades\Route;

Route::get('user', [
    'uses' => 'UserController@index',
])
    ->can('Main Menu: Access Control List: Users - List')
    ->name('user.index');

This will ensure that the user will be able to access the route only if they have the permission Main Menu: Access Control List: Users - List.

You can create your own naming system for permission names if you prefer. For example, use user.index instead of the longer Main Menu: Access Control List: Users - List.

Roles, Permissions, and Precedence

If you create a user and assign a role to them, the user will have all the permissions that the role has. However, if you assign a permission directly to the user, this will override the permissions that the user has through the role. So keep in mind that: permissions assigned directly to the user will always override the permissions that the user has through the roles.