<?php
namespace App\Controller;
use App\Entity\User;
use App\Entity\Role;
use App\Utils\EmailSignature;
use App\Utils\XmlRender;
use App\Form\ChangePasswordFormType;
use Doctrine\ORM\EntityManagerInterface;
use App\Service\UserSession;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Ldap\Adapter\ExtLdap\Adapter;
use Symfony\Component\Ldap\Ldap;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Form\Form;
use Sabre\VObject\Component\VCard;
use Sabre\VObject\Document;
class ProfileController extends AbstractController
{
private $pdo;
#[Route('/profile', name: 'profile')]
public function profile(Request $request, UserSession $userSession): Response
{
if (!$user = $this->getUser()) return $this->redirectToRoute('login');
else $userData = $userSession->getEntryFromSession();
$type = preg_split('/@/',$user->getUsername());
$vcard = new VCard([
'FN' => mb_convert_case($userData->getFirstname(), MB_CASE_TITLE, "UTF-8").' '.preg_replace(array('/\bVon\b/u','/\bDe\b/u'), array('von','de'), mb_convert_case($userData->getLastname(), MB_CASE_TITLE, "UTF-8")),
'N' => [ preg_replace(array('/\bVon\b/u','/\bDe\b/u'), array('von','de'), mb_convert_case($userData->getLastname(), MB_CASE_TITLE, "UTF-8")), mb_convert_case($userData->getFirstname(), MB_CASE_TITLE, "UTF-8"), '', '', ''],
'ROLE' => $userData->getDepartment(),
'TITLE' => mb_convert_case($userData->getJob(), MB_CASE_TITLE, "UTF-8"),
'NOTE' => 'Site '.$userData->getOrganization(),
]);
$vcard->add('ADR', ['', '', $userData->getStreet(), $userData->getCity(), '', $userData->getZipcode()], ['type' => 'work']);
if($type[1] == 'batiformes.com' || $type[1] == 'scorev.fr') $vcard->add('EMAIL', $user->getUsername(), ['type' => 'work']);
if($userData->getPhone() != '') $vcard->add('TEL', $userData->getPhone(), ['type' => 'work']);
if($userData->getMobile() != '') $vcard->add('TEL', $userData->getMobile(), ['type' => 'cell']);
if($userData->getFax() != '') $vcard->add('TEL', $userData->getFax(), ['type' => 'fax']);
if($userData->getOrganization() == 'SCOREV'){
$vcard->add('ORG', 'SCOREV');
$vcard->add('URL', 'https://www.scorev.fr', ['type' => 'work']);
$vcard->add('PHOTO', 'https://www.scorev.fr/assets/images/vcard/logo_vcard.jpg', ['type' => 'JPEG']);
}
if($userData->getOrganization() == 'TOLARTOIS'){
$vcard->add('ORG', 'TOLARTOIS');
$vcard->add('URL', 'https://www.tolartois.com', ['type' => 'work']);
$vcard->add('PHOTO', 'https://www.tolartois.com/assets/images/vcard/logo_vcard.jpg', ['type' => 'JPEG']);
}
if($userData->getOrganization() != 'TOLARTOIS' && $userData->getOrganization() != 'SCOREV'){
$vcard->add('ORG', 'Bati Formes');
$vcard->add('URL', 'https://www.batiformes.com', ['type' => 'work']);
$vcard->add('PHOTO', 'https://www.batiformes.com/assets/images/vcard/logo_vcard.jpg', ['type' => 'JPEG']);
}
$vcard = $vcard->convert(Document::VCARD30);
$vcard = base64_encode($vcard->serialize());
$nickhandle = preg_split('/@/',$user->getUsername());
$qrcode = $request->getScheme() . '://' . $request->getHttpHost() . '/qr-code/png/' . $userData->getWeb() . '/vcard/' . preg_replace('/\./', '-', $nickhandle[0]) . '.html';
$signature = new EmailSignature();
$email = $signature->signature($userData,$user->getUsername(),$vcard);
$password = $this->createForm(ChangePasswordFormType::class);
$password->handleRequest($request);
/*$defaultData = ['message' => 'Type your message here'];
$form = $this->createFormBuilder($defaultData)
->add('name', TextType::class)
->add('email', EmailType::class)
->add('message', TextareaType::class)
->add('send', SubmitType::class)
->getForm();
$form->handleRequest($request);*/
return $this->render('profile/index.html.twig', [
'title_meta' => 'Mon compte utilisateur',
'page' => 'profile',
'user' => $userData,
'vcard' => $vcard,
'qrcode' => $qrcode,
'email' => $email,
'password' => $password->createView(),
]);
}
#[Route('/profile/password', name: 'profile_pswd')]
public function profile_pswd(Request $request, Adapter $ldapAdapter, EntityManagerInterface $entityManager, UserPasswordHasherInterface $passwordEncoder): Response
{
if (!$user = $this->getUser()) return $this->redirectToRoute('login');
$form = $this->createForm(ChangePasswordFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted()){
if (!$form->isValid()) {
$data = [
'alert' => 'error',
'message' => $this->getErrorMessages($form)
];
}
if($form->isValid()) {
$userpassword = '{SHA}' . base64_encode(sha1( $form->get('plainPassword')->getData(), TRUE ));
$ldap = new Ldap($ldapAdapter);
$ldap->bind($this->getParameter('app.ldap_service_user').','.$this->getParameter('app.ldap_service_dn'), $this->getParameter('app.ldap_service_password'));
$entryManager = $ldap->getEntryManager();
$query = $ldap->query($this->getParameter('app.ldap_service_dn'), '(&(uid='.$user->getUsername().'))');
$result = $query->execute()->toArray();
$entry = $result[0];
$entry->setAttribute('userPassword', [$userpassword]);
$entryManager->update($entry);
$password = $passwordEncoder->hashPassword($this->getUser(), $form->get('plainPassword')->getData());
$entityManager->getRepository(User::class)->upgradePassword($this->getUser(),$password);
$bdd = $this->getDatabaseConnection();
$sabrePswdUpdate = $bdd->prepare("UPDATE `users` SET `digesta1`= md5('".$user->getUsername().":BaikalDAV:".$form->get('plainPassword')->getData()."') WHERE `username`='".$user->getUsername()."' ");
$sabrePswdUpdate->execute();
$file = '/opt/picapport/.picapport/users/user/'.$user->getUsername().'/'.$user->getUsername().'.xml';
$xmlUser = new XmlRender();
$xmlUser->user_edit($file,$form->get('plainPassword')->getData());
$pathToPicApportScript = "/home/websites/scripts/picapport.sh";
$process = new Process(['sh', $pathToPicApportScript]);
$process->run();
$bdd = null;
$data = [
'alert' => 'success',
'message' => 'Votre mot de passe a été modifié.'
];
}
} else {
$data = [
'alert' => 'error',
'message' => 'Une erreur est intervenue.'
];
}
return $this->json(
$data,
headers: ['Content-Type' => 'application/json;charset=UTF-8']
);
}
#[Route('/profile/add', name: 'profile_add')]
public function profile_add(Request $request, Adapter $ldapAdapter, EntityManagerInterface $entityManager, UserSession $userSession): Response
{
$submittedToken = $request->request->get('token');
if ($this->isCsrfTokenValid('picture-add', $submittedToken))
{
if ($_FILES['file']['size'] != '0') {
$userSession->getEntryFromSession();
$data = file_get_contents($_FILES['file']['tmp_name']);
$picture = base64_encode($data);
$ldap = new Ldap($ldapAdapter);
$ldap->bind($this->getParameter('app.ldap_service_user').','.$this->getParameter('app.ldap_service_dn'), $this->getParameter('app.ldap_service_password'));
$entryManager = $ldap->getEntryManager();
$query = $ldap->query($this->getParameter('app.ldap_service_dn'), '(&(uid='.$this->getUser()->getUsername().'))');
$result = $query->execute()->toArray();
$entry = $result[0];
$entryManager->addAttributeValues($entry, 'jpegPhoto', [$picture]);
$userSession->addImageFromSession($picture);
$data = [
'alert' => 'success',
'message' => 'data:image/jpeg;base64,'.$picture
];
}
else{
$data = [
'alert' => 'danger',
'message' => "Aucun finchié n'a été récupéré."
];
}
return $this->json(
$data,
headers: ['Content-Type' => 'application/json;charset=UTF-8']
);
} else {
$data = [
'alert' => 'danger',
'message' => 'Problème de CRSF.'
];
return $this->json(
$data,
headers: ['Content-Type' => 'application/json;charset=UTF-8']
);
}
}
#[Route('/profile/delete', name: 'profile_delete')]
public function profile_delete(Request $request, Adapter $ldapAdapter, EntityManagerInterface $entityManager, UserSession $userSession): Response
{
$submittedToken = $request->request->get('token');
if ($this->isCsrfTokenValid('picture-delete', $submittedToken))
{
$ldap = new Ldap($ldapAdapter);
$ldap->bind($this->getParameter('app.ldap_service_user').','.$this->getParameter('app.ldap_service_dn'), $this->getParameter('app.ldap_service_password'));
$entryManager = $ldap->getEntryManager();
$query = $ldap->query($this->getParameter('app.ldap_service_dn'), '(&(uid='.$this->getUser()->getUsername().'))');
$result = $query->execute()->toArray();
$entry = $result[0];
$entryManager->removeAttributeValues($entry, 'jpegPhoto', []);
$userSession->deleteImageFromSession();
$data = [
'alert' => 'success',
'message' => '/assets/images/avatar.jpg'
];
return $this->json(
$data,
headers: ['Content-Type' => 'application/json;charset=UTF-8']
);
} else {
$data = [
'alert' => 'danger',
'message' => 'Problème de CRSF.'
];
return $this->json(
$data,
headers: ['Content-Type' => 'application/json;charset=UTF-8']
);
}
}
#[Route('/profile/notify', name: 'profile_notify')]
public function profile_notify(Request $request, EntityManagerInterface $entityManager): Response
{
$submittedToken = $request->request->get('token');
if ($this->isCsrfTokenValid('notifications-token', $submittedToken))
{
$user = $this->getUser();
$notifications = $user->getParameters();
foreach($notifications as $key => $value){
if($key == $request->request->get('id')) {
if($request->request->get('box') == 0) $notification = false;
if($request->request->get('box') == 1) $notification = true;
$notifications[$key] = $notification;
}
}
$user->setParameters($notifications);
$entityManager->persist($user);
$entityManager->flush();
$data = [
'alert' => 'success',
'message' => 'Vos péférences ont été updatées'
];
return $this->json(
$data,
headers: ['Content-Type' => 'application/json;charset=UTF-8']
);
} else {
$data = [
'alert' => 'error',
'message' => 'Problème de CRSF.'
];
return $this->json(
$data,
headers: ['Content-Type' => 'application/json;charset=UTF-8']
);
}
}
#[Route('/vcard/{_site}/{_id}', name: 'vcard')]
public function vcard(Adapter $ldapAdapter, EntityManagerInterface $entityManager, string $_site, string $_id): Response
{
$ext = '@batiformes.com';
if($_site == 'SCOREV') $ext = '@scorev.fr';
$mail = preg_replace('/-/','.',$_id).$ext;
$data = [];
$ldap = new Ldap($ldapAdapter);
$ldap->bind($this->getParameter('app.ldap_service_user').','.$this->getParameter('app.ldap_service_dn'), $this->getParameter('app.ldap_service_password'));
$query = $ldap->query($this->getParameter('app.ldap_service_dn'), '(&(uid='.$mail.'))');
$result = $query->execute()->toArray();
$entry = $result[0];
if(!empty($entry)){
$role = $entityManager->getRepository(Role::class)->findOneBy(array("description" => $entry->getAttribute('o')[0]));
$vcard = new VCard([
'FN' => mb_convert_case($entry->getAttribute('givenName')[0], MB_CASE_TITLE, "UTF-8").' '.preg_replace(array('/\bVon\b/u','/\bDe\b/u'), array('von','de'), mb_convert_case($entry->getAttribute('sn')[0], MB_CASE_TITLE, "UTF-8")),
'N' => [ ucfirst($entry->getAttribute('sn')[0]), mb_convert_case($entry->getAttribute('givenName')[0], MB_CASE_TITLE, "UTF-8"), '', '', ''],
'ROLE' => $entry->getAttribute('departmentNumber')[0],
'TITLE' => mb_convert_case($entry->getAttribute('title')[0], MB_CASE_TITLE, "UTF-8"),
'NOTE' => 'Site '.$entry->getAttribute('o')[0],
]);
$vcard->add('ADR', ['', '', $role->getData()['direction'], $role->getData()['city'], '', $role->getData()['zipcode']], ['type' => 'work']);
$vcard->add('EMAIL', $mail, ['type' => 'work']);
if($entry->hasAttribute('telephoneNumber')) $vcard->add('TEL', $entry->getAttribute('telephoneNumber')[0], ['type' => 'work']);
if($entry->hasAttribute('mobile')) $vcard->add('TEL', $entry->getAttribute('mobile')[0], ['type' => 'cell']);
if($entry->hasAttribute('facsimileTelephoneNumber')) $vcard->add('TEL', $entry->getAttribute('facsimileTelephoneNumber')[0], ['type' => 'fax']);
if($_site == 'SCOREV'){
$vcard->add('ORG', 'SCOREV');
$vcard->add('URL', 'https://www.scorev.fr', ['type' => 'work']);
$vcard->add('PHOTO', 'https://www.scorev.fr/assets/images/vcard/logo_vcard.jpg', ['type' => 'JPEG']);
}
if($_site == 'TOLARTOIS'){
$vcard->add('ORG', 'TOLARTOIS');
$vcard->add('URL', 'https://www.tolartois.com', ['type' => 'work']);
$vcard->add('PHOTO', 'https://www.tolartois.com/assets/images/vcard/logo_vcard.jpg', ['type' => 'JPEG']);
}
if($_site != 'TOLARTOIS' && $_site != 'SCOREV'){
$vcard->add('ORG', 'Bati Formes');
$vcard->add('URL', 'https://www.batiformes.com', ['type' => 'work']);
$vcard->add('PHOTO', 'https://www.batiformes.com/assets/images/vcard/logo_vcard.jpg', ['type' => 'JPEG']);
}
$vcard = $vcard->convert(Document::VCARD30);
$data['email'] = $mail;
$data['name'] = strtoupper($entry->getAttribute('sn')[0]);
$data['firstname'] = ucfirst($entry->getAttribute('givenName')[0]);
$data['activity'] = ucfirst($entry->getAttribute('title')[0]);
$data['mobile'] = ($entry->hasAttribute('mobile') ? $entry->getAttribute('mobile')[0] : '');
$data['mobileFormated'] = chunk_split($data['mobile'], 2, " ");
$data['phone'] = ($entry->hasAttribute('telephoneNumber') ? $entry->getAttribute('telephoneNumber')[0] : '');
$data['phoneFormated'] = chunk_split($data['phone'], 2, " ");
$data['street'] = $role->getData()['direction'];
$data['city'] = $role->getData()['city'];
$data['zipcode'] = $role->getData()['zipcode'];
$data['lat'] = $role->getData()['lat'];
$data['lng'] = $role->getData()['lng'];
$data['map'] = $role->getData()['gmap'];
$data['vcard'] = base64_encode($vcard->serialize());
}
return $this->json(
$data,
headers: ['Content-Type' => 'application/json;charset=UTF-8']
);
}
private function getDatabaseConnection()
{
if ($this->pdo === null) {
$this->pdo = new \PDO('mysql:host=ma77924-001.dbaas.ovh.net:35815;dbname='.$this->getParameter('app.sabre_bdd'),'sabre','d4cvRR2bNvqsbmC68yPFJJa1ACw87DD');
$this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$this->pdo->query("SET NAMES 'UTF8'");
}
return $this->pdo;
}
// Generate an array contains a key -> value with the errors where the key is the name of the form field
protected function getErrorMessages(Form $form)
{
$errors = array();
foreach ($form->getErrors() as $key => $error) {
$errors[] = $error->getMessage();
}
foreach ($form->all() as $child) {
if (!$child->isValid()) {
$errors[$child->getName()] = $this->getErrorMessages($child);
}
}
return $errors;
}
}