<?php
namespace App\Controller;
use App\Entity\Token;
use App\Entity\User\Consumer;
use App\Entity\User\Admin;
use App\Entity\User\Identity;
use App\Entity\User\Referent;
use App\Entity\User\User;
use App\Form\RequestResetPasswordType;
use App\Form\User\ResetPasswordType;
use App\Manager\TokenManager;
use App\Message\Email\SendInitializationAccountByEmailMessage;
use App\Repository\MediaObject\MediaObjectRepository;
use App\Service\SendInBlue;
use Doctrine\ORM\EntityManagerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class SecurityController extends AbstractController
{
/**
* @Route("/security", name="security")
*/
public function index()
{
return $this->render('security/index.html.twig', [
'controller_name' => 'SecurityController',
]);
}
/**
* @Route("/login", name="app_login")
* @throws \Exception
*/
public function login(AuthenticationUtils $authenticationUtils, Request $request): Response
{
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
if ($_ENV['RESTRICTION_ACCESS'] && $_ENV['CHECK_MAINTENANCE_PAGE_ON']) {
$allowedIp = [];
$clientIp = $request->getClientIp();
if (isset($_ENV['ALLOWED_IP']) && $_ENV['ALLOWED_IP']) {
$allowedIp = explode(',', $_ENV['ALLOWED_IP']);
}
if (in_array($clientIp, $allowedIp)) {
return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error, 'csrf_token' => 'authenticate']);
}
return $this->render('error/maintenance.html.twig');
}
return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error, 'csrf_token' => 'authenticate']);
}
/**
* @Route("/client_login", name="app_client_login")
*/
public function clientlogin(AuthenticationUtils $authenticationUtils, MediaObjectRepository $mediaObjectRepository): Response
{
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
$logo = $mediaObjectRepository->findOneLikeByName(strtolower($_ENV['APP_PROJET']));
return $this->render('security/client_login.html.twig', [
'last_username' => $lastUsername,
'error' => $error,
'csrf_token' => 'authenticate',
'logo_path' => $logo ? $logo->getFilePath() : null
]);
}
/**
* @Route("/api/public/request-reset-password", name="app_request_reset_password")
* @param Request $request
*
* @return JsonResponse
*/
public function requestResetPassword(Request $request, EntityManagerInterface $entityManager, SendInBlue $sendInBlue,
TokenManager $tokenManager, MessageBusInterface $bus)
{
$data = json_decode($request->getContent(), true);
$form = $this->createForm(RequestResetPasswordType::class, $data);
$form->submit($data);
$email = $data['email'];
if ($form->isValid() && $user = $entityManager->getRepository(Consumer::class)->findOneBy(['email' => $email])) {
if (!$user->isOptinProcess()) {
$url = $_ENV['PRE_INSCRIPTION_MILLERET'];
$templateId = $_ENV['PRE_INSCRIPTION_MILLERET_TEMPLATE_ID'];
$token_initialization = $entityManager->getRepository(Token::class)->findOneBy(['user' => $user, 'name' => Token::NAME_INITIALIZATION_PASSWORD]);
$token = $tokenManager->requestInitializationForgottenPassword($token_initialization);
$identity = $entityManager->getRepository(Identity::class)->findOneBy(['id' => $user->getIdentity()->getId()]);
$url = $url . $token->getId();
$bus->dispatch(new SendInitializationAccountByEmailMessage(
$user->getId(),
$email,
$identity->getGender(),
$identity->getFirstName(),
$identity->getLastName(),
$templateId,
$url)
);
} else {
if ($entityManager->getRepository(Token::class)->countActiveToken($user, Token::NAME_FORGOTTEN_PASSWORD) >= Token::MAX_REQUEST_FORGOTTEN_PASSWORD) {
return new JsonResponse(['error' => 'limit'], 200);
}
$token = $tokenManager->requestResetPassword($user);
$sendInBlue->sendTemplate($data['templateId'], [
'to' => [
["email" => $email]
],
'templateParameters' =>
[
'URL' => $data['url'] . $token->getId(),
'SURNAME' => $token->getUser()->getIdentity()->getFormatedGender() . ' ' . $token->getUser()->getIdentity()->getLastName() . ' ' . $token->getUser()->getIdentity()->getFirstName()
],
]);
}
}
return new JsonResponse(null, 204);
}
/**
* @Route("/forget_password", name="app_forgotten_password")
*/
public function forgottenPassword(Request $request, MediaObjectRepository $mediaObjectRepository,
EntityManagerInterface $entityManager, TokenManager $tokenManager,
SendInBlue $sendInBlue)
{
$error = "";
$success = false;
$request->request->add([
'templateId' => $_ENV['TEMPLATE_RESET_PASSWORD_ADMIN'],
'url' => $request->getSchemeAndHttpHost() . '/reset_password/',
]);
$form = $this->createForm(RequestResetPasswordType::class, $request->request->all());
$form->submit($request->request->all());
if ($form->isValid()) {
$success = true;
$userForgotPassword = $entityManager->getRepository(Referent::class)->findOneBy(['email' => $form->getData()['email']]);
if (!$userForgotPassword) {
$userForgotPassword = $entityManager->getRepository(Admin::class)->findOneBy(['email' => $form->getData()['email'], 'active' => true]);
}
if ($userForgotPassword) {
if ($entityManager->getRepository(Token::class)->countActiveToken($userForgotPassword, Token::NAME_FORGOTTEN_PASSWORD) >= Token::MAX_REQUEST_FORGOTTEN_PASSWORD) {
return new JsonResponse(['error' => 'limit'], 200);
}
$token = $tokenManager->requestResetPassword($userForgotPassword);
$sendInBlue->sendTemplate($form->getData()['templateId'], [
'to' => [
["email" => $userForgotPassword->getEmail()]
],
'templateParameters' =>
[
'URL' => $form->getData()['url'] . $token->getId(),
'SURNAME' => ''
],
]);
}
} else if (isset($form->getData()['email'])) {
$error = "Veuillez renseignez une adresse mail valide";
}
$logo = $mediaObjectRepository->findOneLikeByName(strtolower($_ENV['APP_PROJET']));
return $this->render('security/forgotten_password.html.twig', [
'logo_path' => $logo ? $logo->getFilePath() : null,
'error' => $error,
'success' => $success,
]);
}
/**
* @Route("/reset_password/{token}", name="app_client_reset_password")
* @ParamConverter("token", class="App:Token", options={"id"= "token"})
*/
public function resetPassword(Token $token, Request $request, MediaObjectRepository $mediaObjectRepository,
UserPasswordHasherInterface $passwordEncoder, TokenManager $tokenManager,
EntityManagerInterface $entityManager)
{
$form = $this->createForm(ResetPasswordType::class);
$form->handleRequest($request);
$redirectionPage = 'security/reset_password.html.twig';
$success = false;
$loginRoute = $token->getReferent() ? 'app_client_login' : 'app_login';
$user = $token->getReferent() ?? $token->getUser();
if ($tokenManager->checkValidityToken($token) && $user) {
if ($form->isSubmitted() && $form->isValid()) {
$encodedPassword = $passwordEncoder->hashPassword($user, $form->getData()['plainPassword']);
$user->setPassword($encodedPassword);
// We reset the token so that the user can reset his password once
$token
->setUser(null)
->setReferent(null);
$entityManager->flush();
$success = true;
}
} else {
$redirectionPage = 'security/expired_token.html.twig';
}
$logo = $mediaObjectRepository->findOneLikeByName(strtolower($_ENV['APP_PROJET']));
return $this->render($redirectionPage, [
'logo_path' => $logo ? $logo->getFilePath() : null,
'login_route' => $loginRoute,
'form' => $form->createView(),
'token' => $token->getId(),
'success' => $success
]);
}
/**
* @Route("/logout", name="app_logout")
*/
public function logout()
{
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
}
}