Роль из основной конфигурации в расширении: заимствование, ручная сборка и перенос прав через XML

· 10 мин

Содержание

Скопировать роль в расширение 1С командой «Копировать» → «Вставить» нельзя: в Конфигураторе метаданные не переносятся из дерева основной конфигурации в дерево расширения. Рабочих путей три. Роль можно заимствовать (Добавить в расширение в контекстном меню), создать в расширении свою роль и проставить права вручную или перенести права через выгрузку в XML-файлы.

Частое заблуждение: «скопирую роль в расширение, уберу лишние галочки — и пользователь потеряет доступ». Не потеряет. Права ролей в 1С складываются, а не вычитаются. Роль из расширения может только добавить права, но не может отнять то, что уже дала роль основной конфигурации. Задачу «урезать доступ» расширением не решить.

Почему роль не переносится в расширение простым копированием

Роль хранит права не по именам, а по внутренним идентификаторам объектов метаданных. Расширение видит только два вида объектов: собственные и заимствованные. Справочника, который вы не заимствовали, для расширения не существует. Поэтому и права на него записать некуда.

Отсюда главное правило: прежде чем переносить права, заимствуйте в расширение все объекты, на которые эти права нужны. Иначе часть прав просто потеряется.

Какой путь выбрать, зависит от цели:

Что нужно сделать с ролью?

Подготовка расширения перед копированием роли

Перед работой сделайте три вещи.

  1. 💾 Сохраните текущее расширение в файл. В Конфигураторе откройте Конфигурация → Расширения конфигурации, выделите расширение и выберите в меню действий сохранение в файл .cfe. Это откат, если что-то пойдёт не так.
  2. 📋 Составьте список объектов, на которые роль даёт права. Откройте роль в основной конфигурации, включите в редакторе прав отбор только объектов с установленными правами и выпишите их.
  3. 🔗 Заимствуйте эти объекты. В дереве основной конфигурации щёлкните объект правой кнопкой и выберите Добавить в расширение. Для справочника или документа заимствуется сам объект, без реквизитов. Если нужны права на отдельные реквизиты, заимствуйте и их.

Заимствование ради одних только прав — нормальная практика. Заимствованный объект без изменений не меняет поведение основной конфигурации и почти не мешает её обновлению.

Расширения появились в платформе 8.3.6, а возможности по ролям в них постепенно расширялись. Если редактор не даёт сделать что-то из описанного ниже, проверьте, что номер платформы не ниже актуального для вашей конфигурации, и режим совместимости расширения.

Способ 1. Копирование роли в расширение вручную

Этот способ подходит, когда объектов немного или когда новая роль должна отличаться от исходной.

Вариант А: заимствовать роль

  1. В основной конфигурации раскройте ветку Общие → Роли.
  2. Щёлкните нужную роль правой кнопкой и выберите Добавить в расширение.
  3. Откройте заимствованную роль в дереве расширения.
  4. Отметьте права на собственные объекты расширения: новые справочники, отчёты, обработки, команды.

Права, которые роль даёт в основной конфигурации, в заимствованной роли не отображаются и не редактируются. Они остаются там, где были. Вы лишь дописываете права на объекты расширения.

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

Вариант Б: своя роль с правами исходной

  1. В дереве расширения на ветке Общие → Роли добавьте новую роль. Дайте ей имя с префиксом расширения, например мр_БухгалтерРасширенный.
  2. Откройте исходную роль основной конфигурации и разместите два окна рядом.
  3. Проходите по объектам сверху вниз и повторяйте галочки: Чтение, Добавление, Изменение, Удаление, Просмотр, Редактирование, интерактивные права.
  4. Перенесите флаги на вкладке свойств роли: «Устанавливать права для новых объектов», «Устанавливать права для реквизитов и табличных частей по умолчанию», «Независимые права подчинённых объектов».
  5. Если в исходной роли есть ограничения доступа на уровне записей, скопируйте тексты условий и шаблоны ограничений. Шаблоны лежат на отдельной вкладке роли, и без них условия с #ИмяШаблона не заработают.

Для сверки удобно окно «Все роли». Оно открывается из контекстного меню ветки Роли и показывает права всех ролей одной таблицей. По нему быстро видно, где новая роль отстаёт от исходной.

В редакторе роли можно выделить несколько объектов сразу и установить право одним действием. Для двадцати справочников с правом Чтение это минута работы, а не двадцать.

Способ 2. Перенос прав роли через выгрузку конфигурации в файлы

Когда в роли сотни объектов, ручная работа превращается в источник ошибок. Права роли в файловом виде лежат в одном XML-файле, и его можно перенести.

Схема такая:

  1. В расширении создайте пустую роль с нужным именем. Так платформа сама создаст файлы роли с корректным идентификатором.
  2. Выгрузите основную конфигурацию и расширение в файлы.
  3. Возьмите файл Roles\ИмяРоли\Ext\Rights.xml из выгрузки основной конфигурации.
  4. Удалите из него объекты, которых нет в расширении (об этом — в способе 3).
  5. Положите результат на место Rights.xml пустой роли в выгрузке расширения.
  6. Загрузите расширение из файлов и обновите конфигурацию базы данных.

Выгрузку и загрузку удобно делать пакетным режимом Конфигуратора:

set V8="C:\Program Files\1cv8\8.3.24.1548\bin\1cv8.exe"
set BASE=/S "srv01\buh"
set AUTH=/N "Администратор" /P "пароль"

rem Выгрузка основной конфигурации
%V8% DESIGNER %BASE% %AUTH% /DumpConfigToFiles "C:\dump\main" /Out "C:\dump\log_main.txt"

rem Выгрузка расширения
%V8% DESIGNER %BASE% %AUTH% /DumpConfigToFiles "C:\dump\ext" -Extension "МоёРасширение" /Out "C:\dump\log_ext.txt"

rem Загрузка расширения после замены Rights.xml
%V8% DESIGNER %BASE% %AUTH% /LoadConfigFromFiles "C:\dump\ext" -Extension "МоёРасширение" /Out "C:\dump\log_load.txt"

rem Обновление конфигурации базы данных для расширения
%V8% DESIGNER %BASE% %AUTH% /UpdateDBCfg -Extension "МоёРасширение" /Out "C:\dump\log_upd.txt"

Путь к 1cv8.exe и номер платформы подставьте свои. Для файловой базы вместо /S используйте /F "C:\Bases\Buh".

Загрузка расширения из файлов полностью заменяет его содержимое. Выгружайте расширение непосредственно перед правкой и не меняйте его параллельно в Конфигураторе, иначе чужие изменения пропадут.

Если команда отработала, а роль не изменилась, откройте файл из /Out. Пакетный режим не показывает окон с ошибками, всё пишется в лог.

Способ 3. Скрипт, который чистит Rights.xml под расширение

Готовые обработки для копирования ролей ходят по сети, но из режима 1С:Предприятие роль не создать: метаданные меняются только в Конфигураторе или EDT. Поэтому любая такая обработка по сути делает то же, что способ 2: правит XML. Проще написать такой фильтр самому.

Скрипт на Python берёт Rights.xml исходной роли и Configuration.xml из выгрузки расширения. Он оставляет права только на объекты, которые в расширении есть, и печатает список выброшенных.

import sys
import xml.etree.ElementTree as ET

MD = "{http://v8.1c.ru/8.3/MDClasses}"


def ext_objects(cfg_path):
    """Имена объектов расширения в виде Catalog.Номенклатура."""
    root = ET.parse(cfg_path).getroot()
    names = set()
    for child_objects in root.iter(MD + "ChildObjects"):
        for item in child_objects:
            kind = item.tag.split("}")[1]
            names.add(f"{kind}.{item.text}")
    return names


def filter_rights(src, dst, allowed):
    tree = ET.parse(src)
    root = tree.getroot()
    ns = root.tag[1:].split("}")[0]
    ET.register_namespace("", ns)
    ET.register_namespace("xs", "http://www.w3.org/2001/XMLSchema")
    ET.register_namespace("xsi", "http://www.w3.org/2001/XMLSchema-instance")

    dropped = []
    for obj in list(root.findall(f"{{{ns}}}object")):
        name = obj.find(f"{{{ns}}}name").text
        if name not in allowed:
            root.remove(obj)
            dropped.append(name)

    tree.write(dst, encoding="UTF-8", xml_declaration=True)
    return dropped


if __name__ == "__main__":
    rights_src, ext_cfg, rights_dst = sys.argv[1:4]
    removed = filter_rights(rights_src, rights_dst, ext_objects(ext_cfg))
    print(f"Убрано записей: {len(removed)}")
    for name in removed:
        print("  ", name)

Запуск:

python filter_rights.py "C:\dump\main\Roles\Бухгалтер\Ext\Rights.xml" "C:\dump\ext\Configuration.xml" "C:\dump\ext\Roles\мр_БухгалтерРасширенный\Ext\Rights.xml"

Что скрипт делает сознательно консервативно:

  • 🔹 оставляет только записи вида Тип.Имя, которые совпадают с объектами расширения;
  • 🔹 выбрасывает права на реквизиты, табличные части и формы (Catalog.Номенклатура.Attribute.Артикул): в расширении их может не быть, даже если сам справочник заимствован;
  • 🔹 выбрасывает общие права конфигурации (Configuration.…): у расширения своё имя конфигурации, эти галочки проще проставить в редакторе;
  • 🔹 не трогает шаблоны ограничений и флаги роли, они переезжают как есть.

Список выброшенных записей — это готовый перечень того, что ещё нужно заимствовать. Заимствуйте эти объекты, повторите выгрузку и прогоните скрипт ещё раз.

В EDT роль хранится в файле .rights в том же XML-формате. Там удобнее сравнить две роли встроенным сравнением файлов и перенести нужные блоки руками.

Роль расширения и формы: управляемые и обычные

С формами роль связана двумя способами, и оба надо проверить после переноса.

Видимость по ролям. У реквизитов управляемой формы есть свойства «Просмотр» и «Редактирование» со списком ролей. В командном интерфейсе подсистем есть настройка видимости команд по ролям. Если исходная роль была отмечена в этих местах, новая роль из расширения автоматически туда не попадает. Пользователь с новой ролью увидит форму иначе, чем с исходной.

Что делать:

  1. Заимствуйте форму, в которой настроена видимость по ролям.
  2. В заимствованной форме отметьте роль расширения в свойствах нужных реквизитов.
  3. Для команд откройте командный интерфейс заимствованной подсистемы и отметьте видимость для новой роли.

Если вы выбрали заимствование роли (вариант А), этот шаг обычно не нужен: роль та же, и её отметки в основной конфигурации продолжают действовать.

Обычные формы. Расширения рассчитаны на управляемые формы. Обычную форму заимствовать и изменить в расширении нельзя. Поэтому в конфигурации на обычных формах роль из расширения управляет только доступом к объекту целиком: права на чтение и изменение справочника работают, а видимость отдельных полей обычной формы по новой роли не настроить.

Проверка роли в расширении после копирования

Не проверяйте под своей учётной записью: у администратора есть ПолныеПрава, и он увидит всё независимо от новой роли.

  1. Создайте тестового пользователя.
  2. Назначьте ему только новую роль и минимальную роль для входа, которую требует ваша конфигурация. В типовых на БСП пользователей настраивают через профили групп доступа: добавьте роль расширения в копию профиля.
  3. Зайдите под тестовым пользователем и пройдите сценарий: открыть список, создать элемент, провести документ, сформировать отчёт.
  4. Сравните результат с пользователем, у которого исходная роль.

Права можно проверить и кодом, например во внешней обработке под администратором:

Объект = Метаданные.Справочники.Номенклатура;
РольРасширения = Метаданные.Роли.мр_БухгалтерРасширенный;

Сообщить("Чтение: " + ПравоДоступа("Чтение", Объект, РольРасширения));
Сообщить("Изменение: " + ПравоДоступа("Изменение", Объект, РольРасширения));

Функция ПравоДоступа с ролью в третьем параметре показывает, что даёт именно эта роль, без учёта остальных ролей пользователя. Под самим пользователем пригодится РольДоступна("мр_БухгалтерРасширенный"): она подтвердит, что роль ему назначена.

Роль перенесена корректно, если
Выполнено: 0 / 6

Ошибки при копировании роли в расширение

Диагностика: выберите симптом

Ещё одна ловушка — режимы расширения. Если расширение подключено в безопасном режиме или с защитой от опасных действий, а права не применяются, посмотрите его свойства в списке Расширения конфигурации и лог регистрации. Меняйте эти настройки только по согласованию с тем, кто отвечает за безопасность базы.

Частые вопросы

Можно ли через расширение запретить пользователю действие, которое разрешает типовая роль?
Нет. Права ролей суммируются. Чтобы запретить действие, уберите у пользователя типовую роль или замените её более узкой.
Слетит ли роль из расширения при обновлении типовой конфигурации?
Своя роль расширения останется. Права на заимствованные объекты сохранятся, пока эти объекты есть в основной конфигурации под теми же именами.
Нужно ли переназначать заимствованную роль пользователям?
Нет. Заимствованная роль — та же роль основной конфигурации. У кого она была, тот получает и новые права после перезапуска сеанса.
Можно ли перенести роль из одного расширения в другое?
Да, тем же способом: выгрузите оба расширения в файлы и перенесите Rights.xml. Объекты первого расширения во втором должны существовать, иначе права на них потеряются.
Почему роль расширения не видна в профилях групп доступа?
Расширение должно быть подключено к базе и активно. После подключения перезапустите сеанс и откройте профиль заново.