55 lines
1.8 KiB
PHP
55 lines
1.8 KiB
PHP
<?php
|
|
|
|
namespace App\Providers;
|
|
|
|
use App\Events\RoleAssigned;
|
|
use App\Events\UserCreated;
|
|
use App\Events\UserDeleted;
|
|
use App\Events\UserUpdated;
|
|
use App\Listeners\PublishUserEventToMqtt;
|
|
use App\Models\User;
|
|
use Illuminate\Cache\RateLimiting\Limit;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Event;
|
|
use Illuminate\Support\Facades\Gate;
|
|
use Illuminate\Support\Facades\RateLimiter;
|
|
use Illuminate\Support\ServiceProvider;
|
|
|
|
class AppServiceProvider extends ServiceProvider
|
|
{
|
|
/**
|
|
* Register any application services.
|
|
*/
|
|
public function register(): void
|
|
{
|
|
//
|
|
}
|
|
|
|
/**
|
|
* Bootstrap any application services.
|
|
*/
|
|
public function boot(): void
|
|
{
|
|
// Defense-in-depth: super-admin bypasses every permission/policy check,
|
|
// even if a permission is later removed or misconfigured — except
|
|
// self-delete, which must never be allowed for any role, so that
|
|
// check is enforced here too rather than left to fall through to
|
|
// a policy this bypass would otherwise short-circuit.
|
|
Gate::before(function (User $user, string $ability, array $arguments = []) {
|
|
if ($ability === 'delete' && ($arguments[0] ?? null) instanceof User && $arguments[0]->id === $user->id) {
|
|
return false;
|
|
}
|
|
|
|
return $user->hasRole('super-admin') ? true : null;
|
|
});
|
|
|
|
RateLimiter::for('api', function (Request $request) {
|
|
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
|
|
});
|
|
|
|
// Registered explicitly — auto-discovery doesn't reliably match a
|
|
// union-typed handle() parameter across multiple event classes.
|
|
Event::listen([UserCreated::class, UserUpdated::class, UserDeleted::class, RoleAssigned::class], PublishUserEventToMqtt::class);
|
|
}
|
|
}
|