chris tophe
chris tophe

Reputation: 27

Middleware filter on all my route group except one

I have a problem for activate a middlware on a route group on laravel 5.7. It's a simple middlware for filter post (centre in my case) which is or not to the logged user .

I activate the middleware on a group of 4 routes (edit, delete, show and destroy) and it's ok for all but not for update. For update nobody can do it.

I have this middlware in Centrepolicy

<?php

namespace App\Policies;
use Illuminate\Support\Facades\Auth;
use App\Models\Auth\User;
use App\models\Centre;
use Illuminate\Auth\Access\HandlesAuthorization;

class CentrePolicy
{
    use HandlesAuthorization;






    public function manage(User $user, Centre $centre)
    {
        if(!Auth::user()->hasRole('administrator')) {
            return $user->id === $centre->user_id;
        }
        return true;

    }

My route

/*
 * All route names are prefixed with 'admin.auth'.
 */
Route::group([
    'prefix'     => 'auth',
    'as'         => 'auth.',
    'namespace'  => 'Auth',
    'middleware' => ['permission:voir liste centre']
], function () {

    Route::group(['namespace' => 'Centre'], function () {


        Route::get('centres/create', 'CentreController@create')->name('centre.create');
          Route::get('centres', 'CentreController@index')->name('centre.index');
        Route::post('centres/store', 'CentreController@store')->name('centre.store');
    });
        Route::group(['prefix' => 'centres/{centre}', 'namespace' => 'Centre', 'middleware' => ['can:manage,centre']], function () {
       Route::get('/edit', 'CentreController@edit')->name('centre.edit');
        Route::get('/show', 'CentreController@show')->name('centre.show');
            Route::put('/update', 'CentreController@update')->name('centre.update');
        Route::get('/delete', 'CentreController@destroy')->name('centre.destroy');

    });

my controller

<?php

namespace App\Http\Controllers\Backend\Auth\Centre;


use Illuminate\Http\Request;
use App\Models\Centre;
use App\Models\Auth\user;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;


class CentreController extends Controller
{


    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index(Guard $auth)
    {
       /// $centres = centre::get()->paginate(5);
        $centres = DB::table('centres')->paginate(10 );
        if(!Auth::user()->hasRole('administrator')) {
            $centres = $auth->user()->centre()->paginate(10);
        }
        return view('backend.centre.index', compact('centres'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return Response
     */
    public function create()
    {
        $centre = new Centre;
        return view('backend.centre.createcentre', ['centre' => $centre ]);
      /// return view('backend.centre.createcentre');

    }

    /**
     * Store a newly created resource in storage.
     *
     * @return Response
     */
    public function store(Request $request)
    {

        $centres = new Centre($request->all());
        $centres->user_id = Auth::user()->id;
        $centres->save();

        return redirect()->route('admin.auth.centre.index');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return Response
     */
    public function show(Centre $centre)
    {


        return view('backend.centre.show', compact('centre'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return Response
     */
    public function edit(Centre $centre)
    {


            return view('backend.centre.editcentre', compact('centre'));

    }

    /**
     * Update the specified resource in storage.
     *
     * @param  int  $id
     * @return Response
     */
    public function update($id, Request $request)
    {

        $centres = Centre::find($id);
        $centres->update($request->all());
        return redirect()->route('admin.auth.centre.index');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return Response
     */
    public function destroy(Centre $centre)
    {

        $centre->delete();
        return redirect()->route('admin.auth.centre.index');
    }





}

And my model

<?php

namespace App\Models;
use App\Models\Auth\user;
use Illuminate\Database\Eloquent\Model;
use Spatie\Permission\Traits\HasRoles;


class Centre extends Model
{


    protected $fillable = ['titre', 'description', 'enligne', 'user_id', 'capacite', 'slug'];

/*
    public function setSlugAttribute($value)
    {
        if (empty($slug)) {
            $this->attributes['slug'] = str_slug($this->titre);
        }
    }
*/
    public function user()
    {
        return $this->belongsTo(User::class);
    }

My form for edit route is

<?php
///dd($centre);

if($centre->id){
    $options = ['method' =>'put', 'route' =>['admin.auth.centre.update', $centre]];
} else {
    $options = ['method' =>'post', 'route' => ['admin.auth.centre.store']];
}

?>


{!! Form::model($centre, $options) !!}
<div class="form-group">
    {{ Form::label('Titre', 'Titre', ['class' => 'control-label']) }}
    {!! Form::text('titre', null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
    {{ Form::label('description', 'description', ['class' => 'control-label']) }}
    {!! Form::textarea('description', null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
    {{ Form::label('capacité maximum', 'capacite', ['class' => 'control-label']) }}
    {!! Form::textarea('capacite', null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
    {!! Form::hidden('enligne', '0') !!}
    {!! Form::checkbox('enligne', '1' , null) !!}

</div>

{!!Form::submit("Envoyer", ['class' => 'btn btn-primary'])!!}
{!! Form::close() !!}

When i arrive on the update page on admin/auth/centres/13/update i'm on a 403 error and in the debug bar i have 3 gate, 2 first are ok and last :

success
array:4 [▼
  "ability" => "view backend"
  "result" => true
  "user" => 1
  "arguments" => "[]"
]
success
array:4 [▼
  "ability" => "voir liste centre"
  "result" => true
  "user" => 1
  "arguments" => "[]"
]
error
array:4 [▼
  "ability" => "manage"
  "result" => null
  "user" => 1
  "arguments" => "[0 => 13]"
]

I think there is a problem with argument but this route is the same than delete/show/destroy so i don't understand

edit today i try to write the middleware like that :

public function manage(User $user, Centre $centre)
    {

        return true;

    }

But nothing to do, don't work. What action can desactive this middleware only on the update route because it's active and ok on 3 another routes?

Upvotes: 0

Views: 986

Answers (1)

Nikola Gavric
Nikola Gavric

Reputation: 3543

I think the problem is you are trying to access id as a first parameter in the function and Request as second. The way it is supposed to work with Laravel is that, if you need Request inside the function, it always must be first parameter inside the function and then all the other parameters can follow, if for some reason you don't need Request and you don't include it as a function parameter then you can use other parameter as first one, but as soon as you add Request as one of parameters, it needs to be the first parameter.

So a simple fix I think would be:

...
public function update(Request $request, $id) {
...

EDIT: After you've updated your answer with showing us how u are sending the id of the model yo u are updating, it seems to me you are sending it wrong. It should be something along these lines:

...
$options = ['method' =>'put', 'route' => ['admin.auth.centre.update', $centre->id]];
...

EDIT: Another thing that came to my mind is why are you using Auth::user() from inside the Policy when you already got the Authenticated user within $user variable?

Try changing your if statement code to this:

...
    if(!$user->hasRole('administrator')) {
        return $user->id === $centre->user_id;
    }
...

Upvotes: 1

Related Questions