Andy Wijaya
Andy Wijaya

Reputation: 157

Multiple Roles Filters in Laravel Controller Constructor

I have a question about filtering a controller and its actions for multiple user roles. Lets say i have a controller named MyController :

public class MyController extends \BaseController
{
   public static function index()
   {
   }

   public static function show()
   {
   }

   public static function create()
   {
   }

   public static function store()
   {
   }

   public static function other()
   {
   }
}

And i have 2 filters for each roles, named admin and staff :

Route::filter('admin', function()
{
    // Lines of code to get role
    if($role != 'admin') return View::make('errors.401');
});

Route::filter('staff', function()
{
    // Lines of code to get role
    if($role != 'staff') return View::make('errors.401');
});

Then, i'm trying to use beforeFilter on the constructor of MyController :

public function __construct()
{
    $this->beforeFilter('admin', ['only' => ['index', 'show', 'create', 'store']]);
    $this->beforeFilter('staff', ['only' => ['index', 'show']]);
}

When I added the first beforeFilter, it works as I expected (when I logged in to my application as staff, I cannot access the index, show, create, and store methods). But when I added the second filter and logged in as staff again, I cannot access the index and show actions, which is I expected to be accessible by staff.

My questions are, is it possible to define filters for multiple roles in the constructor of a controller? (In this case, I want to make action index and show accessible by admin and staff, but create and store only accessible by admin) And if it is possible, how could I achieve that?

Thanks.

Upvotes: 0

Views: 1940

Answers (3)

Drudge Rajen
Drudge Rajen

Reputation: 7987

First you should make a controller that should handle access control ... as below

Acl Controller

 class ACLController extends \BaseController {

        /**
         * admin access control list
         * @return array
         */
        private function adminACL() {
            return array(
                'users' => array(
                    'users',
                    'users.show',
   //similar access list for admin users

                ),



      );
        }



/**
     * staff access control list
     * @return array
     */
    private function staffACL() {
        return array(

            'staff' => array(
                'staff',
                'staff.index',
//similar access list for staff user

            ),

        );
    }

//Method that check access of related user

    /**
     * check access level
     * @param string $value
     * @return boolean
     */
    public function hasAccessLevel($value) {
        $user = //get user role here
        if ($user->roles == 'staff') {
            return TRUE;

            } elseif ($user->roles == 'admin') {
                $newAcl = array();
                foreach ($this->adminACL() as $aclBreak) {
                    foreach ($aclBreak as $acl) {
                        $newAcl[] = $acl;
                    }
                }
                if (!in_array($value, $newAcl)) {
                    return FALSE;
                } else {
                    return TRUE;
                }
            } else {
                $newAcl = array();
                foreach ($this->staffACL() as $aclBreak) {
                    foreach ($aclBreak as $acl) {
                        $newAcl[] = $acl;
                    }
                }
                if (!in_array($value, $newAcl)) {
                    return FALSE;
                } else {
                    return TRUE;
                }
            }
        }
        }

Filter the access route...

Route::filter('hasAccess',function($route,$request,$value){
    try{
        $Routeacl = new App\Controllers\ACLController();        
        if(!$acl->hasAccessLevel($value))
        {            
            return Redirect::to('admin/dashboard')->withErrors(array(Lang::get('en.user_noaccess')));
        }
    }catch(\Exception $e){
        echo $e->getMessage();
    }
});

And then in your route just check if it has access

    Route::get('/', array('as' => 'index', 'before' => 'hasAccess:index', 'uses' => 'MyController@Index'));

Happy coding :)

Upvotes: 1

Ali Irawan
Ali Irawan

Reputation: 2124

I assume you have Admin can access all feature, and staff can access everything except "show"

This is the controller

class MyController extends \BaseController
{
   public function __construct(){
       $this->beforeFilter('admin', ['only' => ['show']]);
   }    
   public function index()
   {
    echo "index";
   }

   public function show()
   {
    echo "show";
   }
}

See in your last post, you are using public class, I believe in PHP you will just need class, in function better don't use static.

Here is the filters.php

Route::filter('admin', function()
{
    // Lines of code to get role
    if($role != 'admin') return "This is only for admin";
});

In the routes.php

Route::get("/my", "MyController@index");
Route::get("/show", "MyController@show");

Then try to login as admin, you will can access "index" and "show" Then try to login as staff, you will can access "index" but cannot access "show"

Upvotes: 0

Laurence
Laurence

Reputation: 60048

Is an admin always a staff member? If so - you could just do this:

Route::filter('staff', function()
{
    // Lines of code to get role
    if(($role != 'staff') && ($role != 'admin'))return View::make('errors.401');
});

Upvotes: 0

Related Questions