Commit 83d6bcca authored by Patrick Barroca's avatar Patrick Barroca 😁
Browse files

wip : reset-password action

parent 4019730d
......@@ -322,6 +322,22 @@ class AuthController extends ZendAfi_Controller_Action {
}
public function resetPasswordAction() {
$this->view->title = $this->_('Réinitialisation du mot de passe');
if (!$user = Class_Users::find((int)$this->_getParam('id')))
return $this->view->message = $this->_('Utilisateur inconnu');
$lostpass = new Class_User_LostPass($user);
$created = $this->_getParam('created');
if ($this->_getParam('token', '') != $lostpass->tokenAt($created))
return $this->view->message = $this->_('Jeton de réinitialisation invalide');
if ($lostpass->tokenHasExpiredFrom($created))
return $this->view->message = $this->_('Jeton de réinitialisation expiré');
}
public function registerAction() {
if (Class_AdminVar::get('INTERDIRE_ENREG_UTIL')) {
$this->_redirect('/');
......
<?php
$this->openBoite($this->title);
if ($this->message)
echo $this->tag('div', $this->message);
$this->closeBoite();
......@@ -21,7 +21,11 @@
class Class_User_LostPass {
use Trait_TimeSource;
const MAX_MINUTES = 30;
const TOKEN_SEPARATOR = '@';
const TOKEN_DATE_FORMAT = 'YmdHis';
protected $_user;
......@@ -32,11 +36,26 @@ class Class_User_LostPass {
public function send() {
$strategy = $this->_user->isAbonne()
? new Class_User_LostPassPatron()
: new Class_User_LostPassLocal();
? new Class_User_LostPassPatron($this)
: new Class_User_LostPassLocal($this);
return $strategy->sendTo($this->_user);
}
public function tokenAt($date) {
$parts = [$this->_user->getId(), $this->_user->getLogin(), $date];
return sha1(implode(static::TOKEN_SEPARATOR, $parts));
}
public function tokenHasExpiredFrom($date) {
$from = DateTime::createFromFormat(static::TOKEN_DATE_FORMAT, $date);
$now = new DateTime($this->getCurrentDateTime());
$from->add(new DateInterval('PT' . static::MAX_MINUTES . 'M'));
return $from < $now;
}
}
......@@ -44,7 +63,15 @@ class Class_User_LostPass {
abstract class Class_User_LostPassSender {
use Trait_Translator;
protected $_lostpass;
public function __construct($lostpass) {
$this->_lostpass = $lostpass;
}
public function sendTo($user) {
echo $this->_contentFor($user);exit;
$error = (new Class_Mail())
->sendMail(Class_Profil::getCurrentProfil()->getTitreSite(),
$this->_contentFor($user),
......@@ -90,12 +117,10 @@ class Class_User_LostPassPatron extends Class_User_LostPassSender {
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));
$created_at_part = date(Class_User_LostPass::TOKEN_DATE_FORMAT, $created_at);
$token = $this->_lostpass->tokenAt($created_at_part);
return
sprintf("%s\n\n",
......@@ -105,7 +130,8 @@ class Class_User_LostPassLocal extends Class_User_LostPassSender{
'controller' => 'auth',
'action' => 'reset-password',
'id' => $user->getId(),
'token' => $token], null, true))
'token' => $token,
'created' => $created_at_part], null, true))
. $this->_("ATTENTION : ce lien créé à %s est valide pendant %s minutes\n",
date('H:i', $created_at),
Class_User_LostPass::MAX_MINUTES)
......
<?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
*/
abstract class AuthControllerResetPasswordTestCase extends AbstractControllerTestCase {
protected $_storm_default_to_volatile=true;
protected function urlFor($id, $token, $created) {
return sprintf('/opac/auth/reset-password/id/%s/token/%s/created/%s',
$id, $token, $created);
}
}
class AuthControllerResetPasswordActionTest
extends AuthControllerResetPasswordTestCase {
public function setUp() {
parent::setUp();
Class_User_LostPass::setTimeSource((new TimeSourceForTest('2017-11-30'))
->atCoffeeTime());
}
public function tearDown() {
Class_User_LostPass::setTimeSource(null);
parent::tearDown();
}
/** @test */
public function unknownUserShouldHaveError() {
$this->dispatch($this->urlFor(45, sha1('test'), '20231207040545'), true);
$this->assertXPathContentContains('//div', 'Utilisateur inconnu',
$this->_response->getBody());
}
/** @test */
public function badTokenShouldHaveError() {
$this->fixture('Class_Users',
['id' => 45,
'login' => 'sysnoadm',
'password' => 'supersecret']);
$this->dispatch($this->urlFor(45, sha1('test'), '20231207040545'), true);
$this->assertXPathContentContains('//div', 'Jeton de réinitialisation invalide',
$this->_response->getBody());
}
/** @test */
public function outdatedTokenShouldHaveError() {
$user = $this->fixture('Class_Users',
['id' => 45,
'login' => 'sysnoadm',
'password' => 'supersecret']);
$token = (new Class_User_LostPass($user))->tokenAt('20071207040545');
$this->dispatch($this->urlFor(45, $token, '20071207040545'), true);
$this->assertXPathContentContains('//div', 'Jeton de réinitialisation expiré',
$this->_response->getBody());
}
/** @test */
public function validTokenShouldDisplayForm() {
$user = $this->fixture('Class_Users',
['id' => 45,
'login' => 'sysnoadm',
'password' => 'supersecret']);
$token = (new Class_User_LostPass($user))->tokenAt('20171130154500');
$this->dispatch($this->urlFor(45, $token, '20171130154500'), true);
$this->assertXPath('//form[contains(@action, "auth/reset-password")]',
$this->_response->getBody());
}
}
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