Как запретить конкретному пользователю редактировать чужие документы Заказ клиенту

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

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

Ситуация осложняется тем, что у пользователя могут быть полные права, что делает стандартный механизм RLS (Row-Level Security) неэффективным. Разберем по шагам, как решить эту задачу с помощью расширения конфигурации, проанализируем различные методы реализации и выберем наиболее надежный.

Проблема использования административных прав

Прежде чем переходить к коду, проанализируем важный технический нюанс. Если пользователь обладает ролью Полные права, платформа 1С игнорирует любые ограничения RLS. В этом случае единственным способом контроля остается программное прерывание операций в модулях объектов или форм. Однако, как правильно заметили участники обсуждения, лучшим решением будет создание отдельного профиля групп доступа, куда войдут все необходимые роли, кроме ПолныеПрава. Это позволит стандартному функционалу ограничений на уровне записей работать корректно.

Решение 1: Ограничение через форму документа (уровень интерфейса)

Самый простой и быстрый способ — это модификация формы документа через расширение. Мы добавим проверку в обработчик события ПриОткрытии. Если текущий пользователь совпадает с «целевым» пользователем (которого мы ограничиваем) и не совпадает с ответственным в документе, мы переводим форму в режим ТолькоПросмотр.

Рассмотрим пример кода, который можно разместить в модуле формы документа ЗаказКлиента в рамках расширения:


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

&НаКлиенте
Процедура Расш_ПриОткрытииПосле(Отказ)
    // Вызываем серверную проверку
    Если ПроверитьОграничениеДоступа() Тогда
        ЭтаФорма.ТолькоПросмотр = Истина;
    КонецЕсли;
КонецПроцедуры

Важное замечание: использование метода НайтиПоНаименованию считается плохой практикой в промышленной разработке. Если имя пользователя изменится (например, на "Настя" вместо "Анастасия"), код перестанет работать. Правильнее использовать поиск по уникальному идентификатору (UUID) или проверку вхождения пользователя в определенную группу доступа.

Решение 2: Использование БСП для идентификации пользователя

В современных конфигурациях, таких как 1С:Комплексная автоматизация 2.4 или 1С:ERP, используется Библиотека стандартных подсистем (БСП). Для получения текущего пользователя рекомендуется использовать функции общего модуля Пользователи. Проанализируем более профессиональный подход к реализации функции проверки:


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

Решение 3: Защита на уровне записи (Модуль объекта)

Метод с ограничением формы (ТолькоПросмотр) имеет существенную уязвимость: пользователь с правами администратора может обойти его, используя внешние обработки, групповое изменение реквизитов или консоль запросов. В этих случаях форма документа просто не открывается, а значит, событие ПриОткрытии не отрабатывает.

Разберем, как сделать защиту по-настоящему надежной. Нам необходимо создать в расширении обработчик события ПередЗаписью в модуле объекта документа ЗаказКлиента.

Проанализируем логику проверки:

  1. Проверяем, не является ли объект новым (новые заказы разрешаем создавать).
  2. Получаем значение ответственного непосредственно из базы данных, а не из текущего объекта (чтобы пользователь не мог подменить ответственного в форме и нажать «Записать»).
  3. Если пользователь совпадает с ограничиваемым и он не был ответственным в исходной версии документа — прерываем запись с выдачей ошибки.

// В модуле объекта ЗаказКлиента (Расширение)
&Перед("ПередЗаписью")
Процедура Расш_ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

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

Дополнительные рекомендации по безопасности

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

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

← На главную