| Package Data | |
|---|---|
| Maintainer Username: | TortueTorche |
| Maintainer Contact: | tortuetorche@spam.me (TortueTorche) |
| Package Create Date: | 2013-09-27 |
| Package Last Update: | 2017-08-30 |
| Home Page: | http://laravel.io/forum/02-03-2014-authority-controller-authorization-library-cancan-port |
| Language: | PHP |
| License: | MIT |
| Last Refreshed: | 2025-10-29 03:05:35 |
| Package Statistics | |
|---|---|
| Total Downloads: | 33,216 |
| Monthly Downloads: | 3 |
| Daily Downloads: | 0 |
| Total Stars: | 154 |
| Total Watchers: | 17 |
| Total Forks: | 17 |
| Total Open Issues: | 5 |

AuthorityController is an PHP authorization library for Laravel 5.3 which restricts what resources a given user is allowed to access.
All permissions are defined in a single location:
config/authority-controller.php
and not duplicated across controllers, routes, views, and database queries.
For Laravel 5.2 supports see AuthorityController 2.2 branch
For Laravel 5.0 or 5.1 supports see AuthorityController 2.1 branch
For Laravel 4.1 or 4.2 supports see AuthorityController 1.2 branch
You can see in action this package with this Laravel 5.3 demo application.
It's an extension of the authority-laravel package.
And a port of the best Ruby authorization library: CanCan.
Authority ports some features of CanCan and this package ports almost all the other features.
authority-controller package to your composer.json file to require AuthorityController:composer require efficiently/authority-controller:dev-master
config/app.php: Efficiently\AuthorityController\AuthorityControllerServiceProvider::class,
'Params' => Efficiently\AuthorityController\Facades\Params::class,
'Authority' => Efficiently\AuthorityController\Facades\Authority::class,
Authority::can('update', SomeModel::class);
We have provided a basic table structure to get you started in creating your roles and permissions.
Publish them to your migrations directory or copy them directly.
php artisan vendor:publish --provider="Efficiently\AuthorityController\AuthorityControllerServiceProvider" --tag="migrations"
Run the migrations
php artisan migrate
This will create the following tables
To utilize these tables, you can add the following methods to your User model. You will also need to create Role and Permission Model stubs (replacing App\Authority\ with you own namespace)..
//app/User.php
public function roles()
{
return $this->belongsToMany(Authority\Role::class)->withTimestamps();
}
public function permissions()
{
return $this->hasMany(Authority\Permission::class);
}
public function hasRole($key)
{
$hasRole = false;
foreach ($this->roles as $role) {
if ($role->name === $key) {
$hasRole = true;
break;
}
}
return $hasRole;
}
//app/Authority/Role.php
<?php
namespace App\Authority;
use Illuminate\Database\Eloquent\Model;
class Role extends Model {}
//app/Authority/Permission.php
<?php
namespace App\Authority;
use Illuminate\Database\Eloquent\Model;
class Permission extends Model {}
In your app/Http/Controllers/Controller.php file, add the ControllerAdditions trait and disable the use of the AuthorizesRequests trait:
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Efficiently\AuthorityController\ControllerAdditions as AuthorityControllerAdditions;
class Controller extends BaseController
{
// use AuthorizesRequests;
use DispatchesJobs, ValidatesRequests;
use AuthorityControllerAdditions;
//code...
}
NB: If you really need the default Laravel Authorization system, you can use the AuthorizesRequests trait, if you alias its authorize and authorizeResource methods, like this:
<?php
//code...
class Controller extends BaseController
{
use DispatchesJobs, ValidatesRequests;
use AuthorizesRequests, AuthorityControllerAdditions {
AuthorityControllerAdditions::authorize insteadof AuthorizesRequests;
AuthorizesRequests::authorize as illuminateAuthorize;
AuthorizesRequests::authorizeResource as illuminateAuthorizeResource;
}
//code...
}
AuthorityController expects that auth()->user() return the current authenticated user. Now, by default Laravel 5 handles this.
User permissions are defined in an AuthorityController configuration file.
You can publish the AuthorityController default configuration file with the command below:
php artisan vendor:publish --provider="Efficiently\AuthorityController\AuthorityControllerServiceProvider" --tag="config"
This will place a copy of the configuration file at config/authority-controller.php. The config file includes an initialize function, which is a great place to setup your rules and aliases.
//config/authority-controller.php
<?php
$serializer = new SuperClosure\Serializer;
return [
'initialize' => $serializer->serialize(function ($authority) {
$user = auth()->guest() ? new App\User : $authority->getCurrentUser();
// Action aliases. For example:
$authority->addAlias('moderate', ['read', 'update', 'delete']);
// Define abilities for the passed in user here. For example:
if ($user->hasRole('admin')) {
$authority->allow('manage', 'all');
} else {
$authority->allow('read', 'all');
}
})
];
See Defining Authority rules for details.
The current user's permissions can then be checked using the Authority::can() and Authority::cannot() methods in the view and controller.
@if (Authority::can('update', $article))
{{ link_to_route("articles.edit", "Edit", $article->id) }}
@endif
See Checking Authority rules for more information
The authorize() method in the controller will throw an exception if the user is not able to perform the given action.
public function show($id)
{
$this->article = App\Article::find($id);
$this->authorize('read', $this->article);
}
Setting this for every action can be tedious, therefore the loadAndAuthorizeResource() method is provided to automatically authorize all actions in a RESTful style resource controller. It will use a before filter to load the resource into an instance variable and authorize it for every action.
<?php
namespace App\Http\Controllers;
class ArticlesController extends Controller
{
public function __construct()
{
$this->loadAndAuthorizeResource();
}
public function show($id)
{
// $this->article is already loaded and authorized
}
}
See Authorizing Controller Actions for more information.
The Efficiently\AuthorityController\Exceptions\AccessDenied exception is thrown when calling authorize() in the controller and the user is not able to perform the given action. A message can optionally be provided.
Authority::authorize('read', 'App\Product', 'Unable to read this product.');
You can catch the exception and modify its behavior in the render() method of the app/Exceptions/Handler.php file. For example here we set the error message to a flash and redirect to the home page.
//app/Exceptions/Handler.php
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
//code...
if ($e instanceof \Efficiently\AuthorityController\Exceptions\AccessDenied) {
$msg = $e->getMessage();
\Log::error('Access denied! '.$msg);
return redirect('/home')->with('flash_alert', $msg);
}
return parent::render($request, $e);
}
//code...
See Exception Handling for more information.
Authority introduction.
Authority-Laravel general usage.
Because AuthorityController is a CanCan port, you can also read the Wiki docs of CanCan here.
Your controllers have now a $params property:
<?php
namespace App\Http\Controllers;
class ProductsController extends Controller
{
//code...
public function update($id)
{
$this->params['id'] == $id;//-> true
$this->params['product'];//-> ["name" => "Best movie"]
$this->params['controller'];//-> 'products'
$this->params['action'];//-> 'update'
//code...
}
//code...
}
#### 2.3.0-dev
#### 2.2.0
#### 2.1.1
#### 2.1.0
illuminate/html package by the laravelcollective/html packagetests directory are now only available in Composer's dev mode to avoid conflicts#### 2.0.0
User => App\User
controllerClass which is by default Illuminate\Routing\Controller
authory-controller config file from app/config/packages/efficiently/authority-controller/config.php to config/authority-controller.php
authory-controller migrations files (see the section Create Roles and Permissions Tables of this README)BaseController::flushAuthorityEvents() static method.
Useful for functional tests with Codeception (see issue #14 and this Wiki page for more explanations).composer.json file.authority-php\authority package.
Read the Wiki doc for more information: Authority-Precedence.Parameters class to allow custom routes with id and parent_id routes's parameters (fix #6).Params::get('controller') behaviour is now like Rails. It returns controller name in snake_case and in plural.ControllerResource class, the #load_collection method, who uses in the User model #accessible_by method. Looks complicated.
Instead, use specific query scopes with collectionScope option to filtering your data in your collection (e.g. index) controller actions.
Because you'll allowing/denying access by roles or check user's authorizations on each record of the collection.Ability class, the #attributes_for method.
Looks useless with Authority because rules conditions are only possible by Closure not by associative array. And CanCan handles #attribute_for only for Hash (associative array) conditions.#skip_* methods in ControllerAdditions.allow() and deny() methods of Authority, the third argument isn't an optional hash (associative array) of conditions but an anonymous function (Closure):$authority->allow('update', 'App\Product', function ($self, $product) {
return $product->available === true;
});
It's only compatible with PHP >= 5.6 and Laravel >= 5.3 framework.
See Wiki page Differences between CanCan and AuthorityController
It's following the D.R.W.J.P.I. principle:
Don't Reinvent the Wheel, Just Port It ! -- (c) 2013 A.D.
If you have any issues with AuthorityController, please add an issue on GitHub or fork the project and send a pull request.
To get the tests running you should install PHPUnit and run phpunit tests.
AuthorityController was heavily inspired by CanCan and uses Authority-Laravel.