mercredi 10 avril 2019

Authorization gate not called during service provider

I have an admin gate defined in my AuthServiceProvider that is used to add global query scopes to some models. Suppose I had models A, that is observed by an Observer (registered in AppServiceProvider), and B, that makes use of the admin gate to add global query scopes.

// app/Providers/AuthServiceProvider.php
class AuthServiceProvider extends ServiceProvider
{
  public function boot()
  {
    Gate::define('admin', [static::class, 'admin']);
  }

  public static function admin(User $user): bool
  {
    return $user->group->name === 'Admin';
  }
}

// app/B.php
class B extends Eloquent
{
  public static function boot()
  {
    parent::boot();

    if (!Gate::allows('admin')) {
      static::addGlobalScope('public', function ($query) {
        $query->where('public', true);
      });
    }
  }
}

Up to this point everything worked fine. Then I added a model C that has an Observer and uses the admin gate. As C::observe() fires C::boot() and the AppServiceProvider is registered before the AuthServiceProvider the gate was not defined and I extracted the Observer registration to a new ObserverServiceProvider that is registered after AuthServiceProvider.

// app/C.php
class C extends Eloquent
{
  public static function boot()
  {
    parent::boot();

    if (!Gate::allows('admin')) {
      static::addGlobalScope('public', function ($query) {
        $query->where('public', true);
      });
    }
  }
}

// app/Providers/ObserverServiceProvider.php
class ObserverServiceProvider extends ServiceProvider
{
  public function boot()
  {
    A::observe(AObserver::class);
    C::observe(CObserver::class);
  }
}

// config/app.php
'providers' => [
  //...
  App\Providers\AppServiceProvider::class,
  App\Providers\AuthServiceProvider::class,
  //...
  App\Providers\ObserverServiceProvider::class,
]

My problem:

The observers for A and C are still working, as well as the admin gate in B's boot() method, but Gate::allows('admin') in C always returns false without even calling the gate function.

Adding a var_dump(Gate::has('admin')) in C::boot() outputs true and using @can('admin') later in the View during the same request works fine as well, so the gate is definitely defined and working in principle.



from Newest questions tagged laravel-5 - Stack Overflow http://bit.ly/2KrSH4P
via IFTTT

Aucun commentaire:

Enregistrer un commentaire