Add new reset password option see BT#9897

1.10.x
Julio Montoya 10 years ago
parent 76dca6eb4a
commit 4c0780aa76
  1. 33
      app/Migrations/Schema/V110/Version20150803171220.php
  2. 29
      main/auth/lostPassword.php
  3. 68
      main/auth/reset.php
  4. 81
      main/inc/lib/login.lib.php
  5. 5
      main/install/configuration.dist.php
  6. 12
      src/Chamilo/UserBundle/Entity/Manager/UserManager.php
  7. 1
      src/Chamilo/UserBundle/Entity/Repository/UserRepository.php
  8. 55
      src/Chamilo/UserBundle/Entity/User.php

@ -0,0 +1,33 @@
<?php
/* For licensing terms, see /license.txt */
namespace Application\Migrations\Schema\V110;
use Application\Migrations\AbstractMigrationChamilo;
use Doctrine\DBAL\Schema\Schema;
/**
* Class Version20150803171220
*
* @package Application\Migrations\Schema\V110
*/
class Version20150803171220 extends AbstractMigrationChamilo
{
/**
* @param Schema $schema
*/
public function up(Schema $schema)
{
$this->addSql('ALTER TABLE user ADD confirmation_token VARCHAR(255) NULL');
$this->addSql('ALTER TABLE user ADD password_requested_at DATETIME DEFAULT NULL');
}
/**
* @param Schema $schema
*/
public function down(Schema $schema)
{
$this->addSql('ALTER TABLE user DROP confirmation_token');
$this->addSql('ALTER TABLE user DROP password_requested_at');
}
}

@ -82,7 +82,15 @@ if (isset($_GET['reset']) && isset($_GET['id'])) {
} else {
$form = new FormValidator('lost_password');
$form->addElement('header', $tool_name);
$form->addElement('text', 'user', array(get_lang('LoginOrEmailAddress'), get_lang('EnterEmailUserAndWellSendYouPassword')), array('size'=>'40'));
$form->addElement(
'text',
'user',
array(
get_lang('LoginOrEmailAddress'),
get_lang('EnterEmailUserAndWellSendYouPassword'),
),
array('size' => '40')
);
$form->addButtonSend(get_lang('Send'));
// Setting the rules
@ -90,19 +98,27 @@ if (isset($_GET['reset']) && isset($_GET['id'])) {
if ($form->validate()) {
$values = $form->exportValues();
$users_related_to_username = Login::get_user_accounts_by_username(
$usersRelatedToUsername = Login::get_user_accounts_by_username(
$values['user']
);
if ($users_related_to_username) {
if ($usersRelatedToUsername) {
$by_username = true;
foreach ($users_related_to_username as $user) {
foreach ($usersRelatedToUsername as $user) {
if ($_configuration['password_encryption'] != 'none') {
$message = Login::handle_encrypted_password($user, $by_username);
$setting = api_get_configuration_value('user_reset_password');
if ($setting) {
$userObj = Database::getManager()->getRepository('ChamiloUserBundle:User')->find($user['uid']);
Login::sendResetEmail($userObj);
} else {
$message = Login::handle_encrypted_password($user, $by_username);
Display::addFlash($message);
}
} else {
$message = Login::send_password_to_user($user, $by_username);
Display::addFlash($message);
}
Display::addFlash($message);
}
} else {
Display::addFlash(
@ -119,7 +135,6 @@ if (isset($_GET['reset']) && isset($_GET['id'])) {
$controller = new IndexManager($tool_name);
//$tpl = new Template($tool_name);
$controller->set_login_form();
$tpl = $controller->tpl;
$tpl->assign('form', $formToString);

@ -0,0 +1,68 @@
<?php
/* For license terms, see /license.txt */
use ChamiloSession as Session;
require_once '../inc/global.inc.php';
$token = isset($_GET['token']) ? $_GET['token'] : '';
if (!ctype_alnum($token)) {
$token = '';
}
$tpl = new Template(null);
// Build the form
$form = new FormValidator('reset', 'POST', api_get_self().'?token='.$token);
$form->addElement('header', get_lang('ResetPassword'));
$form->addHidden('token', $token);
$form->addElement('password', 'pass1', get_lang('Password'));
$form->addElement('password', 'pass2', get_lang('Confirmation'), array('id' => 'pass2', 'size' => 20, 'autocomplete' => 'off'));
$form->addRule('pass1', get_lang('ThisFieldIsRequired'), 'required');
$form->addRule('pass2', get_lang('ThisFieldIsRequired'), 'required');
$form->addRule(array('pass1', 'pass2'), get_lang('PassTwo'), 'compare');
$form->addButtonSave(get_lang('Update'));
$ttl = api_get_configuration_value('user_reset_password_token_limit');
if (empty($ttl)) {
$ttl = 3600;
}
if ($form->validate()) {
$em = Database::getManager();
$values = $form->exportValues();
$password = $values['pass1'];
$token = $values['token'];
/** @var \Chamilo\UserBundle\Entity\User $user */
$user = UserManager::getManager()->findUserByConfirmationToken($token);
if ($user) {
if (!$user->isPasswordRequestNonExpired($ttl)) {
Display::addFlash(Display::return_message(get_lang('LinkExpired')), 'warning');
header('Location: '.api_get_path(WEB_CODE_PATH).'auth/lostPassword.php');
exit;
}
$user->setPlainPassword($password);
$userManager = UserManager::getManager();
$userManager->updateUser($user, true);
Display::addFlash(Display::return_message(get_lang('Updated')));
header('Location: '.api_get_path(WEB_PATH));
exit;
} else {
if (empty($user)) {
Display::addFlash(
Display::return_message(get_lang('UserDoesNotExist'))
);
}
}
}
$tpl->assign('form', $form->toHtml());
$content = $tpl->get_template('auth/set_temp_password.tpl');
$tpl->assign('content', $tpl->fetch($content));
$tpl->display_one_col_template();

@ -11,6 +11,8 @@ use ChamiloSession as Session;
* @package chamilo.login
*/
use Chamilo\UserBundle\Entity\User;
/**
* Class
* @package chamilo.login
@ -83,7 +85,6 @@ class Login
*/
public static function send_password_to_user($user, $by_username = false)
{
$email_subject = "[" . api_get_setting('siteName') . "] " . get_lang('LoginRequest'); // SUBJECT
if ($by_username) { // Show only for lost password
@ -109,9 +110,17 @@ class Login
$email_admin = api_get_setting('emailAdministrator');
if (api_mail_html('', $email_to, $email_subject, $email_body, $sender_name, $email_admin) == 1) {
return get_lang('YourPasswordHasBeenReset');
} else {
$admin_email = Display :: encrypted_mailto_link(api_get_setting('emailAdministrator'), api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname')));
$admin_email = Display:: encrypted_mailto_link(
api_get_setting('emailAdministrator'),
api_get_person_name(
api_get_setting('administratorName'),
api_get_setting('administratorSurname')
)
);
return sprintf(get_lang('ThisPlatformWasUnableToSendTheEmailPleaseContactXForMoreInformation'), $admin_email);
}
}
@ -128,7 +137,8 @@ class Login
{
$email_subject = "[" . api_get_setting('siteName') . "] " . get_lang('LoginRequest'); // SUBJECT
if ($by_username) { // Show only for lost password
if ($by_username) {
// Show only for lost password
$user_account_list = self::get_user_account_list($user, true, $by_username); // BODY
$email_to = $user['email'];
} else {
@ -141,17 +151,37 @@ class Login
$email_body .= "\n\n" . get_lang('SignatureFormula') . ",\n" . api_get_setting('administratorName') . " " . api_get_setting('administratorSurname') . "\n" . get_lang('PlataformAdmin') . " - " . api_get_setting('siteName');
$sender_name = api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname'), null, PERSON_NAME_EMAIL_ADDRESS);
$sender_name = api_get_person_name(
api_get_setting('administratorName'),
api_get_setting('administratorSurname'),
null,
PERSON_NAME_EMAIL_ADDRESS
);
$email_admin = api_get_setting('emailAdministrator');
if (@api_mail_html('', $email_to, $email_subject, $email_body, $sender_name, $email_admin) == 1) {
$result = @api_mail_html(
'',
$email_to,
$email_subject,
$email_body,
$sender_name,
$email_admin
);
if ($result == 1) {
if (CustomPages::enabled()) {
return get_lang('YourPasswordHasBeenEmailed');
} else {
return Display::return_message(get_lang('YourPasswordHasBeenEmailed'));
}
} else {
$admin_email = Display :: encrypted_mailto_link(api_get_setting('emailAdministrator'), api_get_person_name(api_get_setting('administratorName'), api_get_setting('administratorSurname')));
$admin_email = Display:: encrypted_mailto_link(
api_get_setting('emailAdministrator'),
api_get_person_name(
api_get_setting('administratorName'),
api_get_setting('administratorSurname')
)
);
$message = sprintf(get_lang('ThisPlatformWasUnableToSendTheEmailPleaseContactXForMoreInformation'), $admin_email);
if (CustomPages::enabled()) {
@ -162,6 +192,36 @@ class Login
}
}
/**
* @param User $user
*/
public function sendResetEmail(User $user)
{
//if (null === $user->getConfirmationToken()) {
$uniqueId = api_get_unique_id();
$user->setConfirmationToken($uniqueId);
$user->setPasswordRequestedAt(new \DateTime());
Database::getManager()->persist($user);
Database::getManager()->flush();
$url = api_get_path(WEB_CODE_PATH).'auth/reset.php?token='.$uniqueId;
api_mail_html(
'',
$user->getEmail(),
get_lang('ResetPasswordInstructions'),
sprintf(
get_lang('ResetPasswordCommentWithUrl'),
$url
)
);
Display::addFlash(Display::return_message(get_lang('CheckYourEmailAndFollowInstructions')));
error_log($url);
//}
}
/**
* Gets the secret word
* @author Olivier Cauberghe <olivier.cauberghe@UGent.be>, Ghent University
@ -790,7 +850,7 @@ class Login
* Returns true if user exists in the platform when asking the password
*
* @param string $username (email or username)
* @return boolean
* @return array|boolean
*/
public static function get_user_accounts_by_username($username)
{
@ -802,7 +862,6 @@ class Login
$email = false;
}
$condition = '';
if ($email) {
$condition = "LOWER(email) = '".Database::escape_string($username)."' ";
} else {
@ -812,10 +871,10 @@ class Login
$tbl_user = Database :: get_main_table(TABLE_MAIN_USER);
$query = "SELECT user_id AS uid, lastname AS lastName, firstname AS firstName, username AS loginName, password, email,
status AS status, official_code, phone, picture_uri, creator_id
FROM $tbl_user
FROM $tbl_user
WHERE ( $condition AND active = 1) ";
$result = Database::query($query);
$num_rows = Database::num_rows($result);
$result = Database::query($query);
$num_rows = Database::num_rows($result);
if ($result && $num_rows > 0) {
return Database::store_result($result);
}

@ -223,3 +223,8 @@ $_configuration['system_stable'] = NEW_VERSION_STABLE;
'language',
'extra_fields'
];*/
// Reset password in portal
//$_configuration['user_reset_password'] = false;
// password token expired
//$_configuration['user_reset_password_token_limit'] = 3600;

@ -1,4 +1,5 @@
<?php
/* For licensing terms, see /license.txt */
namespace Chamilo\UserBundle\Entity\Manager;
@ -12,4 +13,15 @@ use Sonata\UserBundle\Entity\UserManager as BaseUserManager;
class UserManager extends BaseUserManager
{
/**
* Finds a user either by confirmation token
*
* @param string $token
*
* @return UserInterface
*/
public function findUserByConfirmationToken($token)
{
return $this->findUserBy(array('confirmationToken' => $token));
}
}

@ -173,5 +173,4 @@ class UserRepository extends EntityRepository
return $queryBuilder->getQuery()->getResult();
}
}

@ -275,6 +275,21 @@ class User extends BaseUser //implements ParticipantInterface, ThemeUser
*/
protected $lastLogin;
/**
* Random string sent to the user email address in order to verify it
*
* @var string
* @ORM\Column(name="confirmation_token", type="string", length=255, nullable=true)
*/
protected $confirmationToken;
/**
* @var \DateTime
*
* @ORM\Column(name="password_requested_at", type="datetime", nullable=true, unique=false)
*/
protected $passwordRequestedAt;
/**
* @ORM\OneToMany(targetEntity="Chamilo\CoreBundle\Entity\CourseRelUser", mappedBy="user")
**/
@ -1509,4 +1524,44 @@ class User extends BaseUser //implements ParticipantInterface, ThemeUser
return $this->sessionCourseSubscriptions;
}
/**
* @return string
*/
public function getConfirmationToken()
{
return $this->confirmationToken;
}
/**
* @param string $confirmationToken
*
* @return User
*/
public function setConfirmationToken($confirmationToken)
{
$this->confirmationToken = $confirmationToken;
return $this;
}
/**
* @return \DateTime
*/
public function getPasswordRequestedAt()
{
return $this->passwordRequestedAt;
}
/**
* @param int $ttl
* @return bool
*/
public function isPasswordRequestNonExpired($ttl)
{
return $this->getPasswordRequestedAt() instanceof \DateTime &&
$this->getPasswordRequestedAt()->getTimestamp() + $ttl > time();
}
}

Loading…
Cancel
Save