-
Notifications
You must be signed in to change notification settings - Fork 17
Defining Authority rules
The configuration file is where all user permissions are defined. An example configuration looks like this.
// config/authority-controller.php # For Laravel 5.0
// app/config/packages/efficiently/authority-controller/config.php # For Laravel 4.*
return [
'initialize' => function ($authority) {
$user = Auth::guest() ? new User : $authority->getCurrentUser();
//an example using the `hasRole` function, see below examples for more details
if ($user->hasRole('admin')) {
$authority->allow('manage', 'all');
} else {
$authority->allow('read', 'all');
}
}
];
The current user model is passed into the initialize Closure
, so the permissions can be modified based on any user attributes. AuthorityController makes no assumption about how roles are handled in your application. See Role Based Authorization for an example.
The allow
method is used to define permissions and requires two arguments. The first one is the action you're setting the permission for, the second one is the class name of object you're setting it on.
$authority->allow('update', 'Article');
You can pass manage
to represent any action and all
to represent any object.
$authority->allow('manage', 'Article'); // user can perform any action on the article
$authority->allow('read', 'all'); // user can read any object
$authority->allow('manage', 'all'); // user can perform any action on any object
Common actions are read
, create
, update
and destroy
but it can be anything. See Action Aliases and Custom Actions for more information on actions.
You can pass an array for either of these parameters to match any one. For example, here the user will have the ability to update or destroy both articles and comments.
$authority->allow(['update', 'destroy'], ['Article', 'Comment']);
Important notice about manage. As you read above it represents ANY action on the object. So if you have something like:
$authority->allow('manage', 'User');
$authority->allow('invite', 'User');
and if you take a test of last invite
rule you always get true
. Why? That's because manage
represents ANY action on object and manage
is not just create
, read
, update
, destroy
on object.
If you want only CRUD actions on object, you should create custom action that called crud
for example, and use it instead of manage
:
return [
'initialize' => function ($authority) {
$user = Auth::guest() ? new User : $authority->getCurrentUser();
//action aliases
$authority->addAlias('crud', ['create', 'read', 'update', 'delete']);
$authority->allow('crud', 'User');
$authority->allow('invite', 'User');
}
];
A conditional callback can be passed to further restrict which records this permission applies to. Here the user will only have permission to read active projects which he owns.
$authority->allow('read', 'Project', function ($self, $project) {
return $project->active === true && $self->user()->id === $project->user_id;
});
Here another example:
$authority->allow('update', 'Project', function ($self, $project) {
return $project->priority < 3;
});
If the Closure returns true then the user has that authority, otherwise he will be denied access.
The Closure is only evaluated when an actual instance object is present. It is not evaluated when checking permissions on the class (such as in the index action). This means any conditions which are not dependent on the object attributes should be moved outside of the Closure.
// don't do this
$authority->allow('update', 'Project', function ($self, $project) {
return $self->user()->hasRole('admin'); // this won't always get called
});
// do this
if ($user->hasRole('admin')) {
return $authority->allow('update', 'Project');
}
See Checking Authority rules for more information.
It is possible to define multiple authority rules for the same resource. Here the user will be able to read projects which are released OR available for preview.
$authority->allow('read', 'Project', function ($self, $project) {
return $project->released === true;
});
$authority->allow('read', 'Project', function ($self, $project) {
return $project->preview === true;
});
The deny
method takes the same arguments as allow
and defines which actions the user is unable to perform. This is normally done after a more generic allow
call.
$authority->allow('manage', 'Project');
$authority->deny('destroy', 'Project');
The order of these calls is important. See Authority Precedence for more details.