Reputation: 157
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
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
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
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