Доработки RLS. Примеры шаблонов. (в т.ч исключения из ограничений)

Допиливаем шаблоны RLS.

Даем доступ пользователям к некоторым объектам

1. Даем доступ к некоторым объектам или исключение из правил для RLS

2. Добавляем поиск показателя ограничения в регистрах. 

 Публикацию планирую наращивать,  если желаете получить пример реализации какого-нибудь механизма в шаблоне РЛС — пишите в коменты.

1. Исключения в RLS

RLS достаточно точный механизм, ограничивающий доступ к таблицам базы по определенным условиям. Хоть и подразумевается что пользователь имеющий доступ только к некоторым документам определенного, к примеру, подразделения, на практике бывает необходимость все же выборочно давать доступ к объектам, запрещенным настройкой RLS.

Для примера – доступ ограничен по Организации и Подразделению для менеджера по кадрам. В случае перемещения сотрудника из подразделение в подразделение необходимо чтобы документ перемещения и сотрудник были видны в обоих подразделениях. Ну и при увольнении сотрудника типовая конфигурация пытается получить доступ к документу приема, который является документом первого подразделения.

На этом примере и проиллюстрирую не сложный механизм исключений из правил для RLS.

Исходные данные:

Шаблон ограничений для объектов где показатели для ограничения находятся в шапке документа:

ТекущаяТаблица
ИЗ
#ТекущаяТаблица КАК ТекущаяТаблица
ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ РАЗЛИЧНЫЕ
СоставГруппы.Ссылка КАК ГруппаПользователей
ИЗ
Справочник.ГруппыПользователей.ПользователиГруппы КАК СоставГруппы
ГДЕ
СоставГруппы.Пользователь = &ТекущийПользователь) КАК ГруппыПользователей
ПО (ИСТИНА)
ГДЕ
НЕ ГруппыПользователей.ГруппаПользователей ЕСТЬ NULL
И
(НЕ 1 В
(ВЫБРАТЬ ПЕРВЫЕ 1
1
ИЗ
РегистрСведений.НазначениеВидовОбъектовДоступа КАК НазначениеВидовОбъектовДоступа
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиПравДоступаПользователей КАК НастройкиПравДоступаПользователей
ПО
НастройкиПравДоступаПользователей.ОбъектДоступа = ВЫБОР
КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.ПодразделенияОрганизаций)
ТОГДА
ВЫБОР КОГДА ТипЗначения(ТекущаяТаблица.#Параметр(2)) = ТипЗначения(NULL)
ТОГДА НастройкиПравДоступаПользователей.ОбъектДоступа
ИНАЧЕ
ТекущаяТаблица.#Параметр(2)
КОНЕЦ
КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации)
ТОГДА ТекущаяТаблица.#Параметр(1)
КОНЕЦ
И НастройкиПравДоступаПользователей.ВидОбъектаДоступа = НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа
И
НастройкиПравДоступаПользователей.ОбластьДанных =
ЗНАЧЕНИЕ(Перечисление.ОбластиДанныхОбъектовДоступа.ПустаяСсылка)
И НастройкиПравДоступаПользователей.Пользователь = ГруппыПользователей.ГруппаПользователей
ГДЕ
НазначениеВидовОбъектовДоступа.ГруппаПользователей = ГруппыПользователей.ГруппаПользователей
И НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа В (
ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.ПустаяСсылка)
, ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.ПодразделенияОрганизаций)
, ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации)
)
И НастройкиПравДоступаПользователей.ОбъектДоступа ЕСТЬ NULL
))

Шаблон ограничений для объектов где Организация в шапке, Подразделение в табличной части:

ТекущаяТаблица
ИЗ
#ТекущаяТаблица КАК ТекущаяТаблица
ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ РАЗЛИЧНЫЕ
СоставГруппы.Ссылка КАК ГруппаПользователей
ИЗ
Справочник.ГруппыПользователей.ПользователиГруппы КАК СоставГруппы
ГДЕ
СоставГруппы.Пользователь = &ТекущийПользователь) КАК ГруппыПользователей
ПО (ИСТИНА)
ГДЕ
НЕ ГруппыПользователей.ГруппаПользователей ЕСТЬ NULL
И
(НЕ 1 В
(ВЫБРАТЬ ПЕРВЫЕ 1
1
ИЗ
РегистрСведений.НазначениеВидовОбъектовДоступа КАК НазначениеВидовОбъектовДоступа
ГДЕ
НазначениеВидовОбъектовДоступа.ГруппаПользователей = ГруппыПользователей.ГруппаПользователей
И ВЫБОР
КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации)
ТОГДА ВЫБОР
КОГДА 1 В
(ВЫБРАТЬ ПЕРВЫЕ 1
1
ИЗ
(ВЫБРАТЬ
1 КАК Поле
) КАК Оптимизация ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиПравДоступаПользователей КАК НастройкиПравДоступаПользователей
ПО
НастройкиПравДоступаПользователей.ОбъектДоступа = ТекущаяТаблица.Организация
И НастройкиПравДоступаПользователей.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации)
И НастройкиПравДоступаПользователей.ОбластьДанных = ЗНАЧЕНИЕ(Перечисление.ОбластиДанныхОбъектовДоступа.ПустаяСсылка)
И НастройкиПравДоступаПользователей.Пользователь = НазначениеВидовОбъектовДоступа.ГруппаПользователей)
ТОГДА ИСТИНА
ИНАЧЕ ЛОЖЬ
КОНЕЦ

КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.ПодразделенияОрганизаций)
ТОГДА ВЫБОР
КОГДА (НЕ 1 В
(ВЫБРАТЬ ПЕРВЫЕ 1
1
ИЗ
Документ.#Параметр(1) КАК ТабличнаяЧастьДокумента ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ПодразделенияОрганизаций КАК ПодразделенияОрганизации
ПО
ПодразделенияОрганизации.Ссылка = ТабличнаяЧастьДокумента.#Параметр(2) ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиПравДоступаПользователей КАК НастройкиПравДоступаПользователей
ПО
НастройкиПравДоступаПользователей.ОбъектДоступа = ПодразделенияОрганизации.Ссылка
И НастройкиПравДоступаПользователей.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.ПодразделенияОрганизаций)
И НастройкиПравДоступаПользователей.ОбластьДанных = ЗНАЧЕНИЕ(Перечисление.ОбластиДанныхОбъектовДоступа.ПустаяСсылка)
И НастройкиПравДоступаПользователей.Пользователь = НазначениеВидовОбъектовДоступа.ГруппаПользователей
ГДЕ
ТабличнаяЧастьДокумента.Ссылка = ТекущаяТаблица.Ссылка
И НастройкиПравДоступаПользователей.ОбластьДанных ЕСТЬ NULL ))
ТОГДА ИСТИНА
ИНАЧЕ ЛОЖЬ
КОНЕЦ
ИНАЧЕ ИСТИНА
КОНЕЦ = ЛОЖЬ))
И НЕ ГруппыПользователей.ГруппаПользователей ЕСТЬ NULL

Итак. Начнем с создания регистра сведений ДОП_ИсключенияПравДоступа. В нем мы будем хранить объекты к которым необходимо дать доступ и показатель – по которому необходимо дать доступ. Допустим для подразделения «Основное» следует дать доступ к документу «Прием на работу в организацию №000000001» который относится к другому подразделению. Создадим соответственно 2 измерения – ОбъектДоступа и ПоказательДоступа.

Следующим шагом следует обеспечить заполнение нашего регистра. В случае, приведенном в качестве примера, нас интерисует документ КадровоеПеремещение. Создадим подписку на событие, по событию ОбработкаПроведения и в новом общем модуле опишем движения по нашему регистру:

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

Все, подготовительный этап окончен. Данные о объектах к которым необходимо дать доступ и о подразделениях, которым необходимо дать доступ к этим объектам попадают в регистр. Осталось немного поправить шаблоны ограничений добавив несколько строк.

Для шаблона с показателями в шапке:

ТекущаяТаблица
ИЗ
#ТекущаяТаблица КАК ТекущаяТаблица
ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ РАЗЛИЧНЫЕ
СоставГруппы.Ссылка КАК ГруппаПользователей
ИЗ
Справочник.ГруппыПользователей.ПользователиГруппы КАК СоставГруппы
ГДЕ
СоставГруппы.Пользователь = &ТекущийПользователь) КАК ГруппыПользователей
ПО (ИСТИНА)
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДОП_ИсключенияПравДоступа КАК ОбъектыДоступа
ПО ТекущаяТаблица.Ссылка = ОбъектыДоступа.ОбъектДоступа
ГДЕ
НЕ ГруппыПользователей.ГруппаПользователей ЕСТЬ NULL
И
(НЕ 1 В
(ВЫБРАТЬ ПЕРВЫЕ 1
1
ИЗ
РегистрСведений.НазначениеВидовОбъектовДоступа КАК НазначениеВидовОбъектовДоступа
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиПравДоступаПользователей КАК НастройкиПравДоступаПользователей
ПО
(НастройкиПравДоступаПользователей.ОбъектДоступа = ВЫБОР
КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.ПодразделенияОрганизаций)
ТОГДА
ВЫБОР КОГДА ТипЗначения(ТекущаяТаблица.#Параметр(2)) = ТипЗначения(NULL)
ТОГДА НастройкиПравДоступаПользователей.ОбъектДоступа
ИНАЧЕ
ТекущаяТаблица.#Параметр(2)
КОНЕЦ
КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации)
ТОГДА ТекущаяТаблица.#Параметр(1)
КОНЕЦ
ИЛИ НастройкиПравДоступаПользователей.ОбъектДоступа = ВЫБОР
КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.ПодразделенияОрганизаций)
ТОГДА
ВЫБОР КОГДА ТипЗначения(ТекущаяТаблица.#Параметр(2)) = ТипЗначения(NULL)
ТОГДА НастройкиПравДоступаПользователей.ОбъектДоступа
ИНАЧЕ
ОбъектыДоступа.ПоказательДоступа
КОНЕЦ
КОНЕЦ
)
И НастройкиПравДоступаПользователей.ВидОбъектаДоступа = НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа
И
НастройкиПравДоступаПользователей.ОбластьДанных =
ЗНАЧЕНИЕ(Перечисление.ОбластиДанныхОбъектовДоступа.ПустаяСсылка)
И НастройкиПравДоступаПользователей.Пользователь = ГруппыПользователей.ГруппаПользователей
ГДЕ
НазначениеВидовОбъектовДоступа.ГруппаПользователей = ГруппыПользователей.ГруппаПользователей
И НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа В (
ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.ПустаяСсылка)
, ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.ПодразделенияОрганизаций)
, ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации)
)
И НастройкиПравДоступаПользователей.ОбъектДоступа ЕСТЬ NULL
))

И для шаблона ограничений с Организацией в шапке и подразделением в табличной части:

ТекущаяТаблица
ИЗ
#ТекущаяТаблица КАК ТекущаяТаблица
ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ РАЗЛИЧНЫЕ
СоставГруппы.Ссылка КАК ГруппаПользователей
ИЗ
Справочник.ГруппыПользователей.ПользователиГруппы КАК СоставГруппы
ГДЕ
СоставГруппы.Пользователь = &ТекущийПользователь) КАК ГруппыПользователей
ПО (ИСТИНА)
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДОП_ИсключенияПравДоступа Как ОбъектыДоступа
ПО ТекущаяТаблица.Ссылка = ОбъектыДоступа.ОбъектДоступа
ГДЕ
НЕ ГруппыПользователей.ГруппаПользователей ЕСТЬ NULL
И
(НЕ 1 В
(ВЫБРАТЬ ПЕРВЫЕ 1
1
ИЗ
РегистрСведений.НазначениеВидовОбъектовДоступа КАК НазначениеВидовОбъектовДоступа
ГДЕ
НазначениеВидовОбъектовДоступа.ГруппаПользователей = ГруппыПользователей.ГруппаПользователей
И ВЫБОР
КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации)
ТОГДА ВЫБОР
КОГДА 1 В
(ВЫБРАТЬ ПЕРВЫЕ 1
1
ИЗ
(ВЫБРАТЬ
1 КАК Поле
) КАК Оптимизация ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиПравДоступаПользователей КАК НастройкиПравДоступаПользователей
ПО
НастройкиПравДоступаПользователей.ОбъектДоступа = ТекущаяТаблица.Организация
И НастройкиПравДоступаПользователей.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации)
И НастройкиПравДоступаПользователей.ОбластьДанных = ЗНАЧЕНИЕ(Перечисление.ОбластиДанныхОбъектовДоступа.ПустаяСсылка)
И НастройкиПравДоступаПользователей.Пользователь = НазначениеВидовОбъектовДоступа.ГруппаПользователей)
ТОГДА ИСТИНА
ИНАЧЕ ЛОЖЬ
КОНЕЦ
КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.ПодразделенияОрганизаций)
ТОГДА ВЫБОР
КОГДА (НЕ 1 В
(ВЫБРАТЬ ПЕРВЫЕ 1
1
ИЗ
Документ.#Параметр(1) КАК ТабличнаяЧастьДокумента ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ПодразделенияОрганизаций КАК ПодразделенияОрганизации
ПО
ПодразделенияОрганизации.Ссылка = ТабличнаяЧастьДокумента.#Параметр(2) ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиПравДоступаПользователей КАК НастройкиПравДоступаПользователей
ПО
(НастройкиПравДоступаПользователей.ОбъектДоступа = ПодразделенияОрганизации.Ссылка
ИЛИ НастройкиПравДоступаПользователей.ОбъектДоступа = ОбъектыДоступа.ПоказательДоступа)
И НастройкиПравДоступаПользователей.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.ПодразделенияОрганизаций)
И НастройкиПравДоступаПользователей.ОбластьДанных = ЗНАЧЕНИЕ(Перечисление.ОбластиДанныхОбъектовДоступа.ПустаяСсылка)
И НастройкиПравДоступаПользователей.Пользователь = НазначениеВидовОбъектовДоступа.ГруппаПользователей
ГДЕ
ТабличнаяЧастьДокумента.Ссылка = ТекущаяТаблица.Ссылка
И НастройкиПравДоступаПользователей.ОбластьДанных ЕСТЬ NULL ))
ТОГДА ИСТИНА
ИНАЧЕ ЛОЖЬ
КОНЕЦ
ИНАЧЕ ИСТИНА
КОНЕЦ = ЛОЖЬ))
И НЕ ГруппыПользователей.ГруппаПользователей ЕСТЬ NULL

Вот и все. Осталось только указать параметры для шаблона для документов. Это наименования реквизитов, содержащих организацию и подразделение (знаю что это можно было убрать – зато иллюстрирует работу с параметрами) для шаблона для объектов с организацией и подразделением в табличной части и наименование документа + наименование табличной части и наименование реквизита, содержащего подразделение.

2. Поиск показателя ограничения в регистрах

Продолжим. Во многих кадровых и расчетных документах явно не указывается подразделение организации. Зато есть сотрудник, нам этого вполне хватит, чтобы найти его подразделение. 

Для начала разберем конструкцию:

ЛЕВОЕ СОЕДИНЕНИЕ
(ВЫБРАТЬ
СрезПоследних.Период КАК Период,
СрезПоследних.Сотрудник КАК Сотрудник,
Регистр.Регистратор КАК Регистратор,
Регистр.ПодразделениеОрганизации КАК ПодразделениеОрганизации
ИЗ
(ВЫБРАТЬ
РаботникиОрганизаций.Сотрудник КАК Сотрудник,
МАКСИМУМ(РаботникиОрганизаций.Период) КАК Период
ИЗ
РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций

СГРУППИРОВАТЬ ПО
РаботникиОрганизаций.Сотрудник) КАК СрезПоследних
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций КАК Регистр
ПО СрезПоследних.Период = Регистр.Период
И СрезПоследних.Сотрудник = Регистр.Сотрудник)ПодразделениеСотрудника
ПО ТекущаяТаблица.#Параметр(2) = ПодразделениеСотрудника.Сотрудник

Так как в RLS нельзя использовать виртуальные таблицы — нам придется ее сделать самостоятельно, что мы выше и сделали.

То есть мы получили подразделение по сотруднику из РС Работники организации. Осталось только внедрить этот кусочек в наши шаблоны RLS. Сотрудники обычно находятся в табличной части документа. В этот шаблон мы и добавим наш новый кусочек

ТекущаяТаблица

ИЗ

#ТекущаяТаблица КАК ТекущаяТаблица

ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ РАЗЛИЧНЫЕ

СоставГруппы.Ссылка КАК ГруппаПользователей

ИЗ

Справочник.ГруппыПользователей.ПользователиГруппы КАК СоставГруппы

ГДЕ

СоставГруппы.Пользователь = &ТекущийПользователь) КАК ГруппыПользователей

ПО (ИСТИНА)

ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДОП_ИсключенияПравДоступа Как ОбъектыДоступа

ПО ТекущаяТаблица.Ссылка = ОбъектыДоступа.ОбъектДоступа

ГДЕ

НЕ ГруппыПользователей.ГруппаПользователей ЕСТЬ NULL

И

(НЕ 1 В

(ВЫБРАТЬ ПЕРВЫЕ 1

1

ИЗ

РегистрСведений.НазначениеВидовОбъектовДоступа КАК НазначениеВидовОбъектовДоступа
ГДЕ

НазначениеВидовОбъектовДоступа.ГруппаПользователей = ГруппыПользователей.ГруппаПользователей

И ВЫБОР

КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации)

ТОГДА ВЫБОР

КОГДА 1 В

(ВЫБРАТЬ ПЕРВЫЕ 1

1

ИЗ

(ВЫБРАТЬ

1 КАК Поле

) КАК Оптимизация ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиПравДоступаПользователей КАК НастройкиПравДоступаПользователей

ПО

НастройкиПравДоступаПользователей.ОбъектДоступа = ТекущаяТаблица.Организация

И НастройкиПравДоступаПользователей.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации)

И НастройкиПравДоступаПользователей.ОбластьДанных = ЗНАЧЕНИЕ(Перечисление.ОбластиДанныхОбъектовДоступа.ПустаяСсылка)

И НастройкиПравДоступаПользователей.Пользователь = НазначениеВидовОбъектовДоступа.ГруппаПользователей)

ТОГДА ИСТИНА

ИНАЧЕ ЛОЖЬ

КОНЕЦ

КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.ПодразделенияОрганизаций)

ТОГДА ВЫБОР

КОГДА (НЕ 1 В

(ВЫБРАТЬ ПЕРВЫЕ 1

1

ИЗ

Документ.#Параметр(1) КАК ТабличнаяЧастьДокумента

ЛЕВОЕ СОЕДИНЕНИЕ
(ВЫБРАТЬ
СрезПоследних.Период КАК Период,
СрезПоследних.Сотрудник КАК Сотрудник,
Регистр.Регистратор КАК Регистратор,
Регистр.ПодразделениеОрганизации КАК ПодразделениеОрганизации
ИЗ
(ВЫБРАТЬ
РаботникиОрганизаций.Сотрудник КАК Сотрудник,
МАКСИМУМ(РаботникиОрганизаций.Период) КАК Период
ИЗ
РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций

СГРУППИРОВАТЬ ПО
РаботникиОрганизаций.Сотрудник) КАК СрезПоследних
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций КАК Регистр
ПО СрезПоследних.Период = Регистр.Период
И СрезПоследних.Сотрудник = Регистр.Сотрудник)ПодразделениеСотрудника
ПО ТабличнаяЧастьДокумента.#Параметр(2) = ПодразделениеСотрудника.Сотрудник

ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ПодразделенияОрганизаций КАК ПодразделенияОрганизации

ПО

ПодразделенияОрганизации.Ссылка = ПодразделениеСотрудника.ПодразделениеОрганизации ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиПравДоступаПользователей КАК НастройкиПравДоступаПользователей

ПО

(НастройкиПравДоступаПользователей.ОбъектДоступа = ПодразделенияОрганизации.Ссылка

ИЛИ НастройкиПравДоступаПользователей.ОбъектДоступа = ОбъектыДоступа.ПоказательДоступа)

И НастройкиПравДоступаПользователей.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.ПодразделенияОрганизаций)

И НастройкиПравДоступаПользователей.ОбластьДанных = ЗНАЧЕНИЕ(Перечисление.ОбластиДанныхОбъектовДоступа.ПустаяСсылка)

И НастройкиПравДоступаПользователей.Пользователь = НазначениеВидовОбъектовДоступа.ГруппаПользователей

ГДЕ

ТабличнаяЧастьДокумента.Ссылка = ТекущаяТаблица.Ссылка

И НастройкиПравДоступаПользователей.ОбластьДанных ЕСТЬ NULL ))

ТОГДА ИСТИНА

ИНАЧЕ ЛОЖЬ

КОНЕЦ

ИНАЧЕ ИСТИНА

КОНЕЦ = ЛОЖЬ))

И НЕ ГруппыПользователей.ГруппаПользователей ЕСТЬ NULL

 В результате мы видем объекты с сотрудниками только своего подразделения. Надеюсь этот материал поможет разобраться с RLS и не отказываться от него из-за его якобы «сложности»

Пишите коменты,  если что не ясно – растолкую. Так же принимаю критику =) Всем приятного чтения!

Подготовленно совместно с VasiL` //infostart.ru/community/profile/102806/

38 Comments

  1. anig99

    В чем ноу-хау? Всё это есть в типовых.

    Reply
  2. crs

    В типовых нельзя сделать исключение RLS. Если запретил организацию, пользователь ни при каких условиях ни ее, ни связанные объекты видеть не будет

    Reply
  3. EvilDoc

    Собственно, уже ответили =) Вот интересно ранее кто-то сталкивался с подобной задачей и как ее реализовывал?

    Reply
  4. petrov_al

    Интересна сама по себе идея использования дополнительных регистров для исключений. А как кстати при обновлении для RLS шаблонов, можно применить приоритеты?

    Reply
  5. anig99

    (2) А. Увидел. Вообще ещё есть вариант не давать доступ к объекту, но дать доступ к ссылке и некоторым реквизитам.

    Reply
  6. kapustinag

    Проверяли работу этого механизма на РЕАЛЬНО большой базе, с достаточно большим количеством одновременно работающих пользователей? Не тормозит?

    Если у пользователя постепенно накапливается много исключений, к которым он должен получить доступ, то, мне кажется, будет притормаживать.

    Reply
  7. EvilDoc

    (5) В первый раз слышу. Был бы счастлив узнать о подобном механизме — то есть давать доступ к уникальной ссылке и к определенным реквизитам в обход RLS типовыми или более простыми, нежели мной предложенный, способами =) Буду рад любой информации.

    (6) РЛС работает чуточку быстрее прочих систем контроля доступа, представленные, к примеру, здесь http://kb.mista.ru/article.php?id=134.

    А что касается именно исключений из РЛС, да, в каждый запрос добавляется ни чуть не изящное исключение.

    Мое имхо — может тормозить и скорее всего будет в случае большого количества (больше 10к) у каждой группы пользователей… На реально большой базе. Может быть для этих случаев есть смысл не использовать РЛС впринципе или допустим только по организации — зависит от задачи. МБ распределенка решит, но локально с озвученой проблемой идея справляется. Для каждого конкретного случая нужны свои идеи =) Тут я привел реализацию определенной задачи, которая, думаю, поможет многим с подобными проблемами. Я как бы хотел донести суть а не полную реализацию. Хотя получилось что полная реализация присутствует =)) И вот мне интересно кому эта «суть» помогла и кто нашел другие решения, особенно более «изящные».

    з..ы. Жду критики — как сделать лучше — это в радость. Ну и кому помогло — тоже в радость =)) Не за что =)))

    Reply
  8. CagoBHuK

    РЛС нет смысла использовать на больших базах. Это сводит полезность Record-Livel Security к нулю.

    Reply
  9. EvilDoc

    (8) CagoBHuK, А разве есть более быстрые альтернативы? Для ограничения доступа RLS наиболее шустрый. Из других вариантов разве что распределенка.

    Reply
  10. a-novoselov

    А не проще и менее затратно было бы просто добавить в шаблон связь по «ИЛИ» со вторым реквизитом (то же имя реквизита из параметра) и поменять шаблон для нужных документов? А если системе необходимо «посмотреть» недоступный документ, например, в обработке проведения другого документа, то выполнять обработку в привелегированном режиме?

    Reply
  11. EvilDoc

    В контексте озвученой задачи речь идет о интерактивной работе с запрещенным объектом. В частности просмотр. Ибо менеджер по кадпам должен видеть сам факт перемещения. Чтобы избежать ситуации с неизвестно куда пропавшими сотрудниками =)

    Reply
  12. dyak84

    Да автору безусловное спасибо есть что почитать есть над чем поразмыслить.Так держать Спасибо.

    Reply
  13. EvilDoc

    Да автор вообще красава)

    Reply
  14. 20tanush

    EvilDoc, есть необходимость доработать шаблон ограничения, когда исключением является дата документа. Вот в этой темке описываю задачу: http://forum.infostart.ru/forum42/topic135726/message1401591/?result=reply#message1401591

    Можете помочь советом?

    Reply
  15. EvilDoc

    (14) 20tanush, Отписался

    Reply
  16. NatalyaVP

    По пункту 2. Какие значения в параметрах? Параметр 1 — это сотрудник? Параметр 2 — это подразделение?

    Я сделала шаблон, в ограничении права на чтение что писать? шаблон(«»,»»), а реквизиты как написать. Вот, например, документ «Командировки организаций», табличная часть, в ней сотрудник, в нём подразделение.

    шаблон(«командировкиОрганизаций.Работники.Сотрудник»,»командировкиОрганизаций.Работники.Сотрудник.подразделение»). Так?

    Заранее спасибо за ответ.

    Reply
  17. EvilDoc

    Параметр1 — имя табличной части, Параметр 2 — реквизит в котором хранится сотрудник в данной ТЧ.

    Пример из УПП — #Шаблон(«Работники»,»Сотрудник»)

    Reply
  18. EvilDoc

    (16) NatalyaVP, #Шаблон(«Работники»,»Сотрудник»)

    Reply
  19. Orangeman

    Добрый день . Коллеги подскажите вот если стоит ограничение вида

    #ПоЗначениям(«Документ.ВнутреннееПеремещениеБСО», «Чтение», «»,

    «Организации», «Организация»,

    «ИсточникиФинансовогоОбеспечения»,»ИФО»,

    «Подразделения»,»ПодразделениеОтправитель»,

    «»,»»,

    «»,»»,»»,»»,»»,»»,»»,»»,

    «»,»»,»»,»»,»»,»»,»»,»»,

    «»,»»,»»,»»,»»,»»,»»,»»

    )

    И ситуация похожа хочу так же чтобы были доступны документы в которых ПодразделениеПолучатель соответствует моему(по которому ограничиваю запись). Создал так же регистр сведений в него пишу при записи документа, сам документ регистратор и подразделения . Как мне в данном ограничении # ПоЗначениям приудить условие ИЛИ мол выводи те документы которые в регистре с моим подразделением и те которые тут по ПодразделениюОтправителю, Я не совсем понимаю где в настройках пользователя или может еще где хранится информация по Подразделению ему доступному с чем как бы сравнит Подразделение в документе Конфа типовая БГУ 2.0

    Reply
  20. Orangeman

    Как то коряво написал ,ну суть такая хочу выводить пользователю документы в которых ему доступно Подразделение отправитель плюс к ним документы из регистра сведений по некому отбору вот как можно записать условие

    Reply
  21. kote

    .. не ошибка, но оплошность:

    ТОГДА
    
    ВЫБОР КОГДА ТипЗначения(ТекущаяТаблица.#Параметр(2)) = ТипЗначения(NULL)
    
    ТОГДА НастройкиПравДоступаПользователей.ОбъектДоступа
    
    ИНАЧЕ
    

    Показать

    Вот это

     ТипЗначения(ТекущаяТаблица.#Параметр(2)) = ТипЗначения(NULL)

    будет работать в 5-8 раз медленнее, чем

     (ТекущаяТаблица.#Параметр(2)) ЕСТЬ NULL 

    . Для RLS особенно актуально.

    Никогда так не делайте!

    Reply
  22. EvilDoc

    (21) kote, разработчикам РЛС для УПП уже поздновато сообщать о их оплошности)

    Reply
  23. ДмитрийС

    Кто-нибудь знает как правильно настраивать РЛС по табличным частям? В топике конечно указано (через связь по ссылке ТЧ и ТекущейТаблицей), но объясню свой вопрос:

    Я настраиваю запрет доступа по выбранным подразделениям. Т.е. если у пользователя стоит запрет на определенное подразделение (именно в использовании в конкретном документе, а не вообще), то он не должен ни ввести новый, ни исправить старый документ, если в нем было (будет) хоть в одной строке указано запретное подразделение.

    При указанном способе происходит проверка не ТекущейТаблицы, а именно ССЫЛКИ на табличную часть. Если происходит ввод нового документа, то временная ссылка уже существует и РЛС отработает правильно. А вот при изменении существующего документа ограничения РЛС встраиваются в запрос на изменение (Update) к субд (мониторю профайлером). Т.е. изменения ссылки не происходит.

    Получается, что пользователю запрещено отредактировать существующий документ с запрещенным подразделением (это хорошо). НО! Разрешается в существующем документе с разрешенными подразделениями поменять подразделение на запрещенное и провести. И в этом случае РЛС будет молчать.

    Reply
  24. EvilDoc

    Если вы не хотите ограничивать сам справочник Подразделения, то средствами РЛС вы это не решите.

    Reply
  25. ДмитрийС

    (24) Я отлично это решаю, если реквизит шапки, а не ТЧ.

    Reply
  26. ДмитрийС

    (25) Может я просто как то не так настраиваю рлс по ТЧ(

    Reply
  27. EvilDoc

    хм.. возможно шаблон указан только на чтение, а на запись нет? Сложно предположить. И да — должно дать выбрать ваше подразделение — но не должно позволить записать такой документ

    Reply
  28. EvilDoc

    По поводу не правильно — у меня тут прям цветом было красиво выделено — что куда вставлял — но потом разработчики сийта изменили оформление и все пропало.. Стало ненаглядно и запутанно.

    Reply
  29. ДмитрийС

    (27) На чтение у меня свободный доступ. Шаблон ограничения стоит на добавление и изменение документа, причем одинаковый.

    Да, подразделение можно менять как угодно, а вот записать с запрещенным нельзя.

    (28) Не совсем понял о чем вы? Или это у обсуждаемой теме не относится?

    Reply
  30. EvilDoc

    (29) давайте попробую взглянуть на ваш шаблон

    Reply
  31. ДмитрийС

    мое ограничение выглядит так:

    ГДЕ
    НЕ 1 В      (ВЫБРАТЬ ПЕРВЫЕ 1      1      ИЗ      Документ.ПлатежноеПоручениеИсходящее.РасшифровкаПлатежа КАК ТабличнаяЧастьДокумента ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ПраваДоступаПользователейКОбъектам КАК ПраваДоступаПользователейКОбъектам
    ПО      ПраваДоступаПользователейКОбъектам.ОбъектДоступа = ТабличнаяЧастьДокумента.ЦентрЗатрат
    И ПраваДоступаПользователейКОбъектам.ОбластьДанных = ЗНАЧЕНИЕ(Перечисление.ОбластиДанныхОграниченияПравДоступа.ПодразделенияПлатежныеДокументыЗапрет)
    И ПраваДоступаПользователейКОбъектам.Пользователь В (&ГруппыТекущегоПользователя)
    И ПраваДоступаПользователейКОбъектам.Изменение
    ГДЕ      ТекущаяТаблица.Ссылка = ТабличнаяЧастьДокумента.Ссылка)
    Reply
  32. EvilDoc

    Вроде все верно. В консоли запросов отрабатывает верно?

    Reply
  33. ДмитрийС

    Конечно))

    Он даже отрабатывает, когда пользователь хочет запрещенное подразделение поменять на разрешенное и провести или просто перепровести документ. Тут 1С пишет про недостаточность прав. А вот когда в документе разрешенное подразделение меняется на запрещенное, то молчит.

    Reply
  34. timujeen

    Решал аналогичную задачу но в качестве носителя информации для ограничения использовал Параметры пользователя.

    Для регистров например запрос выглядет так:

    ТекущаяТаблица ИЗ #ТекущаяТаблица КАК ТекущаяТаблица
    ГДЕ
    (ТекущаяТаблица.Сотрудник В(&СписокДоступныхСотрудников   )  )

    Есть проблема в предоставлении пользоваетлю права для записи пустого документа, так как у меня не запрещенные подразделения, а наоборот разрешенные. Пытался использовать:

    НЕ ТабличнаяЧастьДокумента.НомерСтроки В(1)

    — проверку на наличия первой строки в документе, но не помогло.

    Reply
  35. pavel_pss

    Все конечно интересно, но ты пишешь (Вот и все. Осталось только указать параметры для шаблона для документов)

    Вопрос а где ин нужно указывать то ??????

    Я сам как раз из тех для кого пока это сложно.

    Reply
  36. pavel_pss

    И плиз можете подсказать какую нить книжку или сайт, по рлс

    Reply
  37. batia777

    Всем привет. Подскажите пожалуйста, если стоит ограничение RLS на справочники Сотрудники и ПодразделенияОрганизаций в ЗУП 2.1 Укр в документе Кадровое перемещение происходит тупиковая ситуация: Кадровик откуда переводится сотрудник может выбрать своего сотрудника, но не может выбрать Подразделения Куда. Обойти как-то средствами RLS это можно?

    Reply
  38. EvilDoc

    (37) У кадровика должны быть права на подразделение — куда переводится сотрудник. Иначе система просто не даст провести документ (а не только выбрать подразделение). Но полагаю у вас у этого кадровика нет права на сотрудника. Возможно переводом должен заниматься некий «старший» кадровик, имеющий доступ ко всем подразделениям.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *