Как настроить роль для редактирования только одного реквизита в 1С:Предприятии 8

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Проблема 1: Ошибка нарушения прав доступа при записи (Принцип атомарности)

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

Выясним причину такого поведения платформы. В 1С:Предприятии запись любого ссылочного объекта (документа, справочника) в базу данных всегда происходит атомарно. Это значит, что объект перезаписывается в таблице СУБД целиком, а не отдельными полями. Платформа физически не может обновить значение одного реквизита, если у пользователя нет права на изменение всего объекта.

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

  1. Откроем конфигуратор и перейдем к редактированию нашей роли.
  2. Для целевого объекта метаданных (например, Документ.РеализацияТоваровУслуг) на уровне самого объекта обязательно установим права "Изменение" (а также "Чтение", "Просмотр" и "Интерактивное изменение", если пользователь должен редактировать форму визуально).
  3. Перейдем на вкладку "Реквизиты" внутри настройки прав этого объекта в роли.
  4. Вручную снимем флажок "Редактирование" со всех реквизитов и табличных частей объекта, оставив этот флажок активным только для того единственного реквизита, который пользователю разрешено изменять.
  5. Право "Просмотр" на остальные реквизиты можно оставить активным, чтобы пользователь видел остальные данные, но не мог их скорректировать.

При такой настройке платформа 1С автоматически сделает все остальные поля на управляемой форме недоступными для изменения (переведет их в режим "Только просмотр"), оставив доступным для интерактивного ввода только разрешенное поле. Для проектирования сложных профилей и подбора прав под выбранные объекты можно использовать инструмент для аудита прав и автоподбора ролей БСП.

Проблема 2: Парадокс "РольДоступна == Ложь" для администраторов

Другой частый сценарий: разработчик пытается программно ограничить доступность элементов на форме, ориентируясь на созданную роль. Однако при проверке под учетной записью администратора (с Полными правами) метод РольДоступна("ИмяНашейРоли") возвращает значение Ложь, хотя полные права по определению должны включать все возможности.

Проанализируем ситуацию. В современных типовых конфигурациях, использующих БСП, механизм авторизации и назначения ролей оптимизирован. При входе пользователя с профилем "Администратор" система для экономии памяти и ускорения работы сеанса физически назначает ему на уровне платформы только базовые роли, такие как ПолныеПрава и АдминистраторСистемы. Все остальные точечные роли ему физически не сопоставляются в сеансе, так как полные права и так перекрывают любые проверки прав на уровне метаданных. Именно из-за этой оптимизации прямой вызов стандартного метода платформы возвращает отрицательный результат.

Рассмотрим правильные способы программной проверки ролей:

Способ 1. Использование функций общего модуля БСП

Для конфигураций на базе БСП вместо стандартного метода платформы следует использовать вызов специализированных функций, которые корректно учитывают наличие полных прав:


// Корректная проверка роли в БСП
Если УправлениеДоступом.ЕстьРоль("ИмяНовойРоли") Тогда
    // Логика для пользователей с назначенной ролью или полными правами
КонецЕсли;

Также можно использовать аналогичный метод из другого модуля:


Если Пользователи.РолиДоступны("ИмяНовойРоли") Тогда
    // Код выполняется, если роль доступна или пользователь является администратором
КонецЕсли;

Способ 2. Проверка непосредственного права доступа (Рекомендация 1С:ИТС)

Наиболее гибким и архитектурно верным решением по стандартам разработки 1С является проверка не конкретного имени роли, а фактического права доступа к метаданным. Это позволяет отвязать программный код от жестко заданных имен ролей в конфигураторе:


// Проверка права на редактирование конкретного реквизита документа
ЕстьДоступ = ПравоДоступа("Редактирование", Метаданные.Документы.ИмяДокумента, , "ИмяРеквизита");
Если ЕстьДоступ Тогда
    // Разрешаем редактирование на форме
КонецЕсли;

Проблема 3: Программное управление доступностью элементов управляемой формы

Иногда требуется решить задачу исключительно на уровне интерфейса управляемой формы, не прибегая к жестким ограничениям ролей на уровне базы данных (например, когда разные пользователи должны видеть форму по-разному в зависимости от контекста работы).

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Проверяем, нужно ли ограничивать права для текущего пользователя
    НужноОграничитьДоступ = Не УправлениеДоступом.ЕстьРоль("РазрешитьРедактированиеВсехРеквизитов");
    
    Если НужноОграничитьДоступ Тогда
        
        // Устанавливаем свойство ТолькоПросмотр для всей формы
        ЭтотОбъект.ТолькоПросмотр = Истина;
        
        // Делаем исключение для конкретного элемента формы
        ИмяРазрешенногоЭлемента = "ИмяРеквизита";
        Если Элементы.Найти(ИмяРазрешенногоЭлемента) <> Неопределено Тогда
            Элементы[ИмяРазрешенногоЭлемента].ТолькоПросмотр = Ложь;
            Элементы[ИмяРазрешенногоЭлемента].Доступность = Истина;
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

Важный нюанс: при установке ТолькоПросмотр = Истина для всей формы кнопка проведения и записи может стать недоступной. Чтобы пользователь мог записать измененный реквизит, нам потребуется явно разрешить доступность кнопок записи:


Элементы.ФормаЗаписатьИЗакрыть.Доступность = Истина;
Элементы.ФормаЗаписать.Доступность = Истина;

Проблема 4: Использование типового механизма БСП "Запрет редактирования реквизитов объектов"

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

Разберем по шагам, как настроить этот механизм для своего объекта:

Шаг 1. Настройка модуля менеджера объекта

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


Функция ПолучитьБлокируемыеРеквизитыОбъекта() Экспорт
    Результат = Новый Массив;
    // Указываем реквизиты, которые нельзя редактировать без особых прав
    Результат.Добавить("Организация");
    Результат.Добавить("Контрагент");
    Результат.Добавить("СуммаДокумента");
    Возврат Результат;
КонецФункции

Шаг 2. Интеграция в модуль формы объекта

В модуле управляемой формы объекта добавим вызовы стандартных процедур БСП в обработчики создания и записи на сервере:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Блокируем реквизиты при открытии формы
    ЗапретРедактированияРеквизитовОбъектов.ЗаблокироватьРеквизиты(ЭтотОбъект);
КонецПроцедуры

&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
    // Повторно блокируем реквизиты после записи документа
    ЗапретРедактированияРеквизитовОбъектов.ЗаблокироватьРеквизиты(ЭтотОбъект);
КонецПроцедуры

После выполнения этих настроек система автоматически заблокирует указанные поля для всех пользователей, у которых нет роли "Редактирование реквизитов объектов" (или аналогичной роли БСП, дающей право обхода блокировок). На форме появится стандартная кнопка разблокировки в меню "Еще", что обеспечит единообразие интерфейса системы и избавит вас от необходимости писать громоздкий программный код ручной блокировки элементов. Для автоматической разблокировки ключевых полей у доверенных пользователей подойдёт расширение для автоматического разрешения редактирования реквизитов.

← На главную