Мистика - перестаёт пускать в админку и не только

Всем привет!
Кто-нибудь сталкивался с тем, что при правильном логине и пароле перестаёт пускать в админку? И так же не логинит на фронте с теми же пользовательскими данными сниппетом Login.

Запара какая-то непонятная.
С фронта анонимусы создают объявления, при помощи Тикетс. Модераторы и администраторы могут входить по логину и паролю.
Ситуация такая: я, как член группы «Administrators» залогинен в админке, затем захожу с помощью сниппета Login на фронт — всё нормально. Потом с фронта делаю логаут (для своих проверок), захожу снова — всё, "Неправильное имя пользователя или пароль. Проверьте введённые данные и попытайтесь снова.". Затем из админки делаю «Перезагрузить права доступа» и «Завершить все сеансы», меня разлогивает, захожу снова — та же песня — "Неправильное имя пользователя или пароль. Проверьте введённые данные и попытайтесь снова.".
При чём, после возникновения этой ошибки на фронте, простой логаут из админки — и всё, не пускает.
Данные верные (заполняются из менеджера паролей).

Папку с кэшем, куки, таблицу сессий — всё чистил. Система последняя — 2.2.8. Хостинг менял, история не изменилась.

И это происходит не только с главным админом, а со всеми пользователями.
Помогает только принудительное изменение пароля напрямую в базе.

И вот сижу я сейчас без доступа в админку, ибо пароль постоянно менять тупо задолбало :-(
В общем мистика.
Алексей Карташов
25 июня 2013, 16:35
modx.pro
3 352
0

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

Василий Наумкин
25 июня 2013, 20:51
0
Ни разу такого не встречал.

А если попробовать зайти прям из другого брайзура?
Ошибки в логах на сервере есть?
Php-apc или другой кэшер включен?
    Алексей Карташов
    25 июня 2013, 21:04
    0
    А если попробовать зайти прям из другого брайзура?
    Так же ошибка
    Ошибки в логах на сервере есть?
    Пусто :-(
    Php-apc или другой кэшер включен?
    Вроде нет. Во всяком случае с кэшем не игрался и все настройки кэша по умолчанию из коробки.

    Сейчас вообще жесть какая-то — после последней попытки логина через Login тупо перестала отображаться форма входа. Вот вообще нету. Папку с кэшем чистил несколько раз (мало ли). Раньше такого не было.
      Василий Наумкин
      25 июня 2013, 22:47
      0
      Вот прям не знаю чем помочь, ни разу такого не видал.
        Алексей Карташов
        25 июня 2013, 23:56
        0
        Эх, буду тогда по кускам сайт воссоздавать, других вариантов уже нету.
        Спасибо вам!
          Алексей Карташов
          27 июня 2013, 06:51
          0
          Корень проблемы нашёл — как обычно, ссзб.
          В форме добавления нового тикета, кроме, собственно, полей тикета, так же есть поля для редактирования данных пользователя. И если пользователь залогинен, то данные автоматом подставляются в эти поля. Если не залогинен, то их надо вписать и юзер автоматом создастся и залогинится. Так вот при добавлении тикета поля пользователя обрабатываются отдельно — если надо — юзер создаётся, если что-то изменилось — юзер обновляется.
          Так вот обновление юзера происходило вот так:
          function userUpdate ($user, $data) {
          	$result			= array();
          	$userProfile	= $user->getOne('Profile');
          	$userProfile	= $userProfile->toArray();
          	// $changedData	= array_diff($data, array_intersect_key($userProfile, $data));
          	$changedData	= array_intersect_key($data, $userProfile);
          	if (count($changedData)) {
          		/**
          		 * Всё внимание на массивы, которые передаются в процессор:
          		 */
          		$response = $this->modx->runProcessor('web/user/update', array_merge(
          			$userProfile,
          			$user->toArray(),
          			$changedData
          		));
          		if ($response->isError()) {
          			$errors = $this->getResponseErrors($response);
          			$result = array_merge($result, $errors);
          		}
          		$this->modx->error->reset();
          	}
          	return $result;
          }

          И фишка вышла такая — благодаря $user->toArray() в процессор передаётся так же поле текущего пароля. А точнее не сам пароль, а его хэш (в базе же пароли хешированные лежат). А процессор, получив заполненное поле пароля, делал из него новый хэш и его записывал. Соответственно, пароль-то фактически каждый раз менялся. Вот такой вот я балда :-)

          Изначально я считал, что в процессор достаточно передать id-шник юзера и поля, которые надо изменить. А оказалось, что нифига — этому процессору обязательно нужны ещё логин и мыло (которое надо тянуть из профайла). Поэтому решил перебдеть, собрав все данные в кучу. И зря, как выяснилось)
          Переделал на это и всё заработало:
          function userUpdate ($user, $data) {
          	$result			= array();
          	$userProfile	= $user->getOne('Profile');
          	$userProfile	= $userProfile->toArray();
          	// $changedData	= array_diff($data, array_intersect_key($userProfile, $data));
          	$changedData	= array_intersect_key($data, $userProfile);
          	if (count($changedData)) {
          		$response = $this->modx->runProcessor('web/user/update', array_merge(array(
          			'id'		=> $user->id,
          			'username'	=> $user->username,
          			'email'		=> $userProfile['email']
          		), $changedData));
          
          		if ($response->isError()) {
          			$errors = $this->getResponseErrors($response);
          			$result = array_merge($result, $errors);
          		}
          		$this->modx->error->reset();
          	}
          	return $result;
          }

          Василий, я не зря отвечаю в этой ветке именно тебе, потому что в процессе копания выяснилась интересная особенность тикетов, возможно даже баг.
          Помнишь, ты мне как-то помогал разобраться с изменением алиасов при создании тикетов? К алиасу добаляется id тикета в плагине на «OnDocFormSave» вот так:
          $resource	= &$modx->event->params['resource'];
          $alias		= $resource->get('alias');
          $alias		= (strpos($alias, $id.'-') !== 0) ? $id.'-'.$alias : $alias;
          $resource->set('alias', $alias);
          $resource->save();

          У меня в сниппете myTicketForm в самом конце, после всех шаманств и отработки всех процессоров, идёт редирект на этот тикет:
          $redirectTo = $modx->makeUrl($result['id'],'','','full');
          $modx->sendRedirect($redirectTo);

          И вот в чём дело — редирект происходит на uri со старым алиасом, т.е. на тот, который был до моих изменений! Хотя все плагины отработали и всё должно было измениться. Но и это не самое интересное — у самого тикета алиас сохранился таким, каким я его и сделал, с id-шником! Т.е. makeUrl берёт uri документа из какого-нибудь alias_map, а там данные ещё старые. В итоге редирект происходит на не существующий адрес. Но и это ещё не всё — страница открывается! xD
          Т.е., положим у тикета сформировался такой алиас — 'this-is-ticket-alias'. В плагине к нему подставляется id тикета: '123-this-is-ticket-alias'. И этот алиас фактически у ресурса и записан, но в кэше лежит 'this-is-ticket-alias', и при редиректе на этот адрес открывается только что созданный тикет (хотя адрес-то фактически не существующий)!
          И вот только после того, как в админке что-нибудь изменю/сохраню или просто тыкну «обновить сайт» — кэш очищается и по адресу 'this-is-ticket-alias' как и положено вылезает 404, а сам документ становится доступен по '123-this-is-ticket-alias'.
          Такие дела.

          В процессе копания пришёл к вот этому.
          Заменил код метода на:
          $this->xpdo->cacheManager->refresh(array(
          	'db' => array(),
          	'auto_publish' => array('contexts' => array($this->context_key)),
          	'context_settings' => array('contexts' => array($this->context_key)),
          	'resource' => array('contexts' => array($this->context_key)),
          ));
          Не помогло.
          Потом заменил на одну строчку:
          $this->xpdo->reloadContext($this->context_key);
          И всё встало на свои места, всё заработало как надо. Только вот теперь чистится весь кэш сайта, а собственная система кэширования тикетов получается не при делах :-(

          Выходит проблема именно в кэшировании тикетов. Точнее в очистке кэша.
          Как-то так.
            Василий Наумкин
            27 июня 2013, 08:44
            0
            Менять alias нужно на событии OnBeforeDocFormSave, тогда карта алиасов обновится, и все должно быть ок.

            Вот этот момент в процессоре.
              Алексей Карташов
              27 июня 2013, 18:30
              0
              Да, так работает, но id ресурса в событии OnBeforeDocFormSave ещё не известно!
              А в OnDocFormSave известен id, но не обновляется карта алиасов. Как ж мне быть?
      Алексей Карташов
      25 июня 2013, 21:06
      0
      Может попробовать обновить php с 5.2 на 5.3? Сейчас 5.2 стоит.
    Александр Донский
    26 июня 2013, 00:13
    0
    Проблема возникла сама по себе? Никаких мыслей по этому поводу?
      Алексей Карташов
      26 июня 2013, 00:21
      0
      Да вот в том-то и дело, что предпосылок к такой проблеме нету совершенно. Обычный Login, обычное добавление ресурсов с фронтэнда с помощью Tickets. Хостинги разные были — проблема везде одна. Логическим/эмпирическим путём пытался сообразить откуда ноги растут — х его знает. Первый раз такое
      Дмитрий Кондаков
      26 июня 2013, 15:25
      0
      что-то было подобное, но хоть убей не помню решение проблемы, обязательно сообщу если вспомню, помню только что в админку пускало с логином и пустым полем пароля)
        Алексей Карташов
        27 июня 2013, 06:54
        0
        Да, встречал несколько постов, где говорили, что админка пускает без пароля. У меня, этот способ не заработал, конечно (см. выше — проблема была в другом), но ведь чёрт возьми! Как так? Система пускает в админ.панель тупо по логину? Без пароля? И это реально так бывало? Достаточно знать логин админа? Это ведь какая-то особенная жесть, если такое дело вдруг на рабочем сайте обнаружится
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        15