Question

I am developing a site using laravel 4, and trying to implement my ACL using Sentry 2. I need help on how to structure the following:

I have the following permissions for role HR:

Staffs|View staff details
Staffs|Register new staff
Staffs|Edit staff details
Staffs|Delete staff details

Corresponding to the following routes:

//get route to staffs landing page
Route::get('staffs/view-staffs', 'UsersController@getManageStaffs'); 

//post routes
Route::post('staffs/add-staff', 'UsersController@postAddStaff');
Route::post('staffs/update-staff', 'UsersController@postUpdateStaff');
Route::post('staffs/delete-staff', 'UsersController@postDeleteStaff');

I need access control for the following:

  1. link on my menu for view-staffs: if all staff permission are disabled, disable link. This is how i am doing it:

    if($user->hasAnyAccess(array('Staffs|View staff details', 'Staffs|Register new staff', 'Staffs|Edit staff details', 'Staffs|Delete staff details')))
    {
        //display menu link
    }
    
  2. my routes: if all staff permissions are disabled, disable all routes that fall under "staffs/"

    //For this, i have no idea how to restrict routes based on my permissions
    //But i don't want to do it like i did in (1) within my controllers
    
  3. disable action buttons that corresbond to a disabled permission

    //same as no (1)
    
Was it helpful?

Solution

You can do something like the following:

In app/filters.php, create a filter as follows.

Route::filter('permissions', function()
{
    $name = Route::current()->getName();
    $name =  'system' . ( ! empty($name) ? '.' : '') . $name;

    if (!UserHelper::hasPermission($name)) {
        App::abort(401, 'You are not authorized to access route '.$name);
    }
});

You can apply the filter by putting a before filter on your route, e.g.

Route::group(array('before' => 'permissions'), function()
{
    // routes
}

With this system, you could create permission groups like these:

Sentry::getGroupProvider()->create(array(
    'id' => 1,
    'name'        => 'Super Administrators',
    'permissions' => array(
        'system' => 1,
    ),
));

Sentry::getGroupProvider()->create(array(
    'id' => 2,
    'name'        => 'Administrators',
    'permissions' => array(
        'system.users' => 1,
        'system.products' => 1,
        'system.store' => 1,
        'system.profile' => 1,
    ),
));
Sentry::getGroupProvider()->create(array(
    'id' => $id++,
    'name'        => 'Managers',
    'permissions' => array(
        'system.products' => 1,
        'system.store' => 1,
        'system.profile' => 1,
    ),
));

So if a user has the system.products permission, he'd be able to use every products route.

Now, for the part where you wish to show links to certain groups, you can do that with a helper like this:

public static function has($permission)
{
    $all = [];
    $parts = explode('.',$permission);
    $permission = '';

    foreach($parts as $part) {
        $permission .= (!empty($permission) ? '.' : '') . $part;
        $all[] = $permission;
    }

    return Sentry::check() and Sentry::getUser()->hasAnyAccess($all);
}

You'd simply pass the route name (e.g. system.products) to the function and it'll return whether the user has access to it. Source: https://laracasts.com/forum/conversation/post/2819

OTHER TIPS

There is a cool package for sentry ACL that implements a fully featured admin panel https://github.com/intrip/laravel-authentication-acl

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top