В этой статье мы подробно разберем задачу, с которой часто сталкиваются разработчики и администраторы баз данных 1С: необходимость получить сводный отчет о том, кто имеет доступ к системе и какими правами (профилями) эти пользователи обладают. В условиях администрирования большого количества баз задача кажется тривиальной, но архитектура подсистемы "Управление доступом" в современных конфигурациях (БГУ 2.0, ERP, Бухгалтерия предприятия 3.0 и др.) имеет свои нюансы, которые могут привести к пустым или некорректным результатам выборки.
Мы проанализируем типичные ошибки при построении такого запроса и составим правильный алгоритм действий, объединяющий данные о статусе пользователя и его группах доступа.
Обычно задача формулируется следующим образом: "Нужно вывести всех пользователей, у которых стоит галочка 'Вход в программу разрешен', и показать, какие Профили групп доступа им назначены".
Часто, пытаясь решить эту задачу "в лоб", разработчики пишут запрос, соединяя таблицу пользователей напрямую со справочником ГруппыДоступа. Пример ошибочной логики выглядит так:
ВЫБРАТЬ
Сведения.Пользователь,
Группы.Профиль
ИЗ
РегистрСведений.СведенияОПользователях КАК Сведения
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ГруппыДоступа КАК Группы
ПО Сведения.Пользователь = Группы.Пользователь // Ошибка здесь
Почему этот запрос не работает или выводит "все подряд"? Проблема кроется в структуре хранения данных в Библиотеке Стандартных Подсистем (БСП). В справочнике ГруппыДоступа (в шапке элемента) нет реквизита "Пользователь", если это не специальная группа персонального доступа (которая используется редко). Связь "Группа — Пользователь" хранится в табличной части этого справочника.
Давайте разберем по шагам, как построить корректный запрос.
Для начала нам нужно правильно отобрать тех, кого мы считаем "активными". Просто проверить галочку "Вход в программу разрешен" недостаточно. В системе могут быть пользователи, которые помечены на удаление или признаны недействительными, но запись в регистре сведений у них могла остаться. Подобную задачу сопоставления данных часто решает специализированная обработка пользователей ИБ, которая выводит информацию по ключевым реквизитам.
Для максимально точной выборки мы будем использовать данные из регистра сведений СведенияОПользователях (где хранится флаг входа) и справочника Пользователи (где хранится статус недействительности).
Сформулируем критерии отбора:
ВходВПрограммуРазрешен = Истина).Недействителен = Ложь).Фрагмент запроса для отбора пользователей будет выглядеть так:
ВЫБРАТЬ
СведенияОПользователях.Пользователь КАК Пользователь
ПОМЕСТИТЬ ВТ_АктивныеПользователи
ИЗ
РегистрСведений.СведенияОПользователях КАК СведенияОПользователях
ГДЕ
СведенияОПользователях.ВходВПрограммуРазрешен = ИСТИНА
И НЕ СведенияОПользователях.Пользователь.Недействителен
И НЕ СведенияОПользователях.Пользователь.ПометкаУдаления
Использование временной таблицы ВТ_АктивныеПользователи позволит нам оптимизировать запрос и избежать лишних чтений при дальнейшем соединении с таблицами прав.
Теперь перейдем к самой сложной части — получению прав. Права в 1С (в типовых конфигурациях) назначаются через Группы доступа. Группа доступа связывает конкретный Профиль (набор ролей) с конкретными Пользователями. Чтобы понять, какие роли входят в эти профили, администраторы часто используют список профилей с отбором по роли.
Важно запомнить: список пользователей, входящих в группу доступа, находится в табличной части Пользователи справочника ГруппыДоступа. Именно к этой табличной части нам нужно обращаться. Для тех, кому важна быстрая проверка прав доступа на объект метаданных, понимание этой связи является ключевым.
Посмотрим на структуру связей:
Справочник.ГруппыДоступа (Шапка) — здесь хранится ссылка на Профиль.Справочник.ГруппыДоступа.Пользователи (Табличная часть) — здесь хранится ссылка на Пользователя и ссылка на саму группу (через поле Ссылка).Следовательно, чтобы получить профиль пользователя, нам нужно выполнить внутреннее соединение с табличной частью.
ВЫБРАТЬ
ГруппыДоступаПользователи.Пользователь КАК Пользователь,
ГруппыДоступаПользователи.Ссылка.Профиль КАК Профиль
ИЗ
Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
Здесь ГруппыДоступаПользователи.Ссылка — это ссылка на элемент справочника (саму группу), откуда мы через точку получаем Профиль.
Теперь объединим наши знания. Мы соединим отобранных активных пользователей с табличной частью групп доступа. Если в вашей системе настроены сложные ограничения на уровне записей, вам может пригодиться отчет по ограничениям пользователей и группам доступа (поможет отчет по анализу прав доступа), но для базового списка достаточно следующего запроса:
ВЫБРАТЬ
СведенияОПользователях.Пользователь КАК Пользователь
ПОМЕСТИТЬ ВТ_РазрешенныеПользователи
ИЗ
РегистрСведений.СведенияОПользователях КАК СведенияОПользователях
ГДЕ
СведенияОПользователях.ВходВПрограммуРазрешен = ИСТИНА
И НЕ СведенияОПользователях.Пользователь.Недействителен
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_РазрешенныеПользователи.Пользователь КАК Пользователь,
ЕСТЬNULL(ГруппыДоступаПользователи.Ссылка.Профиль, "Нет профиля / Группа пользователей") КАК Профиль,
ГруппыДоступаПользователи.Ссылка КАК ГруппаДоступа
ИЗ
ВТ_РазрешенныеПользователи КАК ВТ_РазрешенныеПользователи
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
ПО ВТ_РазрешенныеПользователи.Пользователь = ГруппыДоступаПользователи.Пользователь
УПОРЯДОЧИТЬ ПО
Пользователь.Наименование
При работе с этим запросом необходимо учитывать несколько архитектурных особенностей конфигураций на базе БСП.
В табличной части ГруппыДоступа.Пользователи может быть указан не конкретный пользователь (например, "Иванов И.И."), а Группа пользователей (например, "Бухгалтерия").
Для решения этой проблемы и детального понимания полномочий часто требуется анализ прав и ролей (удобно через отчет по анализу прав пользователей и ролей), который позволяет увидеть, какие права наследуются через группы и иерархию.
Один пользователь может входить в несколько групп доступа. В результате выполнения запроса вы получите несколько строк для одного и того же пользователя (по одной строке на каждый профиль). Если вы выводите это в отчет (СКД), сгруппируйте записи по полю Пользователь, чтобы профили перечислялись в детальных записях.
В некоторых случаях (если включена соответствующая опция) могут создаваться скрытые группы доступа с индивидуальными настройками. Они также попадут в выборку через табличную часть, так как механизм един.
Для корректного вывода прав доступа выполните следующие действия:
РегистрСведений.СведенияОПользователях с фильтром ВходВПрограммуРазрешен.Недействителен в самом справочнике пользователей.Справочник.ГруппыДоступа.Пользователи.ГруппыДоступаПользователи.Ссылка.Профиль.