Commit 4019730d authored by Patrick Barroca's avatar Patrick Barroca 😁
Browse files

wip : lostpass refactoring

parent 42f3ec38
......@@ -20,6 +20,10 @@
*/
class AuthController extends ZendAfi_Controller_Action {
const
LOST_PASS_NOLOGIN = 1,
LOST_PASS_NOUSER = 2,
LOST_PASS_NOMAIL = 4;
public function init() {
$this->view->locale = Zend_Registry::get('locale');
......@@ -54,12 +58,13 @@ class AuthController extends ZendAfi_Controller_Action {
public function getErrorMessages($error_code) {
$messages= [1 => $this->_('Veuillez saisir votre identifiant.'),
2 => $this->_('Identifiant inconnu.'),
4 => $this->_("Votre mail n'est pas renseigné dans votre compte lecteur. Merci de vous adresser à la bibliothèque pour récupérer votre mot de passe ou bien le remplacer par un nouveau.")];
if (isset($messages[$error_code]))
return $messages[$error_code];
return '';
$messages = [static::LOST_PASS_NOLOGIN => $this->_('Veuillez saisir votre identifiant.'),
static::LOST_PASS_NOUSER => $this->_('Identifiant inconnu.'),
static::LOST_PASS_NOMAIL => $this->_("Votre mail n'est pas renseigné dans votre compte lecteur. Merci de vous adresser à la bibliothèque pour récupérer votre mot de passe ou bien le remplacer par un nouveau.")];
return isset($messages[$error_code])
? $messages[$error_code]
: '';
}
......@@ -84,13 +89,13 @@ class AuthController extends ZendAfi_Controller_Action {
$password = $f->filter($this->_request->getPost('password'));
if (empty($username))
return $this->view->_('Entrez votre identifiant S.V.P.');
return $this->_('Entrez votre identifiant S.V.P.');
if (empty($password))
return $this->view->_('Entrez votre mot de passe S.V.P.');
return $this->_('Entrez votre mot de passe S.V.P.');
if (!ZendAfi_Auth::getInstance()->authenticateLoginPassword($username, $password))
return $this->view->_('Identifiant ou mot de passe incorrect.');
return $this->_('Identifiant ou mot de passe incorrect.');
$user = Class_Users::getIdentity();
$this->_helper->trackEvent('authentification', 'connexion', 'utilisateur', $user->getId());
......@@ -296,25 +301,24 @@ class AuthController extends ZendAfi_Controller_Action {
public function lostpassAction() {
$preferences = $this->_loginPrefFromWidgetOrModule();
$options = ['username_label' => $preferences["identifiant"],
'username_placeholder' => $preferences["identifiant_exemple"]];
$this->view->form = ZendAfi_Form_LostPassword::newWithOptions(['username_label' => $preferences["identifiant"],
'username_placeholder' => $preferences["identifiant_exemple"]])
$form = ZendAfi_Form_LostPassword::newWithOptions($options)
->setAction($this->view->url(['module' => 'opac',
'controller' => 'auth',
'action' => 'lostpass'], null , true));
$this->view->form = $form;
if(!$this->_request->isPost())
if(!$this->_request->isPost()
|| !$form->isValid($this->_request->getPost()))
return;
$user = ZendAfi_Filters_Post::filterStatic($this->_request->getPost('lost_username'));
$classe_user = new Class_Users();
$ret = $classe_user->lostpass($user);
$login = ZendAfi_Filters_Post::filterStatic($this->_request->getPost('lost_username'));
$this->view->username = $login;
$this->view->message = $this->getErrorMessages($ret["error"]);
$this->view->message_mail = isset($ret["message_mail"])
? $ret["message_mail"]
: '';
$this->view->username=$user;
$user = Class_Users::findFirstValidOrNotBy(['login' => $login]);
$this->view->message_mail = (new Class_User_LostPass($user))->send();
}
......
......@@ -16,29 +16,22 @@
*
* You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
* along with BOKEH; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
////////////////////////////////////////////////////////////////////////////////////////
// OPAC3 : ENVOI DE MAILS
///////////////////////////////////////////////////////////////////////////////////////
class Class_Mail
{
class Class_Mail {
use Trait_Translator;
private $params_ok=false; // Flag de controle si un mail peut etre envoyé
private $mail_from; // Header from
private $_translate;
//---------------------------------------------------------------------------------
// constructeur : init des parametres
//---------------------------------------------------------------------------------
public function __construct() {
$this->_translate = Zend_Registry::get('translate');
$this->params_ok = false;
$this->mail_from = Class_Profil::getCurrentProfil()->getMailSiteOrPortail();
if (!$this->mail_from)
$this->mail_from = Class_CosmoVar::get('mail_admin');
if ($this->isMailValid($this->mail_from)) {
ini_set('sendmail_from', $this->mail_from);
$this->params_ok=true;
......@@ -46,12 +39,7 @@ class Class_Mail
}
public function _translate($message) {
return $this->_translate->_($message);
}
public function mail($destinataire, $sujet, $body, $headers) {
public function mail($destinataire, $sujet, $body) {
$mail = new ZendAfi_Mail('utf8');
$mail
->setSubject($sujet)
......@@ -67,21 +55,21 @@ class Class_Mail
}
}
//---------------------------------------------------------------------------------
// Envoi de mail
//---------------------------------------------------------------------------------
public function sendMail($sujet,$body,$destinataire,$data=false)
{
public function sendMail($sujet, $body, $destinataire, $data=false) {
$error_message = sprintf('%s <br/> %s',
$this->_translate("Les paramètres d'envoi de mails du portail sont incomplets."),
$this->_translate("Merci de le signaler aux responsables de la bibliothèque."));
$this->_("Les paramètres d'envoi de mails du portail sont incomplets."),
$this->_("Merci de le signaler aux responsables de la bibliothèque."));
if(!$this->params_ok or !trim($body))
return $error_message;
// Controle des parametres
if(!trim($destinataire))
return $this->_translate->_("Adresse du destinataire absente.");
return $this->_("L'Adresse du destinataire est absente.");
if (!$this->isMailValid($destinataire))
return $this->_("L'adresse e-mail du destinataire est incorrecte.");
if($this->params_ok==false or !trim($body))
return $error_message;
// Fusion
if($data)
......@@ -93,20 +81,12 @@ class Class_Mail
}
}
$body = wordwrap($body, 60);
// Envoi du mail
$ret=$this->getHeaders($destinataire);
if (array_isset("erreur", $ret))
return $ret["erreur"];
else
$headers=$ret["headers"];
$statut = $this->mail($destinataire, $sujet, $body, $headers);
if($statut == false)
return $error_message;
$statut = $this->mail($destinataire, $sujet, $body);
return "";
return (true === $statut)
? ''
: $error_message;
}
......@@ -114,27 +94,4 @@ class Class_Mail
$validator = new Zend_Validate_EmailAddress();
return $validator->isValid($mail);
}
//---------------------------------------------------------------------------------
// Constitution des headers
//---------------------------------------------------------------------------------
protected function getHeaders($destinataire)
{
$ret = array('headers' => '');
if (!$this->isMailValid($destinataire)) {
$ret["erreur"]= "L'adresse e-mail du destinataire est incorrecte.";
return $ret;
}
// Headers
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=UTF-8' . "\r\n";
$headers .= 'To: '.$destinataire. "\r\n";
$headers .= 'From: '.$this->mail_from . "\r\n";
$ret["headers"]=$headers;
return $ret;
}
}
?>
\ No newline at end of file
}
\ No newline at end of file
<?php
/**
* Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
*
* BOKEH is free software; you can redistribute it and/or modify
* it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
* the Free Software Foundation.
*
* There are special exceptions to the terms and conditions of the AGPL as it
* is applied to this software (see README file).
*
* BOKEH is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
* along with BOKEH; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class Class_User_LostPass {
const MAX_MINUTES = 30;
protected $_user;
public function __construct($user) {
$this->_user = $user;
}
public function send() {
$strategy = $this->_user->isAbonne()
? new Class_User_LostPassPatron()
: new Class_User_LostPassLocal();
return $strategy->sendTo($this->_user);
}
}
abstract class Class_User_LostPassSender {
use Trait_Translator;
public function sendTo($user) {
$error = (new Class_Mail())
->sendMail(Class_Profil::getCurrentProfil()->getTitreSite(),
$this->_contentFor($user),
$user->getMail());
return $error
? '<p class="error">' . $error . '</p>'
: $this->_successMessage();
}
protected function _contentFor($user) {
return '';
}
protected function _successMessage() {
return '';
}
}
class Class_User_LostPassPatron extends Class_User_LostPassSender {
protected function _contentFor($user) {
return
sprintf("%s\n\n",
$this->_('Vous avez fait une demande de mot de passe sur le portail.'))
. $this->_("Votre identifiant : %s\n", $user->getLogin())
. $this->_("Votre mot de passe : %s\n", $user->getPassword())
. sprintf("%s\n\n", $this->_('Bonne navigation sur le portail'))
;
}
protected function _successMessage() {
return $this->_('Un mail vient de vous être envoyé avec vos paramètres de connexion.');
}
}
class Class_User_LostPassLocal extends Class_User_LostPassSender{
use Trait_TimeSource;
const TOKEN_SEPARATOR = '@';
protected function _contentFor($user) {
$created_at = $this->getCurrentTime();
$parts = [$user->getId(), ];
$token = sha1(implode(static::TOKEN_SEPARATOR, $parts));
return
sprintf("%s\n\n",
$this->_('Vous avez fait une demande de réinitialisation de votre mot de passe sur le portail.'))
. $this->_("Votre lien de réinitialisation : %s\n",
Class_Url::absolute(['module' => 'opac',
'controller' => 'auth',
'action' => 'reset-password',
'id' => $user->getId(),
'token' => $token], null, true))
. $this->_("ATTENTION : ce lien créé à %s est valide pendant %s minutes\n",
date('H:i', $created_at),
Class_User_LostPass::MAX_MINUTES)
. sprintf("%s\n\n", $this->_('Bonne navigation sur le portail'));
}
protected function _successMessage() {
return $this->_('Un mail vient de vous être envoyé contenant un lien de réinitialisation du mot de passe.');
}
}
\ No newline at end of file
......@@ -321,6 +321,14 @@ class UsersLoader extends Storm_Model_Loader {
$count_params = $this->_buildSearchParams($defaults, $where, $valide_subscription);
return Class_Users::countBy($count_params);
}
public function findFirstValidOrNotBy($params) {
if (!$user = Class_Users::findFirstBy($params))
$user = Class_UsersNonValid::findFirstBy($params);
return $user;
}
}
......@@ -1115,7 +1123,7 @@ class Class_Users extends Storm_Model_Abstract {
}
function lostpass($login) {
public function lostpass($login) {
if(!trim($login))
return ['error' => 1];
......
......@@ -29,11 +29,12 @@ class ZendAfi_Form_LostPassword extends ZendAfi_Form {
['label' => $this->getAttrib('username_label'),
'placeholder' => $this->getAttrib('username_placeholder'),
'required' => true,
'allowEmpty' => false])
'allowEmpty' => false,
'validators' => ['LostUsername']])
->addDisplayGroup(['lost_username'],
'lostpass_display_group',
['legend' => $this->_('Récupération du mot de passe')])
['legend' => ''])
->setAttribs([])
->setName('form_lostpass');
}
......
<?php
/**
* Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
*
* BOKEH is free software; you can redistribute it and/or modify
* it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
* the Free Software Foundation.
*
* There are special exceptions to the terms and conditions of the AGPL as it
* is applied to this software (see README file).
*
* BOKEH is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
* along with BOKEH; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class ZendAfi_Validate_LostUsername extends Zend_Validate_Abstract {
use Trait_Translator;
const
NO_USER = 'no_user',
NO_MAIL = 'no_mail';
public function __construct() {
$this->_messageTemplates =
[static::NO_USER => $this->_('Identifiant inconnu.'),
static::NO_MAIL => $this->_("Votre mail n'est pas renseigné dans votre compte lecteur. Merci de vous adresser à la bibliothèque pour récupérer votre mot de passe ou bien le remplacer par un nouveau.")];
}
/**
* @param $value mixed
* @param $fields array
* @return boolean
*/
public function isValid($value, array $fields_values = array()) {
$value = ZendAfi_Filters_Post::filterStatic($value);
if (!$user = Class_Users::findFirstValidOrNotBy(['login' => $value])) {
$this->_error(static::NO_USER);
return false;
}
if (!$user->hasMail()) {
$this->_error(static::NO_MAIL);
return false;
}
return true;
}
}
......@@ -1316,27 +1316,27 @@ class AuthControllerLoginActionWithDefaultPreferencesRenderTest extends AuthCont
}
}
class AuthControllerLostPasswordUnknownPostTest extends AbstractControllerTestCase{
protected $_storm_default_to_volatile = true;
public function setUp() {
parent::setUp();
}
class AuthControllerLostPasswordUnknownPostTest extends AbstractControllerTestCase{
protected $_storm_default_to_volatile = true;
/** @test */
public function withUnknowUserShouldDisplayError() {
$this->postDispatch('/opac/auth/lostpass',['lost_username' => 'unknown']);
$this->assertXPathContentContains('//div', 'Identifiant inconnu',$this->_response->getBody());
$this->postDispatch('/opac/auth/lostpass', ['lost_username' => 'unknown']);
$this->assertXPathContentContains('//div',
'Identifiant inconnu',
$this->_response->getBody());
}
/** @test */
public function withEmptyUserShouldDisplayError() {
$this->postDispatch('/opac/auth/lostpass',['lost_username' => '']);
$this->assertXPathContentContains('//div', 'Veuillez saisir votre identifiant.',$this->_response->getBody());
$this->postDispatch('/opac/auth/lostpass', ['lost_username' => '']);
$this->assertXPathContentContains('//div',
'Une valeur est requise',
$this->_response->getBody());
}
}
......
......@@ -16,22 +16,21 @@
*
* You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
* along with BOKEH; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class Class_MailTesting extends Class_Mail {
protected
$_destinataire,
$_sujet,
$_body,
$_headers,
protected
$_destinataire,
$_sujet,
$_body,
$_headers,
$_mail_return_value;
public function mail($destinataire, $sujet, $body, $headers) {
public function mail($destinataire, $sujet, $body) {
$this->_destinataire = $destinataire;
$this->_sujet = $sujet;
$this->_body = $body;
$this->_headers = $headers;
return $this->_mail_return_value;
}
......@@ -58,21 +57,22 @@ class Class_MailTesting extends Class_Mail {
class MailToZorkFromFlorenceTest extends Storm_Test_ModelTestCase {
class MailToZorkFromFlorenceTest extends ModelTestCase {
protected $_storm_default_to_volatile=true;
public function setUp() {
parent::setUp();
Class_CosmoVar::getLoader()
->newInstanceWithId('mail_admin')
->setValeur('florence@astrolabe-melun.fr');
Class_Profil::getCurrentProfil()->setMailSite('');
Class_Profil::getPortail()->setMailSite('');
$this->fixture('Class_Profil', ['id' => 1,
'mail_site' => '']);
$this->_mail_testing = new Class_MailTesting();
$this->_mail_testing->mailReturns(true);
$this->_status = $this->_mail_testing->sendMail('Bienvenue !',
$this->_status = $this->_mail_testing->sendMail('Bienvenue !',
'Vous êtes inscrit',
'zork@gmail.com');
}
......@@ -100,35 +100,28 @@ class MailToZorkFromFlorenceTest extends Storm_Test_ModelTestCase {
function bodyShouldBeVousEtesInscrit() {
$this->assertEquals('Vous êtes inscrit', $this->_mail_testing->getBody());
}
/** @test */
function headersShouldContainSenderFlorence() {
$this->assertContains('From: florence@astrolabe-melun.fr',
$this->_mail_testing->getMailHeaders());
}
}
class MailErrorsTest extends Storm_Test_ModelTestCase {
class MailErrorsTest extends ModelTestCase {
protected $_storm_default_to_volatile=true;
public function setUp() {
parent::setUp();
Class_Profil::getCurrentProfil()->setMailSite('');
Class_Profil::getPortail()->setMailSite('');
$profil = $this->fixture('Class_Profil', ['id' => 1, 'mail_site' => '']);
Class_Profil::setCurrentProfil($profil);
}
/** @test */
function withoutMailAdminShouldReturnErrorMessage() {
Class_CosmoVar::getLoader()
->newInstanceWithId('mail_admin')
->setValeur('');
Class_CosmoVar::setValueOf('mail_admin', '');
$mail_testing = new Class_MailTesting();
$mail_testing->mailReturns(true);
$status = $mail_testing->sendMail('Bienvenue !',
$status = $mail_testing->sendMail('Bienvenue !',
'Vous êtes inscrit',
'zork@gmail.com');
$this->assertContains("Les paramètres d'envoi de mails du portail sont incomplets.",
......@@ -156,16 +149,15 @@ class MailErrorsTest extends Storm_Test_ModelTestCase {
Class_CosmoVar::getLoader()
->newInstanceWithId('mail_admin')
->setValeur('laurent@gmail.com');
$mail_testing = new Class_MailTesting();
$mail_testing->mailReturns(false);
$status = $mail_testing->sendMail('Bienvenue !',
$status = $mail_testing->sendMail('Bienvenue !',
'Vous êtes inscrit',
'zork@gmail.com');
$this->assertContains("Les paramètres d'envoi de mails du portail sont incomplets.",
$status);
}
}
?>
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment