Permissions (Authorization)
Permissions are configured as class constants in app/Enums/Permission.php. For example:
public const ViewExamples = 'View Examples';
public const CreateExamples = 'Create New Examples';
public const EditExamples = 'Edit Examples';
public const DeleteExamples = 'Delete Examples';
public const ExportExamples = 'Export Examples';
public const AuditExamples = 'Audit Examples';
The values correspond to the permissions.name database column, and should be human-readable, in Title Case. They must be unique, and must not conflict with any installed Nexus packages.
There are two types of permission - static and dynamic.
Static Permissions
Static permissions are stored in the database and can be assigned to users/roles via the GUI. They cannot be changed at runtime and are not context-dependent.
To declare a static permission, add it to the $tree array in the same file:
public static array $tree = [
'Examples' => [
'View' => self::ViewExamples,
'Create' => self::CreateExamples,
'Edit' => self::EditExamples,
'Delete' => self::DeleteExamples,
'Export' => self::ExportExamples,
'Audit' => self::AuditExamples,
],
//...
];
Then run this to update the database:
scripts/artisan.sh permission:sync
It will appear in the admin area.
Note: If you add a permission to $tree and forget to run the permission:sync command, it will show up in the admin area but you will get a validation error when you try to save.
Renaming Static Permissions
You can freely change the constant names, as long as you update all references in the code (including JavaScript), but changing the value (human-readable name) of a static permission will cause the sync script to assume the old one was deleted and a new one was added.
To get around that, you can write a migration to rename it in the database - for example:
<?php
use Alberon\NexusUsers\Models\Permission;
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Permission::rename('Old Name', 'New Name');
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Permission::rename('New Name', 'Old Name');
}
}
Then run:
scripts/artisan.sh migrate
scripts/artisan.sh permission:sync
Dynamic Permissions
Dynamic permissions are standard Laravel gates, defined in code and determined at runtime based on the user, context (e.g. specific records) and other permissions (static and dynamic).
This part is not specific to the Nexus Users package, but is included here for completeness.
Dynamic permissions are declared as constants in app/Enums/Permission.php, the same as static permissions:
public const DynamicPermissionExample = 'Dynamic Permission Example';
But they must not be added to the $tree array. Instead they are declared in app/Providers/AuthServiceProvider.php as Laravel Gates:
//--------------------------------------
// Custom gates
//--------------------------------------
Gate::define(Permission::DynamicPermissionExample, static function (User $user) {
return $user->can_do_something;
});
They may check other permissions, which can be useful for combining permissions with other logic:
Gate::define(Permission::ViewAnyUsers, static function (User $user) {
return $user->can(Permission::ViewStaffUsers)
|| $user->can(Permission::ViewStudentUsers);
});
They may take additional parameters, like any other Laravel gate:
Gate::define(Permission::ViewPost, static function (User $user, Post $post) {
return $post->is_draft
? $user->can(Permission::ViewDraftPosts)
: $user->can(Permission::ViewPublishedPosts);
});
Warning: If you use the Gate facade, make sure you use Gate::forUser($user)->, not just Gate:: - for example:
Gate::define(Permission::ViewAnyUsers, static function (User $user) {
return Gate::forUser($user)->any([
Permission::ViewStaffUsers,
Permission::ViewStudentUsers,
]);
});