feat: access denied if email is not validated

This commit is contained in:
Maël Gangloff
2024-08-05 02:00:13 +02:00
parent 925f3708c0
commit 34b0ce7a9b
2 changed files with 67 additions and 1 deletions

View File

@@ -52,7 +52,7 @@ security:
json_login:
check_path: api_login
username_path: email
success_handler: lexik_jwt_authentication.handler.authentication_success
success_handler: App\Security\JWTAuthenticator
failure_handler: lexik_jwt_authentication.handler.authentication_failure
login_throttling:
limiter: app.login_rate_limiter

View File

@@ -0,0 +1,66 @@
<?php
namespace App\Security;
use App\Entity\User;
use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent;
use Lexik\Bundle\JWTAuthenticationBundle\Events;
use Lexik\Bundle\JWTAuthenticationBundle\Response\JWTAuthenticationSuccessResponse;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
readonly class JWTAuthenticator implements AuthenticationSuccessHandlerInterface
{
public function __construct(
private JWTTokenManagerInterface $jwtManager,
private EventDispatcherInterface $dispatcher,
private iterable $cookieProviders = [],
private bool $removeTokenFromBodyWhenCookiesUsed = true
) {
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token): Response
{
return $this->handleAuthenticationSuccess($token->getUser());
}
public function handleAuthenticationSuccess(UserInterface $user, $jwt = null): Response
{
if (($user instanceof User) && !$user->isVerified()) {
throw new AccessDeniedHttpException('This user has not yet validated their email address.');
}
if (null === $jwt) {
$jwt = $this->jwtManager->create($user);
}
$jwtCookies = [];
foreach ($this->cookieProviders as $cookieProvider) {
$jwtCookies[] = $cookieProvider->createCookie($jwt);
}
$response = new JWTAuthenticationSuccessResponse($jwt, [], $jwtCookies);
$event = new AuthenticationSuccessEvent(['token' => $jwt], $user, $response);
$this->dispatcher->dispatch($event, Events::AUTHENTICATION_SUCCESS);
$responseData = $event->getData();
if ($jwtCookies && $this->removeTokenFromBodyWhenCookiesUsed) {
unset($responseData['token']);
}
if ($responseData) {
$response->setData($responseData);
} else {
$response->setStatusCode(Response::HTTP_NO_CONTENT);
}
return $response;
}
}