Skip to content

Commit

Permalink
feat: add Retry-After header if needed
Browse files Browse the repository at this point in the history
  • Loading branch information
maelgangloff committed Aug 5, 2024
1 parent 4e6649f commit 686d39d
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 10 deletions.
5 changes: 3 additions & 2 deletions src/Controller/DomainRefreshController.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,13 @@ public function __invoke(string $ldhName, KernelInterface $kernel): ?Domain

if (false === $kernel->isDebug() && true === $this->getParameter('limited_features')) {
$limiter = $this->rdapRequestsLimiter->create($userId);
$limit = $limiter->consume();

if (false === $limiter->consume()->isAccepted()) {
if (false === $limit->isAccepted()) {
$this->logger->warning('User {username} was rate limited by the API.', [
'username' => $this->getUser()->getUserIdentifier(),
]);
throw new TooManyRequestsHttpException();
throw new TooManyRequestsHttpException($limit->getRetryAfter()->getTimestamp() - time());
}
}

Expand Down
24 changes: 21 additions & 3 deletions src/Controller/MeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,30 @@
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\RateLimiter\RateLimiterFactory;
use Symfony\Component\Serializer\SerializerInterface;

class MeController extends AbstractController
{
public function __invoke(): UserInterface
public function __construct(
private readonly SerializerInterface $serializer,
private readonly RateLimiterFactory $rdapRequestsLimiter,
) {
}

public function __invoke(): Response
{
return $this->getUser();
$user = $this->getUser();
$limiter = $this->rdapRequestsLimiter->create($user->getUserIdentifier());
$limit = $limiter->consume(0);

$data = $this->serializer->serialize($user, 'json', ['groups' => 'user:list']);

return new JsonResponse($data, Response::HTTP_OK, [
'eu.domainwatchdog.ratelimiter.rdap.remaining' => $limit->getRemainingTokens(),
'eu.domainwatchdog.ratelimiter.rdap.limit' => $limit->getLimit(),
], true);
}
}
14 changes: 9 additions & 5 deletions src/Controller/RegistrationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,16 @@ public function register(Request $request, UserPasswordHasherInterface $userPass

$limiter = $this->userRegisterLimiter->create($request->getClientIp());

if (false === $this->kernel->isDebug() && false === $limiter->consume()->isAccepted()) {
$this->logger->warning('IP address {ip} was rate limited by the Registration API.', [
'ip' => $request->getClientIp(),
]);
if (false === $this->kernel->isDebug()) {
$limit = $limiter->consume();

throw new TooManyRequestsHttpException();
if (false === $limit->isAccepted()) {
$this->logger->warning('IP address {ip} was rate limited by the Registration API.', [
'ip' => $request->getClientIp(),
]);

throw new TooManyRequestsHttpException($limit->getRetryAfter()->getTimestamp() - time());
}
}

$user = $this->serializer->deserialize($request->getContent(), User::class, 'json', ['groups' => 'user:register']);
Expand Down

0 comments on commit 686d39d

Please sign in to comment.