|
|
@@ -2,107 +2,71 @@ |
|
|
|
|
|
|
|
namespace Lc\SovBundle\Authenticator; |
|
|
|
|
|
|
|
use Lc\SovBundle\Model\User\UserInterface; |
|
|
|
use Lc\SovBundle\Doctrine\EntityManager; |
|
|
|
use Lc\SovBundle\Repository\User\UserStore; |
|
|
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; |
|
|
|
use Symfony\Component\Form\FormFactoryInterface; |
|
|
|
use Symfony\Component\HttpFoundation\RedirectResponse; |
|
|
|
use Symfony\Component\HttpFoundation\Request; |
|
|
|
use Symfony\Component\Security\Core\User\UserInterface as SfUserInterface; |
|
|
|
use Symfony\Component\HttpFoundation\Response; |
|
|
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; |
|
|
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; |
|
|
|
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; |
|
|
|
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException; |
|
|
|
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException; |
|
|
|
use Symfony\Component\Security\Core\Security; |
|
|
|
use Symfony\Component\Security\Core\User\UserProviderInterface; |
|
|
|
use Symfony\Component\Security\Csrf\CsrfToken; |
|
|
|
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface; |
|
|
|
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator; |
|
|
|
use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface; |
|
|
|
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator; |
|
|
|
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge; |
|
|
|
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; |
|
|
|
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials; |
|
|
|
use Symfony\Component\Security\Http\Authenticator\Passport\Passport; |
|
|
|
use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; |
|
|
|
use Symfony\Component\Security\Http\Util\TargetPathTrait; |
|
|
|
|
|
|
|
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface |
|
|
|
class LoginFormAuthenticator extends AbstractLoginFormAuthenticator |
|
|
|
{ |
|
|
|
use TargetPathTrait; |
|
|
|
|
|
|
|
public const LOGIN_ROUTE = 'sov_login'; |
|
|
|
|
|
|
|
private $entityManager; |
|
|
|
private $urlGenerator; |
|
|
|
private $csrfTokenManager; |
|
|
|
private $passwordEncoder; |
|
|
|
protected $parameterBag; |
|
|
|
protected UrlGeneratorInterface $urlGenerator; |
|
|
|
protected UserStore $userStore; |
|
|
|
protected FormFactoryInterface $formFactory; |
|
|
|
protected ParameterBagInterface $parameterBag; |
|
|
|
|
|
|
|
public function __construct( |
|
|
|
EntityManager $entityManager, |
|
|
|
UrlGeneratorInterface $urlGenerator, |
|
|
|
CsrfTokenManagerInterface $csrfTokenManager, |
|
|
|
UserPasswordEncoderInterface $passwordEncoder, |
|
|
|
ParameterBagInterface $parameterBag |
|
|
|
) |
|
|
|
{ |
|
|
|
$this->entityManager = $entityManager; |
|
|
|
UrlGeneratorInterface $urlGenerator, |
|
|
|
UserStore $userStore, |
|
|
|
FormFactoryInterface $formFactory, |
|
|
|
ParameterBagInterface $parameterBag |
|
|
|
) { |
|
|
|
$this->urlGenerator = $urlGenerator; |
|
|
|
$this->csrfTokenManager = $csrfTokenManager; |
|
|
|
$this->passwordEncoder = $passwordEncoder; |
|
|
|
$this->userStore = $userStore; |
|
|
|
$this->formFactory = $formFactory; |
|
|
|
$this->parameterBag = $parameterBag; |
|
|
|
} |
|
|
|
|
|
|
|
public function supports(Request $request) |
|
|
|
public function supports(Request $request): bool |
|
|
|
{ |
|
|
|
return self::LOGIN_ROUTE === $request->attributes->get('_route') |
|
|
|
&& $request->isMethod('POST'); |
|
|
|
return $request->isMethod('POST') && $this->getLoginUrl($request) === $request->getPathInfo(); |
|
|
|
} |
|
|
|
|
|
|
|
public function getCredentials(Request $request) |
|
|
|
public function authenticate(Request $request): PassportInterface |
|
|
|
{ |
|
|
|
$credentials = [ |
|
|
|
'email' => $request->request->get('email'), |
|
|
|
'password' => $request->request->get('password'), |
|
|
|
'csrf_token' => $request->request->get('_csrf_token'), |
|
|
|
]; |
|
|
|
$request->getSession()->set( |
|
|
|
Security::LAST_USERNAME, |
|
|
|
$credentials['email'] |
|
|
|
$email = $request->request->get('email'); |
|
|
|
$password = $request->request->get('password'); |
|
|
|
$csrfToken = $request->request->get('_csrf_token'); |
|
|
|
|
|
|
|
return new Passport( |
|
|
|
new UserBadge($email, function ($userIdentifier) { |
|
|
|
return $this->userStore->getOneByEmail($userIdentifier); |
|
|
|
}), |
|
|
|
new PasswordCredentials($password), |
|
|
|
[new CsrfTokenBadge('authenticate', $csrfToken)] |
|
|
|
); |
|
|
|
|
|
|
|
return $credentials; |
|
|
|
} |
|
|
|
|
|
|
|
public function getUser($credentials, UserProviderInterface $userProvider) |
|
|
|
{ |
|
|
|
$token = new CsrfToken('authenticate', $credentials['csrf_token']); |
|
|
|
if (!$this->csrfTokenManager->isTokenValid($token)) { |
|
|
|
throw new InvalidCsrfTokenException(); |
|
|
|
} |
|
|
|
|
|
|
|
$user = $this->entityManager->getRepository(UserInterface::class)->findOneBy( |
|
|
|
['email' => $credentials['email']] |
|
|
|
); |
|
|
|
|
|
|
|
if (!$user) { |
|
|
|
// fail authentication with a custom error |
|
|
|
throw new CustomUserMessageAuthenticationException('Email could not be found.'); |
|
|
|
} |
|
|
|
|
|
|
|
return $user; |
|
|
|
} |
|
|
|
|
|
|
|
public function checkCredentials($credentials, SfUserInterface $user) |
|
|
|
{ |
|
|
|
return $this->passwordEncoder->isPasswordValid($user, $credentials['password']); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Used to upgrade (rehash) the user's password automatically over time. |
|
|
|
*/ |
|
|
|
public function getPassword($credentials): ?string |
|
|
|
{ |
|
|
|
return $credentials['password']; |
|
|
|
} |
|
|
|
|
|
|
|
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey) |
|
|
|
{ |
|
|
|
public function onAuthenticationSuccess( |
|
|
|
Request $request, |
|
|
|
TokenInterface $token, |
|
|
|
string $providerKey |
|
|
|
): RedirectResponse { |
|
|
|
$routeName = 'home'; |
|
|
|
$email = $request->request->get('email'); |
|
|
|
$loginRedirection = $this->parameterBag->get('lc_sov.login_redirection'); |
|
|
@@ -112,7 +76,7 @@ class LoginFormAuthenticator extends AbstractFormLoginAuthenticator implements P |
|
|
|
if (isset($useReferer) && $useReferer == true) { |
|
|
|
$url = $request->request->get('_target_path'); |
|
|
|
} else { |
|
|
|
$user = $this->entityManager->getRepository(UserInterface::class)->findOneBy(['email' => $email]); |
|
|
|
$user = $this->userStore->getOneByEmail($email); |
|
|
|
|
|
|
|
if (!empty($user)) { |
|
|
|
$roles = $user->getRoles(); |
|
|
@@ -132,8 +96,8 @@ class LoginFormAuthenticator extends AbstractFormLoginAuthenticator implements P |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected function getLoginUrl() |
|
|
|
protected function getLoginUrl(Request $request): string |
|
|
|
{ |
|
|
|
return $this->urlGenerator->generate(self::LOGIN_ROUTE); |
|
|
|
} |
|
|
|
} |
|
|
|
} |