unstoppablecarl / arbiter
Manage Laravel User abilities that target Users
Installs: 11
Dependents: 0
Suggesters: 1
Security: 0
Stars: 3
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/unstoppablecarl/arbiter
Requires
- php: >=5.6.4
- illuminate/contracts: 5.4.* || 5.5.* || 5.6.*
- illuminate/support: 5.4.* || 5.5.* || 5.6.*
Requires (Dev)
- laravel/framework: 5.4.* || 5.5.* || 5.6.*
- phpunit/phpunit: ^5.7 || ^6 || ^7
- satooshi/php-coveralls: ^1.0
- squizlabs/php_codesniffer: ^3.0
Suggests
- unstoppablecarl/gate-crasher: Safer Laravel superuser auth
This package is not auto-updated.
Last update: 2025-10-26 09:14:28 UTC
README
Manage Laravel User abilities that target Users.
About
Determining a way to authorize what actions can be performed by one User on another may seem like a simple problem at first. Most Role based permission modules are designed to allow multiple roles per user. This is an extremely powerful and flexible design pattern but creates a hard to define authorization case: When User-A can update users with Role-1, and User-B has Role-1 and Role-2, how should your application determine if User-A update User-B?
Arbiter provides a solution to this problem without getting in the way of an existing or separate multi-role based authorization system.
Requirements
- PHP >= 5.5.9
- Laravel >= 5.2
Installation
The preferred method of installation is via Packagist and Composer.
Run the following command to install the package and add it as a requirement to your project's composer.json:
composer require unstoppablecarl/arbiter
Overview
Each User has exactly one Primary Role. Primary Roles are used to determine what actions a user can perform on other users and vice-versa. Each Primary Role is identified with a unique name string.
The UserWithPrimaryRole interface is implemented on the User model.
<?php interface UserWithPrimaryRole { /* * Get the Primary Role of this user. * @return string */ public function getPrimaryRoleName(); }
The developer implements the interface with a strategy for determining what the Primary Role of a user is.
Primary Role Implementation Strategies
- Using an existing multi-role based system:
- Define some roles as "Primary". Each User has exactly one Primary Role.
- Define a numeric priority to each Role. The Primary Role of a User is the Role with the highest priority assigned to them.
- Users have exactly one Role which is used as the Primary Role. This is often a good starting point projects where it is unclear how complex the roles/permissions requirements will become.
Basic Usage
User
Implement the UserWithPrimaryRole Interface on your User model.
See UnstoppableCarl\Arbiter\Contracts\UserWithPrimaryRole
<?php namespace App; use UnstoppableCarl\Arbiter\Contracts\UserWithPrimaryRole; class User implements UserWithPrimaryRole { public function getPrimaryRoleName() { // @TODO implement Primary Role strategy // simple example // not recommended return $this->primary_role ?: 'default_primary_role'; } }
User Policy
Create App\Policies\UserPolicy and set it as the policy for the User model in App\Providers\AuthServiceProvider
See UserPolicy
<?php namespace App\Policies; use UnstoppableCarl\Arbiter\Policies\UserPolicy as ArbiterUserPolicy; class UserPolicy extends ArbiterUserPolicy { }
User Authority
Create and bind an implementation of the UserAuthorityContract in your AuthServiceProvider or continue with the Config Based User Authority below.
Config Based Implementation
Arbiter includes a simple config based UserAuthority implementation to quickly get your project up and running.
ArbiterServiceProvider
Add the Service Provider to config/app.php
UnstoppableCarl\Arbiter\Providers\ArbiterServiceProvider::class,
Configure
Publish the config file.
php artisan vendor:publish --provider=UnstoppableCarl\Arbiter\Providers\ArbiterServiceProvider
Primary Role Abilities can be configured in config/arbiter.php.
Customizing The User Policy
The UserPolicy functionality is organized into seperate traits to allow use of only the functionality you want.
- See
UserPolicy Trait: HasUserAuthority
Adds a reference to the UserAuthority instance.
- Required for
HasAbilitiesandHasGetterstraits. - Gets the primary role of ability targets that implement the
UserWithPrimaryRoleinterface via atoPrimaryRolemethod.
Trait: HasAbilities
Adds the typical abilities of a UserPolicy matching them to the methods and abilities of the UserAuthority.
- Requires
HasUserAuthoritytrait. - Methods
- create
- update
- delete
- view
- changePrimaryRoleFrom
- changePrimaryRoleTo
- changePrimaryRole
Trait: HasGetters
Adds getters to allow retrieval of all primary roles a user can perform given abilities on.
- Requires
HasUserAuthoritytrait. - Methods
- getViewablePrimaryRoles
- getCreatablePrimaryRoles
- getChangeableFromPrimaryRoles
- getChangeableToPrimaryRoles
- getDeletablePrimaryRoles
- getPrimaryRoles
Trait: HasTargetSelfOverrides
Allows overriding the returned value of a UserPolicy ability check, when the source and target of the check are the same User. The ability check is overriden by using the before method behavior of Laravel Policies.
- The
$targetSelfOverridesproperty must be set to an implementation of theTargetSelfOverridesContract. In the includedUserPolicyit is set via the constructor. TargetSelfOverridesis a minimal implementation included and used by default in theArbiterServiceProvider.
Adding User Authority Abilities
The following shows how to add an ability to the UserPolicy that checks a custom ability set in the UserAuthority.
<?php namespace App\Policies; use UnstoppableCarl\Arbiter\Contracts\UserWithPrimaryRole; use UnstoppableCarl\Arbiter\Policies\UserPolicy as ArbiterUserPolicy; class UserPolicy extends ArbiterUserPolicy { /** * Can ban users with $target Primary Role * @param UserWithPrimaryRole $source * @param UserWithPrimaryRole|null $target * @return */ public function ban(UserWithPrimaryRole $source, $target = null) { $source = $this->toPrimaryRole($source); $target = $this->toPrimaryRole($target); $ability = 'ban'; return $this->userAuthority()->canOrAny($source, $ability, $target); } }
Running Tests
Run Unit Tests
$ composer phpunit
Run Codesniffer (psr-2)
$ composer phpcs
Run both
$ composer test
Contributing
Contributions and Pull Requests welcome!
Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.
Authors
- Carl Olsen - Initial work - Unstoppable Carl
See also the list of contributors who participated in this project.
License
This project is licensed under the MIT License - see the LICENSE.md file for details