При работе в конфигурации «Управление производственным предприятием» (УПП 1.3) программисты часто сталкиваются с ситуацией, когда пользователю назначена роль, дающая полные права на объект, но система все равно выдает ошибку «Отказ в доступе». Особенно остро эта проблема проявляется при работе с регистрами расчета (например, ОсновныеНачисления), когда включен механизм ограничения доступа на уровне записей (RLS). Рассмотрим подробно, почему это происходит и как решить проблему без назначения системной роли ПолныеПрава.
В платформе 1С:Предприятие 8 реализован механизм суммирования прав: если пользователю назначено несколько ролей, то его итоговые права являются объединением прав всех назначенных ролей. Если одна роль разрешает чтение объекта без ограничений, а другая накладывает условие RLS, то по логике системы пользователь должен видеть все записи. Однако на практике, особенно в старых конфигурациях на обычных формах, таких как УПП 1.3, механизм RLS может вести себя иначе.
Выясним причину конфликта. В типовой конфигурации УПП существует обязательная роль Пользователь. В этой роли для многих объектов (включая регистры расчета) прописано жесткое ограничение RLS: ГДЕ Ложь (или WHERE FALSE). Это делается для того, чтобы запретить доступ к данным «по умолчанию», если не назначена специализированная роль. Когда вы добавляете пользователю свою роль, которая разрешает всё, платформа пытается объединить условия RLS из роли Пользователь и вашей новой роли.
Проблема заключается в том, что для сложных объектов, таких как регистры расчета, платформа при выполнении операций записи или изменения данных инициирует неявные проверки. Если в одной из ролей (в данном случае Пользователь) право на изменение не просто ограничено условием, а вообще не отмечено флажком в конфигураторе, система может заблокировать операцию еще до того, как проверит «разрешающую» роль.
Экспериментальным путем и на основе опыта эксплуатации УПП 1.3 было найдено решение, которое позволяет обойти этот баг платформы (или особенность реализации RLS для регистров расчета). Суть решения заключается в формальном определении права в ограничивающей роли.
Пользователь (или ту типовую роль, которая накладывает ограничение ГДЕ Ложь).ОсновныеНачисления или ДополнительныеНачисления).ГДЕ Ложь), а флажок «Изменение» просто снят.ГДЕ Ложь.На первый взгляд это кажется нелогичным: мы даем право на изменение и тут же его запрещаем условием Ложь. Однако для движка RLS платформы 1С это принципиальная разница. Рассмотрим, что меняется «под капотом»:
Когда флажок Изменение снят, платформа считает, что у данной роли вообще нет легитимного пути для модификации данных. При попытке объединения прав с другой ролью возникает конфликт в логике построения SQL-запроса. Если же флажок установлен, но ограничен условием Ложь, платформа корректно объединяет условия (например, Истина ИЛИ Ложь), что в итоге дает Истина и позволяет пользователю беспрепятственно работать с данными, имея вторую разрешающую роль.
Важно понимать, почему эта проблема чаще всего возникает именно в регистрах расчета. Посмотрим на структуру этих объектов. Регистры расчета — это не просто плоские таблицы. Они связаны с:
При попытке записать набор записей в РегистрРасчета, платформа автоматически проверяет связанные записи в таблицах перерасчетов. Если у пользователя стоит жесткое ограничение на чтение или изменение этих данных в роли Пользователь, транзакция прерывается с ошибкой «Отказ в доступе». Установка флажка Изменение с условием Ложь заставляет систему правильно интерпретировать права при модификации связанных данных.
Многие программисты ошибочно полагают, что создание роли, где проставлены все галочки и нет условий RLS, эквивалентно системной роли ПолныеПрава. Это не так. Разберем разницу:
Роль «Полные права» — это специальный флаг в системе. Если у пользователя есть эта роль, платформа полностью отключает механизм RLS. Запросы к базе данных отправляются напрямую без добавления условий WHERE.
Ваша роль «Все разрешено» — она работает в рамках механизма RLS. Даже если в самой роли условий нет, платформа обязана проверить условия в других ролях (например, в роли Пользователь) и объединить их. Именно в момент этого объединения на уровне SQL-запроса происходит сбой, если структура прав в роли Пользователь неполная (отсутствуют флажки на критических правах).
Если вы не хотите вносить изменения в типовую роль Пользователь, можно рассмотреть следующие варианты:
Привилегированный. В этом случае проверка прав на время выполнения кода будет отключена.Подведем итог: если вы столкнулись с необъяснимым «Отказом в доступе» в УПП, проанализируйте роль Пользователь. Убедитесь, что для проблемного объекта в этой роли определены (даже через ГДЕ Ложь) все базовые права: Чтение, Добавление, Изменение. Это обеспечит корректную работу оптимизатора запросов 1С при суммировании ролей.