При работе с конфигурациями 1С, особенно версий 8.2 и ранних 8.3, нередко возникает задача по корректировке прав доступа пользователей. Одна из таких задач – массовое снятие права "Интерактивное удаление" для всех документов в определенной роли. Казалось бы, простая операция, но на практике она может столкнуться с неожиданными препятствиями в стандартном конфигураторе. Мы рассмотрим, почему возникает эта проблема и как ее эффективно решить.
Суть проблемы: Пользователи сталкиваются с ситуацией, когда при попытке снять флажок "Интерактивное удаление" на верхнем уровне ("Документы") в редакторе прав роли, флажок оказывается серым. Это означает, что для некоторых документов в этой роли право есть, а для некоторых нет. При попытке кликнуть на серый флажок, вместо его снятия, он сначала становится активным (устанавливается для всех документов), и что критично – одновременно устанавливаются права на "Чтение", "Изменение" и "Удаление" для ВСЕХ ДОКУМЕНТОВ в этой роли. Естественно, такой побочный эффект крайне нежелателен, так как нарушает существующие тонкие настройки прав доступа.
Такое поведение наблюдается в конфигураторе 1С:Предприятия 8.2 (например, на платформе 8.2.16.368) и может проявляться в аналогичных условиях на более новых платформах, запущенных в режиме совместимости. Стандартные инструменты, такие как редактор "Все роли" или различные внешние обработки для назначения ролей, часто не могут решить эту проблему без нежелательных побочных эффектов, поскольку они используют тот же механизм работы с правами, что и основной редактор роли.
Прежде чем переходить к более радикальным методам, давайте рассмотрим, почему стандартные средства конфигуратора, казалось бы, предназначенные для этих целей, не решают нашу проблему:
Когда мы открываем конкретную роль в конфигураторе и переходим на ветку "Документы", мы видим список всех документов конфигурации. Напротив каждого документа есть набор флажков, отвечающих за различные права, включая "Интерактивное удаление". Если мы хотим изменить это право для всех документов сразу, мы пытаемся воздействовать на флажок, расположенный на верхнем уровне, напротив узла "Документы".
Если для части документов право "Интерактивное удаление" установлено, а для другой части нет, этот флажок на верхнем уровне отображается серым. Это индикатор смешанного состояния. При попытке снять серый флажок, конфигуратор интерпретирует это действие как команду "установить право для всех" (чтобы привести их к одному состоянию), а затем уже при повторном клике позволит снять его. Хуже того, в определенных версиях платформы или конфигураций, такое действие автоматически устанавливает также права "Чтение", "Изменение" и "Удаление" для всех документов, что является серьезным нарушением логики существующих прав.
Изменение права для каждого документа по отдельности, конечно, возможно. Мы можем заходить в каждый документ, снимать галку "Интерактивное удаление", сохранять роль. Однако, при наличии десятков или сотен документов, такой подход становится непрактичным и крайне трудоемким. Этот метод не подходит для массовых операций.
Этот инструмент позволяет нам просматривать и редактировать права для всех ролей на все объекты метаданных в одном окне, что значительно удобнее для обзорного анализа. Мы выбираем нужную роль, переходим на вкладку "Документы" и пытаемся найти там флажок "Интерактивное удаление" для всего раздела "Документы".
К сожалению, поведение здесь оказывается аналогичным: серый флажок, попытка снять который приводит к его активации для всех документов и установке дополнительных прав ("Чтение", "Изменение", "Удаление"). Таким образом, редактор "Все роли" также не предоставляет прямого и безопасного решения для нашей задачи.
Существуют различные внешние обработки, предназначенные для более удобного управления правами доступа пользователей, например, обработки для просмотра ролей пользователей или назначения прав. Некоторые из них могут помочь в анализе, но большинство из них используют те же стандартные механизмы изменения прав, что и конфигуратор. Это означает, что они, скорее всего, столкнутся с той же проблемой "серого флажка" и нежелательной установкой других прав. Обработки, которые позволяют лишь "назначить роли пользователям и посмотреть права на объекты", не предоставляют функциональности для редактирования самой структуры роли и ее прав на метаданные.
Таким образом, мы видим, что для нашей специфической задачи требуется более глубокий и программный подход, который позволит обойти ограничения стандартного интерфейса конфигуратора.
Наиболее эффективным и контролируемым способом массового изменения прав доступа, особенно когда стандартные инструменты конфигуратора не справляются, является программная модификация конфигурации на уровне файлов. Этот метод включает выгрузку конфигурации в XML-файлы, изменение необходимых параметров с помощью скрипта, а затем загрузку измененных файлов обратно.
Важно: Перед выполнением любых действий по изменению конфигурации, особенно путем манипуляции с файлами, обязательно создайте резервную копию информационной базы. Всегда выполняйте такие операции сначала на тестовой копии базы, чтобы убедиться в корректности изменений и отсутствии непредвиденных последствий.
Прежде всего, нам необходимо получить файловое представление конфигурации. Это позволит нам получить доступ к XML-файлам, в которых хранятся описания ролей и их прав.
После успешной выгрузки в указанной папке вы увидите множество подпапок и файлов. Нас интересует папка с именем Roles.
Теперь, когда у нас есть доступ к файлам, мы можем написать скрипт, который пройдет по всем XML-файлам ролей и изменит значение права "Delete" (удаление) на false.
Для выполнения этого шага мы будем использовать внутренний язык 1С (либо любой другой язык программирования, который умеет работать с файлами и XML, но для удобства и интеграции с платформой, 1С-скрипт предпочтителен). Мы можем создать временную внешнюю обработку в 1С для выполнения этого скрипта.
Рассмотрим пример кода на встроенном языке 1С, который выполнит эту задачу:
// Определите путь к папке, куда была выгружена конфигурация.
// Замените "C:\Config_XML_Dump" на ваш актуальный путь.
ПутьКВыгрузкеКонфигурации = "C:\Config_XML_Dump";
ПапкаРолей = ПутьКВыгрузкеКонфигурации + "\Roles";
// Проверяем, существует ли папка с ролями
Если НЕ ФайлСуществует(ПапкаРолей) Тогда
Сообщить("Ошибка: Папка с ролями не найдена по пути: " + ПапкаРолей);
Возврат;
КонецЕсли;
// Ищем все XML-файлы внутри папки Roles и всех ее подпапок
// (роли могут быть разложены по подпапкам в зависимости от их структуры)
НайденныеФайлы = НайтиФайлы(ПапкаРолей, "*.xml", ИСТИНА);
Если НайденныеФайлы.Количество() = 0 Тогда
Сообщить("В папке " + ПапкаРолей + " не найдено XML-файлов ролей.");
Возврат;
КонецЕсли;
Сообщить("Найдено файлов ролей для обработки: " + НайденныеФайлы.Количество());
Сообщить("Начинаем обработку...");
Для Каждого Файл Из НайденныеФайлы Цикл
Текст = Новый ТекстовыйДокумент;
Попытка
// Читаем файл в кодировке UTF-8. Это стандартная кодировка для XML 1С.
Текст.Прочитать(Файл.ПолноеИмя, "utf-8");
СтрокаXML = Текст.ПолучитьТекст();
НоваяСтрокаXML = СтрокаXML;
// Переменная для подсчета изменений в текущем файле
КоличествоИзмененийВФайле = 0;
// Ищем все вхождения тега Delete и меняем соответствующее значение
// Право "Интерактивное удаление" в файле XML представлено тегом Delete
// и следующим за ним тегом true или false
ПозицияПоиска = 1;
Пока ИСТИНА Цикл
// Ищем тег Delete
ИтераторНачалаТега = СтрНайти(НоваяСтрокаXML, "Delete ", , ПозицияПоиска);
Если ИтераторНачалаТега = 0 Тогда
Прервать; // Больше не найдено вхождений
КонецЕсли;
// Находим позицию после тега Delete
ПозицияПослеТегаDelete = ИтераторНачалаТега + СтрДлина("Delete ");
// Ищем тег за найденным Delete
ИтераторНачалоЗначения = СтрНайти(НоваяСтрокаXML, "", , ПозицияПослеТегаDelete);
Если ИтераторНачалоЗначения = 0 Тогда
// Не найдено соответствующее значение, переходим к следующему поиску "Delete"
ПозицияПоиска = ПозицияПослеТегаDelete + 1;
Продолжить;
КонецЕсли;
// Ищем закрывающий тег
ИтераторКонецЗначения = СтрНайти(НоваяСтрокаXML, " ", , ИтераторНачалоЗначения);
Если ИтераторКонецЗначения = 0 Тогда
// Не найдено закрывающего тега, переходим к следующему поиску "Delete"
ПозицияПоиска = ИтераторНачалоЗначения + 1;
Продолжить;
КонецЕсли;
// Извлекаем текущее значение (true/false)
ТекущееЗначение = Сред(НоваяСтрокаXML, ИтераторНачалоЗначения + СтрДлина(""), ИтераторКонецЗначения - (ИтераторНачалоЗначения + СтрДлина("")));
// Если текущее значение "true", меняем его на "false"
Если СтрСравнить(ТекущееЗначение, "true", Ложь) = 0 Тогда // Ложь для регистронезависимого сравнения
НоваяСтрокаXML = Лев(НоваяСтрокаXML, ИтераторНачалоЗначения + СтрДлина("") - 1)
+ "false"
+ Сред(НоваяСтрокаXML, ИтераторКонецЗначения);
КоличествоИзмененийВФайле = КоличествоИзмененийВФайле + 1;
// Так как строка изменилась, нам нужно скорректировать позицию для следующего поиска
ПозицияПоиска = ИтераторКонецЗначения + СтрДлина("false") - СтрДлина(ТекущееЗначение);
Иначе
// Значение уже "false" или другое, просто двигаемся дальше
ПозицияПоиска = ИтераторКонецЗначения + СтрДлина(" ");
КонецЕсли;
КонецЦикла;
// Если были изменения, записываем измененный текст обратно в файл
Если КоличествоИзмененийВФайле > 0 Тогда
Текст.УстановитьТекст(НоваяСтрокаXML);
Текст.Записать(Файл.ПолноеИмя, "utf-8");
Сообщить("Файл " + Файл.Имя + " успешно обновлен. Изменений: " + КоличествоИзмененийВФайле);
Иначе
Сообщить("В файле " + Файл.Имя + " изменения не потребовались.");
КонецЕсли;
Исключение
Сообщить("Ошибка при обработке файла " + Файл.ПолноеИмя + ": " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
Сообщить("Обработка файлов завершена.");
// Внимание: Роль "Полные права" может быть специфичной и не всегда корректно выгружаться/загружаться
// стандартными средствами из файлов из-за внутренних механизмов платформы.
// После общей загрузки конфигурации из файлов, если вы изменяли эту роль,
// возможно, потребуется вручную проверить и скорректировать ее права в конфигураторе.
// В данном случае, мы меняем права для "Delete", которое относится к интерактивному удалению
// и редко ставится для "Полных прав", но стоит об этом помнить.
Пояснения к коду:
НайтиФайлы для рекурсивного поиска всех XML-файлов в папке Roles.ТекстовыйДокумент в кодировке utf-8, которая является стандартной для файлов конфигурации 1С.Delete . Важно понимать, что в структуре XML-файлов конфигурации 1С, права доступа описываются как пары тегов ... и ... . Право "Интерактивное удаление" имеет имя Delete.Delete , мы ищем соответствующий ему тег . равно true (то есть право разрешено), мы заменяем его на false.Данный скрипт гарантирует, что право "Интерактивное удаление" будет изменено только там, где оно было установлено на true, и не затронет другие права, связанные с чтением, изменением или удалением объектов, поскольку он оперирует только конкретным тегом Delete.
После того как XML-файлы ролей были успешно модифицированы, нам необходимо загрузить их обратно в информационную базу.
Важный нюанс с ролью "Полные права": Роль "Полные права" в 1С имеет особую природу. Иногда она может не выгружаться или не загружаться из файлов так же прямолинейно, как другие роли, из-за внутренних механизмов платформы. Если вы обнаружите, что после загрузки конфигурации права роли "Полные права" не соответствуют ожиданиям (хотя наше изменение конкретно права "Delete" обычно не затрагивает "Полные права" в этом контексте), возможно, потребуется вручную проверить и скорректировать ее права в конфигураторе.
Перенос только прав: Если вы работали на тестовой базе и хотите перенести изменения прав в рабочую базу, не затрагивая другие части конфигурации, вы можете воспользоваться механизмом Сравнение/Объединение конфигураций.
.cf (Конфигурация -> Сохранить конфигурацию в файл...)..cf файл.Таким образом, хотя стандартные средства конфигуратора 1С могут быть удобны для рутинных операций, для решения специфических и массовых задач, таких как контролируемое снятие права "Интерактивное удаление" без побочных эффектов, приходится прибегать к более продвинутым методам работы с конфигурацией на уровне файлов. Этот подход требует определенных навыков программирования и тщательности, но обеспечивает полный контроль над процессом и гарантирует достижение желаемого результата.