<?php
namespace App\Controller;
use App\Entity\SMS;
use Symfony\Component\Mime\Email;
use App\Repository\UserRepository;
use App\Form\ResetPasswordFormType;
use App\Form\SetSMSFormType;
use App\Form\InitPasswordFormType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\HttpFoundation\Request ;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
class SecurityController extends AbstractController
{
#[Route(path: '/login', name: 'app_login')]
public function login(AuthenticationUtils $authenticationUtils): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('app_home');
}
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login.html.twig', [
'last_username' => $lastUsername,
'error' => $error
]);
}
#[Route(path: '/logout', name: 'app_logout')]
public function logout(): void
{
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
}
#[Route(path: '/forget-pass', name: 'app_forgetPassword')]
public function forgetPass(Request $request, UserRepository $userRepository,
TokenGeneratorInterface $tokenGenerator,
EntityManagerInterface $entityManager,
MailerInterface $mailer): Response
{
$form = $this->createForm(ResetPasswordFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$email = $form->get('email')->getData();
$user = $userRepository->findOneBy([
'email' => $email
]);
if($user) {
/* envoi par mail */
// si user existe génère un token de réinitilisation -> on utilise le Tokengenerator de symfony
/*
$token = $tokenGenerator->generateToken();
$user->setResetToken($token);
$entityManager->persist($user);
$entityManager->flush();
// on génére un lien réinitilisation de mot de passe
$baseUrl = $request->getScheme() . '://' . $request->getHttpHost() . $request->getBasePath();
$url = $baseUrl . $this->generateUrl('app_resetPassword', ['token' => $token, UrlGeneratorInterface::ABSOLUTE_URL]);
*/
// Données du mail
/*
$html = '<p>Bonjour ' . $user->getNom() . ' ' . $user->getPrenom() . '</p>
<p>Afin de réinitialiser votre mot de passe, veillez cliquer sur ce lien:</p>
<a href=" '. $url . ' ">' . $url . '</a>
<p>Meilleures salutations</p>';
$email = (new Email())
->from('mbe@vertotek.com')
->to($user->getEmail())
->subject('Réinitilisation de mot de passe')
->html($html);
$mailer->send($email);
$this->addFlash('success', 'Email envoyé avec succès');
//return $this->redirectToRoute('app_login');
return $this->render('security/reset_password_message.html.twig', [
'user' => $user
]);
*/
/**** fin de l'envoi par mail */
$token = random_int(100000, 999999);
//$token = 224466;
$phone_number = $user->getPhoneNumber();
$hidden_number = '';
for($i = 0; $i < strlen($phone_number) - 4; $i++) {
$hidden_number = $hidden_number . '*';
}
$hidden_number = $hidden_number . substr($phone_number, -4);
if($phone_number != null) {
// On sauvegarde la date de creation de token
$user->setResetToken($token);
$user->setResetTokenCreatedAt(new \DateTimeImmutable());
$entityManager->persist($user);
$entityManager->flush();
$sender = 'Apol - Time Manager';
$str_sms = 'APOL votre de code de validation: '. $token;
//Envoi SMS
$arr_data_from_sms = [];
$status = '';
$credits = '';
$message = '';
$arr_data_from_sms = $this->sendSMS($str_sms, $phone_number, $sender);
$status = 1;
if(isset($arr_data_from_sms['status'])) $status = $arr_data_from_sms['status'];
if(isset($arr_data_from_sms['credits'])) $credits = $arr_data_from_sms['credits'];
if(isset($arr_data_from_sms['message'])) $message = $arr_data_from_sms['message'];
$sms = new Sms();
$sms->setStatus($status);
$sms->setCredits($credits);
$sms->setMessage($message);
$sms->setPhoneNumber($phone_number);
$entityManager->persist($sms);
$entityManager->flush();
if($status === 1) {
$this->addFlash('success', 'Merci de saisir le code que vous avez reçu par SMS au '. $hidden_number);
return $this->redirectToRoute('app_set_sms');
} else {
$this->addFlash('danger', 'Problème avec l\'envoi de SMS. Merci de contacter votre administrateur');
return $this->redirectToRoute('app_login');
}
} else {
$this->addFlash('danger', 'Aucun no de mobile trouvé. Contactez votre administrateur');
}
return $this->render('security/reset_password_message.html.twig', [
'user' => $user
]);
}
$this->addFlash('danger', 'Un problème est survenu');
return $this->redirectToRoute('app_login');
}
return $this->render('security/reset_password_request.html.twig', [
'form' => $form->createView(),
]);
}
#[Route(path: '/set-sms', name: 'app_set_sms')]
public function setSms(Request $request, UserRepository $userRepository,
EntityManagerInterface $entityManager,
UserPasswordHasherInterface $userPasswordHasher): Response
{
//on vérifier si le token de l'utilisateur existe
$form = $this->createForm(SetSMSFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$code = $form->get('code')->getData();
$user = $userRepository->findOneByResetToken($code);
if($user) {
return $this->redirectToRoute('app_resetPassword', ['token' => $code], Response::HTTP_SEE_OTHER);
//return $this->redirect('app_resetPassword', array('token' => $code));
} else {
$this->addFlash('danger', 'Code SMS invalide ');
}
}
return $this->render('security/set_sms.html.twig', [
'form' => $form->createView()
]);
}
#[Route(path: '/reset-pass/{token}', name: 'app_resetPassword')]
public function resetPass(String $token, Request $request, UserRepository $userRepository,
EntityManagerInterface $entityManager,
UserPasswordHasherInterface $userPasswordHasher): Response
{
//on vérifier si le token de l'utilisateur existe
$user = $userRepository->findOneByResetToken($token);
if($user) {
$form = $this->createForm(InitPasswordFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user->setResetToken('');
$user->setPassword(
$userPasswordHasher->hashPassword(
$user,
$form->get('plainPassword')->getData()
)
);
$entityManager->persist($user);
$entityManager->flush();
$this->addFlash('success', 'Mot de passe enregistré avec succès');
return $this->redirectToRoute('app_login');
}
return $this->render('security/init_password.html.twig', [
'form' => $form->createView()
]);
}
$this->addFlash('danger', 'Jeton invalid');
return $this->redirectToRoute('app_login');
}
#[Route('/mobileApi/forget-pass', name: 'mobile_api_forgetPassword', methods: ['POST'])]
public function mobileForgetPassword(Request $request,
UserRepository $userRepository,
EntityManagerInterface $entityManager,
MailerInterface $mailer): Response
{
$json_in = $request->getContent();
$obj_data = json_decode($json_in);
$email = $obj_data->email;
$user = $userRepository->findOneBy([
'email' => $email
]);
if($user) {
$token = random_int(100000, 999999);
//$token = 224466;
$phone_number = $user->getPhoneNumber();
if($phone_number != null) {
// On sauvegarde la date de creation de token
$user->setResetToken($token);
$user->setResetTokenCreatedAt(new \DateTimeImmutable());
$entityManager->persist($user);
$entityManager->flush();
$sender = 'Apol - Time Manager';
$str_sms = 'APOL votre de code de validation: '. $token;
$this->sendSMS($str_sms, $phone_number, $sender);
$arr_response = [
'code' => 200,
'user_id' => $user->getId(),
'token_code' => $token,
'message' => 'Merci de saisir le code que vous avez reçu par SMS'
];
} else {
$arr_response = [
'code' => 204,
'message' => 'Aucun no de mobile trouvé. Merci de contacter votre administrateur'
];
}
} else {
$arr_response = [
'code' => 400,
'message' => 'Une erreur s\'est produite. Merci de contacter votre administrateur',
];
}
return $this->json($arr_response);
}
private function sendSMS(String $str_sms, String $phone_number, $sender)
{
$apol_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI3MzM3NyIsImlhdCI6MTY3NjE1NDExOS4xMjc1MX0.60yTcAmlGChiWGQ3Dnh82rsefNHa1pHGUsunPjQmh0o";
$token = $apol_token;
$content = $str_sms;
$numbers = array($phone_number);
$sender = $sender;
$recipients = array();
foreach ($numbers as $n) {
$recipients[] = array('value' => $n);
}
$postdata = array(
'sms' => array(
'message' => array(
'text' => $content,
'sender' => $sender
),
'recipients' => array('gsm' => $recipients)
)
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.smsup.ch/send");
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postdata));
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Accept: application/json', 'Authorization: Bearer ' . $token));
$smsUp_response = curl_exec($ch);
curl_close($ch);
/*
$smsResponse ='{"status":1,"message":"OK","ticket":"182384518","cost":1,"credits":49,
"total":1,"sent":1,"blacklisted":0,"duplicated":0,"invalid":0,"npai":0}';
$obj_data = json_decode($smsResponse);
*/
$obj_data = json_decode($smsUp_response);
$status = $obj_data->status;
$message = $obj_data->message;
$credits = $obj_data->credits;
return [
'status' => $status,
'message' => $message,
'credits' => $credits
];
}
/*
* Réception du code depuis le mobile
*/
#[Route('/mobileApi/reset-pass', name: 'mobile_api_resetPassword', methods: ['POST'])]
public function moibleGetTokenPassword(Request $request, UserRepository $userRepository,
EntityManagerInterface $entityManager,
UserPasswordHasherInterface $userPasswordHasher): Response
{
//on vérifier si le token de l'utilisateur existe
try{
$json_in = $request->getContent();
$obj_data = json_decode($json_in);
$uid = $obj_data->user_id;
$plainPassword = $obj_data->password;
$user = $userRepository->findOneBy([
'id' => $uid
]);
if($user) {
$user->setResetToken('');
$user->setPassword(
$userPasswordHasher->hashPassword(
$user,
$plainPassword
)
);
$entityManager->persist($user);
$entityManager->flush();
return $this->json([
'status' => 201,
'user_id' => $user->getId(),
'message' => 'Mot de passe enregistré avec succès'
]);
} else {
return $this->json([
'status' => 403,
'user_id' => null,
'message' => 'Une erreur s\'est produite. Merci de contacter votre administrateur'
]);
}
} catch(Exception $e) {
return $this->json([
'status' => 400,
'message' => $e->getMessage()
]);
}
}
#[Route(path: '/api/login', name: 'api_login')]
public function apiLogin(AuthenticationUtils $authenticationUtils): Response
{
$user = $this->getUser();
return $this->json(['email' => 'mbe@mbe.com']);
}
#[Route('/mobileApi/logout', name: 'mobile_api_logout', methods: ['POST'])]
public function moibleLogout(Request $request, UserRepository $userRepository,
EntityManagerInterface $entityManager): Response
{
//on vérifier si le token de l'utilisateur existe
try{
$json_in = $request->getContent();
$obj_data = json_decode($json_in);
$uid = $obj_data->user_id;
$user = $userRepository->findOneBy([
'id' => $uid
]);
$email = $user->getEmail();
$qb = $entityManager->createQueryBuilder();
$qb->delete('refreshTokens', 'rt');
$qb->where('rt.mail = :email');
$qb->setParameter('email', $email);
$qb->getQuery()->execute();
} catch(Exception $e) {
return $this->json([
'status' => 400,
'message' => $e->getMessage()
]);
}
}
#[Route('/test-email')]
public function sendEmail(MailerInterface $mailer): Response
{
$email = (new Email())
->from('noreply@vertotek.com')
->to('mbenaraich@sky4u.ch')
->subject('Time for Symfony Mailer!')
->text('Sending emails is fun again!')
->html('<p>See Twig integration for better HTML integration!</p>');
$mailer->send($email);
return $this->redirectToRoute('app_home');
}
}