Search code examples
phpauthorizationlaravel-5.1policy

Authorization not working for Users Search


I'm using Laravel 5.1.26, including authorizations with policies. I have a basic ACL model where a user has a Role, of course an integer Role field.

My Roles are: 0 - Administrator (can perform any operation over users); 1- Operator (can't perform any operation over users); 2- Viewer (can't perform any operation over users).

I provide the option to perform a User's search. Only Administrators can perform this because my roles definition. So, I have a method in the UserController to display my results:

public function postSearch(Request $request)
    {
        $this->authorize('search', User::class);
        $query = User::select('name', 'email')
                    ->where('name', 'LIKE', "%$request->name%")
                    ->where('email', 'LIKE', "%$request->email%")
                    ->where('role', '=', "%$request->role%");
        return $this->displayResult($query, $request);
    }

As you see, the authorize method perform the validation, and the rest of code creates the result. Simple.

Problem is because if I search (using an Administrator user for all cases) for an Operator user, then all my operations are disabled: create, delete, edit, etc. Same behaviour if I search for a Viewer user.

But if I search for an Administrator user, then all my operations are enabled!

So, I guess that the authorize method is receiving the user found! Not the user authenticated. How can I solve this? I'm passing the User::class because if I don't pass anything, then my Policies don't work (therefore, I followed the last comment here https://laracasts.com/discuss/channels/laravel/laravel-511s-new-authorization-doesnt-read-policies/?page=2).

Thanks.


Solution

  • After perfom another Search option on my application, I found that Eloquent is a little bit different than usual and I created a Search method on my model. Which basically perform this:

    public function scopeSearch($query, $field, $value)
        {
            if(is_numeric($value))
                return $query->where($field, '=', "$value");
            else
                return $query;
        }
    

    So, I changed my original code to this and my Role is an integer:

    public function postSearch(Request $request)
        {
            $this->authorize('search', User::class);
            $query = User::select('name', 'email')
                        ->where('name', 'LIKE', "%$request->name%")
                        ->where('email', 'LIKE', "%$request->email%")
                        ->search('role', "$request->role");
            return $this->displayResult($query, $request);
    }
    

    Now works fine!