laravellaravel-5laravel-middlewarelaravel-gate

How to pass more than one gate in middleware? (Laravel)


I am creating a Learning Management System for my university final year project (only recently introduced to laravel). I have set up three different roles (admin, instructor and student). I have created two views which only the admin&instructor can access, 'user management' and 'course management'. Within each admin&instructor can create users/courses and delete as required.. a student cannot view these or has access to so that is working as desired. To do so I have created a gate 'manage-user' and then passed this into the middleware.

I have now created a calendar, which I would like all user roles to view.. again i created a gate for this.. due to my current middleware i am getting 'unauthorised access' when a student attempts to view the calendar.. is it possible to pass another gate within the middleware? I tried to do so with no success.. After many attempts of trial and error I have resulted to asking a question on here hoping i can figure this out... i will paste my code below.. any help is appreciated.

AuthServiceProvider.php

public function boot()

{
    $this->registerPolicies();
    //User Management
    Gate::define('manage-users', function($user){
        return $user->hasAnyRoles(['admin', 'instructor']);
    });
    //Calendar
    Gate::define('manage-calendar', function($event){
        return $event->hasAnyRoles(['admin', 'instructor', 'student']);
    });

web.php

    Route::get('/', function () {
        return view('welcome');
    });

    Auth::routes();

    Route::get('/home', 'HomeController@index')->name('home');


    Route::namespace('Admin')->prefix('admin')->name('admin.')->middleware('can:manage-users')->group(function(){
        //Users
        Route::resource('/users', 'UsersController', ['except' => ['show']]);
        //Courses
        Route::resource('/courses', 'CoursesController', ['except' => ['show']]);



        Route::get('events', 'EventsController@index')->name('events.index');
        Route::post('/addEvents', 'EventsController@addEvent')->name('events.add');

    });

I understand that the issue lays within the gate manage-users that I have defined.. I am not sure what way to go about it protect my other routes from students &instructors...

Thanks in advance :)


Solution

  • The manage-users Gate will not allow a user with student role to go through the middleware, even if the manage-calendar Gate does.

    I suggest you regroup the routes to apply the middleware that corresponds to each route:

    Route::namespace('Admin')->prefix('admin')->name('admin.')->group(function(){
        Route::middleware('can:manage-users')->group(function(){
            Route::resource('/users', 'UsersController', ['except' => ['show']]);
            Route::resource('/courses', 'CoursesController', ['except' => ['show']]);
        });
        Route::middleware('can:manage-calendar')->group(function(){
            Route::get('events', 'EventsController@index')->name('events.index');
            Route::post('/addEvents', 'EventsController@addEvent')->name('events.add');
        });
    });