tanerkay / laravel-model-acl
Access control based on individual records / models
Requires
- php: ^8.0
- illuminate/config: ^8.0|^9.0|^10.0
- illuminate/database: ^8.0|^9.0|^10.0
- illuminate/support: ^8.0|^9.0|^10.0
- spatie/laravel-package-tools: ^1.11
Requires (Dev)
- ext-json: *
- orchestra/testbench: ^6.0|^7.0|^8.0
- phpunit/phpunit: ^9.3
This package is auto-updated.
Last update: 2024-05-31 00:23:20 UTC
README
This package allows record-level access control based on custom authorization rules.
This handles cases where you may have many records in a table, but each entity has its own rules for access control. For example, you may have a table of documents, and it's not a simple scenario where a user can edit their own documents, and view all others. Maybe the access of each document has to be set separately, e.g. document X can be edited by Bob & Jane, and viewed by the Staff group; whereas document Y can only be viewed by the Finance team.
Here's a demo of how you can use it:
use Illuminate\Database\Eloquent\Model; use Tanerkay\ModelAcl\Traits\ModelBasedAccessControl; class Report extends Model { use ModelBasedAccessControl; // ... } $post->can('view');
Support the developer
To be added...
Documentation
Installation
Requires PHP 8.0 or higher, and Laravel 8.x or higher (currently supporting up to 9.x)
composer require tanerkay/laravel-model-acl
You can publish the migration with:
php artisan vendor:publish --provider="Tanerkay\ModelAcl\ModelAclServiceProvider" --tag="model-acl-migrations"
php artisan migrate
You can optionally publish the config file with:
php artisan vendor:publish --provider="Tanerkay\ModelAcl\ModelAclServiceProvider" --tag="model-acl-config"
Assigning access control rules to individual models
The addAccessControl()
method can be used to add rules to individual models.
public function addAccessControl( string|array $abilities, object|array $ruleDefinitions, ?string $description = null ): void
It accepts:
- an ability name or list of abilities that can be used in calls to
can()
. - an array of rule definitions, each rule definition is an array containing a class string
'class'
and an array of arguments'arguments'
. - an optional description of the rule, which can be stored in the database alongside the rule definition.
e.g. Restrict a certain post to moderators and admins.
$post->addAccessControl('view', [ [ 'class' => \Tanerkay\ModelAcl\Rules\HasRole::class, 'arguments' => ['admin', 'moderator'], ] ]); // throws exception if $user->hasRole(['admin', 'moderator']) doesn't return true $post->can('view');
The HasRole
class assumes your User
model has a method hasRole()
that accepts a string or an array of strings. You can customize the name of the method using the env key MODEL_ACL_AUTHENTICATABLE_HAS_ROLE
.
Creating custom rules
For other rules or logic, you can construct your own Rule class which implements \Tanerkay\ModelAcl\Contracts\RuleContract
or which extends the abstract class \Tanerkay\ModelAcl\Rules\Rule
.
e.g.
use Tanerkay\ModelAcl\Rules\Rule; class AgeRequirementRule extends Rule { public function authorize(?Authenticatable $user, ...$arguments): void { $user ??= $this->getUser(); if ($user->date_of_birth->diffInYears() < $arguments[0]) { throw new \Exception('Not wise enough'); } } }
$drink = Drink::where('is_alcoholic', true)->first(); $drink->addAccessControl('buy', [ [ 'class' => AgeRequirementRule::class, 'arguments' => 18, ] ]); // throws exception if user is under 18 years of age $drink->can('buy');
Testing
composer test
Thanks
- Spatie for making awesome packages, this package leverages
spatie/laravel-package-tools
and is itself derived fromspatie/laravel-activitylog
.