Hello folks,
I've been trying to define Gate abilities "on the fly", but have run in to some
issues. In particular, I'd like to use a callback registered with Gate::before
to define a new ability via a closure, then have the Gate immediately see and
use that new closure to determine if the user is authorized for that ability.
However, things don't seem to be working as I thought they would.
To illustrate my problem, if I have the following code in my AuthServiceProvider.php,
my user can() perform the requested ability:
// AuthServiceProvider.php
public function boot() {
Gate::define('ability', function ($user) { return true; });
}
// AnywhereElse.php
$user->can('ability'); // returns true
So far, so good. If, however, I do something like the following, it won't work:
// AuthServiceProvider.php
public function boot() {
Gate::before(function ($user, $ability) {
Gate::define($ability, function ($user) { return true; });
}
}
// AnywhereElse.php
$user->can('ability'); // returns false
The Gate implementation calls all registered before callbacks before
attempting to resolve any ability callbacks, so I thought the above code would work as
expected. But, alas, it fails to find the newly "injected" closure for the
ability. Given that the Gate instance is bound to the service container as
a singleton, I figured this wouldn't be an issue.
Can anybody help me understand why this wouldn't work?
Thanks!
(N.B., this example is simplified. I'm not trying to implement an "admin" role that can
do anything. In practice, these closures do more than simply return true.)