Программное добавление пользователей в базы на БСП
Клиент заказал скрипт для Обновлятора для создания пользователей и назначения им прав в конфигурации на БСП — в БП3 и ЗУП3.
Для начала проверим, как все работает в БП3, наверное в ЗУП3 должно работать аналогично? Если там будет своя специфика, то поправим на месте.
Вообще говоря, 1С предполагает ручное создание пользователей и прав и тема автоматизации этого процесса не документирована, а значит, требуется разбираться и смотреть, что можно использовать из готового кода 1С.
Ручное создание пользователя
Создадим пользователя вручную:

Добавим ему права путем включения в нужную группу доступа:

При всех этих манипуляциях я запустил замер производительности и при запуске 1С выключил режим отладки, чтобы не запускало фоновые задания.
Таким образом я нашел код, где программа создает/обновляет пользователя:



Этот код дает нам примерное понимание, как создавать пользователя программно.
Программное включение/исключение пользователя в группы доступа. Неоптимальное
Теперь нужно разобраться, как включить пользователя в группы доступа. Для этого, на самом деле я не анализировал БСП, а посмотрел ссылки на созданного пользователя в базе:

Пользователям назначаются почему-то персональные группы доступа:


Теперь проверяем — если мы снимаем галочку, то права доступа очищаются:

Очищаются они и в конфигураторе:

Теперь попробуем программно изменить группу доступа, написав такой код:
&НаСервере Процедура ИзменитьПраваГБ2НаСервере() ТекПользователь = Справочники.Пользователи.НайтиПоНаименованию("ГБ2"); ТекПрофиль = Справочники.ПрофилиГруппДоступа.НайтиПоНаименованию("Главный бухгалтер"); ТекГруппаДоступа = ДатьПерсональнуюГруппуДоступа(ТекПользователь, ТекПрофиль); ТекГруппаДоступаОбъект = ТекГруппаДоступа.ПолучитьОбъект(); Если ТекГруппаДоступаОбъект.Пользователи.Количество() = 0 Тогда НСтр = ТекГруппаДоступаОбъект.Пользователи.Добавить(); НСтр.Пользователь = ТекПользователь; Сообщить("Добавлен профиль:" + ТекПрофиль); Иначе ТекГруппаДоступаОбъект.Пользователи.Очистить(); Сообщить("Удален профиль:" + ТекПрофиль); КонецЕсли; ТекГруппаДоступаОбъект.Записать(); КонецПроцедуры &НаСервере Функция ДатьПерсональнуюГруппуДоступа(Пользователь, Профиль) З = Новый Запрос( "ВЫБРАТЬ | ГруппыДоступа.Ссылка |ИЗ | Справочник.ГруппыДоступа КАК ГруппыДоступа |ГДЕ | ГруппыДоступа.Профиль = &Профиль | И ГруппыДоступа.Пользователь = &Пользователь | "); З.УстановитьПараметр("Пользователь", Пользователь); З.УстановитьПараметр("Профиль", Профиль); Выборка = З.Выполнить().Выбрать(); Если Выборка.Следующий() Тогда Возврат Выборка.Ссылка; КонецЕсли; КонецФункции &НаКлиенте Процедура ИзменитьПраваГБ2(Команда) ИзменитьПраваГБ2НаСервере(); КонецПроцедуры
Получилось, при первом запуске у пользователя включилась и группа доступа:

И появились роли в конфигураторе:

Проверил, что повторный запуск кода убирает группу доступа и роли в конфигураторе.
Программное включение/исключение пользователя в группы доступа. Правильное
Пока я разбирался с группами доступа, задал вопрос на Мисте и мне подсказали, как более просто включать пользователя в группы доступа.
Получается, можно указать просто название профиля доступа, а 1С сама сделает всю «грязную работу».
В функции ВключитьПрофильПользователю можно указывать идентификатор профиля, но к сожалению, предопределенный только один Администратор:

Поэтому для универсальности будем искать профиль по наименованию:
&НаСервере Процедура ИзменитьПрофильГБНаСервере(Включить) ТекПользователь = Справочники.Пользователи.НайтиПоНаименованию("ГБ2"); ТекПрофиль = Справочники.ПрофилиГруппДоступа.НайтиПоНаименованию("Главный бухгалтер"); Если Включить Тогда УправлениеДоступом.ВключитьПрофильПользователю(ТекПользователь, ТекПрофиль); Иначе УправлениеДоступом.ВыключитьПрофильПользователю(ТекПользователь, ТекПрофиль); КонецЕсли; КонецПроцедуры &НаКлиенте Процедура ВыключитьПрофильГБ(Команда) ИзменитьПрофильГБНаСервере(Ложь); КонецПроцедуры &НаКлиенте Процедура ВключитьПрофильГБ(Команда) ИзменитьПрофильГБНаСервере(истина); КонецПроцедуры
Проверки и тестирование показали, что нужные профили подключаются к пользователю и нужные роли создаются у пользователя информационной базы. При этом должны создаваться сами и группы, если их нет. Это упрощает нашу работу.
Программное создание пользователя и назначение ему прав доступа
Попробуем создать пользователя ГБ3 программно и назначить права доступа:
//Вводные ИмяПользователя = "Главный бухгалтер 3"; ИмяВходаПользователя = "ГБ3"; Пароль = "123"; ВходВПрограммуРазрешен = истина; АутентификацияСтандартная = истина; АутентификацияWindows = ложь; ЗапрещеноИзменятьПароль = ложь; ПоказыватьВСпискеВыбора = истина; //Создаем пользователя ОбновляемыеСвойства = Новый Структура(); ОбновляемыеСвойства.Вставить("Действие", "Записать"); //Не уверен, что без этого будет работать ОбновляемыеСвойства.Вставить("ВходВПрограммуРазрешен", ВходВПрограммуРазрешен); ОбновляемыеСвойства.Вставить("Имя", ИмяВходаПользователя); ОбновляемыеСвойства.Вставить("ПолноеИмя", ИмяПользователя); ОбновляемыеСвойства.Вставить("АутентификацияOpenID", ложь); ОбновляемыеСвойства.Вставить("АутентификацияСтандартная", АутентификацияСтандартная); ОбновляемыеСвойства.Вставить("АутентификацияWindows", АутентификацияWindows); ОбновляемыеСвойства.Вставить("Пароль", Пароль); ОбновляемыеСвойства.Вставить("ПарольУстановлен", истина); ОбновляемыеСвойства.Вставить("ЗапрещеноИзменятьПароль", ЗапрещеноИзменятьПароль); ОбновляемыеСвойства.Вставить("ПоказыватьВСпискеВыбора", ПоказыватьВСпискеВыбора); ПользовательИБСуществует = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяВходаПользователя) <> Неопределено; Пользователи.УстановитьСвойстваПользователяИБ(ИмяВходаПользователя, ОбновляемыеСвойства, НЕ ПользовательИБСуществует); //Создавать нового ставим всегда в Истина ТекПользователь = Справочники.Пользователи.НайтиПоНаименованию(ОбновляемыеСвойства.ПолноеИмя, истина); ПользовательСуществует = ЗначениеЗаполнено(ТекПользователь); //Записываем пользователя в 1С, если его еще нет в базе Если НЕ ПользовательСуществует Тогда Пользователь = Справочники.Пользователи.СоздатьЭлемент(); Пользователь.Наименование = ОбновляемыеСвойства.ПолноеИмя; Пользователь.ДополнительныеСвойства.Вставить( "ОписаниеПользователяИБ", ОбновляемыеСвойства); Пользователь.Записать(); ТекПользователь = Пользователь.Ссылка; КонецЕсли; ТекПрофиль = Справочники.ПрофилиГруппДоступа.НайтиПоНаименованию("Главный бухгалтер"); УправлениеДоступом.ВключитьПрофильПользователю(ТекПользователь, ТекПрофиль);
Проверяем — пользователь и пользователь ИБ созданы:

Причем код можно запускать многократно и при этом обновляются свойства пользователя ИБ. Например, я при первом запуске не добавил свойство «Показывать в списке выбора», добавил и при втором запуске оно установилось.
Также устанавливаются роли и профили групп доступа.
Зайдем под этим пользователем в программу — все ОК, входит нормально.

Теперь настало время проверить, как код работает в Обновляторе. Код смотрите в конце статьи.
Скрипт отработал успешно:

Проверяем, при входе в базу пользователь есть, под пользователем в базу заходит:

В списке пользователей пользователь есть:

Права те, что заказывали:

Как быть с не упрощенными правами (ЗУП3)
Аналогично проверяем на ЗУП 3, получаем ошибку:

Опять берем монитор производительности и находим, что в группы добавление происходит в общей форме Пользователи, в процедуре «ВключитьИсключитьИзГруппы«:

К сожалению (и это недостаток 1С), эта процедура не вынесена в общий модуль, но она несложная и ее можно упрощенно вставить даже в наш код.
В итоге получился универсальный код, который работает и для упрощенной и для не упрощенной системы прав.
В упрощенной каждому профилю и пользователю ставится в соответствие персональная группа доступа. В не упрощенном в одну группу доступа можно включать несколько пользователей.
Проверяем — код в ЗУП3 тоже работает:

Итоговый код скрипта для Обновлятора
Важно! Если добавляете администратора и других пользователей, начинайте с администратора, т.к. иначе получите ошибку, что вы не создали администратора.
Вот какой код получился:
#use "updater1c" // **************************************************************************** // Переменные модуля // **************************************************************************** Перем errors; // Признак того, что при выполнении скрипта были ошибки. Перем updater; // Обновлятор, через который мы получаем информацию о базе, // а также вызываем различные функции обновлятора. Перем connector; // Коннектор для подключения к базе. Перем v8; // Само подключение к базе через коннектор. // **************************************************************************** // Ваш код для выполнения обновлятором // **************************************************************************** Процедура Главная() //=========== НАЧАЛО КОДА ДОБАВЛЕНИЯ ПОЛЬЗОВАТЕЛЕЙ ========== Т = v8.NewObject("ТаблицаЗначений"); Т.Колонки.Добавить("ПолноеИмя"); Т.Колонки.Добавить("Имя"); Т.Колонки.Добавить("Пароль"); Т.Колонки.Добавить("ВходВПрограммуРазрешен"); Т.Колонки.Добавить("АутентификацияСтандартная"); Т.Колонки.Добавить("АутентификацияОС"); Т.Колонки.Добавить("ПользовательОС"); Т.Колонки.Добавить("ЗапрещеноИзменятьПароль"); Т.Колонки.Добавить("ПоказыватьВСпискеВыбора"); Т.Колонки.Добавить("Профили"); //********** НАЧАЛО: ЗДЕСЬ ОПИСЫВАЕМ ПОЛЬЗОВАТЕЛЕЙ *************** Если v8.Метаданные.Имя = "БухгалтерияПредприятия" Тогда //ПОЛЬЗОВАТЕЛИ БП С = Т.Добавить(); С.ПолноеИмя = "Бухгалтер 4"; С.Имя = "Бух4"; С.Пароль = "123"; С.ВходВПрограммуРазрешен = истина; С.АутентификацияСтандартная = истина; // С.АутентификацияОС = ложь; // С.ПользовательОС = Неопределено; С.АутентификацияОС = истина; С.ПользовательОС = "\\test\test"; С.ЗапрещеноИзменятьПароль = ложь; С.ПоказыватьВСпискеВыбора = истина; С.Профили = "Бухгалтер, Главный бухгалтер"; ИначеЕсли v8.Метаданные.Имя = "ЗарплатаИУправлениеПерсоналом" Тогда //ПОЛЬЗОВАТЕЛИ ЗУП С = Т.Добавить(); С.ПолноеИмя = "Кадровик 4"; С.Имя = "Кадровик4"; С.Пароль = "123"; С.ВходВПрограммуРазрешен = истина; С.АутентификацияСтандартная = истина; // С.АутентификацияОС = ложь; // С.ПользовательОС = Неопределено; С.АутентификацияОС = истина; С.ПользовательОС = "\\test\test"; С.ЗапрещеноИзменятьПароль = ложь; С.ПоказыватьВСпискеВыбора = истина; С.Профили = "Бухгалтер"; КонецЕсли; //********** КОНЕЦ ОПИСАНИЯ ПОЛЬЗОВАТЕЛЕЙ *************** Для Каждого С ИЗ Т Цикл //Создаем пользователя ОбновляемыеСвойства = v8.NewObject("Структура"); Для Инд = 1 По Т.Колонки.Количество() Цикл Колонка = Т.Колонки.Получить(Инд - 1); Зн = С.Получить(Инд - 1); Если Колонка.Имя = "Профили" Тогда Продолжить; КонецЕсли; Если Зн <> Неопределено Тогда ОбновляемыеСвойства.Вставить(Колонка.Имя, Зн); КонецЕсли; КонецЦикла; ОбновляемыеСвойства.Вставить("Действие", "Записать"); //Не уверен, что без этого будет работать ОбновляемыеСвойства.Вставить("ПарольУстановлен", истина); ОбновляемыеСвойства.Вставить("АутентификацияOpenID", ложь); ПользовательИБСуществует = v8.ПользователиИнформационнойБазы.НайтиПоИмени(С.Имя) <> Неопределено; v8.Пользователи.УстановитьСвойстваПользователяИБ(С.Имя, ОбновляемыеСвойства, НЕ ПользовательИБСуществует); //Создавать нового ставим всегда в Истина Сообщить(?(ПользовательИБСуществует, "Добавлен", "Обновлен") + " пользователь ИБ: " + С.Имя); ТекПользователь = v8.Справочники.Пользователи.НайтиПоНаименованию(ОбновляемыеСвойства.ПолноеИмя, истина); ПользовательСуществует = v8.ЗначениеЗаполнено(ТекПользователь); //Записываем пользователя в 1С, если его еще нет в базе Если НЕ ПользовательСуществует Тогда Пользователь = v8.Справочники.Пользователи.СоздатьЭлемент(); Пользователь.Наименование = ОбновляемыеСвойства.ПолноеИмя; Пользователь.ДополнительныеСвойства.Вставить( "ОписаниеПользователяИБ", ОбновляемыеСвойства); Пользователь.Записать(); ТекПользователь = Пользователь.Ссылка; Сообщить("Создан пользователь базы: " + С.Имя); КонецЕсли; МассивПрофили = СтрРазделить(С.Профили, ","); Для Каждого ИмяПрофиля ИЗ МассивПрофили Цикл ИмяПрофиля = СокрЛП(ИмяПрофиля); Если v8.УправлениеДоступомСлужебный.УпрощенныйИнтерфейсНастройкиПравДоступа() Тогда ТекПрофиль = v8.Справочники.ПрофилиГруппДоступа.НайтиПоНаименованию(ИмяПрофиля); Если Не v8.ЗначениеЗаполнено(ТекПрофиль) Тогда Сообщить("Не найден профиль: " + ИмяПрофиля, СтатусСообщения.Важное); Продолжить; КонецЕсли; v8.УправлениеДоступом.ВключитьПрофильПользователю(ТекПользователь, ТекПрофиль); Иначе ТекГруппа = v8.Справочники.ГруппыДоступа.НайтиПоНаименованию(ИмяПрофиля); Если Не v8.ЗначениеЗаполнено(ТекГруппа) Тогда Сообщить("Не найдена группа: " + ИмяПрофиля, СтатусСообщения.Важное); Продолжить; КонецЕсли; //Код скопирован из типовой формы ПраваДоступа, несколько упрощен ГруппаДоступаОбъект = ТекГруппа.ПолучитьОбъект(); Добавить = истина; Если Добавить Тогда Если ГруппаДоступаОбъект.Пользователи.Найти(ТекПользователь, "Пользователь") = Неопределено Тогда ГруппаДоступаОбъект.Пользователи.Добавить().Пользователь = ТекПользователь; КонецЕсли; Иначе СтрокаТЧ = ГруппаДоступаОбъект.Пользователи.Найти(ТекПользователь, "Пользователь"); Если СтрокаТЧ <> Неопределено Тогда ГруппаДоступаОбъект.Пользователи.Удалить(СтрокаТЧ); КонецЕсли; КонецЕсли; ГруппаДоступаОбъект.Записать(); КонецЕсли; КонецЦикла; КонецЦикла; //=========== КОНЕЦ КОДА ДОБАВЛЕНИЯ ПОЛЬЗОВАТЕЛЕЙ ========== КонецПроцедуры // **************************************************************************** // Служебные процедуры // **************************************************************************** Процедура ПриНачалеРаботы() errors = Ложь; updater = Новый Updater1C; // Если в скрипте не планируется использовать // подключение к базе - просто закомментируйте // две нижние строки. connector = updater.CreateConnector(); v8 = updater.BaseConnectNew(connector); КонецПроцедуры Процедура ПриОкончанииРаботы() Если v8 <> Неопределено Тогда Попытка ОсвободитьОбъект(v8); v8 = Неопределено; Исключение КонецПопытки; КонецЕсли; Если connector <> Неопределено Тогда Попытка ОсвободитьОбъект(connector); connector = Неопределено; Исключение КонецПопытки; КонецЕсли; Если updater <> Неопределено Тогда Попытка ОсвободитьОбъект(updater); updater = Неопределено; Исключение КонецПопытки; КонецЕсли; Если errors Тогда ЗавершитьРаботу(1); КонецЕсли; КонецПроцедуры // **************************************************************************** // Инициализация и запуск скрипта // **************************************************************************** ПриНачалеРаботы(); Попытка Главная(); updater.КодПользователяВыполнился(); Исключение errors = Истина; Сообщить("" + ОписаниеОшибки() + ""); КонецПопытки; ПриОкончанииРаботы();
Как видно, можно использовать один скрипт для разных баз, прописывая пользователей для разных типов баз (БП, ЗУП) отдельно.
Если в скрипте у Вас возникнут ошибки и вы захотите отладиться, это будет проблематично во внешнем соединении, поэтому просто удалите из кода все строки «v8.» и замените NewObject на Новый, тогда можно будет запускать код в обычной консоли кода.
Кто хочет посмотреть мою тестовую обработку, вот она:

UPD 2024-07-05: у одного пользователя скрипт не работал, т.к. использовалась бухгалтерия локализированная. В этом случае вставьте в любое место код, который покажет название конфигурации и там, где происходит сравнение с v8.Метаданные.Имя, поменяйте на название конфигурации, пример, название изменено на бухгалтерию для Казахстана:

Объем факт: 4 час.




добрый день, а не подскажите в чем проблема, пытаюсь добавить администратора в пустую базу, и выдает ошибку
https://prnt.sc/mnLD6GNqO6W8
https://prnt.sc/hdhlCEzsXWyF
Профиль «Администратор» — это не полноправный пользователь. Поэтому система и ругается что не останется ни одного администратора базы.
Используйте профиль «Полные права».
спасибо, но не помогло, пробовал и добавить полные права и только их указывал, все равно шибка та же самая
https://prnt.sc/08jIzZ0fJztN
https://prnt.sc/99fZM6Kkn8tc
Попробуйте выполнить этот код в консоли кода. Ну или попробуйте создать вручную пользователя с такими профилями.
Хотя я посмотрел код, там сначала создается пользователь, а потом ему назначается права. Так что этот код не будет работать, если в базе вообще нет пользователей.
Надо при создании добавлять пользователю полные права, если у него есть профиль Полные права, как-то так.
да в базе вообще не было пользователей, понял, будем значит вручную добавлять администратора, а затем через обработку пользователей.
Спасибо
Благодарю за этот скрипт, сэкономило мне пол часа времени!
всегда пожалуйста.
Очень познавательно.
спасибо
Дружище! Огромное спасибо тебе! Вот прям респект! Стояла задача на работе в 150 баз добавить по 20 пользователей в каждую! Уже уволиться собирался))) Чуть подредактировал под свои БД и все взлетело
Отлично. Вкалывать должны роботы, а не человек. Это действительно, мощный скрипт!
Ой красава Фиксин, тут как раз надо было штук 30 юзеров заводить с одинаковыми паролями и профилями (внутренн. ЭДО в БГУ), сколько бы я руками тыкал… Спасибо!
Да. Этот скрипт — огонь. Жаль не все умеют в Обновлятор.
А как вам заказать такой код для удаления пользователей в Обновляторе?
Исходя из стоимости 2800 в час, такой код будет стоить 2800. Мои контакты есть в разделе «Контакты сайта».
Только если срочно, не гарантирую, до 18 августа плотно занят.
Огромное спасибо за код!!!)
Пожалуйста! 😉
да, код сильный.
Спасибо, очень подробно расписано. Единственное толковое описание
ну, все следует из практики. пришлось обновлятор мучать для решения этой задачи.
Есть более удобный способ для ЗУП используя функцию СамообслуживаниеСотрудников.НовыйПользователь()
https://www.myblog-1c.ru/%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%BD%D0%BE%D0%B5-%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5-%D0%B8-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D0%BE%D0%BB/
Название модуля звучит как песня… Получше места для размещения функции не нашлось?