четверг, 5 июня 2014 г.

OpenCart (ocStore) Fatal Error: Call to a member function editSettingValue() on a non-object

У нас возникла ошибка при восстановлении пароля администратора в системе opencart (ocstore).
Если администратор забывал пароль, и нажимал "Забыли Пароль?", после чего его перекидывало на страницу "Восстановления пароль". На этой странице необходимо ввести email-адрес после чего на него будет направленна ссылка для по которой можно восстановить пароль.

Но при переходе по этой ссылке выдавалась ошибка:
Call to a member function editSettingValue() on a non-object in admin/controller/common/reset.php on line 95

Причина данной проблемы заключается в файле admin/controller/common/forgotten.php

Проблема заключается в длине секретного кода, который вшивается в ссылку, которая отправляется на почту администратора (http://www.yourdomain.ru/admin/index.php?route=common/reset&code=7c85e875dfb19dd56e759408c2f84f95a9b1e10e)

В Файле  admin/controller/common/forgotten.php

$code = sha1(uniqid(mt_rand(), true)); - генерируется секретный код длинной 40 символов
А когда код заноcиться в базу он обрезается до 32-х символов, соответственно 8 символов теряются, но пользователю все равно отправляется код из 40 символов.

Когда пользователь переходит по ссылки  http://www.yourdomain.ru/admin/index.php?route=common/reset&code=7c85e875dfb19dd56e759408c2f84f95a9b1e10e
В файле admin/controller/common/reset.php:
происходит попытка получить информацию о пользователе использую серкетный код:
$user_info = $this->model_user_user->getUserByCode($code); 
Но т.к. пользователю отправлен секретный код длинной в 40 символов, а при добавлении его в базу он обрезан до 32-х символов, то данная строка получает пустой массив.
 После чего условие перебрасывает выполнение скрипта ветку else, что и вызывает ошибку.

if ($user_info) {



 } else {
      $this->model_setting_setting->editSettingValue('config', 'config_password', '0');
      return $this->forward('common/login');


Решение проблемы:
привести к единой длине отправляемый секретный код, и секретный код который записывается в базу. Делать правки в базе изменяя длину строки code не получиться, если в системе много пользователей. Поэтому мы исправим код, который генерирует "секретный код восстановления"
Для этого мы его обрезаем секретный код до 30 символов функцией substr добавив ее в файл admin/controller/common/forgotten.php:
вместо кода:
$code = sha1(uniqid(mt_rand(), true));
получаем: 
$code = sha1(uniqid(mt_rand(), true));
$code=substr($code,0,30); 

Как результат - все работает и пароли восстанавливаются.

Комментариев нет:

Отправить комментарий