gifts2017

Групповая замена/добавление ограничений доступа RLS

Опубликовал Даниил Матвеев (cargobird) в раздел Администрирование - Защита, права, пароли

Предлагается способ групповой замены/добавления ограничений доступа RLS (Record Level Security, на уровне записей) через обработку XML-файлов конфигурации с наборами прав, как объектов, при помощи механизма ПостроительDOM.

Допустим, поставлена задача ограничения доступа к некоторым организациям с одним условием. Необходимо полное исчезновение организаций: чтобы их не было нигде, ни в договорах контрагентов, ни в кассах ККМ, ни в списках документов, ни в отчетах и т.д. и т.п.

Рассмотрим для примера УТ 10.3.

На первый взгляд ничего сложного. Создаем группу пользователей в справочнике "Группы пользователей", заполняем пользователями (неполноправными), которым надо ограничить доступ к организациям. Задаем доступные для просмотра организации в регистре сведений "Настройки прав доступа пользователей". Включаем константу "Ограничить права доступа на уровне записей". Что видит пользователь в программе после перезапуска. В справочнике "Организации" только те, что разрешены. Но там, где встречаются скрытые организации в поле "Организация" написано "Объект не найден...". Доступа к редактированию этих объектов нет, но не совсем то, что задумывалось.

ОбъектНеНайден

 

Это происходит от того, что в правах доступа к объектам (кроме справочника "Организации", контактной информации и еще некоторых объектов, не прописаны ограничения доступа на уровне записей. Особенно в нетиповых конфигурациях, когда новые роли и метаданные добавляются в конфигурацию в условиях, приближенных к боевым, без оглядки на будущее. И даже в типовой УТ 10.3, у роли МенеджерПоПродажам, например, нет ограничения доступа на уровне записей у корректировки реализации, в отличие от документа-основания - реализации товаров и услуг:

 ОграниченияПоОбъектам


Что есть на программном уровне

На программном уровне платформа 8.2 позволяет посмотреть, есть ли у выбранной роли право чтения/добавления/изменения/удаления выбранного метаданного, а также имеется ли у этого права ограничение доступа RLS, но самого значения ограничения доступа нет:

ЕстьПравоНаЧтение = Ложь;
ЕстьОграничениеРЛС = Ложь;
МетаданныеРоль = Метаданные.Роли["МенеджерПоПродажам"];
МетаданныеСправочника = Метаданные.Справочники["Организации"];
ПравоНаЧтение = ПараметрыДоступа("Read", МетаданныеСправочника, "Ссылка", МетаданныеРоль);		
Если ПравоНаЧтение.Доступность Тогда
	ЕстьПравоНаЧтение = Истина;
	Если ПравоНаЧтение.ОграничениеУсловием Тогда
		ЕстьОграничениеРЛС = Истина; 
	КонецЕсли;
КонецЕсли;

У большинства ролей уже написаны шаблоны ограничений доступа. Их можно посмотреть, открыв роль в конфигураторе и перейдя на вкладку "Шаблоны ограничений".

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

Попробуем автоматизировать.


Как все-таки можно посмотреть содержимое ограничений доступа RLS программно

Выгрузим файлы конфигурации. Конфигурация - Выгрузить файлы конфигурации.

Оставим флажки только на правах:

ВыгрузитьФайлыКонфигурации

Посмотрим XML-файл Роль.МенеджерПоПродажам.Права.xml.

Ветка прав доступа с ограничениями на документ "Заказ покупателя":

Права доступа к заказу покупателя

В конце файла находятся сами шаблоны ограничений для выбранной роли.

Шаблоны ограничений прав доступа


Как это обработать

Используем встроенный в конфигурацию механизм ПостроительDOM.

Прочитаем документ.

ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПолныйПутькФайлу);
	
ПостроительDOM = Новый ПостроительDOM;
ДокументDOM = ПостроительDOM.Прочитать(ЧтениеXML);

Затем, при помощи ОбходДереваDOM, обойдем дерево.

Для перехода вглубь используется метод СледующийУзел(), для перехода по родительским узлам (объекты, права) используется метод СледующийСоседний(), для возврата на родительский узел используется запоминание узла-родителя и переход на него в конце цикла установкой текущего узла.

Там, где содержится условие ограничения доступа, заменяем на нужное нам, если нет - добавляем.

ОбходДереваDOM = Новый ОбходДереваDOM(ДокументDOM);

// переход на уровень rights
ТекУзел = ОбходДереваDOM.СледующийУзел();
// переход на уровень object
ТекУзел = ОбходДереваDOM.СледующийУзел();

// ОБХОД ОБЪЕКТОВ
Пока ТекУзел <> Неопределено Цикл		
	// переход вглубь дерева на уровень name
	ТекУзел = ОбходДереваDOM.СледующийУзел();
	// переход на уровень right
	ТекУзел = ОбходДереваDOM.СледующийСоседний();
	// ОБХОД ПРАВ
	Пока ТекУзел <> Неопределено Цикл
		ОбработкаПрерыванияПользователя();
		УзелПрава = ОбходДереваDOM.ТекущийУзел;		
		
		// переход вглубь дерева на уровень name
		ТекУзел = ОбходДереваDOM.СледующийУзел();
		ЕстьОграничениеПоУсловию = Ложь;
		Пока ТекУзел <> Неопределено Цикл
			ОбработкаПрерыванияПользователя();
			Если ТекУзел.ИмяУзла = "restrictionByCondition" Тогда
				ЕстьОграничениеПоУсловию = Истина;
				// переход вглубь дерева на уровень condition
				ТекУзел = ОбходДереваDOM.СледующийУзел();					
				ТекУзел.ПервыйДочерний.ТекстовоеСодержимое = НовоеЗначениеОграничения;
				Сообщить(ИмяМетаданного + ": заменено ограничение " + ТекУзел.ПервыйДочерний.ТекстовоеСодержимое);
				ВнесеныИзменения = Истина;
				Прервать;
			КонецЕсли; 
			ТекУзел = ОбходДереваDOM.СледующийСоседний();
		КонецЦикла;
		Если НЕ ЕстьОграничениеПоУсловию Тогда
			// вставка условия
			НовыйУзелЗначения1 = ДокументDOM.СоздатьЭлемент("restrictionByCondition");
			НовыйУзелЗначения2 = ДокументDOM.СоздатьЭлемент("condition");
			НовыйУзелЗначения2.ТекстовоеСодержимое = НовоеЗначениеОграничения;
			НовыйУзелЗначения1.ДобавитьДочерний(НовыйУзелЗначения2);
			УзелПрава.ДобавитьДочерний(НовыйУзелЗначения1);
			Сообщить(ИмяМетаданного + ": добавлено ограничение " + УзелПрава.ПервыйДочерний.ТекстовоеСодержимое);
			ВнесеныИзменения = Истина;
		КонецЕсли;			
	        // возврат на уровень прав
		ОбходДереваDOM.ТекущийУзел = УзелПрава;
		ТекУзел = ОбходДереваDOM.СледующийСоседний();
	КонецЦикла;

	// возврат на уровень объекта
	ОбходДереваDOM.ТекущийУзел = УзелОбъекта;
	ТекУзел = ОбходДереваDOM.СледующийСоседний();
КонецЦикла;

Обработанный файл записываем.

ЧтениеXML.Закрыть();
	
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ИмяСохраняемогоФайла);
ЗаписьDOM = Новый ЗаписьDOM;
ЗаписьDOM.Записать(ДокументDOM, ЗаписьXML);
ЗаписьXML.Закрыть();

И последнее - загружаем измененные файлы обратно. Конфигурация - Загрузить файлы конфигурации.

Также оставим флажки только на правах.

 ЗагрузитьФайлыКонфигурации

Сохраняем измененную конфигурацию и готово.


Что умеет приложенная к статье обработка

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

- Позволяет пропустить конструкции запрета ГДЕ Ложь

- Позволяет добавлять ограничение роли, а не заменять при наличии уже существующего ограничения

 Настройка

- Отбирает для редактирования только те роли, которые имеют право изменять выбранные метаданные

- Позволяет дополнительно отобрать по сформированным спискам роли и метаданные

 Отборы по ролям

Отборы по объектам

- Позволяет указать текст ограничения доступа для четырех видов ограничений: чтение, изменение, добавление, удаление; для регистров сведений, накопления и т.д. будут применены только чтение и изменение

- Анализирует выгруженные файлы прав, изменяет в них отмеченные роли и метаданные. Измененные файлы обработка складывает в подпапку "_out" указанной папки с файлами.

Права доступа

- Позволяет копировать шаблоны ограничений доступа с одной роли на другую (вкладка Отборы, вкладка Роли, кнопка Копировать шаблоны ролей)

- В качестве материала для анализа формирует кросс-таблицу по ролям и метаданным с указанием доступа и наличием ограничений доступа по RLS по всем ролям и метаданным по отбору

 Таблица ролей

- Может использоваться в качестве учебного материала по обходу дерева метаданных и обработке xml-файлов через механизм ПостроительDOM

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

Скачать файлы

Наименование Файл Версия Размер
Замена/добавление ограничений RLS 24
.epf 23,10Kb
21.06.15
24
.epf 23,10Kb Скачать

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Василий Коровин (vasyak319) 26.04.15 23:36
Сам вряд ли воспользуюсь, но плюсану, ибо круто.
2. ффф ыыы (zqzq) 27.04.15 09:30
В конфигураторе же есть штатное средство "Все ограничения доступа", ровно для "Групповая замена/добавление ограничений доступа RLS".

Как я делал: Для одной роли прописал шаблон, допустим, МоиКонтрагенты(ИмяСсылки), далее проставил для нужных таблиц РЛС по шаблону, далее через "Все ограничения доступа" раскопировал шаблон и ограничения по другим ролям (даже если у роли нет права на чтение, РЛС всё равно добавлять можно).

PS Почитал, тут более продвинуто и автоматизировано. В плане отбора по реквизиту и объедининия ограничений.
3. Даниил Матвеев (cargobird) 27.04.15 10:36
(2) zqzq, спасибо за информацию, буду теперь знать и штатном средстве. Хотя да, для решаемой задачи нужен именно отбор по реквизиту со всеми связанными с ним ролями и метаданными.
4. Артур Аюханов (artbear) 29.04.15 14:00
Спасибоза разработку!
в работе над RLS очень много неавтоматизированной рутины. надеюсь, эта обработка часть рутины позволяет автоматизировать.
Посмотрю
ffgnebel; cargobird; +2 Ответить
5. Виктор Ким (victorkim64) 23.05.16 04:06
Молодчина, хороший хелп!
cargobird; +1 Ответить