Add rate limiting on login, order, invitation, contact routes

- Login: 5 attempts / 15 min (Symfony login_throttling)
- Order create: 10 / 5 min (sliding window)
- Invitation respond/register: 5 / 15 min
- Contact form: 3 / 10 min
- RateLimiterSubscriber with route-to-limiter mapping
- Returns 429 when rate limited

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-03-22 20:01:01 +01:00
parent 207e985821
commit 36456e8dfe
8 changed files with 227 additions and 2 deletions

View File

@@ -0,0 +1,65 @@
<?php
namespace App\Tests\EventSubscriber;
use App\EventSubscriber\RateLimiterSubscriber;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
class RateLimiterSubscriberTest extends TestCase
{
public function testSubscribedEvents(): void
{
$events = RateLimiterSubscriber::getSubscribedEvents();
self::assertArrayHasKey(KernelEvents::REQUEST, $events);
}
public function testIgnoresNonMappedRoutes(): void
{
$subscriber = new RateLimiterSubscriber([]);
$request = new Request();
$request->attributes->set('_route', 'app_home');
$kernel = $this->createMock(HttpKernelInterface::class);
$event = new RequestEvent($kernel, $request, HttpKernelInterface::MAIN_REQUEST);
$subscriber->onKernelRequest($event);
self::assertNull($event->getResponse());
}
public function testIgnoresSubRequests(): void
{
$subscriber = new RateLimiterSubscriber([]);
$request = new Request();
$request->attributes->set('_route', 'app_order_create');
$kernel = $this->createMock(HttpKernelInterface::class);
$event = new RequestEvent($kernel, $request, HttpKernelInterface::SUB_REQUEST);
$subscriber->onKernelRequest($event);
self::assertNull($event->getResponse());
}
public function testIgnoresMappedRouteWithMissingLimiter(): void
{
$subscriber = new RateLimiterSubscriber([]);
$request = new Request();
$request->attributes->set('_route', 'app_order_create');
$kernel = $this->createMock(HttpKernelInterface::class);
$event = new RequestEvent($kernel, $request, HttpKernelInterface::MAIN_REQUEST);
$subscriber->onKernelRequest($event);
self::assertNull($event->getResponse());
}
}