Разберем детально проблему, с которой рано или поздно сталкивается любой администратор или ведущий разработчик крупной информационной базы на платформе 1С:Предприятие. По умолчанию во многих типовых и самописных конфигурациях у большинства ролей включено право Интерактивное удаление (InteractiveDelete). Это позволяет пользователям (будь то менеджеры, водители или бухгалтеры) случайно или намеренно безвозвратно удалять документы, справочники и другие объекты метаданных в обход стандартной безопасной процедуры пометки на удаление. Если же требуется безопасно и полностью очистить базу от данных конкретной компании, такую задачу выполняет обработка для выборочного удаления организаций.
Когда возникает задача навести порядок в правах доступа, мы обнаруживаем, что ролей в системе может быть несколько десятков (например, 65), а объектов метаданных — сотни (например, 378). Взаимное перемножение этих величин дает колоссальное число настроек — более 24 тысяч ручных операций в конфигураторе! Попытка сделать это вручную обречена на провал. Для имитации действий пользователя и автоматизации подобных монотонных работ в интерфейсе применяется платформа для создания программных роботов.
В этой статье мы подробно проанализируем, почему стандартные средства групповой настройки прав в 1С ломают сопутствующие права, и рассмотрим три надежных способа автоматизации этой задачи: через выгрузку конфигурации в файлы XML, использование современной среды 1C:EDT и самый элегантный архитектурный подход — создание подписки на события.
Казалось бы, платформа 1С предоставляет удобный инструмент групповой настройки — окно «Все роли», в котором можно встать на конкретный объект или ветку объектов (например, «Справочники») и снять галочку Интерактивное удаление сразу для всех ролей. Однако здесь нас подстерегает опасная техническая ловушка.
В платформе 1С существует жесткая зависимость прав. Право на интерактивное удаление объекта логически не может существовать без прав на чтение и изменение этого объекта. Архитектурно это выражается в следующей цепочке зависимостей:
Интерактивное удаление (InteractiveDelete) требует наличия права Удаление (Delete).Удаление требует наличия права Редактирование (Edit).Редактирование требует наличия права Изменение (Update).Изменение требует наличия права Просмотр (View).Просмотр требует наличия права Чтение (Read).Когда мы открываем групповую настройку прав и видим «серую» галочку (которая означает, что у части объектов или ролей это право установлено, а у части — нет), первый же клик по ней переводит флажок в состояние Истина (установлено). При этом платформа автоматически «подтягивает» все зависимые права (Чтение, Просмотр, Изменение, Редактирование, Удаление) и устанавливает их в Истина для всех выбранных объектов и ролей.
Второй клик переводит флажок в значение Ложь (снято). Интерактивное удаление отключается, но автоматически включенные права на Чтение, Редактирование и Изменение обратно не сбрасываются! В итоге мы получаем критическую уязвимость в системе безопасности: пользователи внезапно получают доступ на чтение и редактирование тех объектов, к которым они вообще не должны были иметь доступа.
Именно поэтому использовать стандартный механизм «Все роли» для массового снятия интерактивного удаления категорически противопоказано. Перейдем к разбору безопасных альтернативных вариантов.
Этот способ основан на штатной возможности платформы 1С:Предприятие 8.3 выгружать всю структуру метаданных в текстовые файлы формата XML, обрабатывать их внешними скриптами и загружать обратно в базу. Это абсолютно легальный и безопасный метод, если строго соблюдать технологию.
Рассмотрим пошагово, как реализовать этот подход:
Конфигурация -> Выгрузить конфигурацию в файлы.... Укажем пустую локальную папку (например, C:\UnpackedConfig) и дождемся завершения процесса. Платформа разложит все объекты метаданных по соответствующим каталогам.C:\UnpackedConfig\Roles\<ИмяРоли>\Ext\. Внутри этого каталога находится файл Rights.xml. Именно этот файл описывает, какие права предоставлены данной роли на каждый объект системы.Rights.xml в любом текстовом редакторе, мы увидим узлы, описывающие права на конкретные объекты. Например:
<object>
<name>Catalog.Контрагенты</name>
<right>
<name>InteractiveDelete</name>
<value>true</value>
</right>
</object>
<right> с именем InteractiveDelete и значением true. Наша задача — удалить все такие узлы из всех файлов Rights.xml. При этом, если у объекта нет других явных прав, или если мы удалим этот узел, платформа будет считать это право равным false по умолчанию.Rights.xml и аккуратно удаляет из них упоминания права InteractiveDelete, а также права InteractiveDeletePredefinedData (интерактивное удаление предопределенных данных):
import os
import xml.etree.ElementTree as ET
# Укажем путь к папке с выгруженной конфигурацией
path_to_config = "C:/UnpackedConfig"
print("Старт обработки файлов конфигурации...")
for root, dirs, files in os.walk(path_to_config):
for file in files:
if file.lower() == "rights.xml":
file_path = os.path.join(root, file)
try:
# Парсим XML-файл с сохранением пространства имен
tree = ET.parse(file_path)
xml_root = tree.getroot()
# Пространство имен платформы 1С
ns = {'r': 'http://v8.1c.ru/8.2/roles'}
ET.register_namespace('', 'http://v8.1c.ru/8.2/roles')
modified = False
# Перебираем все узлы объектов
for obj in xml_root.findall('r:object', ns):
for right in obj.findall('r:right', ns):
name_node = right.find('r:name', ns)
if name_node is not None and name_node.text in ['InteractiveDelete', 'InteractiveDeletePredefinedData']:
obj.remove(right)
modified = True
# Если файл был изменен, перезаписываем его
if modified:
tree.write(file_path, encoding='utf-8', xml_declaration=True)
print(f"Успешно обработан файл: {file_path}")
except Exception as e:
print(f"Ошибка при обработке файла {file_path}: {str(e)}")
print("Обработка успешно завершена!")
Конфигурация -> Загрузить конфигурацию из файлов..., выберем нашу папку C:\UnpackedConfig и выполним загрузку.Важное предупреждение: Некоторые разработчики сталкиваются с тем, что после обратной загрузки файлов в конфигураторе отображаются изменения в объектах, которые они не трогали (макеты, картинки, планы счетов). Это связано с тем, что штатный выгрузчик 1С при полной перезаписи файлов может незначительно менять форматирование XML или обновлять служебные заголовки. Чтобы избежать этого эффекта, рекомендуется загружать не всю конфигурацию целиком, а выполнить сравнение и объединение конфигурации с файлами (меню Конфигурация -> Сравнить, объединить с конфигурацией из файлов...), выбрав для объединения только измененные роли.
Если в вашей компании разработка ведется с использованием современной среды 1C:EDT на базе Eclipse, решение задачи становится еще более простым и прозрачным.
Проект в EDT изначально хранится на диске в виде набора XML-файлов и полностью интегрирован с системой контроля версий Git. Чтобы массово снять право на интерактивное удаление в EDT, выполним следующие шаги:
Ctrl + H).*Rights.xml.Git Staging и детально увидеть каждое изменение. Мы четко увидим, что изменились исключительно файлы Rights.xml для наших ролей, а все остальные объекты конфигурации остались нетронутыми. Это полностью исключает риск случайного повреждения макетов или картинок.Несмотря на эффективность первых двух способов, у них есть один существенный недостаток: они изменяют непосредственно роли метаданных. Если ваша конфигурация находится на поддержке и регулярно обновляется, то при очередном обновлении от поставщика новые роли или изменения в существующих ролях могут вернуть право Интерактивное удаление обратно. Вам придется повторять процедуру выгрузки и очистки XML-файлов при каждом обновлении. Для отслеживания таких изменений после обновлений можно использовать обработку для сравнения снимков пользователей и ролей.
Чтобы избежать этой рутины, применим элегантное архитектурное решение на уровне программного кода — создание Подписки на событие. Этот механизм перехватывает попытку удаления любого объекта в системе и блокирует его, если у пользователя нет специального разрешения. При этом физически снимать галочки с 65 ролей вообще не требуется!
Разберем по шагам, как настроить такую подписку:
Общие -> Общие модули. Создадим новый модуль с именем КонтрольПраваУдаленияСобытия. В свойствах модуля обязательно установим флажки Клиент (обычное приложение), Сервер и Внешнее соединение. Модуль должен быть неглобальным.Общие -> Подписки на события. Создадим новую подписку с именем ЗапретитьИнтерактивноеУдалениеПередУдалением. Настроим её свойства:
СправочникОбъект, ДокументОбъект, ПланВидовХарактеристикОбъект). Если нужно запретить удаление вообще для всего, можно выбрать корневые типы.ПередУдалением (BeforeDelete).КонтрольПраваУдаленияСобытия и напишем код обработчика. Нам необходимо учесть важный нюанс: событие ПередУдалением срабатывает как при интерактивном удалении пользователем (через интерфейс), так и при программном удалении (например, при обмене данными через планы обмена или во время работы регламентных заданий). Нам нельзя заблокировать системные процессы, поэтому мы добавим проверку режима загрузки данных и проверку наличия специальной роли у пользователя:
// Обработчик события ПередУдалением для контроля непосредственного удаления
Процедура ЗапретитьИнтерактивноеУдалениеПередУдалением(Источник, Отказ) Экспорт
// Если удаление выполняется в процессе обмена данными (загрузка XML/JSON),
// то блокировать его нельзя, так как это нарушит синхронизацию баз.
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Если удаление выполняется под учетной записью администратора,
// у которого есть полные права или специальная роль "РазрешитьНепосредственноеУдаление"
Если РольДоступна("ПолныеПрава") Или РольДоступна("РазрешитьНепосредственноеУдаление") Тогда
Возврат;
КонецЕсли;
// Во всех остальных случаях блокируем физическое удаление объекта из базы данных
Отказ = Истина;
// Вызываем исключение, чтобы прервать транзакцию и вывести пользователю понятное сообщение
ТекстСообщения = "Внимание! Непосредственное удаление объектов в информационной системе запрещено администратором. "
+ "Пожалуйста, воспользуйтесь стандартной процедурой пометки на удаление (клавиша Delete). "
+ "Удаление помеченных объектов будет произведено регламентным заданием.";
ВызватьИсключение ТекстСообщения;
КонецПроцедуры
Преимущества использования подписки на событие:
РазрешитьНепосредственноеУдаление и назначив её нужным сотрудникам.Проанализируем все три метода, чтобы выбрать оптимальный для вашей ситуации:
| Критерий сравнения | Способ 1. Выгрузка в XML-файлы | Способ 2. Использование 1C:EDT | Способ 3. Подписка на событие |
|---|---|---|---|
| Сложность реализации | Средняя (требуется навык работы со сторонними скриптами Python) | Средняя (требуется установленная среда EDT и Git) | Низкая (настраивается за 10 минут прямо в Конфигураторе 1С) |
| Влияние на обновление конфигурации | Высокое (при каждом обновлении роли могут перезаписываться поставщиком) | Высокое (изменения ролей придется контролировать при слиянии веток) | Нулевое (подписка добавляется как отдельный объект и легко переносится) |
| Безопасность метаданных | Есть риск изменения структуры других файлов при обратной загрузке | Максимальная безопасность благодаря контролю изменений через Git | Максимальная безопасность (файлы ролей вообще не изменяются) |
| Универсальность | Полное отключение прав на уровне платформы | Полное отключение прав на уровне платформы | Блокировка на уровне бизнес-логики (с возможностью исключений в коде) |
Выберем наиболее подходящий вариант под ваши задачи. Если ваша конфигурация полностью самописная и редко претерпевает изменения в структуре ролей, методы с выгрузкой в XML или использованием 1C:EDT отлично подойдут. Если же вы работаете с типовой конфигурацией (например, 1С:ERP, 1С:Комплексная автоматизация или 1С:Управление торговлей), настоятельно рекомендуем остановиться на третьем варианте с подпиской на событие. Это сэкономит вам десятки часов при последующих обновлениях системы.