Skip to content

Defining Authority rules

Tortue Torche edited this page Mar 17, 2015 · 10 revisions

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

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');
    }
];

Defining Authority rules with Closures (conditional callbacks)

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.

Only for Object Attributes

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.

Combining Authority rules

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.

Additional Docs

Clone this wiki locally