Laravel 4 conditional route filter

368 views Asked by At

I have a group of routes that I want to allow the user to access only if they are in a certain department or the id in the route they are trying to access matches their logged in id.

I have:

Route::group(array('before' => 'auth.department:6|auth.me'), function () {

    Route::get('users/{id}/outofoffice', ['as' => 'users.outofoffice.form', 'uses' => 'RackspaceController@outOfOfficeForm']);
    Route::post('users/{id}/outofoffice', ['as' => 'users.outofoffice.save', 'uses' => 'RackspaceController@outOfOfficeSave']);

    Route::get('users', ['as' => 'users.list', 'uses' => 'UserController@index']);
    Route::get('users/{id}/edit', ['as' => 'users.edit', 'uses' => 'UserController@edit']);
    Route::post('users/{id}', ['as' => 'users.update', 'uses' => 'UserController@update']);

});

But it is not working, previously 'auth.department:6' works as expected, but when I change it to 'auth.department:6|auth.me', the user is still denied access. The filters are defined as:

Route::filter('auth.department', function($route, $request)
{
if(Auth::level() > 5) return null;

$departmentIds = array_slice(func_get_args(), 2);

if(!in_array(Auth::dept(), $departmentIds)) {
    if (Request::ajax())
    {
        return Response::make('Unauthorized', 401);
    }
    else
    {
        return Response::make('Unauthorized', 401);
    }
}

});

Route::filter('auth.me', function(\Illuminate\Routing\Route $route, $request){
if($route->getParameter('id') == Auth::id()) {
    return null;
} else {
    return BaseController::failed(['authorization' => ['Unauthorized']], 401);
}
});

I did this:

Route::filter('auth.dept-6-or-me', function(\Illuminate\Routing\Route $route, $request){
if(Auth::level() > 5) return null;
$departmentIds = array_slice(func_get_args(), 2);
if($route->getParameter('id') == Auth::id()) {
    return null;
}
elseif(!in_array(Auth::dept(), $departmentIds)) {
    if (Request::ajax())
    {
        return Response::make('Unauthorized', 401);
    }
    else
    {
        return Response::make('Unauthorized', 401);
    }
} else {
    if (Request::ajax())
    {
        return Response::make('Unauthorized', 401);
    }
    else
    {
        return Response::make('Unauthorized', 401);
    }
}
});
1

There are 1 answers

0
enigmaticus On

Not the solution, but maybe this will help someone.

Same thing, work around was mentioned here How to apply multiple filters on Laravel 4 route group?

Also I've tested this right now because I had the same problem. So, the | sign means only AND, it works on this principle, i was using it with Sentry plugin.

Route::post('/insert', array('as' => 'insertKom', 'uses' => 'KommunikationController@insertKom', 'before' => 'hasAccess:admin|hasAccess:contact.insert'));

For example my 2 permissions are:

hasAccess:admin: 1
hasAccess:contact.insert: 1

This solution passed, user can access the route.

Than changed permission to:

hasAccess:admin: 0
hasAccess:contact.insert: 1

Still, this solution somehow passed. User accessed the route. Not really sure why.

Than changed permission to:

hasAccess:admin: 1
hasAccess:contact.insert: 0

And this one didn't pass. User has no access to the route. Interesting thing, like it's only checking the last permission.