<?php
namespace App\Security\Voter;
use App\Entity\AuthAttempt;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class AuthAttemptVoter extends Voter
{
protected RequestStack $requestStack;
protected EntityManagerInterface $entityManager;
private ContainerInterface $container;
public function __construct(
RequestStack $requestStack,
EntityManagerInterface $entityManager,
ContainerInterface $container
) {
$this->requestStack = $requestStack;
$this->entityManager = $entityManager;
$this->container = $container;
}
const VIEW_AUTH_FORM_CAPTCHA = 'view_auth_form_captcha';
protected function supports($attribute, $subject)
{
return in_array($attribute, [self::VIEW_AUTH_FORM_CAPTCHA]);
}
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
// ... (check conditions and return true to grant permission) ...
switch ($attribute) {
case self::VIEW_AUTH_FORM_CAPTCHA:
return $this->isCanViewAuthFormCaptcha();
break;
}
return false;
}
public function isCanViewAuthFormCaptcha()
{
if (false === $this->container->getParameter('ewz_recaptcha.enabled')) {
return false;
}
$authAttemptsRepo = $this->entityManager->getRepository(AuthAttempt::class);
$request = $this->requestStack->getCurrentRequest();
$clientIp = $request->headers->get('X-Real-IP', $request->getClientIp());
$count = $authAttemptsRepo->getTodayCount($clientIp, $request->attributes->get('_route'));
return $count > 3;
}
}