Многие разработчики 1С сталкиваются с классической задачей: необходимо создать для пользователя ограниченные права доступа. Например, скопировать права существующего пользователя, но добавить к ним полный доступ к документам типа «Авансовый отчет», а также видимость подсистемы покупок и книг продаж/покупок. Разберем типичную ситуацию, когда база находится на поддержке, не редактируется, и разработчик решает пойти путем создания новой роли в расширении.
Ситуация выглядит так: вы создаете новую роль в расширении, переносите в нее необходимые документы, справочники и регистры, назначаете права. При запуске в режиме «Предприятие» роль отображается, вы назначаете ее пользователю. Пользователь видит нужные разделы, но при попытке открыть или создать документ система выдает ошибку: «Нет прав доступа». Проанализируем причину такого поведения и рассмотрим рабочие способы решения этой проблемы вместе.
В отличие от таких конфигураций, как «Управление торговлей», где роли разбиты очень гранулярно (под каждый документ или небольшой бизнес-процесс), в 1С:Бухгалтерия 3.0 (БП 3.0) роли носят более «монолитный» характер. Посмотрим на типовую архитектуру БП 3.0: здесь практически все права на ввод и редактирование данных объединены в одной большой роли — ДобавлениеИзменениеДанныхБухгалтерии.
Выясним, почему добавления только этой роли или создания узкой роли в расширении недостаточно. Авансовый отчет — это сложный документ. При его открытии система обращается к десяткам других объектов:
Если у пользователя нет прав (хотя бы на чтение и просмотр) хотя бы на один из связанных реквизитов, констант или справочников, к которым обращается код формы при открытии (например, в процедуре ПриСозданииНаСервере), платформа немедленно выдаст отказ в доступе.
Разберем первый и наиболее методически правильный подход. Зачастую создавать новую роль в расширении вообще не нужно. В конфигурации с вероятностью 90% уже есть готовые роли, покрывающие необходимый функционал.
Вместо создания роли выполним следующие шаги:
Важное замечание: после изменения ролей пользователя или перенастройки профиля необходимо зайти в информационную базу под полными административными правами и пересохранить карточку этого пользователя. Именно в момент записи карточки пользователя происходит применение прав и обновление служебных таблиц.
Если вы все же решили идти путем расширения и создали новую роль, проанализируем, как работает Библиотека стандартных подсистем (БСП). Система управления доступом в современных конфигурациях не опирается исключительно на метаданные платформы, она тесно связана со служебными справочниками.
Когда вы добавляете роль в расширение, БСП может ее «не увидеть» в пользовательском режиме, пока не обновлен справочник ИдентификаторыОбъектовМетаданных (и его подчиненный аналог для расширений). Без этого система прав просто не распознает вашу новую роль.
Рассмотрим, как это исправить:
/C ЗапуститьОбновлениеИнформационнойБазы.
Процедура ОбновитьИдентификаторы()
Справочники.ИдентификаторыОбъектовМетаданных.ОбновитьДанные();
Справочники.ИдентификаторыОбъектовРасширений.ОбновитьДанные();
КонецПроцедуры
Проанализируем еще одну частую причину ошибки. Если в вашей базе включено разделение учета, например, по организациям, то на многие документы наложено ограничение доступа на уровне записей (RLS).
Когда вы создаете новую роль с нуля в расширении и даете ей полные права на документ АвансовыйОтчет, но забываете прописать шаблоны ограничения доступа (RLS), платформа применяет безопасный подход: если правила RLS включены в целом для объекта, но не заданы в вашей роли, доступ будет запрещен по умолчанию.
Вам необходимо скопировать типовые шаблоны RLS из основной конфигурации для этого документа в вашу новую роль в расширении.
Если вы твердо решили довести до ума вашу узкую роль, приготовьтесь к кропотливой работе. Посмотрим по шагам, как вылавливать недостающие права:
Альтернативно, если код обращается к служебным регистрам, к которым пользователю не нужно иметь прямого доступа, вы можете обернуть эти вызовы в привилегированный модуль (или установить флаг привилегированного режима, если это фоновое задание/отдельная серверная процедура без контекста).
Поскольку выискивание всех связанных справочников для документа — занятие муторное и затратное по времени, опытные разработчики часто идут обратным путем.
Рассмотрим метод ограничения избыточных прав. Вместо создания изолированной роли, мы выдаем пользователю типовую «широкую» роль (например, ДобавлениеИзменениеДанныхБухгалтерии), чтобы он гарантированно мог открывать и записывать все необходимые справочники. Затем с помощью расширения мы «отсекаем» лишнее.
Мы создаем подписки на события или добавляем код в расширение, чтобы запретить открытие и запись всех документов, кроме Авансового отчета. Посмотрим на пример того, как можно ограничить запись других документов через подписку на событие ПередЗаписью:
Процедура Расш1_ПередЗаписьюДокумента(Источник, Отказ, РежимЗаписи, РежимПроведения)
// Проверяем, что это нужный нам пользователь (или профиль/группа)
Если РольДоступна("Расш1_ОграниченныйПользовательАвансовыхОтчетов") Тогда
// Если тип документа не Авансовый отчет, запрещаем запись
Если ТипЗнч(Источник) <> Тип("ДокументОбъект.АвансовыйОтчет") Тогда
Отказ = Истина;
Сообщить("У вас нет прав на редактирование этого типа документов!");
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Точно так же можно вмешаться в процедуру ПриСозданииНаСервере общих форм или форм документов, чтобы выдавать отказ при попытке просто открыть карточку чужого документа.
Такой подход работает намного надежнее и значительно экономит время, избавляя вас от необходимости выискивать сотни связанных объектов метаданных для выдачи точечных прав на чтение.