Разработка систем на платформе «1С:Предприятие 8.3» часто сопряжена с тонкой настройкой прав доступа. Одной из самых коварных ошибок является ситуация, когда пользователю выданы права на чтение и редактирование документа, он видит этот документ в списке, может его открыть, но при попытке сохранить изменения получает системное сообщение: «У пользователя недостаточно прав на исполнение операции над базой данных». При этом отладка может показывать, что ошибка происходит непосредственно на строке ДокОбъект.Записать(), а визуальный анализ прав в конфигураторе подтверждает их наличие.
В этой статье мы подробно разберем, почему так происходит, как работает механизм Record Level Security (RLS) «под капотом» и на что нужно обратить внимание, чтобы устранить подобные «затыки».
Рассмотрим ситуацию, с которой столкнулся автор темы. Есть самописный документ, доступ к которому ограничен по статусам через RLS. Для ролей прописаны ограничения на «Чтение» и «Изменение». Пользователь пытается изменить документ, переводя его в новый статус, который вроде бы добавлен в список разрешенных, но получает отказ.
Проанализируем ключевой нюанс работы RLS на «Изменение». Платформа 1С выполняет проверку условий ограничения доступа дважды:
Если вы меняете статус документа с «Разрешенного» на «Запрещенный» (с точки зрения настроек RLS для данного пользователя), то проверка на втором этапе провалится. Платформа интерпретирует это так: пользователь пытается создать в базе данных запись, к которой у него в дальнейшем не будет доступа на изменение, и блокирует операцию. Это стандартное поведение для предотвращения ситуации, когда пользователь «выбрасывает» документ из своей зоны видимости, лишая себя возможности исправить возможную ошибку записи.
Часто разработчики копируют текст ограничения из права «Чтение» в право «Изменение». Разберем, к чему это приводит. Допустим, условие выглядит так:
ГДЕ Статус = Значение(Перечисление.Статусы.Черновик)
ИЛИ Статус = Значение(Перечисление.Статусы.НаСогласовании)
Если пользователь попытается перевести документ из статуса НаСогласовании в статус Утвержден, транзакция прервется. Несмотря на то что в момент нажатия кнопки «Записать» документ был доступен для редактирования (статус НаСогласовании), после записи он должен получить статус Утвержден, который отсутствует в условии.
Для решения этой проблемы логика права «Изменение» должна быть шире. Мы должны позволить пользователю записывать документ, если он был доступен ему хотя бы в момент начала операции. Однако на уровне чистого RLS в роли это реализовать сложно без разделения прав на статусы «откуда» и «куда».
В процессе обсуждения автор упомянул, что код иногда «не обновляется» — изменения в модуле внесены, но отладчик их игнорирует. Выясним причины такого поведения:
rphost. Если вы видите, что точка останова срабатывает на пустом месте или игнорирует измененные строки, необходимо почистить кэш сервера (каталог snacc) или перезапустить службу сервера 1С.Иногда ошибка «Недостаточно прав» при вызове ДокОбъект.Записать() не имеет отношения к самому документу. Проанализируем смежные области:
Если у пользователя есть право на «Изменение» документа в целом, но нет права на «Редактирование» или «Просмотр» конкретного реквизита, который заполняется программно в модуле объекта при записи, это может вызвать конфликт. Проверьте, чтобы на все реквизиты, участвующие в логике проведения или записи, у пользователя были права хотя бы на Чтение. Как было отмечено в обсуждении, если записываются данные, на которые нет прав, 1С выдаст общую ошибку доступа.
При записи документа (особенно с режимом Записывать или Проводить) система пытается очистить или создать записи в регистрах сведений, накопления или бухгалтерии. Если у пользователя настроен RLS на сам документ, но при этом ограничены права на регистры, в которые этот документ делает движения, ошибка возникнет именно в момент ДокОбъект.Записать().
Посмотрим на пример кода в подписке на событие или в модуле документа:
Движения.ОстаткиТоваров.Записывать = Истина;
Набор = Движения.ОстаткиТоваров;
Набор.Записать();
Если у пользователя нет прав на изменение регистра ОстаткиТоваров, система выдаст ошибку прав. В Журнале регистрации это событие часто отражается как «Отказ в доступе» к метаданным регистра, а не самого документа.
Рассмотрим алгоритм поиска «спрятанных» проверок прав:
РегистрСведений.НастройкиДоступа), на который не хватило прав.Записать(), попробуйте зайти внутрь (F11), чтобы проверить ПередЗаписью и ПриЗаписи.
УстановитьПривилегированныйРежим(Истина);
Объект.Записать();
УстановитьПривилегированныйРежим(Ложь);
Проблема автора темы подтвердила классическое правило RLS: ограничение на изменение проверяет состояние объекта и после записи. Если вы строите систему на статусах, убедитесь, что логика перехода между ними не противоречит правам доступа пользователя, либо выполняйте финальную смену статуса в привилегированном режиме.