Deltacms/core/module/user/user.php

789 lines
29 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 = [];
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
include('./core/module/user/lang/'. $this->getData(['config', 'i18n', 'langAdmin']) . '/lex_user.php');
// 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['core_user']['add'][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['core_user']['add'][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['core_user']['add'][2] . $this->getData(['locale', 'title']),
$text['core_user']['add'][3].'<strong>' . $userFirstname . ' ' . $userLastname . '</strong>,<br><br>' .
$text['core_user']['add'][4] . $this->getData(['locale', 'title']) . $text['core_user']['add'][5].'<br><br>' .
'<strong>'.$text['core_user']['add'][6].'</strong> ' . $this->getInput('userAddId') . '<br>' .
'<small>'.$text['core_user']['add'][7].'</small>',
null
);
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'user',
'notification' => $sent === true ? $text['core_user']['add'][8] : $sent,
'state' => $sent === true ? true : null
]);
}
// Générer la liste des pages disponibles
$redirectPage = array( 'noRedirect'=> array( 'title'=>$text['core_user']['add'][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['core_user']['add'][9],
'view' => 'add'
]);
}
/**
* Suppression
*/
public function delete() {
// Lexique
include('./core/module/user/lang/'. $this->getData(['config', 'i18n', 'langAdmin']) . '/lex_user.php');
// 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['core_user']['delete'][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['core_user']['delete'][1]
]);
}
// Suppression
else {
$this->deleteData(['user', $this->getUrl(2)]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'user',
'notification' => $text['core_user']['delete'][2],
'state' => true
]);
}
}
/**
* Édition
*/
public function edit() {
// Lexique
include('./core/module/user/lang/'. $this->getData(['config', 'i18n', 'langAdmin']) . '/lex_user.php');
if ($this->getUrl(3) !== $_SESSION['csrf'] &&
$this->getUrl(4) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'user',
'notification' => $text['core_user']['edit'][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['core_user']['edit'][1];
}
}
else {
self::$inputNotices['userEditOldPassword'] = $text['core_user']['edit'][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['core_user']['edit'][2],
'state' => true
]);
}
// Générer la liste des pages disponibles
$redirectPage = array( 'noRedirect'=> array( 'title'=> $text['core_user']['edit'][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
include('./core/module/user/lang/'. $this->getData(['config', 'i18n', 'langAdmin']) . '/lex_user.php');
// 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['core_user']['forgot'][0],
$text['core_user']['forgot'][1] .'<strong>' . $this->getData(['user', $userId, 'firstname']) . ' ' . $this->getData(['user', $userId, 'lastname']) . '</strong>,<br><br>' .
$text['core_user']['forgot'][2].'<br><br>' .
'<a href="' . helper::baseUrl() . 'user/reset/' . $userId . '/' . $uniqId . '" target="_blank">' . helper::baseUrl() . 'user/reset/' . $userId . '/' . $uniqId . '</a><br><br>' .
$text['core_user']['forgot'][3].'</small>',
null
);
// Valeurs en sortie
$this->addOutput([
'notification' => ($sent === true ? $text['core_user']['forgot'][4] : $sent),
'state' => ($sent === true ? true : null)
]);
}
// L'utilisateur n'existe pas
else {
// Valeurs en sortie
$this->addOutput([
'notification' => $text['core_user']['forgot'][5]
]);
}
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => $text['core_user']['forgot'][6],
'view' => 'forgot'
]);
}
/**
* Liste des utilisateurs
*/
public function index() {
// Lexique
include('./core/module/user/lang/'. $this->getData(['config', 'i18n', 'langAdmin']) . '/lex_user.php');
$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']),
$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['core_user']['index'][0],
'view' => 'index'
]);
}
/**
* Connexion
*/
public function login() {
// Lexique
include('./core/module/user/lang/'. $this->getData(['config', 'i18n', 'langAdmin']) . '/lex_user.php');
// Soumission du formulaire
$logStatus = '';
if($this->isPost()) {
// Lire Id du compte
$userId = $this->getInput('userLoginId', helper::FILTER_ID, true);
$detectBot ='';
$captcha = true;
// Check le captcha
if( $this->getData(['config','connect','captcha']) ){
$code ='';
if( isset( $_REQUEST['codeCaptcha'])) $code = strtoupper($_REQUEST['codeCaptcha']);
// option de détection de robot en premier cochée et $_SESSION['humanBot']==='human'
if( $_SESSION['humanBot']==='human' && $this->getData(['config', 'connect', 'captchaBot'])=== true ) {
// Présence des cookies et checkbox cochée ?
$detectBot ='bot';
$captcha = false;
if ( isset ($_COOKIE['evtX']) && isset ($_COOKIE['evtO']) && isset ($_COOKIE['evtV']) && isset ($_COOKIE['evtA'])
&& isset ($_COOKIE['evtH']) && isset ($_COOKIE['evtS']) && $this->getInput('userHumanCheck', helper::FILTER_BOOLEAN) === true ) {
// Calcul des intervals de temps
$time1 = 0;
if( isset ($_COOKIE['evtC'])) $time1 = $_COOKIE['evtC'] - $_COOKIE['evtO']; // temps entre fin de saisie et ouverture de la page
$time2 = $_COOKIE['evtH'] - $_COOKIE['evtO']; // temps entre click checkbox et ouverture de la page
$time3 = $_COOKIE['evtV'] - $_COOKIE['evtH']; // temps entre validation formulaire et click checkbox
$time4 = $_COOKIE['evtS'] - $_COOKIE['evtA']; // temps passé sur la checkbox
if( ( $time1 >= 1000 || ( isset ($_COOKIE['evtX']) && !isset ($_COOKIE['evtC']) ) ) && $time2 >= 1000
&& $time3 >=300 && $time4 >=300 && $this->getInput('userInputBlue')==='' ) {
$detectBot = 'human';
$captcha = true;
}
}
// Bot présumé
if( $detectBot === 'bot') $_SESSION['humanBot']='bot';
}
// $_SESSION['humanBot']==='bot' ou option 'Pas de Captcha pour un humain' non validée
elseif( md5($code) !== $_SESSION['captcha'] ) {
$captcha = false;
} else {
$captcha = true;
}
}
/**
* Aucun compte existant
*/
if ( !$this->getData(['user', $userId])) {
$logStatus = $text['core_user']['login'][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['core_user']['login'][1];
// Valeurs en sortie
$this->addOutput([
'notification' => $text['core_user']['login'][2],
'redirect' => helper::baseUrl(),
'state' => false
]);
} else {
// Valeurs en sortie
$this->addOutput([
'notification' => $text['core_user']['login'][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['core_user']['login'][4],
'redirect' => helper::baseUrl(),
'state' => false
]);
} else {
$logStatus = $text['core_user']['login'][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['core_user']['login'][6] . $this->getData(['user',$userId,'firstname']) . ' ' . $this->getData(['user',$userId,'lastname']) ,
'redirect' => $redirectPage,
'state' => true
]);
}
// Sinon notification d'échec
} else {
$notification = $text['core_user']['login'][7];
if( $detectBot = 'bot' ) $notification = $text['core_user']['login'][13];
$logStatus = $captcha === true ? $text['core_user']['login'][8] : $text['core_user']['login'][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['core_user']['login'][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['core_user']['login'][11],
'view' => 'login'
]);
}
/**
* Déconnexion
*/
public function logout() {
// Lexique
include('./core/module/user/lang/'. $this->getData(['config', 'i18n', 'langAdmin']) . '/lex_user.php');
// 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['core_user']['logout'][0],
'redirect' => helper::baseUrl(false),
'state' => true
]);
}
/**
* Réinitialisation du mot de passe
*/
public function reset() {
// Lexique
include('./core/module/user/lang/'. $this->getData(['config', 'i18n', 'langAdmin']) . '/lex_user.php');
// 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['core_user']['reset'][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['core_user']['reset'][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['core_user']['reset'][2],
'view' => 'reset'
]);
}
}
/**
* Importation CSV d'utilisateurs
*/
public function import() {
// Lexique
include('./core/module/user/lang/'. $this->getData(['config', 'i18n', 'langAdmin']) . '/lex_user.php');
// 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'],
$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['core_user']['import'][0] . $this->getData(['locale', 'title']),
$text['core_user']['import'][0].' <strong>' . $item['prenom'] . ' ' . $item['nom'] . '</strong>,<br><br>' .
$text['core_user']['import'][2]. $this->getData(['locale', 'title']) . $text['core_user']['import'][3].'<br><br>' .
'<strong>'.$text['core_user']['import'][4].'</strong> ' . $userId . '<br>' .
'<small>'.$text['core_user']['import'][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'],
$groups[$item['groupe']],
$item['prenom'],
$item['email'],
$item['notification']
];
}
}
}
if (empty(self::$users)) {
$notification = $text['core_user']['import'][6] ;
$success = false;
} else {
$notification = $text['core_user']['import'][7] ;
$success = true;
}
} else {
$notification = $text['core_user']['import'][8];
$success = false;
}
}
// Valeurs en sortie
$this->addOutput([
'title' => $text['core_user']['import'][9],
'view' => 'import',
'notification' => $notification,
'state' => $success
]);
}
}