Search code examples
laravelviewauthorizationpolicy

Why does my view-policy work, but my viewAny-policy not?


I generated a policy with php artisan make:policy StudentPolicy --model=Student. In this policy you have a view and viewAny method. When i test it normally viewAny applies on index() and view on show(), but only the view-policy works, the viewAny has no effect. We still can access the page localhost/student

If we set the return value in viewAny to false or true. It has no effect. The output from php artisan route:list is as show below.

|        | POST      | student                               | student.store             | App\Http\Controllers\StudentController@store                           | web,can:create,App\Models\Student

|        | GET|HEAD  | student                               | student.index             | App\Http\Controllers\StudentController@index                           | web

|        | GET|HEAD  | student/create                        | student.create            | App\Http\Controllers\StudentController@create                          | web,can:create,App\Models\Student

|        | GET|HEAD  | student/{student}                     | student.show              | App\Http\Controllers\StudentController@show                            | web,can:view,student

|        | PUT|PATCH | student/{student}                     | student.update            | App\Http\Controllers\StudentController@update                          | web,can:update,student

|        | DELETE    | student/{student}                     | student.destroy           | App\Http\Controllers\StudentController@destroy                         | web,can:delete,student

|        | GET|HEAD  | student/{student}/edit                | student.edit              | App\Http\Controllers\StudentController@edit                            | web,can:update,student

AuthServiceProvider

    protected $policies = [
        // 'App\Model' => 'App\Policies\ModelPolicy',
        Student::class => StudentPolicy::class,

    ];

StudentPolicy

   public function viewAny(User $user)
    {
        //
        return in_array('view.student.all', $user->rights()->pluck('description')->toArray());
    }

    /**
     * Determine whether the user can view the student.
     *
     * @param  \App\Models\User  $user
     * @param  \App\Models\Student  $student
     * @return mixed
     */
    public function view(User $user, Student $student)
    {
        //
        return in_array('view.student.all', $user->rights()->pluck('description')->toArray());
    }

Studentcontroller

class StudentController extends Controller
{

    public function __construct()
    {
        $this->authorizeResource(Student::class);
    }

If a user is not authorized to viewAny, it may not access localhost/student, it needs to show an unauthorized page.


Solution

  • There is a mismatch in laravel. If you create with Artisan a policy it generates a viewAny method. This viewAny method is not mapped in the AuthorizesRequests trait under the resourceAbilityMap. If you change this mapping an add 'index' => 'viewAny' to it. The only problem is when i do a composer update it gets overwritten, so i need to do a pull request to Laravel itselfs.