Программное добавление пользователей в базы на БСП
Клиент заказал скрипт для Обновлятора для создания пользователей и назначения им прав в конфигурации на БСП — в БП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 августа плотно занят.
Огромное спасибо за код!!!)
Пожалуйста! 😉
да, код сильный.