<?php
namespace App\Controller;
use App\Entity\Contact;
use App\Entity\Requests;
use App\Entity\User;
use App\Form\ContactType;
use App\Form\ResetPasswordScreenType;
use App\Form\ResetPasswordType;
use App\Form\User\UserCreateAccountType;
use App\Form\User\UserCreateProfileType;
use App\Form\User\UserMakeRequestType;
use App\Repository\UserRepository;
use App\Services\EmailService;
use App\Utilities\Random;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use Random\RandomException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
use Symfony\Component\String\Slugger\SluggerInterface;
/**
* Gestion de la page d'accueil du site
*/
class DefaultController extends AbstractController
{
/**
* @var EntityManagerInterface
*/
private $em;
/**
* @var Sluggerinterface
*/
private $slugger;
public function __construct(EntityManagerInterface $em, SluggerInterface $slugger)
{
$this->em = $em;
$this->slugger = $slugger;
}
/**
* Gestion de la page d'accueil
*
* @Route("/", name="app_default_index")
*
* @return Response
*/
public function index(): Response
{
return $this->render("home/index-new.html.twig");
}
/**
* Page participation
*
* @Route("/participation", name="app_default_participation")
*
* @return Response
*/
public function participation(): Response
{
return $this->render("home/participation-new.html.twig");
}
/**
* Page faq
*
* @Route("/foire-aux-questions", name="app_default_faq")
*
* @return Response
*/
public function faq(): Response
{
return $this->render("home/faq-new.html.twig");
}
/**
* Création d'un compte pour un nouveau utilisateur
*
* @Route("/creation-de-compte", name="app_user_register")
*
* @param Request $request
* @param TokenGeneratorInterface $tokenGeneratorInterface
* @param EmailService $emailService
*
* @return Response
* @throws TransportExceptionInterface
*/
public function createAccount(Request $request, TokenGeneratorInterface $tokenGeneratorInterface, EmailService $emailService): Response
{
$user = new User;
$form = $this->createForm(UserCreateAccountType::class, $user);
$form->handleRequest($request);
//dd($user);
if ($form->isSubmitted() && $form->isValid()) {
$user->setVerified(false)
->setVerifiedToken(sha1($tokenGeneratorInterface->generateToken()))
->setVerifiedExpiration((new \DateTimeImmutable)->modify('1 hours'));
$this->em->persist($user);
$this->em->flush();
$emailService->send('email_create_account', $user, 'Création de compte', []);
$this->addFlash('success', "Votre compte a été crée, un mail vous a été envoyé pour confirmation.");
return $this->redirectToRoute('app_default_index');
}
return $this->render('home/create_account.html.twig', ['form' => $form->createView()]);
}
/**
* @Route("verify", name="app_verify_email")
*
* @param Request $request
* @param EntityManagerInterface $entityManagerInterface
* @param EmailService $emailService
* @param TokenGeneratorInterface $tokenGeneratorInterface
* @param UserPasswordHasherInterface $userPasswordHasherInterface
* @return Response
* @throws TransportExceptionInterface
*/
public function verifyEmail(Request $request, EntityManagerInterface $entityManagerInterface, EmailService $emailService, TokenGeneratorInterface $tokenGeneratorInterface, UserPasswordHasherInterface $userPasswordHasherInterface): Response
{
if ($request->query->get('token') === null) {
$this->createNotFoundException();
}
$user = $entityManagerInterface->getRepository(User::class)->findOneBy(['verifiedToken' => $request->query->get('token')]);
if ($user === null) {
return $this->redirectToRoute('app_default_index');
};
if ($user->getVerifiedExpiration()->getTimestamp() < (new \DateTimeImmutable)->getTimestamp()) {
$user->setVerifiedExpiration((new \DateTimeImmutable)->modify('1 hours'))
->setVerifiedToken(sha1($tokenGeneratorInterface->generateToken()));
$entityManagerInterface->persist($user);
$entityManagerInterface->flush();
$emailService->send('email_create_account', $user, 'Création de compte', []);
$this->addFlash('warning', "Un mail de comfirmation de compte vous a été envoyé, veuillez confirmer votre email pour acceder à notre service.");
return $this->redirectToRoute('app_default_index');
}
$defaultPassword = Random::randomString(8);
$user->setPassword($userPasswordHasherInterface->hashPassword($user, $defaultPassword))
->setVerified(true)
->setVerifiedExpiration(null)
->setVerifiedToken(null)
->setLocked(false);
$entityManagerInterface->persist($user);
$entityManagerInterface->flush();
$emailService->send('email_customer_lock_status', $user, '[GRAND PRIX ANSUTEN]', compact('defaultPassword'));
$this->addFlash('success', "Votre adresse e-mail a été vérifiée ! Un e-mail contenant vos informations d'accès à la plateforme vous a été envoyé.");
return $this->redirectToRoute('app_default_index');
}
/**
* Création de profil d'un nouvel utilisateur
*
* @Route("/faire-une-demande/creation-de-compte-profile", name="app_user_request_account_create_step_2")
*
* @param Request $request
* @param UserPasswordHasherInterface $hash
* @param EmailService $emailService
* @return Response
* @throws TransportExceptionInterface|RandomException
*/
public function createProfile(Request $request, UserPasswordHasherInterface $hash, EmailService $emailService): Response
{
$user = $request->getSession()->get('newRequester');
if ($user === null) throw new AccessDeniedHttpException();
$form = $this->createForm(UserCreateProfileType::class, $user);
$form->handleRequest($request);
$certificate = $form->get('certificateFiles')->getData();
if (
$certificate == null
&& ($user->getProfile() == 'Collectivité(Préfecture,Mairie)'
|| $user->getProfile() == "ONG,Association")
) {
$form->get('certificateFiles')->addError(new FormError('Veuillez téleverser les documents légaux de votre entité.'));
}
if ($form->isSubmitted() && $form->isValid()) {
if (
$user->getProfile() == 'Collectivité(Préfecture,Mairie)'
|| $user->getProfile() == "ONG,Association"
) {
$time = time();
$t = intval(substr($time, (strlen($time) - 3)));
$token = intval(substr(mt_rand(), 0, 4)) . $t;
$user->setToken($token);
} else {
$user->setToken($user->getCardNumber());
}
$defaultPassword = self::randomString(8);
$user
->setPassword($hash->hashPassword($user, $defaultPassword))->setRoles(['ROLE_USER']);
$this->em->persist($user);
$this->em->flush();
$emailService->send('email_send_password', $user, "Création de compte", ['defaultPassword' => $defaultPassword]);
$emailService->sendAdmin('email_creation_account', $user, "Création de compte");
$request->getSession()->remove('newRequester');
//$request->getSession()->remove('code_country');
$this->addFlash('success', "Votre compte a été créé, veuillez consulter votre boite mail.");
return $this->redirectToRoute('app_user_request_create', ['id' => $user->getId()]);
}
return $this->render('home/create_profile.html.twig', [
'form' => $form->createView(),
]);
}
/**
* Création d'une demande d'un nouveau utilisateur
*
* @Route("/faire-une-demande/{id}/definition-du-besoin",name="app_user_request_create")
*
* @param User $user
*
* @param Request $request
*
* @return Response
*/
public function createRequest(Request $request, EmailService $emailService, User $user): Response
{
$requests = new Requests();
$form = $this->createForm(UserMakeRequestType::class, $requests);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$requests->setUserRequest($user)->setStatus('transmise')->setSlug($this->slugger->slug($requests->getRequirement(), '-'));
$this->em->persist($requests);
$this->em->flush();
$emailService->send('email_create_new_request', $user, "Transmission de votre demande", ['request' => $requests]);
$emailService->sendAdmin('email_receive_new_request', $user, "Nouvelle demande", ['request' => $requests]);
$this->addFlash('account-success', $user->getEmail());
$request->getSession()->remove('newRequester');
return $this->redirectToRoute('app_default_index');
}
return $this->render('home/create_request.html.twig', ['form' => $form->createView(), 'id_user' => $user->getId()]);
}
/**
* Annulation de la création de la nouvelle demande pour un nouveau utilisateur
*
* @Route("/{id}/annuler-la-demande", name="app_user_request_cancel")
*
* @param Requests $request
*
* @param EntityManagerInterface $em
*
* @return Response
*/
public function cancelRequest(Requests $request, EntityManagerInterface $em): Response
{
$user = $request->getUserRequest();
$em->remove($request);
$em->remove($user);
$em->flush();
return $this->redirectToRoute('app_default_index');
}
/**
* Recherche l'adresse mail pour une réinitialisation
* de mot de passe d'un compte utilisateur
*
* @Route("/demande-de-mot-de-passe-oublie", name="app_user_screen_reset_password", methods={"GET","POST"})
*
* @param UserRepository $userRepository
*
* @param Request $request
*
* @param EmailService $emailService
*
* @return Response
* @throws TransportExceptionInterface
*/
public function screenPasswordUpadate(UserRepository $userRepository, Request $request, EmailService $emailService): Response
{
$form = $this->createForm(ResetPasswordScreenType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$email = $form->get('email')->getData();
$user = $userRepository->findOneBy(['email' => $email]);
if ($user !== null) {
$data = [
'email' => $email,
'expire' => (new DateTime())->modify('15 minutes')->getTimestamp(),
];
$token = self::decrypt_encrypt_token('encrypt', $data);
$this->addFlash('success', "Un mail vous a été envoyé pour la modification de votre mot de passe.");
// Envoi d'email de reinitialisation de compte
$emailService->send("email_reset_password", $user, "Demande de modification de mot de passe", compact('token'));
} else {
$this->addFlash('warning', "Cette adresse e-mail est introuvable");
}
}
return $this->render('security/screen_reset_password.html.twig', ['form' => $form->createView()]);
}
/**
* Réinitialisation de mot de passe d'un compte utilisateur
*
* @Route("/reinitialisation-de-mot-de-passe/{token}", name="app_user_reset_password")
*
* @param $token
* @param UserRepository $userRepository
*
* @param Request $request
*
* @param UserPasswordHasherInterface $userPasswordHasherInterface
*
* @param EntityManagerInterface $em
*
* @param EmailService $emailService
*
* @return Response
* @throws TransportExceptionInterface
*/
public function forgotPassword($token, UserRepository $userRepository, Request $request, UserPasswordHasherInterface $userPasswordHasherInterface, EntityManagerInterface $em, EmailService $emailService): Response
{
if ($token === null) {
throw new NotFoundHttpException('Desolé, cette URL est invalide');
}
$decryptToken = self::decrypt_encrypt_token('decrypt', $token);
$expire = $decryptToken['expire'];
$email = $decryptToken['email'];
if ($expire < time()) {
$this->addFlash('danger', "L'URL pour la réinitialisation de votre mot de passe a expiré");
return $this->redirectToRoute('app_login');
}
$form = $this->createForm(ResetPasswordType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user = $userRepository->findOneBy(['email' => $email]);
$password = $form->get('password')->getData();
if ($user !== null) {
$user->setPassword($userPasswordHasherInterface->hashPassword($user, $password))
->setUpdatedPassword(true);
$em->persist($user);
$em->flush();
$emailService->send("email_reset_password_success", $user, 'Modification de mot de passe', []);
$this->addFlash('success', 'Votre mot de passe a bien été modifié.');
if ($request->query->get('rd') === 'user') {
return $this->redirectToRoute('app_user_index');
}
}
return $this->redirectToRoute('app_login');
}
return $this->render("security/reset_password.html.twig", ['form' => $form->createView()]);
}
/**
* Gestion de formulaire de contact
* pour q'un utilisateur puisse contacter l'ANSUTEN depuis la plateforme
*
* @Route("/contacter", name="app_contact_use")
*
* @param Request $request
*
* @param EmailService $emailService
*
* @param Security $security
*
* @return Response
* @throws TransportExceptionInterface
*/
public function contact_use(Request $request, EmailService $emailService, Security $security): Response
{
$contact = new Contact();
$form = $this->createForm(ContactType::class, $contact);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$emailService->sendContactUse('email_receive_message_from_user', $contact, "Nouveau message");
$this->addFlash('success', "Merci de votre intérêt, votre message a été enovoyé.");
return $this->redirectToRoute('app_default_index');
}
return $this->render('home/contact_use.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @Route("/en-savoir-plus", name="app_about_use")
* @param Request $request
*
* @return Response
*/
public function about_use(Request $request): Response
{
return $this->render('/home/about_use.html.twig');
}
/**
* Cryptage et décryptage du token de réinitialisation de mot de passe
*
* @param string $action
*
* @param mixed $data
*
* @return bool|string|array
*/
public static function decrypt_encrypt_token(string $action, $data)
{
$encrypt_method = "AES-256-CBC";
$secret_key = 'ANSUTEN-GUINEE-2022-BRAINSENSE';
$secret_iv = '123456789101112';
$key = hash('sha256', $secret_key);
$iv = substr(hash('sha256', $secret_iv), 0, 16);
$result = false;
if ($action === 'decrypt') {
$result = json_decode(openssl_decrypt(base64_decode($data), $encrypt_method, $key, 0, $iv), true);
} else if ($action === 'encrypt') {
$result = base64_encode(openssl_encrypt(json_encode($data), $encrypt_method, $key, 0, $iv));
}
return $result;
}
/**
* Fonction de génération de lettre et chiffre
* pour la génération d'un mot de passe aléatoir
*
* @param int $max la taille maximum de la chaine génerée
*
* @return string
* @throws RandomException
*/
private static function randomString(int $max = 8): string
{
$char = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randomString = "";
for ($i = 0; $i < $max; $i++) {
$index = random_int(0, strlen($char) - 1);
$randomString .= $char[$index];
}
return $randomString;
}
}
# zepekegno <moussa.traore-interne@brainsense.fr>