<?php
namespace App\Security;
use App\Entity\Consultant;
use App\Entity\Jeu;
use App\Entity\Session;
use App\Entity\User;
use App\Entity\Candidat;
use App\Repository\CandidatRepository;
use App\Service\Commun\Utils;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
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\Util\TargetPathTrait;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\Translation\Translator;
class FormAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface
{
use TargetPathTrait;
const USERNAME = 'username';
const PASS = 'password';
private $entityManager;
private $router;
private $csrfTokenManager;
private $passwordEncoder;
private $security;
private $params;
private $translator;
private $user;
// public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder, ParameterBagInterface $params, TranslatorInterface $translator)
// {
// $this->entityManager = $entityManager;
// $this->urlGenerator = $urlGenerator;
// $this->csrfTokenManager = $csrfTokenManager;
// $this->passwordEncoder = $passwordEncoder;
//
// $this->params = $params;
// $this->translator = $translator;
// }
public function __construct(EntityManagerInterface $manager, RouterInterface $router, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordHasherInterface $passwordEncoder, Security $security, ParameterBagInterface $params, TranslatorInterface $translator)
{
$this->manager = $manager;
$this->router = $router;
$this->csrfTokenManager = $csrfTokenManager;
$this->passwordEncoder = $passwordEncoder;
$this->security = $security;
$this->params = $params;
$this->translator = $translator;
}
public function supports(Request $request)
{
return 'security_login' === $request->attributes->get('_route')
&& $request->isMethod('POST');
}
public function getCredentials(Request $request)
{
$credentials = [
FormAuthenticator::USERNAME => $request->request->get(FormAuthenticator::USERNAME),
FormAuthenticator::PASS => $request->request->get(FormAuthenticator::PASS),
'csrf_token' => $request->request->get('_csrf_token'),
];
$request->getSession()->set(
Security::LAST_USERNAME,
$credentials[FormAuthenticator::USERNAME]
);
return $credentials;
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
$token = new CsrfToken('authenticate', $credentials['csrf_token']);
if (!$this->csrfTokenManager->isTokenValid($token)) {
throw new InvalidCsrfTokenException();
}
// die;
/** @var User $user */
$user = $this->manager->getRepository(User::class)->findOneBy([FormAuthenticator::USERNAME => $credentials[FormAuthenticator::USERNAME]]);
if (!$user) {
// fail authentication with a custom error
throw new CustomUserMessageAuthenticationException($this->translator->trans('error.identifiant_introuvable'));
}
$roles = $user->getRoles();
if (!$user->getIsActive()) {
throw new CustomUserMessageAuthenticationException($this->translator->trans('error.disable_account'));
}
if (!in_array('ROLE_ADMIN', $roles, true) && !in_array('ROLE_CONSULTANT', $roles, true) && !in_array('ROLE_MANAGER', $roles, true)) {
/** @var Session $session */
//TODO: Verifier si le jeu est OK.
/*$candidat = $this->manager->getRepository(Candidat::class)->find($user->getId());
$jeu = $candidat->getProject()->getJeu();
if ($jeu->getSocietes()->count() === 0 || $jeu->getCorrespondantsCounter() === 0 || $jeu->isValid() === false || $jeu->getEmailModeles()->count() === 0) {
throw new CustomUserMessageAuthenticationException($this->translator->trans('error.jeu_incomplet'));
}*/
$session = $user->getSession();
if (!$session) {
throw new CustomUserMessageAuthenticationException($this->translator->trans('error.non_inscrit'));
}
if ($session->getStatus() == 'CLOSE') {
throw new CustomUserMessageAuthenticationException($this->translator->trans('error.session_cloturee'));
}
if ($session->getStatus() == 'SOON') {
throw new CustomUserMessageAuthenticationException($this->translator->trans('error.session_non_encore_ouverte'));
}
$sessionSartTime = $this->params->get('session_start_time');
$sessionCloseTime = $this->params->get('session_close_time');
$sessionSartTime = strtotime($sessionSartTime);
$sessionCloseTime = strtotime($sessionCloseTime);
$currentDateTime = new \DateTime();
$currentTime = $currentDateTime->format('H:i:s');
$currentTime = strtotime($currentTime);
if($currentTime < $sessionSartTime || $currentTime >= $sessionCloseTime) {
throw new CustomUserMessageAuthenticationException($this->translator->trans('error.session_indisponible'));
}
$candidat = $this->manager->getRepository(Candidat::class)->find($user->getId());
$jeu = $candidat->getProject()->getJeu();
if ($jeu->getSocietes()->count() === 0 || $jeu->getCorrespondantsCounter() === 0 || $jeu->isValid() === false || $jeu->getEmailModeles()->count() === 0) {
throw new CustomUserMessageAuthenticationException($this->translator->trans('error.session_incomplete'));
}
}
return $this->user = $user;
}
public function checkCredentials($credentials, UserInterface $user)
{
return $this->passwordEncoder->isPasswordValid($user, $credentials[FormAuthenticator::PASS]);
}
/**
* 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, $providerKey)
{
$currentDateTime = new \DateTime();
// dump($token->getAttributes());
// dump($request->attributes);
$this->user->eraseCredentials();
$this->user->setConnectionOrigin('form');
$this->user->setSsoPartner('');
$this->user->setDateLastConnection($currentDateTime);
$this->user->addNumberConnection();
$this->manager->flush();
if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
return new RedirectResponse($targetPath);
}
$roles = $token->getRoleNames();
if (in_array('ROLE_ADMIN', $roles, true) || in_array('ROLE_CONSULTANT', $roles, true) || in_array('ROLE_MANAGER', $roles, true)) {
$redirection = new RedirectResponse($this->router->generate('admin_index'));
}else{
// $candidat = $this->candidatRepository->find($this->user->getId());
// /** @var Jeu $jeu */
// $jeu = $candidat->getProject()->getJeu();
//
// $request->setLocale($jeu->getLangue());
//
// $em = $this->managerRegistry->getManager();
//
// $travelDestinationRepository = $em->getRepository(TravelDestination::class);
// $product = $this->getDoctrine()
// ->getRepository(Product::class)
// ->find($id);
//
// $manager = $this->getDoctrine()->getManager();
// $product = $manager->getRepository(Product::class)->find($id);
//
/** @var Candidat $candidat */
$candidat = $this->manager->getRepository(Candidat::class)->find($this->user->getId());
$langueJeu = $candidat->getProject()->getJeu()->getLangue();
$request->setLocale($langueJeu);
$redirection = new RedirectResponse($this->router->generate('mail_inbox'));
// TODO voir si il faut en envisager les autres cas de repture à midi
}
return $redirection;
}
protected function getLoginUrl()
{
return $this->router->generate("security_login");
}
}