Собственный простейший производительный RLS. Начало. УНФ
Типовые RLS чрезмено усложнены. К тому же я являюсь сторонником того, что RLS нужны только для разграничения доступа на чтение. Для контроля записи существуют подписки.
Клиент на УНФ и я сним намучались с типовыми правами доступа. Назначаются они сложно, не так просто, как хотелось бы. К тому же, после обновления права разграничения на почту по непонятной причине перестали работать. Попытки проанализировать работу кода RLS провалились из-за сложности системы, которая превышала возможности бюджета клиента.
Было решено создать собственные, простые и гибкие права доступа, лишенные недостатков типовых. По некоторому размышлению я решил сделать их по производительной схеме — т.е. хранить в базе список доступных каждому пользователей объектов разграничения (организаций, контрагентов).
Попутно я раскрыл еще одну недокументированную возможность шаблонов RLS, которая существенно упрощает работу с RLS — вложенные шаблоны.
Итак, опишу простую (на мой взгляд) схему организации RLS.
У каждого объекта доступа в RLS на чтение прописываем шаблон следующего вида:
ГДЕ
#Объект("ЗаказПокупателя")
Т.е. просто указываем, о каком объекте идет речь, в данном случае речь об заказе покупателя.
Шаблон объект описывает условия доступа ко всем объектам конфигурации:
##Если "#Параметр(1)" = "ЗаказПокупателя" ##Тогда #Доступ("ЗаказПокупателя", "Организация", "Организации") И #Доступ("ЗаказПокупателя", "ГруппаДоступа", "ГруппыКонтрагентов") ##ИначеЕсли "#Параметр(1)" = "ЗаказПоставщика" ##Тогда #Доступ("ЗаказПоставщика", "Организация", "Организации") И #Доступ("ЗаказПокупателя", "ГруппаДоступа", "ГруппыКонтрагентов") ##КонецЕсли
Т.е. все условия RLS по объектам сосредоточены в одном месте, удобно корректировать и проверять логику работы программы.
Нужно еще отметить, что здесь широко используется вложенный запрос #Доступ, который по производительной схеме просто проверяет соответствие реквизита заранее сохраненному списку значений по объекту разграничения доступа (в примере — организация или группа доступа контрагента).
// 1 - ВидДокумента // 2 - ПолеДоступа // 3 - ВидОграниченияДоступа //Например: Доступ("ЗаказПокупателя", "Организация", "Организации") #Параметр(2) В ( ВЫБРАТЬ ЗначениеОбъектаДоступа ИЗ РегистрСведений.гпд_ДетальныеПрава КАК Т ГДЕ Т.Пользователь = &ТекущийПользователь И Т.ОбъектДоступа = &гпд_ОбъектДоступа_#Параметр(1) И Т.ОбъектРазграниченияДоступа = &гпд_ОбъектРазграниченияДоступа_#Параметр(3) )
Тут используются параметры сеанса и они должны быть заполнены.
Сама подсистема получается не очень большой:
На картинке видна схема производительного регистра прав доступа «Детальные права».
Информацию о вложенных запросах почерпнул на Мисте.
Как вы заметили, у данной схемы есть один недостаток — в шаблон Доступ передается вид объекта. Хотя вид и так доступен в запросе.
Я хотел использовать запрос RLS такого вида:
Т ГДЕ Т.Организация В (ВЫБРАТЬ Р.ЗначениеОбъектаДоступа ИЗ РегистрСведений.гпд_ДетальныеПрава КАК Р ГДЕ Р.Пользователь = &ТекущийПользователь И ВЫБОР КОГДА Т.Ссылка ССЫЛКА Документ.ЗаказПокупателя Тогда Р.СсылкаДоступа = ЗНАЧЕНИЕ(Документ.ЗаказПокупателя.ПустаяСсылка) КОГДА Т.Ссылка ССЫЛКА Документ.ЗаказПоставщику ТОГДА Р.СсылкаДоступа = ЗНАЧЕНИЕ(Документ.ЗаказПоставщику.ПустаяСсылка) ИНАЧЕ ИСТИНА КОНЕЦ И Р.ОбъектРазграниченияДоступа = &гпд_ОбъектРазграниченияДоступа_Организации)
Но так не работает, потому что 1С в конструкторе RLS запроса заранее знает, какой у ссылки объекта доступа тип и ругается на другой тип. К тому же это повлекло бы лишний код запроса (все эти проверки типа), а лишний код — лишнее время работы, так что я решил оставить первый параметр шаблона доступ в силе.
Дополнительно должны быть созданы параметры, на которые у пользователя должен быть доступ на чтение. Для нашего примера такие:
Я считаю такую простейшую систему RLS — системой прав здорового человека, а не системой прав курильщика, как у 1С.
Свежие комментарии