RoleMiddleware.php 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. <?php
  2. namespace Middlewares;
  3. use Libs\Logger;
  4. use Libs\Payload;
  5. use Psr\Http\Message\ServerRequestInterface;
  6. /**
  7. * Autorização baseada em papel (RBAC).
  8. *
  9. * Deve ser registrada SEMPRE depois do JwtAuthMiddleware, que popula o
  10. * atributo "user_role" a partir do banco. Bloqueia (403) quando o papel do
  11. * usuário autenticado não está na lista de papéis permitidos para a rota.
  12. *
  13. * Uso na rota:
  14. * $app->post('/v1/register', $authJwt, new RoleMiddleware('admin'), Controller::class);
  15. */
  16. class RoleMiddleware
  17. {
  18. /** @var string[] */
  19. private array $allowedRoles;
  20. public function __construct(string ...$allowedRoles)
  21. {
  22. // Normaliza para comparação case-insensitive e estável.
  23. $this->allowedRoles = array_map(
  24. static fn (string $role): string => mb_strtolower(trim($role)),
  25. $allowedRoles
  26. );
  27. }
  28. public function __invoke(ServerRequestInterface $request, callable $next)
  29. {
  30. $role = mb_strtolower(trim((string) $request->getAttribute('user_role', '')));
  31. if ($role === '' || !in_array($role, $this->allowedRoles, true)) {
  32. Logger::warning('Access denied by role policy', [
  33. 'user_id' => $request->getAttribute('user_id'),
  34. 'role' => $role,
  35. 'allowed' => $this->allowedRoles,
  36. ]);
  37. return Payload::fail('Forbidden: insufficient permissions', [], 'E_FORBIDDEN', 403);
  38. }
  39. return $next($request);
  40. }
  41. }