[switchUser] Версия 1.2.0

Совсем недавно вышла версия 1.1.0, и вот уже сегодня пришлось выпустить версию 1.2.0 :) Поступила жалоба, что на сайте с мультиязычностью не корректно работают лексиконы.

Если очень коротко: то модуль был почти полностью переписан. Главные изменения:
1. Основную инициализацию перенесли из OnWebPageInit в OnMODXInit.
2. Отказались от механизма смены контекстов.
Далее будут детали.

Итак, в чем была проблема с лексиконами?
На сайте использовался собственный плагин смены языковых на событие OnMODXInit. Новый объект пользователя вкупе с $modx->user->addSessionContext() терял текущую настройку языка (она на сессиях была основана). В итоге язык не менялся. Сейчас плагин срабатывает на OnMODXInit с приоритетом -1000, так что все остальные изменения должны быть именно для текущего пользователя.

Помимо этого есть еще очень интересный момент — проверка прав для другого пользователя. Суть заключается в том, что в OnMODXInit сы инициализируем нового пользователя. Но в момент рендеринга страницы нам опять надо проверить привилегированные права, которых с большой долей вероятности нет у текущего пользователя (ведь текущий пользователь $modx->user скорее всего не админ). А права проверить надо именно для админа (который в админке авторизован). Вот тут нам на помощь приходит новая фишка — проверка прав для любых пользователей, не только для текущего. В свое время я писал про это и тогда отправил пулл-реквест, который, честно сказать, не особо надеялся, что одобрят. Суть заключается в том, что раньше в MODX права проверялись только для текущего пользователя. Объясню чуть подробней:
Вот мы выполняем
$modx->hasPermission('load')
На самом деле это синтаксический сахар, и в реальности выполняется следующее:
$modx->context->checkPolicy('load');
Оригинал. То есть не просто право проверяется пользователя, а право пользователя именно в контексте. Так же мы можем проверять права $modx->resource->checkPolicy('view'); (то есть право пользователя на просмотр документа).
Повторюсь, раньше все было заточено только под проверку прав текущего пользователя (даже в методе $modx->hasPermission() не передается никакой пользователь). А вот теперь у нас появилась возможность делать так:
$user = $modx->getObject('modUser', $id);
$hasPermission = $modx->resource->checkPolicy('view', '', $user);
Вот тут мы получаем любого нужного нам пользователя и без его авторизации проверяем его права на объект. К слову, так мы на modxclub.ru при добавлении новых топиков или комментариев проверяем права пользователей на эти топики и шлем только тем, у кого права есть.

Так как же в итоге в модуле реализована разделенная проверка прав? Довольно просто:
1. Когда мы получаем нового пользователя, мы прям в него добавляем оригинального пользователя (здесь нет ничего страшного, это свойство не будет записано в БД, так как нет мета-данных для него).
if ($user = $modx->getObject('modUser', $user_id)) {
    $user->set('OriginalUser', $modx->user);
    $modx->user = $user;
}
2. Далее уже в любом место мы можем проверять права.
if (
    $modx->hasPermission('save_user')
    OR
    (
        $modx->user->OriginalUser
        AND $modx->context->checkPolicy('save_user', null, $modx->user->OriginalUser)
    )
)
P.S. новая версия пакета выложена в modstore.pro
Fi1osof
11 декабря 2015, 19:00
modx.pro
1 647
+6

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

Виталий Валерьевич
12 декабря 2015, 11:33
0
Коля, ссылочку поправь пожалуйста — modstore.pro (за апдейт спасибо)
    Fi1osof
    12 декабря 2015, 16:25
    +1
    Поправил. Спасибо за подсказку! Заработался видимо)

    За апдейт — не за что! Сейчас уже новый выйдет :) Этот уже должен быть совсем стабильный.
    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
    2