Core Concepts

Permissions

On this page

Permissions live in system_roles_in, one row per permission per role. Manage them from:

  • Admin → Roles → Manage (/systemroles/admin/roles/manage?role_id={id}): one role's permissions.
  • Admin → Permissions (/systemroles/admin/roles/permissions): every permission row for every role.

Naming permissions#

Pick one convention and keep to it. We recommend <area>.<action>, in lower case:

article.view
article.create
article.update
article.delete
article.publish
invoice.approve
settings.update

Benefits:

  • easy to read in the matrix;
  • easy to build in code ("{$area}.{$action}");
  • easy to sort and group.

Set both Permission Name and Guard Name to the same value unless you need a friendlier display name. The guard name is always stored in lower case.

The Manage screen#

For one role, the screen shows every permission with:

Column Meaning
Permission Name in_name
Permission Key in_guard_name
Permission Yes (1) or No (0)
Sequence Order, with up and down arrows
Action Edit Permission

Opening the screen fills in any permission the role is missing, switched off (on for the super admin).

Adding a permission#

On a role's Manage screen click Add Permission:

Field Rules
Permission Name Required, max 191, unique for this role
Guard Name Required, max 191, unique for this role, stored lower case
Permission Yes or No, for this role

What happens:

  1. The row is created for this role with your Yes/No choice.
  2. Every other role gets the same permission, switched off.
  3. It is placed at the end of the order.

Then switch it on for the other roles that need it.

Editing a permission#

Click Edit Permission to change the name, guard name, Yes/No or sequence for this role's row only. Renaming a permission on one role does not rename it on the others. To rename a permission everywhere, edit it on each role, or run an update query:

PHP
use BabeRuka\SystemRoles\Models\SystemRolesIn;

SystemRolesIn::where('in_name', 'article.remove')
    ->update(['in_name' => 'article.delete', 'in_guard_name' => 'article.delete']);

Ordering#

The up and down arrows swap a permission's sequence with its neighbour within the same role. Sequence only affects display.

Deleting a permission#

There is no delete button. Rows in user_roles_in point at system_roles_in with ON DELETE RESTRICT. To remove a permission:

PHP
use BabeRuka\SystemRoles\Models\SystemRolesIn;
use BabeRuka\SystemRoles\Models\UserRolesIn;
use Illuminate\Support\Facades\DB;

DB::transaction(function () {
    $ids = SystemRolesIn::where('in_name', 'article.legacy')->pluck('in_id');
    UserRolesIn::whereIn('in_id', $ids)->delete();
    SystemRolesIn::whereIn('in_id', $ids)->delete();
});

Remove the checks from your code first.

The super admin and the matrix#

The super admin passes every check. Its rows exist so the matrix looks complete, but their Yes/No value is ignored by roleHas() and permissionsForRole().

Doing it in code#

Seeding permissions, for example from a migration or seeder:

PHP
use BabeRuka\SystemRoles\Models\SystemRoles;
use BabeRuka\SystemRoles\Models\SystemRolesIn;

$permissions = ['article.view', 'article.create', 'article.update', 'article.delete'];

// Which roles get which permissions switched on
$grants = [
    'admin'   => $permissions,
    'manager' => ['article.view', 'article.create', 'article.update'],
    'user'    => ['article.view'],
];

$seq = (int) SystemRolesIn::max('in_sequence');

foreach (SystemRoles::all() as $role) {
    foreach ($permissions as $name) {
        SystemRolesIn::updateOrCreate(
            ['role_id' => $role->role_id, 'in_name' => $name],
            [
                'in_guard_name' => $name,
                'in_role'       => in_array($name, $grants[$role->role_guard_name] ?? [], true) ? '1' : '0',
                'in_sequence'   => ++$seq,
            ]
        );
    }
}

Reading permissions:

PHP
use BabeRuka\SystemRoles\Services\SystemRolesService;

SystemRolesService::permissionsForRole(3);
// ['article.view' => 1, 'article.create' => 1, 'article.delete' => 0, ...]

SystemRolesService::roleHas(3, 'article.create'); // true

in_role is stored as a string enum ('0', '1', '2'). Compare with '1' in queries, or cast to int.