1.15.01 La double authentification se désactive si le serveur smtp n'est pas joignable

This commit is contained in:
Fred Tempez 2024-12-19 22:01:30 +01:00
parent 13f7203054
commit 91bb26667f
6 changed files with 97 additions and 65 deletions

View File

@ -1,4 +1,4 @@
# ZwiiCampus 1.15.00
# ZwiiCampus 1.15.01
ZwiiCampus (Learning Management System) est logiciel auteur destiné à mettre en ligne des tutoriels. Il dispose de plusieurs modalités d'ouverture et d'accès des contenus. Basé sur la version 13 du CMS Zwii, la structure logicielle est solide, le framework de Zwii est éprouvé.

View File

@ -32,6 +32,7 @@ class config extends common
'blacklistReset' => self::GROUP_ADMIN,
'blacklistDownload' => self::GROUP_ADMIN,
'register' => self::GROUP_ADMIN,
'testmail' => self::GROUP_ADMIN,
];
public static $timezones = [
@ -995,4 +996,32 @@ class config extends common
'redirect' => helper::baseUrl() . 'config/' . $this->getUrl(2),
]);
}
/**
* Envoi un message de test
* @return void
*/
public function testmail()
{
$sent = $this->sendMail(
$this->getUser('mail'),
helper::translate('Test de la messagerie du site'),
'<strong>' . $this->getUser('firstname') . ' ' . $this->getUser('lastname') . '</strong>,<br><br>' .
'<h4>' . helper::translate('Il semblerait que votre messagerie fonctionne correctement !') . '</h4>',
null,
'no-reply@localhost'
);
if ($sent !== true) {
// Désactivation de l'authentification par email
$this->setData(['config', 'connect', 'mailAuth', 0]);
// Journalisation
$this->saveLog($sent);
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config/' . $this->getUrl(2),
'state' => $sent === true ? true : false,
'notification' => $sent === true ? helper::translate('Message de test envoyé avec succès') : helper::translate('Message non envoyé')
]);
}
}

View File

@ -25,29 +25,37 @@
</div>
</div>
<div class="row">
<div class="col4">
<div class="col3">
<?php echo template::select('connectAttempt', $module::$connectAttempt, [
'label' => 'Limitation des tentatives',
'selected' => $this->getData(['config', 'connect', 'attempt'])
]); ?>
</div>
<div class="col4">
<div class="col3">
<?php echo template::select('connectTimeout', $module::$connectTimeout, [
'label' => 'Blocage après échecs',
'selected' => $this->getData(['config', 'connect', 'timeout'])
]); ?>
</div>
<div class="col4">
<?php echo template::select('connectAuthMail', array_merge([''=>'Aucune'], self::$groupNews), [
'label' => 'Validation par messagerie ⚠️',
<div class="col3">
<?php echo template::select('connectAuthMail', array_merge([0 => 'Aucune'], self::$groupNews), [
'label' => 'Validation par clé ⚠️',
'selected' => $this->getData(['config', 'connect', 'mailAuth']),
'help' => 'La connexion est confirmée par une clé transmise par messagerie. Depuis le groupe sélectionnée et les groupes supérieurs. Vérifiez le bon fonctionnement du serveur de messagerie AVANT d\'activer cette option!'
'help' => 'La connexion est confirmée à l\'aide d\'une clé transmise par messagerie. Depuis le groupe sélectionné et les groupes supérieurs.'
]); ?>
</div>
<div class="col3 verticalAlignBottom">
<?php echo template::button('ConfigSendMail', [
'href' => helper::baseUrl() . 'config/testmail',
'value' => 'Message de test',
'ico' => 'mail'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Captcha à la connexion'); ?>

View File

@ -4,11 +4,6 @@
<div class="block">
<h4>
<?php echo helper::translate('Paramètres'); ?>
<!--<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/reseau" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col2">
@ -40,11 +35,6 @@
<div class="block">
<h4>
<?php echo helper::translate('SMTP'); ?>
<!--<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/smtp" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col6">
@ -97,7 +87,7 @@
<?php echo template::password('smtpPassword', [
'label' => 'Mot de passe',
'autocomplete' => 'off',
'value' => $this->getData(['config', 'smtp', 'password'])
'value' => $this->getData(['config', 'smtp', 'password'])
]); ?>
</div>
<div class="col2">
@ -113,3 +103,4 @@
</div>
</div>
</div>
</div>

View File

@ -1228,6 +1228,9 @@ class user extends common
}
}
/**
* Connexion
*/
public function login()
{
// Soumission du formulaire
@ -1324,22 +1327,48 @@ class user extends common
* Le site n'est pas en maintenance
* Double authentification en cas de saisie correcte
*/
// Clé d'authenfication utlisée pour lié le compte au cookie au lieu de stocke le hash du mot de passe
// Clé d'authenfication utilisée pour lier le compte au cookie au lieu de stocker le hash du mot de passe
$authKey = uniqid('', true) . bin2hex(random_bytes(8));
if ($this->getData(['config', 'connect', 'mailAuth']) >= $this->getData(['user', $userId, 'group'])) {
$logStatus = 'Envoi du mail d\'authentification';
// Redirection vers la page d'authentification
$authRedirect = 'user/auth/';
// Stocker la clé envoyée par email
$this->setData(['user', $userId, 'authKey', rand(100000, 999999)]);
// Clé pour la double validation
$keyByMail = rand(100000, 999999);
// La page d'authentification est vide
$authRedirect = '';
if (
$this->getData(['config', 'connect', 'mailAuth']) > 0
&& $this->getData(['user', $userId, 'group']) >= $this->getData(['config', 'connect', 'mailAuth'])
) {
/**
* Envoi d'un email contenant une clé
* Stockage de la clé dans le compte de l'utilisateur
*/
$sent = $this->sendMail(
$this->getData(['user', $userId, 'mail']),
'Validation de la connexion à votre compte',
'<p>Clé de validation à saisir dans le formulaire de connexion :</p>' .
'<h1><center>' . $keyByMail . '</center></h1>',
null,
$this->getData(['config', 'smtp', 'from'])
);
// L'email a été envoyé avec succès, redirection vers la page de double authentification
if ($sent === true) {
$logStatus = helper::translate('Envoi du message d\'authentification');
// Redirection vers la page d'authentification
$authRedirect = 'user/auth/';
// Stocker la clé envoyée par email
$this->setData(['user', $userId, 'authKey', $keyByMail]);
} else {
// Impossible d'envoyer le message
// Double authentification désactivée
$this->setData(['config', 'connect', 'mailAuth', 0]);
$this->setData(['user', $userId, 'authKey', $authKey]);
// Journalisation
$this->saveLog($sent);
}
} else {
$logStatus = 'Connexion réussie';
// La page d'autentification est vide
$authRedirect = '';
$logStatus = helper::translate('Connexion réussie');
$this->setData(['user', $userId, 'authKey', $authKey]);
}
// Validité du cookie
@ -1381,7 +1410,7 @@ class user extends common
// Sinon notification d'échec
} else {
$notification = helper::translate('Captcha, identifiant ou mot de passe incorrects');
$logStatus = $captcha === true ? 'Erreur de mot de passe' : 'Erreur de captcha';
$logStatus = $captcha === true ? helper::translate('Erreur de mot de passe') : helper::translate('Erreur de captcha');
// 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'], false)) {
$this->setData(['user', $userId, 'connectFail', $this->getdata(['user', $userId, 'connectFail']) + 1], false);
@ -1397,7 +1426,7 @@ class user extends common
// Valeurs en sortie
$this->addOutput([
'notification' => $notification
'notification' => $notification,
]);
}
}
@ -1434,9 +1463,11 @@ class user extends common
$targetKey = $this->getData(['user', $this->getUser('id'), 'authKey']);
$inputKey = $this->getInput('userAuthKey', helper::FILTER_INT);
if (
$targetKey === $inputKey &&
$this->getData(['user', $this->getUser('id'), 'connectTimeout']) + 3600 >= time()
// La clé est valide ou le message n'ayant pas été expédié, la double authentification est désactivée
$targetKey === $inputKey || $this->getData(['config', 'connect', 'mailAuth', 0]) === 0
) {
// Redirection
$pageId = $this->getUrl(2);
// La fiche de l'utilisateur contient la clé d'authentification
$this->setData(['user', $this->getUser('id'), 'authKey', $this->getInput('ZWII_AUTH_KEY')]);
@ -1470,39 +1501,12 @@ class user extends common
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl(),
'redirect' => helper::baseUrl() . 'user/auth',
'notification' => helper::translate('La clé est incorrecte'),
'state' => false
]);
}
} else {
/**
* Envoi d'un email contenant une clé
* Stockage de la clé dans le compte de l'utilisateur
*/
// La clé est envoyée une seule fois
$sent = false;
if (
$this->getData(['user', $this->getUser('id'), 'authKey'])
&& $this->getData(['user', $this->getUser('id'), 'connectTimeout']) === 0
) {
$sent = $this->sendMail(
$this->getUser('mail'),
'Tentative de connexion à votre',
//'Bonjour <strong>' . $item['prenom'] . ' ' . $item['nom'] . '</strong>,<br><br>' .
'<p>Clé de validation à saisir dans le formulaire :</p>' .
'<h1><center>' . $this->getData(['user', $this->getUser('id'), 'authKey']) . '</center></h1>',
null,
$this->getData(['config', 'smtp', 'from'])
);
// Stocker l'envoi de l'email
$this->setData(['user', $this->getUser('id'), 'connectTimeout', time()]);
}
// Message envoyé sinon la connexion est réalisée pour ne pas bloquer.
if ($sent === false) {
}
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Double authentification'),

View File

@ -2,7 +2,7 @@
<div class="row">
<div class="col4 offset4">
<?php echo template::text('userAuthKey', [
'label' => helper::translate('Clé reçue par couriel')
'label' => helper::translate('Clé envoyée par message')
]); ?>
</div>
</div>