<?php
namespace App\Controller;
use App\Entity\Logs;
use App\Entity\User;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
class SecurityController extends AbstractController
{
#[Route('/security', name: 'security')]
public function index(): Response
{
return $this->render('security/login.html.twig', [
'controller_name' => 'SecurityController',
]);
}
#[Route("/login", name: "app_login")]
public function login(ManagerRegistry $manager, AuthenticationUtils $authenticationUtils): Response
{
// Si on choisi l'anglais, le cookie est mis à jour et on recharge la page
if (isset($_GET['lang'])) {
if ( $_GET['lang'] == 'eng') {
setcookie("lang",'eng',time()+60*60*24*7, "/");
return $this->redirectToRoute('app_login');
}
}
// Idem si on passe en Français
if (!isset($_COOKIE['lang']) || ($_COOKIE['lang'] != 'fra' && $_COOKIE['lang'] != 'eng')) {
setcookie("lang",'fra',time()+60*60*24*7, "/");
return $this->redirectToRoute('app_login');
}
$entityManager = $manager->getManager();
$logsRepository = $entityManager->getRepository(Logs::class);
$user = $this->getUser();
$lang = $_COOKIE['lang'];
// Un fois connecté
if ($user != null) {
if ($this->isGranted('ROLE_ADMIN') == false) {
// On cherche s'il existe déjà des logs pour l'utilisateur
$logs = $user->getLogs();
// S'il n'y en a pas, on le crée pour la série 1
if (!isset($logs) || $logs == [] || $logs[0] == "") {
$lastLog = new Logs;
$lastLog->setUser($user);
$lastLog->setSerieId(1);
// S'il y en a, on cherche s'il y en a un correspondant à la série actuelle de l'utilisateur
} else {
foreach ($logs as $row) {
if ($row->getSerieId() == $user->getCurrentSerie()) {
$lastLog = $row;
}
}
$lastLog = $logsRepository->find($lastLog->getid());
}
// On rajoute une entrée dans la colonne connexion IP du tableau
$lastLog->connectionLogs();
$entityManager->persist($lastLog);
// On met a jour la BDD utilisateur (derniere connexion et derniere action)
$user->setLastLogin(date("y-m-d H:i:s"));
$user->setLastAction("co_" . date("y-m-d H:i:s"));
// On ne garde que les 20 dernière adresse IP afin d'éviter des erreur de nombre de caractere trop important dans la BDD
$IPs = explode("|", $user->getIpAddress());
if (count($IPs) >= 20) {
$IPs = array_splice($IPs,0,1);
}
array_push($IPs, $this->getIp());
$user->setIpAddress(implode("|",$IPs));
$entityManager->persist($user);
$entityManager->flush();
}
// Si c'est un admin qui se connecte, on va directement au backOffice des Utilisateurs
if ( $this->isGranted("ROLE_ADMIN")) {
return $this->redirectToRoute('user_backoffice');
}
// Si c'est un utilisateur
if ($user->getRoles() == ["ROLE_USER"]) {
// Et que ce n'est NI aussi un admin NI visualiser NI qqun ayant fini sa saisie
if ((array_search("ROLE_ADMIN", $user->getRoles()) == false && $user->getUsername() != 'visualiser') && $user->getCurrentSerie() == 11) {
// On force la déconnexion avec un message d'erreur
session_destroy();
$errorPerso = "Identifiants déjà utilisés";
if ($lang == "eng") $errorPerso = "Login no longer available";
// On retourne sur l'écran de login
return $this->render('security/login.html.twig', [
'errorPerso' => $errorPerso,
'error' => $authenticationUtils->getLastAuthenticationError(),
'lang' => $lang,
]);
}
// Sinon, si l'utilisateur n'a pas rempli ses infos (phrase + sexe + age) on l'envoie sur la page où il le fera, sinon en l'envoie sur le questionnaire
if ( $user->getInfos() !== null ) {
return $this->redirectToRoute('questionnaire');
}
return $this->redirectToRoute('introduction');
}
}
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
$session = [];
if (isset($_SESSION)) {
$session = $_SESSION;
}
return $this->render('security/login.html.twig', [
'last_username' => $lastUsername,
'error' => $error,
'errorPerso' => null,
'session' => $session,
'lang' => $lang,
'table' => "login",
]);
}
// Cette fonction sert à enregistrer les log de déconnexion si on se déconnecte avec le bouton
#[Route("/tologout", name: "to_logout")]
public function toLogout(ManagerRegistry $manager): Response
{
$entityManager = $manager->getManager();
$logsRepository = $entityManager->getRepository(Logs::class);
$userRepository = $entityManager->getRepository(User::class);
$user = $this->getUser();
if (isset($user) && $this->isGranted('ROLE_ADMIN') == false) {
// On cherche les Logs de l'utilisateur
$logs = $user->getLogs();
// On récupere le log de la série actuelle de l'utilisateur
foreach ($logs as $row) {
if ($row->getSerieId() == $user->getCurrentSerie()) {
$lastLog = $row;
}
}
$lastLog = $logsRepository->find($lastLog->getid());
// Toute la suite est pour enregistrer ladite déconnexion en BDD
$deco = explode("|", $lastLog->getDeconnexion());
// On ne garde que les 20 dernières déconnexion pour éviter des erreurs en BDD
if (count($deco) >= 20) {
$deco = array_splice($deco,0,1);
}
array_push($deco, date("y-m-d H:i:s"));
if ($deco == null || $deco[0] == "") {$deco[0] = date("y-m-d H:i:s");}
$user->setLastAction("deco_" . date("y-m-d H:i:s"));
$lastLog->setDeconnexion(implode("|", $deco));
$lastLog->setConnexionIp($lastLog->getConnexionIp() . ($lastLog->getConnexionIp()==null?"":"|") . "deco_" . date("y-m-d H:i:s"));
$entityManager->persist($lastLog);
$entityManager->persist($user);
$entityManager->flush();
}
// Puis on envoie vers la fonction qui déconnecte réellement
return $this->redirectToRoute('app_logout');
}
// La fonction qui déconnecte réallement
#[Route("/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.');
}
protected function getIp() {
//whether ip is from the share internet
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
}
//whether ip is from the proxy
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
//whether ip is from the remote address
else {
$ip = $_SERVER['REMOTE_ADDR'];
}
return $ip;
}
}