timeman 26.400.0 Безопасность

Timeman 26.400.0: LOGIC в фильтре больше не обходит права в timeman.worktimerecord.list

1 мин чтения
Узнавайте о ломающих изменениях Битрикса раньше, чем они доедут до прода: свежие разборы — в канале @bxmax_updates

Обновление безопасности

Закрыта уязвимость или ослабленная проверка прав. Ставить в первую очередь.

В timeman 26.400.0 для коробочного Битрикс24 закрыта дыра в REST-методе timeman.worktimerecord.list: пользователь без права видеть всех мог через LOGIC в фильтре получить записи чужих сотрудников. Ещё боты и другие служебные учётки пропали из CTimeMan::GetAccess(), CTimeMan::GetDirectAccess() и списков полных отчётов, а в V2-провайдерах появилось событие о сохранении отчёта и пакетное чтение состояния рабочего дня. Предыдущий разбор: timeman 26.350.0.

Новое

Подпишитесь на сохранение полного отчёта

D7-событие timeman:OnFullReportSaved (класс Bitrix\Timeman\V2\Public\Event\OnFullReportSavedEvent) приходит, когда отчёт создают, меняют, отправляют или возвращают в черновик. Параметры: userId (владелец), reportId, isSent. Его шлют оба слоя, легаси CTimeManReportFull::Add/Update и V2-сервис, так что отчёт, сохранённый из старого интерфейса, тоже дойдёт до вашего обработчика.

        <?php declare(strict_types=1);

use Bitrix\Main\Event;
use Bitrix\Main\EventManager;

EventManager::getInstance()->addEventHandler(
    'timeman',
    'OnFullReportSaved',
    static function (Event $event): void {
        if (!$event->getParameter('isSent')) {
            return; // черновик, ждём отправки
        }

        $ownerId = (int)$event->getParameter('userId');
        $reportId = (int)$event->getParameter('reportId');
        // например, поставить задачу руководителю или отправить отчёт во внешнюю систему
    },
);

    

Узнайте состояние дня у всей команды одним вызовом

RecordProvider::getCurrentStates(array $userIds, int $at) возвращает CurrentStateCollection: по каждому сотруднику статус дня (opened, paused, closed, none, unknown), тип графика и признак автоматического режима. За раз можно передать не больше 300 id, на 301-м метод бросит ArgumentOutOfRangeException. Параметр $at в теле метода пока не используется.

Проверки прав внутри метода нет, поэтому сначала пропустите список через filterReadableWorktimeUserIds(). Он проверяет canReadWorktime() сразу для всех и считает доступных читателю пользователей один раз на вызов.

        <?php declare(strict_types=1);

use Bitrix\Main\Loader;
use Bitrix\Timeman\V2\Public\Dto\Record\CurrentState;
use Bitrix\Timeman\V2\Public\Provider\RecordProvider;

/** @return list<int> кто сейчас на перерыве */
function findPausedEmployees(array $teamIds): array
{
    Loader::requireModule('timeman');

    $provider = new RecordProvider();
    $readable = $provider->filterReadableWorktimeUserIds($teamIds);
    $paused = [];

    foreach (array_chunk($readable, 300) as $chunk) {
        foreach ($provider->getCurrentStates($chunk, time()) as $state) {
            if ($state->status === CurrentState::STATUS_PAUSED) {
                $paused[] = $state->userId;
            }
        }
    }

    return $paused;
}

    

Там же getAutomaticModeAvailability(int $userId) и getFreshAutomaticModeAvailability(int $userId): режим (schedule, time_tracking, none, unknown) и причина, если он недоступен.

Проверяйте, пора ли сдавать отчёт, не собирая его

FullReportProvider::isReportReadyForSubmit(int $userId): bool отвечает, наступил ли день отчёта или есть ли черновик. Сам отчёт не строится, день отчёта берётся из кеша. В легаси-коде есть (new CUserReportFull($userId))->hasReportDayCome(), но он проверяет только день отчёта, без черновика. В docblock isReportReadyForSubmit() прямо сказано, что на устаревшем кеше он может вернуть true, когда getReportToSend() к отправке ещё не готов. Для бейджа «сдайте отчёт» годится, для решения «отправить автоматически» лучше не надо.

Все новые методы и событие на этом коммите вызываются только внутри timeman или не вызываются вовсе. По виду это API под будущего потребителя.

RealUserFilter: тот же фильтр ботов, что у timeman

Bitrix\Timeman\Repository\Query\RealUserFilter считает служебными пользователей, у которых EXTERNAL_AUTH_ID входит в UserTable::getExternalUserTypes(). Методы: applyToUserQuery(Query) для своей выборки по UserTable, filterRealUserIds(array) и обратный ему selectServiceUserIds(array). Хотите, чтобы ваш отчёт совпадал по людям со штатными списками учёта времени, берите его.

Что сломается

Боты пропали из GetAccess и GetDirectAccess

Список READ в CTimeMan::GetAccess() и результат CTimeMan::GetDirectAccess() теперь проходят через RealUserFilter::filterRealUserIds(). Если ваш код строил по этим массивам права или отчёты и рассчитывал увидеть там служебные учётки, их там больше нет. ['*'] при READ.HEAD == 2 работает как раньше.

То же в интерфейсе. V2-сервис полных отчётов убирает служебных пользователей из видимых списков (сам пользователь в списке остаётся всегда), админский список admin_data_report_full их тоже не показывает, страницы пересчитаны.

REST-клиенты с LOGIC => OR получат меньше записей

Раньше без права «видеть всех» ограничение подмешивалось ключом USER_ID на тот же уровень, что и пользовательский фильтр, и LOGIC => OR его ослаблял. Теперь фильтр клиента вложен целиком, а ограничение задано отдельным whereIn('USER_ID', ...). Счётчик для пагинации считается отдельным запросом с тем же ограничением. Клиент, который передавал LOGIC => OR на верхнем уровне filter, теперь получит только записи доступных ему сотрудников. Если интеграция на этом держалась, она получала чужие данные.

БД

В install.sql для MySQL и PostgreSQL добавлены индексы: (USER_ID, ID) на b_timeman_entries, (DEPARTMENT_ID, SCHEDULE_ID) на b_timeman_work_schedule_department и (USER_ID, SCHEDULE_ID) на b_timeman_work_schedule_user. В декларативный install/migrations/tables.php они не попали, и как их получат уже установленные порталы, из диффа не видно. Если ваши запросы к этим таблицам тормозят, проверьте SHOW INDEX после обновления.

Мелочи и находки

  • Форму комментария к полному отчёту теперь видят только те, кому комментировать разрешено (флаг INFO.CAN_ADD_COMMENT в ответе tools/timeman.php). Раньше она рисовалась всем, а запрет срабатывал при отправке.
  • Контроллер V2 FullReport при отказе в доступе теперь возвращает код ошибки ACCESS_DENIED.
  • При праве «читать всех» admin_data_report_full поднимает всё поддерево сотрудников и режет страницу в PHP. На портале с тысячами людей это может быть заметно.
  • CReportSettings::onUserUpdate теперь сбрасывает кеш отчёта через CUserReportFull::clearReportCache().

Новая версия вышла — разбор уже в Telegram

В канале @bxmax_updates публикуем каждый свежий разбор: что сломается, что устарело и что появилось в API. Узнаете до того, как обновите прод.

Подписаться

Читайте дальше

timeman 26.350.0 Заметное Свежее

Timeman 26.350.0: план дня пишется в нужную запись, блоки БП возвращают Saved

В timeman 26.350.0 для коробочного Битрикс24 блоки «Сохранить план на день» и «Сохранить отчёт сотрудника за день» из нового конструктора бизнес-процессов научились писать в заданную запись рабочего дня, оставлять Markdown как есть и сообщать, сохранилось ли (у отчёта новые настройки в конструкторе,…

2 мин
timeman 26.300.0 Ломающее Свежее

Timeman 26.200.0–26.300.0: выключенный «Учёт рабочего времени» отключает REST timeman.*, перерывы за период отдаёт RecordProvider

Timeman 26.200.0 и 26.300.0 пришли в коробочный Битрикс24 в один прогон. В 26.200.0 модуль начал слушаться настройки портала: если инструмент «Учёт рабочего времени» выключен, перестают работать REST `timeman.*`, контроллеры и компоненты модуля, а уведомления не уходят. В 26.300.0 появился публичный…

2 мин
timeman 26.100.0 Ломающее Свежее

Timeman 26.100.0: время считается по IANA-зоне сотрудника, у CTimeManEntry и REST другие значения

С timeman 26.100.0 учёт рабочего времени берёт зону сотрудника из IANA-идентификатора в `b_user.TIME_ZONE` и считает смещение UTC на момент каждого события, с переходами на летнее и зимнее время. Форматы полей и ответов остались прежними, поменялись значения: `TIME_START`, `TIME_FINISH` и `DURATION`…

3 мин
mail 26.1300.0 Заметное Свежее

Mail 26.1300.0: переезд с Яндекса и Mail.ru, тёмная тема писем и аватары отправителей

Mail 26.1300.0 в коробочном Битрикс24 готовит порталы к тому, что Яндекс и Mail.ru закрыли стандартные почтовые протоколы для внешних сервисов, причём для всех адресов, корпоративных тоже. Модуль научился предлагать перенос почты в Битрикс24 Почту, но по умолчанию эта функция выключена. Кроме того,…

1 мин
Мы используем файлы cookie для улучшения работы сайта. Продолжая использовать сайт, вы соглашаетесь с нашей политикой конфиденциальности.
AI Домовой

AI Домовой История

на связи

пишет…

Можно закрыть чат и перейти на другую страницу. Когда ответ будет готов, на кнопке Домового появится отметка.

Нет истории чатов
AI Домовой

Нужна авторизация

Войдите, чтобы задавать вопросы AI Домовому.

Войти