<?php
namespace App\Controller;
use App\Entity\Suggestion;
use App\Entity\User;
use App\Entity\BioAuth;
use App\Entity\BioAuthHistory;
use App\Form\UserType;
use App\Form\SuggestionType;
use App\Repository\UserRepository;
use App\Repository\BioAuthRepository;
use App\Repository\ApplicationRepository;
use App\Repository\BioAuthHistoryRepository;
use App\Repository\CheckQrRepository;
use App\Repository\SuggestionRepository;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Google\Auth\Credentials\ServiceAccountCredentials;
Use Google\Auth\HttpHandler\HttpHandlerFactory;
class SecurityController extends AbstractController
{
/**
* @Route("/login", name="app_login")
*/
public function index(Request $request, AuthenticationUtils $authenticationUtils, UserRepository $userRepo): Response
{
$login = $request->get('_username');
$pass = $request->get('_password');
$msg = "";
if($login)
{
$usr = $userRepo->findOneBy(['username'=>$login]);
if(!empty($usr))
{
if (password_verify($pass, $usr->getPassword()))
{
$session = $request->getSession();
$session->set('usrLogin', $usr->getUsername());
$session->set('usrFirstName', $usr->getFirstName());
$session->set('usrSurName', $usr->getSurName());
$session->set('usrFullName', $usr->getSurName()." ".$usr->getFirstName());
$session->set('usrPhone', $usr->getPhone());
$session->set('usrEmail', $usr->getEmail());
$session->set('usrOrganization', $usr->getOrganization());
//$session->set('usrIsBioAuth', $usr->getIsBioAuth());
if($usr->getIsBioAuth()==2)//Pending bio verification
{
return $this->redirectToRoute('dashboard_double_auth_verification');
}
if($usr->getIsBioAuth()==0 or $usr->getIsBioAuth() == null)//Pending bio subscription
{
return $this->redirectToRoute('dashboard_double_auth_subscription');
}
return $this->redirectToRoute('dashboard_double_auth_verification');
}else{
$msg = "Wrong password...";
}
}else{
$msg = "Wrong login...";
}
}
if($msg)
{
$this->get('session')->getFlashBag()->add('danger', $msg);
}
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
//dump($authenticationUtils);
return $this->render('security/index.html.twig', [
'controller_name' => 'LoginController',
'last_username' => $lastUsername,
'error' => $error,
'msg' => $msg,
]);
/*
return $this->render('security/index.html.twig', [
'controller_name' => 'SecurityController',
]);
*/
}
/**
* @Route("/home", name="app_home")
*/
public function homePage(Request $request, SuggestionRepository $suggestionRepo, UserRepository $userRepo): Response
{
$session = $request->getSession();
$login = $session->get('usrLogin');
$suggestion = new Suggestion();
$form = $this->createForm(SuggestionType::class, $suggestion);
$form->handleRequest($request);
if($login)
{
$usr = $userRepo->findOneBy(['username'=>$login]);
if(!empty($usr))
{
$session = $request->getSession();
$session->set('usrLogin', $usr->getUsername());
$session->set('usrFirstName', $usr->getFirstName());
$session->set('usrFullName', $usr->getSurName()." ".$usr->getFirstName());
$session->set('usrSurName', $usr->getSurName());
$session->set('usrPhone', $usr->getPhone());
$session->set('usrEmail', $usr->getEmail());
$session->set('usrOrganization', $usr->getOrganization());
//$session->set('usrIsBioAuth', $usr->getIsBioAuth());
if($usr->getIsBioAuth()==2)//Pending bio verification
{
return $this->redirectToRoute('dashboard_double_auth_verification');
}
if($usr->getIsBioAuth()==0 or $usr->getIsBioAuth() == null)//Pending bio subscription
{
return $this->redirectToRoute('dashboard_double_auth_subscription');
}
if ($form->isSubmitted() && $form->isValid())
{
$suggestion->setUser($usr);
$suggestionRepository->add($suggestion, true);
$this->get('session')->getFlashBag()->add('success', "Succesfully saved...");
//return $this->redirectToRoute('app_suggestion_index', [], Response::HTTP_SEE_OTHER);
}
}else
{
$this->get('session')->getFlashBag()->add('danger', "An error occurred during the operation, try again...");
return $this->redirectToRoute('app_login');
}
}else
{
$this->get('session')->getFlashBag()->add('danger', "Your session has expired, log in...");
return $this->redirectToRoute('app_login');
}
return $this->renderForm('security/home.html.twig',
[
'userName' => $session->get('usrFullName'),
'suggestion' => $suggestion,
'form' => $form,
]);
}
/**
* @Route("/enroll", name="app_enroll")
*/
public function enroll(Request $request, UserRepository $userRepo): Response
{
$user = new User();
$form = $this->createForm(UserType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid())
{
$userRepo->add($user, true);
$this->get('session')->getFlashBag()->add('success', "Your account has been successfully created...");
return $this->redirectToRoute('app_login', [], Response::HTTP_SEE_OTHER);
}
return $this->renderForm('security/enroll.html.twig', [
'user' => $user,
'form' => $form,
]);
}
/**
* Subscribe IDO to an account for Bio validation OK
*
* @Route("/double/auth/subscription", name="dashboard_double_auth_subscription", methods={"GET", "POST"})
*
*/
public function doubleAuthSubscriptionAction(Request $request, BioAuthRepository $bioAuthRepository, CheckQrRepository $checkQrRepository, ApplicationRepository $applicationRepository, UserRepository $userRepo): Response
{
$session = $request->getSession();
$lgin = $session->get('usrLogin');
$fullName = $session->get('usrFullName');
// $session->set('usrFullName', $usr->getUsername()." ".$usr->getFirstName());
if($_POST)
{
$action = $request->get("action");
if($action=="preenroler")
{
$civilite = $request->get("civilite");
$nom = $request->get("nom");
$prenom = $request->get("prenom");
$dateNaissance = $request->get("dateNaissance");
$lieuNaissance = $request->get("lieuNaissance");
$nationalite = $request->get("nationalite");
$numeroTelephone = $request->get("numeroTelephone");
$adresseEmail = $request->get("adresseEmail");
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $this->getParameter('kyvala_host').'/person/pre/enrolement/new/json',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => array('civilite' => 'Mme/Mr','nom' => $nom,'prenom' =>$prenom,'dateNaissance' => $dateNaissance,'lieuNaissance' => $lieuNaissance ,'nationalite' => $nationalite,'numeroTelephone' => $numeroTelephone,'adresseEmail' => $adresseEmail ),
));
$response = curl_exec($curl);
$response = json_decode($response,true);
curl_close($curl);
if($response['Etat']=="SUCCESS")
{
return $this->render('security/kyvala-subscription.html.twig', array(
'isModal'=>3,// pour le préenrolement succes
'message'=>$response['Message'],
'reference'=>$response['sqr'],
'statut'=>$response['Etat']
));
}else
{
// erreur de traitement
$this->get('session')->getFlashBag()->add('warning', "An error occurred while saving. Please try again...");
}
}elseif($action=="souscrire")
{
$ref1 = $request->get("ref1");
$ref2 = $request->get("ref2");
$ref3 = $request->get("ref3");
$reference = $ref1."-". $ref2."-". $ref3;
$identifiant = $session->get('usrLogin');;
$appKey = $this->getParameter('token_key');
if (!empty($identifiant) && !empty($reference) && !empty($appKey))
{
$application = $applicationRepository->findOneBy(['applicationPass'=>$appKey]);
if($application)
{
$checkQr = $checkQrRepository->findOneBy(['numero'=>$reference]);
//$person = $personRepository->findOneBySqr($reference);
if($checkQr)
{
$userToActivate = $bioAuthRepository->findOneBy(['application'=>$application, 'identification'=>$identifiant]);
if(!$userToActivate)
{
$bioAuth = new BioAuth();
$bioAuth->setIdentification($identifiant);
$bioAuth->SetUserReference($checkQr);
$bioAuth->setApplication($application);
$bioAuthRepository->add($bioAuth, false);
/*
$return = array(
'Etat' => 'SUCCESS',
'Message' => "Double authentification configurée avec succès sur ce compte...",
'civility'=>$checkQr->getPersonCivil()[0]->getCivility(),
'firstName'=>$checkQr->getPersonCivil()[0]->getFirstName(),
'lastName'=>$checkQr->getPersonCivil()[0]->getLastName(),
'selfie_link'=>"uploads/kyvala/enrolment/".$checkQr->getPersonBiometrics()[0]->getFace(),
//'sqr'=>$person->getCheckQr()->getNumero(),
//'hash'=>$person->getCheckQr()->getLibelle(),
//'transactionId'=>$person->getEnrolmentId(),
//'transactionUid'=>$person->getEnrolmentUid(),
);
*/
$acc = $userRepo->findOneby(["username"=>$identifiant]);
$acc->setIsBioAuth(1);//activation de la double auth
$userRepo->add($acc, true);
return $this->render('security/kyvala-subscription.html.twig', array(
'isModal'=>2,// pour la souscription directe
'message'=>"Biometric authentication successfully configured on this account...",
'referece'=>$reference,
'statut'=>'SUCCESS',
'nom'=>$checkQr->getPersonCivil()[0]->fullName(),
'loginUser'=>$lgin,
'selfie_link'=>"uploads/kyvala/enrolment/".$checkQr->getPersonBiometrics()[0]->getFace(),
));
}else
{
$this->get('session')->getFlashBag()->add('warning', "Unable to continue processing. Two-factor authentication for this account is already enabled....");
}
}else
{
$this->get('session')->getFlashBag()->add('warning', "This IDO is not associated with any enrolled individual. Please check and try again...");
}
}else
{
$this->get('session')->getFlashBag()->add('warning', "You do not have permission for this request...");
}
}else
{
$this->get('session')->getFlashBag()->add('warning', "Missing required parameters...");
}
}
}
return $this->render('security/kyvala-subscription.html.twig', array(
'isModal'=>1,
'loginUser'=>$lgin,
'fullName'=>$fullName
));
}
/**
* Initier une transaction de double véritifation sur Kyvala Poc OK
*
* @Route("/double/auth/verification", name="dashboard_double_auth_verification", methods ={"GET", "POST"})
*
*/
public function doubleAuthVerificationAction(Request $request, BioAuthHistoryRepository $bioAuthHistoryRepository, BioAuthRepository $bioAuthRepository, ApplicationRepository $applicationRepository, CheckQrRepository $checkQrRepository): Response
{
$session = $request->getSession();
//Get sqr and image link
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://checktatoo.com/fr/notification/generate/qr/sqr/token',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
));
$response = curl_exec($curl);
$response = json_decode($response,true);
curl_close($curl);
//dump($response);
if($response['Etat']=="SUCCESS")
{
/*
{
"Etat": "SUCCESS",
"Message": "Le qr a été généré avec succès...",
"step": "process",
"hash": "1BDKqdWcWw1yXPSVDadPB9Q==",
"ref": "6159-6416-5827",
"qrCode": "checktatoo.com/qrcode/token_authentification_qr_2024090306593077.png"
}
*/
$identifiant = $session->get('usrLogin');// app unique identifier
$authReference = $response['ref'];//project transaction reference
$appKey = $this->getParameter('token_key');// project unique key
if (!empty($identifiant) && !empty($authReference) && !empty($appKey))
{
$application = $applicationRepository->findOneBy(['applicationPass'=>$appKey]);
if($application)
{
$bioAuth = $bioAuthRepository->findOneBy(['application'=>$application, 'identification'=>$identifiant]);
if($bioAuth)
{
try
{
//Buffering the output
ob_start();
//Getting configuration details
system('ipconfig /all');
//Storing output in a variable
$configdata=ob_get_contents();
// Clear the buffer
ob_clean();
//Extract only the physical address or Mac address from the output
$mac = "Adresse physique";
//$mac = "Physical";
$pmac = strpos($configdata, $mac);
// Get Physical Address
$macaddr=substr($configdata,($pmac+41),17);
//$macaddr=substr($configdata,($pmac+36),17);
$bioAuthHistory = new BioAuthHistory();
$bioAuthHistory->setTransactionReference($authReference);
$bioAuthHistory->setBioAuth($bioAuth);
// get client infos
$bioAuthHistory->setHttpRemoteIp(htmlspecialchars($request->server->get('HTTP_REMOTE_IP')));
$bioAuthHistory->setRemotePort(htmlspecialchars($request->server->get('REMOTE_PORT')));
$bioAuthHistory->setRemoteAdress(htmlspecialchars($request->server->get('REMOTE_ADDR')));
$bioAuthHistory->setHttpUserAgent(htmlspecialchars($request->server->get('HTTP_USER_AGENT')));
$bioAuthHistory->setGeoipLongitude(htmlspecialchars($request->server->get('GEOIP_LONGITUDE')));
$bioAuthHistory->setGeoipLatitude(htmlspecialchars($request->server->get('GEOIP_LATITUDE')));
$bioAuthHistory->setGeoipAreaCode(htmlspecialchars($request->server->get('GEOIP_AREA_CODE')));
$bioAuthHistory->setGeoipDmaCode(htmlspecialchars($request->server->get('GEOIP_DMA_CODE')));
$bioAuthHistory->setGeoipCity(htmlspecialchars($request->server->get('GEOIP_CITY')));
$bioAuthHistory->setGeoipRegion(htmlspecialchars($request->server->get('GEOIP_REGION')));
$bioAuthHistory->setGeoipCountryName(htmlspecialchars($request->server->get('GEOIP_COUNTRY_NAME')));
$bioAuthHistory->setGeoipCountryCode(htmlspecialchars($request->server->get('GEOIP_COUNTRY_CODE')));
$bioAuthHistory->setUniqueId(htmlspecialchars($request->server->get('UNIQUE_ID')));
$bioAuthHistory->setMac(htmlspecialchars($macaddr));
//Send notification to Firebase
//if(!empty($bioAuthHistory->getBioAuth()->getUserReference()->getPersoncivil()[0]->getFirebaseToken()))
if(!empty($bioAuthHistory->getBioAuth()->getUserReference()->getPersonAppIdentitiesUserReference()[0]->getToken()))
{
$this->ParamsWithSendPushNotification($bioAuthHistory->getBioAuth()->getUserReference()->getPersonAppIdentitiesUserReference()[0]->getToken(),"Authentication request!!! ",$bioAuthHistory->getTransactionReference().": ".$bioAuthHistory->getBioAuth()->getUserReference()->getPersoncivil()[0]->fullName().", Please confirm that you wish to access your account in the space ". $bioAuthHistory->getBioAuth()->getApplication()->getName(). " from a device with the ip address : ". $bioAuthHistory->getHttpRemoteIp() ." on the ".date("d-m-Y H:i:s")." or report if it's not you.");
$this->ParamsWithSendPushNotification($bioAuthHistory->getBioAuth()->getUserReference()->getPersonAppIdentitiesUserReference()[0]->getToken(),"Demande d'authentification !!! ",$bioAuthHistory->getTransactionReference().": ".$bioAuthHistory->getBioAuth()->getUserReference()->getPersoncivil()[0]->fullName().", Merci de confirmer que vous souhaitez acceder à votre compte dans l'espace ". $bioAuthHistory->getBioAuth()->getApplication()->getName(). " à partir d'un périphérique ayant l'adresse ip : ". $bioAuthHistory->getHttpRemoteIp() ." le ".date("d-m-Y H:i:s")." ou signalez s'il ne s'agit pas de vous.");
}
$bioAuthHistoryRepository->add($bioAuthHistory, true);
return $this->render('security/kyvala-verification.html.twig', array(
'Message' => "Request for biometric authentication successfully registered...",
'nom'=>$bioAuthHistory->getBioAuth()->getUserReference()->getPersonCivil()[0]->fullName(),
'selfie_link'=>"uploads/kyvala/enrolment/".$bioAuthHistory->getBioAuth()->getUserReference()->getPersonBiometrics()[0]->getFace(),
'Etat' => 'SUCCESS',
'step'=>'process',
'ref'=>$response['ref'],
'stop'=>'1',
'qrCode'=>$response['qrCode'],
'key'=>$this->getParameter('token_key')
));
} catch (\Throwable $error)
{
//not actions
$fs = new Filesystem();
//$fs->appendToFile('EventLogFiles.txt', "\r\n ".json_encode($error));
$fs->appendToFile('EventLogFiles.txt', "\r\n ".$error);
/*$return = array(
'Etat' =>'FAILED' ,
'Message' =>"Une erreur est survenue lors de l'opération. Veuillez essayer ultérieurement SVP",
'error'=>json_encode($error),
);*/
$this->get('session')->getFlashBag()->add('warning', "An error occurred during the operation. Please try later...");
return $this->redirectToRoute('app_login');
}
}else
{
$this->get('session')->getFlashBag()->add('warning', "Biometric authentication has not yet been configured on this account. Please follow the following steps to activate the service on your account...");
return $this->redirectToRoute('app_login');
}
}else
{
$this->get('session')->getFlashBag()->add('warning', "You do not have permission for this request...");
return $this->redirectToRoute('app_login');
}
}else
{
$this->get('session')->getFlashBag()->add('warning', "Missing required parameters...");
return $this->redirectToRoute('app_login');
}
}elseif($response['Etat']=="FAILED")
{
$this->get('session')->getFlashBag()->add('warning', "Unable to reach the partner's server, try again...");
return $this->redirectToRoute('app_login');
}
}
/**
* Check Status of an existing authentification OK
*
* @Route("/check/auth/status", name="dashboard_check_auth_status", methods={"GET", "POST"})
*
*/
public function checkAuthStatusAction(Request $request, BioAuthHistoryRepository $bioAuthHistoryRepository, ApplicationRepository $applicationRepository, UserRepository $userRepo): Response
{
//$em = $this->getDoctrine()->getManager();
//$reference = $request->get('authReference');
//$appKey = $this->getParameter('token_key');
$authReference = $request->get("authReference");//project transaction reference
$appKey = $this->getParameter('token_key');// project unique key
if (!empty($authReference) && !empty($appKey))
{
$application = $applicationRepository->findOneBy(['applicationPass'=>$appKey]);
if($application)
{
$bioAuthHistory = $bioAuthHistoryRepository->findOneBy(['transactionReference'=>$authReference]);
if($bioAuthHistory)
{
/*
$return = array(
'Etat' => 'SUCCESS',
'Message' => "Enregistrement recupérée avec succès...",
'authentication_status' => $bioAuthHistory->getUserAccess(),
'transaction_reference' => $bioAuthHistory->getTransactionReference(),
//'nom'=>$bioAuthHistory->getBioAuth()->getPerson()->fullName(),
//'sqr'=>$bioAuthHistory->getBioAuth()->getPerson()->getCheckQr()->getNumero(),
//'hash'=>$bioAuthHistory->getBioAuth()->getPerson()->getCheckQr()->getLibelle(),
//'transactionId'=>$bioAuthHistory->getBioAuth()->getPerson()->getEnrolmentId(),
//'transactionUid'=>$bioAuthHistory->getBioAuth()->getPerson()->getEnrolmentUid(),
);*/
switch ($bioAuthHistory->getUserAccess())
{
case 'GRANTED':
# code...
$identifiant = $bioAuthHistory->getBioAuth()->getIdentification();
$account = $userRepo->findOneby(["username"=>$identifiant]);
$account->setIsBioAuth(1);// on met que le bio auth est ok.
$userRepo->add($account, true);
$this->get('session')->getFlashBag()->add('success', "Double authentication completed successfully. Welcome ".$account->fullName());
break;
case 'REJECTED':
# code...
break;
case 'SIGNALED':
# code...
break;
default:
# code...
break;
}
$return = array(
'Etat' =>'SUCCESS' ,
'Message' =>"Record successfully recovered...",
'auth_status'=>$bioAuthHistory->getUserAccess()
);
}else
{
$return = array(
'Etat' =>'FAILED' ,
'Message' =>"The reference is not associated with any pending transaction...",
);
}
}else
{
$return = array(
'Etat' =>'FAILED' ,
'Message' =>"You do not have permission for this request...",
);
}
}else
{
$return = array(
'Etat' =>'FAILED' ,
'Message' =>"Missing required parameters...",
);
}
return new JsonResponse($return);
}
//notifications push avec paramètres OK
public function ParamsWithSendPushNotification($user_notification_token,$title,$message)
{
//https://www.youtube.com/watch?v=YHniUsrmX9Y
$fs = new Filesystem();
$credential = new ServiceAccountCredentials(
"https://www.googleapis.com/auth/firebase.messaging",
json_decode(file_get_contents
("kyvala-45525-firebase-adminsdk-cxpp5-cf78b66d72.json"),true)
);
$token = $credential->fetchAuthToken(HttpHandlerFactory::build());
$accessToken = $token['access_token'];
$ch = curl_init("https://fcm.googleapis.com/v1/projects/kyvala-45525/messages:send");
curl_setopt($ch, CURLOPT_HTTPHEADER,[
'Content-Type: application/json',
'Authorization: ' . 'Bearer ' .$accessToken
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{
"message": {
"token":"'.$user_notification_token.'",
"notification": {
"title":"'.$title.'",
"body":"'.$message.'",
"image":"http://poc.kyvala.com/uploads/TOKEN/Token-logo-avec-fond.png"
}
}
}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
$response = curl_exec($ch);
if (curl_errno($ch))
{
print "Error: " . curl_error($ch);
$fs->appendToFile('EventLogNotification.txt', "\r\n ".date("d-m-Y H:i:s")." : deviceToken :".$user_notification_token.", Title: ".$title.", Notification: ".$message.", Error: ".json_encode(curl_error($ch)));
exit();
}else
{
$json = json_decode($response, true);
}
// Show me the result
curl_close($ch);
//dump($season_data);
$fs->appendToFile('EventLogNotification.txt', "\r\n ".date("d-m-Y H:i:s")." : DeviceToken :".$user_notification_token.", Title: ".$title.", Notification: ".$message.", Retours: ".json_encode($response));
// return a JSON object to caller
return $json;
}
}