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