unstoppablecarl / arbiter
Manage Laravel User abilities that target Users
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: 2024-12-08 05:03:35 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
HasAbilities
andHasGetters
traits. - Gets the primary role of ability targets that implement the
UserWithPrimaryRole
interface via atoPrimaryRole
method.
Trait: HasAbilities
Adds the typical abilities of a UserPolicy
matching them to the methods and abilities of the UserAuthority
.
- Requires
HasUserAuthority
trait. - 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
HasUserAuthority
trait. - 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
$targetSelfOverrides
property must be set to an implementation of theTargetSelfOverridesContract
. In the includedUserPolicy
it is set via the constructor. TargetSelfOverrides
is 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