Deltacms/core/module/user/user.php

945 lines
32 KiB
PHP

<?php
/**
* This file is part of DeltaCMS.
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
* @author Sylvain Lelièvre <lelievresylvain@free.fr>
* @copyright Copyright (C) 2021-2022, Sylvain Lelièvre
* @license GNU General Public License, version 3
* @link https://deltacms.fr/
*
* Delta was created from version 11.2.00.24 of ZwiiCMS
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2021, Frédéric Tempez
*/
class user extends common {
public static $actions = [
'add' => self::GROUP_ADMIN,
'delete' => self::GROUP_ADMIN,
'import' => self::GROUP_ADMIN,
'index' => self::GROUP_ADMIN,
'edit' => self::GROUP_MEMBER,
'logout' => self::GROUP_MEMBER,
'forgot' => self::GROUP_VISITOR,
'login' => self::GROUP_VISITOR,
'reset' => self::GROUP_VISITOR
];
public static $users = [];
//Paramètres pour choix de la signature
public static $signature = [
self::SIGNATURE_ID => 'Identifiant',
self::SIGNATURE_PSEUDO => 'Pseudo',
self::SIGNATURE_FIRSTLASTNAME => 'Prénom Nom',
self::SIGNATURE_LASTFIRSTNAME => 'Nom Prénom'
];
public static $signature_en = [
self::SIGNATURE_ID => 'Identifier',
self::SIGNATURE_PSEUDO => 'Username',
self::SIGNATURE_FIRSTLASTNAME => 'First name Name',
self::SIGNATURE_LASTFIRSTNAME => 'Name First name'
];
public static $userId = '';
public static $userLongtime = false;
public static $separators = [
';' => ';',
',' => ',',
':' => ':'
];
// Variable pour construire la liste des pages du site
public static $pagesList = [];
public static $orphansList = [];
/**
* Ajout
*/
public function add() {
// Lexique
$text = [];
$val = $this->getData(['config', 'i18n', 'langAdmin']);
switch ($val) {
case 'fr' :
$text[0] = 'Identifiant déjà utilisé';
$text[1] = 'Incorrect';
$text[2] = 'Compte créé sur ';
$text[3] = 'Bonjour ';
$text[4] = 'Un administrateur vous a créé un compte sur le site. ';
$text[5] = 'Vous trouverez ci-dessous les détails de votre compte.';
$text[6] = 'Identifiant du compte :';
$text[7] = 'Nous ne conservons pas les mots de passe, en conséquence nous vous conseillons de conserver ce message tant que vous ne vous êtes pas connecté. Vous pourrez modifier votre mot de passe après votre première connexion.';
$text[8] = 'Utilisateur créé';
$text[9] = 'Nouvel utilisateur';
$text[10] = 'Aucune';
break;
case 'en' :
$text[0] = 'Identifier already in use';
$text[1] = 'Incorrect';
$text[2] = 'Account created on ';
$text[3] = 'Hello ';
$text[4] = 'An administrator has created an account for you on the site. ';
$text[5] = 'Below you will find your account details.';
$text[6] = 'Account ID :';
$text[7] = 'We do not store passwords, therefore we advise you to keep this message until you have logged in. You can change your password after your first login.';
$text[8] = 'User created';
$text[9] = 'New user';
$text[10] = 'None';
break;
}
// Soumission du formulaire
if($this->isPost()) {
$check=true;
// L'identifiant d'utilisateur est indisponible
$userId = $this->getInput('userAddId', helper::FILTER_ID, true);
if($this->getData(['user', $userId])) {
self::$inputNotices['userAddId'] = $text[0];
$check=false;
}
// Double vérification pour le mot de passe
if($this->getInput('userAddPassword', helper::FILTER_STRING_SHORT, true) !== $this->getInput('userAddConfirmPassword', helper::FILTER_STRING_SHORT, true)) {
self::$inputNotices['userAddConfirmPassword'] = $text[1];
$check = false;
}
// Crée l'utilisateur
$userFirstname = $this->getInput('userAddFirstname', helper::FILTER_STRING_SHORT, true);
$userLastname = $this->getInput('userAddLastname', helper::FILTER_STRING_SHORT, true);
$userMail = $this->getInput('userAddMail', helper::FILTER_MAIL, true);
// Stockage des données
$this->setData([
'user',
$userId,
[
'firstname' => $userFirstname,
'forgot' => 0,
'group' => $this->getInput('userAddGroup', helper::FILTER_INT, true),
'lastname' => $userLastname,
'pseudo' => $this->getInput('userAddPseudo', helper::FILTER_STRING_SHORT, true),
'signature' => $this->getInput('userAddSignature', helper::FILTER_INT, true),
'mail' => $userMail,
'password' => $this->getInput('userAddPassword', helper::FILTER_PASSWORD, true),
"connectFail" => null,
"connectTimeout" => null,
"accessUrl" => null,
"accessTimer" => null,
"accessCsrf" => null,
"files" => $this->getInput('userAddFiles', helper::FILTER_BOOLEAN),
"redirectPageId" => $this->getInput('userRedirectPageId', helper::FILTER_STRING_SHORT)
]
]);
// Envoie le mail
$sent = true;
if($this->getInput('userAddSendMail', helper::FILTER_BOOLEAN) && $check === true) {
$sent = $this->sendMail(
$userMail,
$text[2] . $this->getData(['locale', 'title']),
$text[3].'<strong>' . $userFirstname . ' ' . $userLastname . '</strong>,<br><br>' .
$text[4] . $this->getData(['locale', 'title']) . $text[5].'<br><br>' .
'<strong>'.$text[6].'</strong> ' . $this->getInput('userAddId') . '<br>' .
'<small>'.$text[7].'</small>',
null
);
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'user',
'notification' => $sent === true ? $text[8] : $sent,
'state' => $sent === true ? true : null
]);
}
// Générer la liste des pages disponibles
$redirectPage = array( 'noRedirect'=> array( 'title'=>$text[10]));
self::$pagesList = $this->getData(['page']);
foreach(self::$pagesList as $page => $pageId) {
if ($this->getData(['page',$page,'block']) === 'bar' ||
$this->getData(['page',$page,'disable']) === true) {
unset(self::$pagesList[$page]);
}
}
self::$pagesList = array_merge( $redirectPage, self::$pagesList);
// Valeurs en sortie
$this->addOutput([
'title' => $text[9],
'view' => 'add'
]);
}
/**
* Suppression
*/
public function delete() {
// Lexique
$text = [];
$val = $this->getData(['config', 'i18n', 'langAdmin']);
switch ($val) {
case 'fr' :
$text[0] = 'Action non autorisée';
$text[1] = 'Impossible de supprimer votre propre compte';
$text[2] = 'Utilisateur supprimé';
break;
case 'en' :
$text[0] = 'Unauthorised action';
$text[1] = 'Unable to delete your own account';
$text[2] = 'Deleted user';
break;
}
// Accès refusé
if(
// L'utilisateur n'existe pas
$this->getData(['user', $this->getUrl(2)]) === null
// Groupe insuffisant
AND ($this->getUrl('group') < self::GROUP_MODERATOR)
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
}
// Jeton incorrect
elseif ($this->getUrl(3) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'user',
'notification' => $text[0]
]);
}
// Bloque la suppression de son propre compte
elseif($this->getUser('id') === $this->getUrl(2)) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'user',
'notification' => $text[1]
]);
}
// Suppression
else {
$this->deleteData(['user', $this->getUrl(2)]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'user',
'notification' => $text[2],
'state' => true
]);
}
}
/**
* Édition
*/
public function edit() {
// Lexique
$text = [];
$val = $this->getData(['config', 'i18n', 'langAdmin']);
switch ($val) {
case 'fr' :
$text[0] = 'Action non autorisée';
$text[1] = 'Incorrect';
$text[2] = 'Modifications enregistrées';
$text[3] = 'Aucune';
break;
case 'en' :
$text[0] = 'Unauthorised action';
$text[1] = 'Incorrect';
$text[2] = 'Registered changes';
$text[3] = 'None';
break;
}
if ($this->getUrl(3) !== $_SESSION['csrf'] &&
$this->getUrl(4) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'user',
'notification' => $text[0]
]);
}
// Accès refusé
if(
// L'utilisateur n'existe pas
$this->getData(['user', $this->getUrl(2)]) === null
// Droit d'édition
AND (
// Impossible de s'auto-éditer
(
$this->getUser('id') === $this->getUrl(2)
AND $this->getUrl('group') <= self::GROUP_VISITOR
)
// Impossible d'éditer un autre utilisateur
OR ($this->getUrl('group') < self::GROUP_MODERATOR)
)
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
}
// Accès autorisé
else {
// Soumission du formulaire
if($this->isPost()) {
// Double vérification pour le mot de passe
$newPassword = $this->getData(['user', $this->getUrl(2), 'password']);
if($this->getInput('userEditNewPassword')) {
// L'ancien mot de passe est correct
if(password_verify($this->getInput('userEditOldPassword'), $this->getData(['user', $this->getUrl(2), 'password']))) {
// La confirmation correspond au mot de passe
if($this->getInput('userEditNewPassword') === $this->getInput('userEditConfirmPassword')) {
$newPassword = $this->getInput('userEditNewPassword', helper::FILTER_PASSWORD, true);
// Déconnexion de l'utilisateur si il change le mot de passe de son propre compte
if($this->getUser('id') === $this->getUrl(2)) {
helper::deleteCookie('DELTA_USER_ID');
helper::deleteCookie('DELTA_USER_PASSWORD');
}
}
else {
self::$inputNotices['userEditConfirmPassword'] = $text[1];
}
}
else {
self::$inputNotices['userEditOldPassword'] = $text[1];
}
}
// Modification du groupe
if(
$this->getUser('group') === self::GROUP_ADMIN
AND $this->getUrl(2) !== $this->getUser('id')
) {
$newGroup = $this->getInput('userEditGroup', helper::FILTER_INT, true);
}
else {
$newGroup = $this->getData(['user', $this->getUrl(2), 'group']);
}
// Modification de nom Prénom
if($this->getUser('group') === self::GROUP_ADMIN){
$newfirstname = $this->getInput('userEditFirstname', helper::FILTER_STRING_SHORT, true);
$newlastname = $this->getInput('userEditLastname', helper::FILTER_STRING_SHORT, true);
}
else{
$newfirstname = $this->getData(['user', $this->getUrl(2), 'firstname']);
$newlastname = $this->getData(['user', $this->getUrl(2), 'lastname']);
}
// Modifie l'utilisateur
$this->setData([
'user',
$this->getUrl(2),
[
'firstname' => $newfirstname,
'forgot' => 0,
'group' => $newGroup,
'lastname' => $newlastname,
'pseudo' => $this->getInput('userEditPseudo', helper::FILTER_STRING_SHORT, true),
'signature' => $this->getInput('userEditSignature', helper::FILTER_INT, true),
'mail' => $this->getInput('userEditMail', helper::FILTER_MAIL, true),
'password' => $newPassword,
'connectFail' => $this->getData(['user',$this->getUrl(2),'connectFail']),
'connectTimeout' => $this->getData(['user',$this->getUrl(2),'connectTimeout']),
'accessUrl' => $this->getData(['user',$this->getUrl(2),'accessUrl']),
'accessTimer' => $this->getData(['user',$this->getUrl(2),'accessTimer']),
'accessCsrf' => $this->getData(['user',$this->getUrl(2),'accessCsrf']),
'files' => $this->getInput('userEditFiles', helper::FILTER_BOOLEAN),
'redirectPageId' => $this->getInput('userRedirectPageId', helper::FILTER_STRING_SHORT)
]
]);
// Redirection spécifique si l'utilisateur change son mot de passe
if($this->getUser('id') === $this->getUrl(2) AND $this->getInput('userEditNewPassword')) {
$redirect = helper::baseUrl() . 'user/login/' . str_replace('/', '_', $this->getUrl());
}
// Redirection si retour en arrière possible
elseif($this->getUser('group') === 3) {
$redirect = helper::baseUrl() . 'user';
}
// Redirection normale
else {
$redirect = helper::baseUrl();
}
// Valeurs en sortie
$this->addOutput([
'redirect' => $redirect,
'notification' => $text[2],
'state' => true
]);
}
// Générer la liste des pages disponibles
$redirectPage = array( 'noRedirect'=> array( 'title'=> $text[3]) );
self::$pagesList = $this->getData(['page']);
foreach(self::$pagesList as $page => $pageId) {
if ($this->getData(['page',$page,'block']) === 'bar' ||
$this->getData(['page',$page,'disable']) === true) {
unset(self::$pagesList[$page]);
}
}
self::$pagesList = array_merge( $redirectPage, self::$pagesList);
// Valeurs en sortie
$this->addOutput([
'title' => $this->getData(['user', $this->getUrl(2), 'firstname']) . ' ' . $this->getData(['user', $this->getUrl(2), 'lastname']),
'view' => 'edit'
]);
}
}
/**
* Mot de passe perdu
*/
public function forgot() {
// Lexique
$text = [];
$val = $this->getData(['config', 'i18n', 'langAdmin']);
switch ($val) {
case 'fr' :
$text[0] = 'Réinitialisation de votre mot de passe';
$text[1] = 'Bonjour ';
$text[2] = 'Vous avez demandé à changer le mot de passe lié à votre compte. Vous trouverez ci-dessous un lien vous permettant de modifier celui-ci.';
$text[3] = 'Si nous n\'avez pas demandé à réinitialiser votre mot de passe, veuillez ignorer ce mail.';
$text[4] = 'Un mail vous a été envoyé afin de continuer la réinitialisation';
$text[5] = 'Cet utilisateur n\'existe pas';
$text[6] = 'Mot de passe oublié ?';
break;
case 'en' :
$text[0] = 'Reset your password';
$text[1] = 'Hello ';
$text[2] = 'You have requested to change the password linked to your account. Below you will find a link to change your password.';
$text[3] = 'If you have not asked us to reset your password, please ignore this email.';
$text[4] = 'An email has been sent to you to continue the reset';
$text[5] = 'This user does not exist';
$text[6] = 'Forgot your password ?';
break;
}
// Soumission du formulaire
if($this->isPost()) {
$userId = $this->getInput('userForgotId', helper::FILTER_ID, true);
if($this->getData(['user', $userId])) {
// Enregistre la date de la demande dans le compte utilisateur
$this->setData(['user', $userId, 'forgot', time()]);
// Crée un id unique pour la réinitialisation
$uniqId = md5(json_encode($this->getData(['user', $userId])));
// Envoi le mail
$sent = $this->sendMail(
$this->getData(['user', $userId, 'mail']),
$text[0],
$text[1] .'<strong>' . $this->getData(['user', $userId, 'firstname']) . ' ' . $this->getData(['user', $userId, 'lastname']) . '</strong>,<br><br>' .
$text[2].'<br><br>' .
'<a href="' . helper::baseUrl() . 'user/reset/' . $userId . '/' . $uniqId . '" target="_blank">' . helper::baseUrl() . 'user/reset/' . $userId . '/' . $uniqId . '</a><br><br>' .
$text[3].'</small>',
null
);
// Valeurs en sortie
$this->addOutput([
'notification' => ($sent === true ? $text[4] : $sent),
'state' => ($sent === true ? true : null)
]);
}
// L'utilisateur n'existe pas
else {
// Valeurs en sortie
$this->addOutput([
'notification' => $text[5]
]);
}
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => $text[6],
'view' => 'forgot'
]);
}
/**
* Liste des utilisateurs
*/
public function index() {
// Lexique
$text = [];
$val = $this->getData(['config', 'i18n', 'langAdmin']);
switch ($val) {
case 'fr' :
$text[0] = 'Liste des utilisateurs';
break;
case 'en' :
$text[0] = 'List of users';
break;
}
$userIdsFirstnames = helper::arrayCollumn($this->getData(['user']), 'firstname');
ksort($userIdsFirstnames);
foreach($userIdsFirstnames as $userId => $userFirstname) {
if ($this->getData(['user', $userId, 'group'])) {
self::$users[] = [
$userId,
$userFirstname . ' ' . $this->getData(['user', $userId, 'lastname']),
self::$groups[$this->getData(['user', $userId, 'group'])],
template::button('userEdit' . $userId, [
'href' => helper::baseUrl() . 'user/edit/' . $userId . '/back/'. $_SESSION['csrf'],
'value' => template::ico('pencil')
]),
template::button('userDelete' . $userId, [
'class' => 'userDelete buttonRed',
'href' => helper::baseUrl() . 'user/delete/' . $userId. '/' . $_SESSION['csrf'],
'value' => template::ico('cancel')
])
];
}
}
// Valeurs en sortie
$this->addOutput([
'title' => $text[0],
'view' => 'index'
]);
}
/**
* Connexion
*/
public function login() {
// Lexique
$text = [];
$val = $this->getData(['config', 'i18n', 'langAdmin']);
switch ($val) {
case 'fr' :
$text[0] = 'Compte inconnu';
$text[1] = 'Compte inconnu verrouillé';
$text[2] = 'Compte verrouillé';
$text[3] = 'Captcha, identifiant ou mot de passe incorrects';
$text[4] = 'Seul un administrateur peut se connecter lors d\'une maintenance';
$text[5] = 'Connexion réussie';
$text[6] = 'Bienvenue ';
$text[7] = 'Captcha, identifiant ou mot de passe incorrects';
$text[8] = 'Erreur de mot de passe';
$text[9] = 'Erreur de captcha';
$text[10] = 'Accès bloqué ';
$text[11] = 'Connexion';
$text[12] = '';
break;
case 'en' :
$text[0] = 'unknown account';
$text[1] = 'Unknown account locked';
$text[2] = 'Account locked';
$text[3] = 'Incorrect captcha, username or password';
$text[4] = 'Only an administrator can log in during maintenance';
$text[5] = 'Successful connection';
$text[6] = 'Welcome ';
$text[7] = 'Incorrect captcha, username or password';
$text[8] = 'Password error';
$text[9] = 'Captcha error';
$text[10] = 'Account locked ';
$text[11] = 'Connection';
$text[12] = '';
break;
}
// Soumission du formulaire
$logStatus = '';
if($this->isPost()) {
// Lire Id du compte
$userId = $this->getInput('userLoginId', helper::FILTER_ID, true);
// Check le captcha
if(
$this->getData(['config','connect','captcha'])
AND password_verify($this->getInput('userLoginCaptcha', helper::FILTER_INT), $this->getInput('userLoginCaptchaResult') ) === false )
{
$captcha = false;
} else {
$captcha = true;
}
/**
* Aucun compte existant
*/
if ( !$this->getData(['user', $userId])) {
$logStatus = $text[0];
//Stockage de l'IP
$this->setData([
'blacklist',
$userId,
[
'connectFail' => $this->getData(['blacklist',$userId,'connectFail']) + 1,
'lastFail' => time(),
'ip' => helper::getIp()
]
]);
// Verrouillage des IP
$ipBlackList = helper::arrayCollumn($this->getData(['blacklist']), 'ip');
if ( $this->getData(['blacklist',$userId,'connectFail']) >= $this->getData(['config', 'connect', 'attempt'])
AND in_array($this->getData(['blacklist',$userId,'ip']),$ipBlackList) ) {
$logStatus = $text[1];
// Valeurs en sortie
$this->addOutput([
'notification' => $text[2],
'redirect' => helper::baseUrl(),
'state' => false
]);
} else {
// Valeurs en sortie
$this->addOutput([
'notification' => $text[3]
]);
}
/**
* Le compte existe
*/
} else {
// Cas 4 : le délai de blocage est dépassé et le compte est au max - Réinitialiser
if ($this->getData(['user',$userId,'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) < time()
AND $this->getData(['user',$userId,'connectFail']) === $this->getData(['config', 'connect', 'attempt']) ) {
$this->setData(['user',$userId,'connectFail',0 ]);
$this->setData(['user',$userId,'connectTimeout',0 ]);
}
// Check la présence des variables et contrôle du blocage du compte si valeurs dépassées
// Vérification du mot de passe et du groupe
if (
( $this->getData(['user',$userId,'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) ) < time()
AND $this->getData(['user',$userId,'connectFail']) < $this->getData(['config', 'connect', 'attempt'])
AND password_verify($this->getInput('userLoginPassword', helper::FILTER_STRING_SHORT, true), $this->getData(['user', $userId, 'password']))
AND $this->getData(['user', $userId, 'group']) >= self::GROUP_MEMBER
AND $captcha === true
) {
// RAZ
$this->setData(['user',$userId,'connectFail',0 ]);
$this->setData(['user',$userId,'connectTimeout',0 ]);
// Expiration
$expire = $this->getInput('userLoginLongTime') ? strtotime("+1 year") : 0;
$c = $this->getInput('userLoginLongTime', helper::FILTER_BOOLEAN) === true ? 'true' : 'false';
setcookie('DELTA_USER_ID', $userId, $expire, helper::baseUrl(false, false) , '', helper::isHttps(), true);
setcookie('DELTA_USER_PASSWORD', $this->getData(['user', $userId, 'password']), $expire, helper::baseUrl(false, false), '', helper::isHttps(), true);
setcookie('DELTA_USER_LONGTIME', $c, $expire, helper::baseUrl(false, false), '', helper::isHttps(), true);
// Accès multiples avec le même compte
$this->setData(['user',$userId,'accessCsrf',$_SESSION['csrf']]);
// Valeurs en sortie lorsque le site est en maintenance et que l'utilisateur n'est pas administrateur
if(
$this->getData(['config', 'maintenance'])
AND $this->getData(['user', $userId, 'group']) < self::GROUP_ADMIN
) {
$this->addOutput([
'notification' => $text[4],
'redirect' => helper::baseUrl(),
'state' => false
]);
} else {
$logStatus = $text[5];
// Page de redirection par défaut
$redirectPage = helper::baseUrl() . str_replace('_', '/', str_replace('__', '#', $this->getUrl(2)));
if( null !==($this->getData(['user',$userId,'redirectPageId'])) AND $this->getData(['user',$userId,'redirectPageId']) !== 'noRedirect') $redirectPage = helper::baseUrl() . $this->getData(['user',$userId,'redirectPageId']);
// Valeurs en sortie
$this->addOutput([
'notification' => $text[6] . $this->getData(['user',$userId,'firstname']) . ' ' . $this->getData(['user',$userId,'lastname']) ,
'redirect' => $redirectPage,
'state' => true
]);
}
// Sinon notification d'échec
} else {
$notification = $text[7];
$logStatus = $captcha === true ? $text[8] : $text[9];
// Cas 1 le nombre de connexions est inférieur aux tentatives autorisées : incrément compteur d'échec
if ($this->getData(['user',$userId,'connectFail']) < $this->getData(['config', 'connect', 'attempt'])) {
$this->setData(['user',$userId,'connectFail',$this->getdata(['user',$userId,'connectFail']) + 1 ]);
}
// Cas 2 la limite du nombre de connexion est atteinte : placer le timer
if ( $this->getdata(['user',$userId,'connectFail']) == $this->getData(['config', 'connect', 'attempt']) ) {
$this->setData(['user',$userId,'connectTimeout', time()]);
}
// Cas 3 le délai de bloquage court
if ($this->getData(['user',$userId,'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) > time() ) {
$notification = $text[10] . ($this->getData(['config', 'connect', 'timeout']) / 60) . ' minutes.';
}
// Valeurs en sortie
$this->addOutput([
'notification' => $notification
]);
}
}
}
// Journalisation
$dataLog = mb_detect_encoding(date('d\/m\/y',time()), 'UTF-8', true)
? date('d\/m\/y',time()) . ';' . date('H\:i',time()) . ';'
: utf8_encode(date('d\/m\/y',time())) . ';' . utf8_encode(date('H\:i',time())) . ';' ;
$dataLog .= helper::getIp($this->getData(['config','connect','anonymousIp'])) . ';';
$dataLog .= $this->getInput('userLoginId', helper::FILTER_ID) . ';' ;
$dataLog .= $this->getUrl() .';' ;
$dataLog .= $logStatus ;
$dataLog .= PHP_EOL;
if ($this->getData(['config','connect','log'])) {
file_put_contents(self::DATA_DIR . 'journal.log', $dataLog, FILE_APPEND);
}
// Stockage des cookies
if (!empty($_COOKIE['DELTA_USER_ID'])) {
self::$userId = $_COOKIE['DELTA_USER_ID'];
}
if (!empty($_COOKIE['DELTA_USER_LONGTIME'])) {
self::$userLongtime = $_COOKIE['DELTA_USER_LONGTIME'] == 'true' ? true : false;
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => $text[11],
'view' => 'login'
]);
}
/**
* Déconnexion
*/
public function logout() {
// Lexique
$text = [];
$val = $this->getData(['config', 'i18n', 'langAdmin']);
switch ($val) {
case 'fr' :
$text[0] = 'Déconnexion réussie';
break;
case 'en' :
$text[0] = 'Successfully disconnected';
break;
}
// Ne pas effacer l'identifiant mais seulement le mot de passe
if (array_key_exists('DELTA_USER_LONGTIME',$_COOKIE)
AND $_COOKIE['DELTA_USER_LONGTIME'] !== 'true' ) {
helper::deleteCookie('DELTA_USER_ID');
helper::deleteCookie('DELTA_USER_LONGTIME');
}
helper::deleteCookie('DELTA_USER_PASSWORD');
session_destroy();
// Valeurs en sortie
$this->addOutput([
'notification' => $text[0],
'redirect' => helper::baseUrl(false),
'state' => true
]);
}
/**
* Réinitialisation du mot de passe
*/
public function reset() {
// Lexique
$text = [];
$val = $this->getData(['config', 'i18n', 'langAdmin']);
switch ($val) {
case 'fr' :
$text[0] = 'Incorrect';
$text[1] = 'Nouveau mot de passe enregistré';
$text[2] = 'Réinitialisation du mot de passe';
break;
case 'en' :
$text[0] = 'Incorrect';
$text[1] = 'New password registered';
$text[2] = 'Resetting the password';
break;
}
// Accès refusé
if(
// L'utilisateur n'existe pas
$this->getData(['user', $this->getUrl(2)]) === null
// Lien de réinitialisation trop vieux
OR $this->getData(['user', $this->getUrl(2), 'forgot']) + 86400 < time()
// Id unique incorrecte
OR $this->getUrl(3) !== md5(json_encode($this->getData(['user', $this->getUrl(2)])))
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
}
// Accès autorisé
else {
// Soumission du formulaire
if($this->isPost()) {
// Double vérification pour le mot de passe
if($this->getInput('userResetNewPassword')) {
// La confirmation ne correspond pas au mot de passe
if($this->getInput('userResetNewPassword', helper::FILTER_STRING_SHORT, true) !== $this->getInput('userResetConfirmPassword', helper::FILTER_STRING_SHORT, true)) {
$newPassword = $this->getData(['user', $this->getUrl(2), 'password']);
self::$inputNotices['userResetConfirmPassword'] = $text[0];
}
else {
$newPassword = $this->getInput('userResetNewPassword', helper::FILTER_PASSWORD, true);
}
// Modifie le mot de passe
$this->setData(['user', $this->getUrl(2), 'password', $newPassword]);
// Réinitialise la date de la demande
$this->setData(['user', $this->getUrl(2), 'forgot', 0]);
// Réinitialise le blocage
$this->setData(['user', $this->getUrl(2),'connectFail',0 ]);
$this->setData(['user', $this->getUrl(2),'connectTimeout',0 ]);
// Valeurs en sortie
$this->addOutput([
'notification' => $text[1],
//'redirect' => helper::baseUrl() . 'user/login/' . str_replace('/', '_', $this->getUrl()),
'redirect' => helper::baseUrl(),
'state' => true
]);
}
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => $text[2],
'view' => 'reset'
]);
}
}
/**
* Importation CSV d'utilisateurs
*/
public function import() {
// Lexique
$text = [];
$val = $this->getData(['config', 'i18n', 'langAdmin']);
switch ($val) {
case 'fr' :
$text[0] = 'Compte créé sur ';
$text[1] = 'Bonjour ';
$text[2] = 'Un administrateur vous a créé un compte sur le site';
$text[3] = '. Vous trouverez ci-dessous les détails de votre compte.';
$text[4] = 'Identifiant du compte :';
$text[5] = 'Un mot de passe provisoire vous été attribué, à la première connexion cliquez sur Mot de passe Oublié.';
$text[6] = 'Rien à importer, erreur de format ou fichier incorrect';
$text[7] = 'Importation effectuée';
$text[8] = 'Erreur de lecture, vérifiez les permissions';
$text[9] = 'Importation';
break;
case 'en' :
$text[0] = 'Account created on ';
$text[1] = 'Hello ';
$text[2] = 'An administrator has created an account for you on the site';
$text[3] = '. You will find your account details below.';
$text[4] = 'Account ID :';
$text[5] = 'A temporary password has been assigned to you, the first time you log in click on Forgot password.';
$text[6] = 'Nothing to import, format error or incorrect file';
$text[7] = 'Importation done';
$text[8] = 'Read error, check permissions';
$text[9] = 'Importation';
break;
}
// Soumission du formulaire
$notification = '';
$success = true;
if($this->isPost()) {
// Lecture du CSV et construction du tableau
$file = $this->getInput('userImportCSVFile',helper::FILTER_STRING_SHORT, true);
$filePath = self::FILE_DIR . 'source/' . $file;
if ($file AND file_exists($filePath)) {
// Analyse et extraction du CSV
$rows = array_map(function($row) { return str_getcsv($row, $this->getInput('userImportSeparator') ); }, file($filePath));
$header = array_shift($rows);
$csv = array();
foreach($rows as $row) {
$csv[] = array_combine($header, $row);
}
// Traitement des données
foreach($csv as $item ) {
// Données valides
if( array_key_exists('id', $item)
AND array_key_exists('prenom',$item)
AND array_key_exists('nom',$item)
AND array_key_exists('groupe',$item)
AND array_key_exists('email',$item)
AND $item['nom']
AND $item['prenom']
AND $item['id']
AND $item['email']
AND $item['groupe']
) {
// Validation du groupe
$item['groupe'] = (int) $item['groupe'];
$item['groupe'] = ( $item['groupe'] >= self::GROUP_BANNED AND $item['groupe'] <= self::GROUP_ADMIN )
? $item['groupe'] : 1;
// L'utilisateur existe
if ( $this->getData(['user',helper::filter($item['id'] , helper::FILTER_ID)]))
{
// Notification du doublon
$item['notification'] = template::ico('cancel');
// Création du tableau de confirmation
self::$users[] = [
helper::filter($item['id'] , helper::FILTER_ID),
$item['nom'],
$item['prenom'],
self::$groups[$item['groupe']],
$item['prenom'],
helper::filter($item['email'] , helper::FILTER_MAIL),
$item['notification']
];
// L'utilisateur n'existe pas
} else {
// Nettoyage de l'identifiant
$userId = helper::filter($item['id'] , helper::FILTER_ID);
// Enregistre le user
$create = $this->setData([
'user',
$userId, [
'firstname' => $item['prenom'],
'forgot' => 0,
'group' => $item['groupe'] ,
'lastname' => $item['nom'],
'mail' => $item['email'],
'pseudo' => $item['prenom'],
'signature' => 1, // Pseudo
'password' => uniqid(), // A modifier à la première connexion
"connectFail" => null,
"connectTimeout" => null,
"accessUrl" => null,
"accessTimer" => null,
"accessCsrf" => null
]]);
// Icône de notification
$item['notification'] = $create ? template::ico('check') : template::ico('cancel');
// Envoi du mail
if ($create
AND $this->getInput('userImportNotification',helper::FILTER_BOOLEAN) === true) {
$sent = $this->sendMail(
$item['email'],
$text[0] . $this->getData(['locale', 'title']),
$text[0].' <strong>' . $item['prenom'] . ' ' . $item['nom'] . '</strong>,<br><br>' .
$text[2]. $this->getData(['locale', 'title']) . $text[3].'<br><br>' .
'<strong>'.$text[4].'</strong> ' . $userId . '<br>' .
'<small>'.$text[5].'</small>'
);
if ($sent === true) {
// Mail envoyé changement de l'icône
$item['notification'] = template::ico('mail') ;
}
}
// Création du tableau de confirmation
self::$users[] = [
$userId,
$item['nom'],
$item['prenom'],
self::$groups[$item['groupe']],
$item['prenom'],
$item['email'],
$item['notification']
];
}
}
}
if (empty(self::$users)) {
$notification = $text[6] ;
$success = false;
} else {
$notification = $text[7] ;
$success = true;
}
} else {
$notification = $text[8];
$success = false;
}
}
// Valeurs en sortie
$this->addOutput([
'title' => $text[9],
'view' => 'import',
'notification' => $notification,
'state' => $success
]);
}
}