Проверка доступности прав на уровне RLS на запись объекта
Доброго времени суток.
подскажите есть ли штатный (или может какие-то наработки) механизм проверки прав доступа на уровне RLS на запись объекта ?
на Справочник ХХХ назначены RLS на запись, перед определённой обработкой необходимо проверить объект на доступность прав по RLS, если нет то прервать обработку, если есть то создать несколько объектов и изменить значение в проверяемом объекте.
подскажите есть ли штатный (или может какие-то наработки) механизм проверки прав доступа на уровне RLS на запись объекта ?
на Справочник ХХХ назначены RLS на запись, перед определённой обработкой необходимо проверить объект на доступность прав по RLS, если нет то прервать обработку, если есть то создать несколько объектов и изменить значение в проверяемом объекте.
По теме из базы знаний
- Конфигурация Flowcon: Набор инструментов для управления задачами, проектами и бизнесом в 1С
- Подсистема БСП «Управление доступом», основные объекты и регистры
- Назад в прошлое! Небольшие заметки по администрированию пользователей в УПП
- Управление сборкой. Расширение для конфигурации СППР
- Внутренний механизм работы шаблонов ролей в производительном методе RLS
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
(6)
да, сейчас на подобном варианте остановился, не совсем конечно то что надо - ибо есть реквизиты (редактор, дата изменения) которые изменяются подпиской, если Объект.Записать() то эти реквизиты перезаполнятся, а на 2м этапе пользователь переобуется (отменит ввод) - получится зазря первоначальный элемент записывали...
да, сейчас на подобном варианте остановился, не совсем конечно то что надо - ибо есть реквизиты (редактор, дата изменения) которые изменяются подпиской, если Объект.Записать() то эти реквизиты перезаполнятся, а на 2м этапе пользователь переобуется (отменит ввод) - получится зазря первоначальный элемент записывали...
(14)
Глобальный контекст (Global context)
ПравоДоступа (AccessRight)
Синтаксис:
ПравоДоступа(<Право>, <ОбъектМетаданных>, <Пользователь/Роль>, <СтандартныйРеквизитСтандартнаяТабличнаяЧасть>)
Глобальный контекст (Global context)
ПравоДоступа (AccessRight)
Синтаксис:
ПравоДоступа(<Право>, <ОбъектМетаданных>, <Пользователь/Роль>, <СтандартныйРеквизитСтандартнаяТабличнаяЧасть>)
Справочник = Метаданные.Справочники.Конкуренты;
Если Не ПравоДоступа("Чтение", Справочник) Тогда
Предупреждение(НСтр("ru = 'Доступ к данному справочнику закрыт!';"
+ " en = 'Access denied!'"));
КонецЕсли;
(15) нет, это не то
У меня в запросе собираются документы Реализация по отбору, причём часть из этих документов закрыто по RLS для пользователя (Контрагент в недоступной ему группе доступа).
Так вот проблема была, когда обращаешься к реквизитам отобранных документов, если документ для данного пользователя запрещен для просмотра ... выходит ошибка.
Через Попытку я проверяю возможность прочитать реквизит:
* если не читаемо, то я НЕ делаю обращение к реквизитам, но сам документ вывожу в отчет (это даёт сделать),
* если читаемо - то дополнительно реквизиты вывожу в отчет
Меня это полностью устраивает )))
PS
в запросе мне не надо фильтровать "ТОЛЬКО РАЗРЕШЕННЫЕ", так как в отчет должны попасть все документы по отбору, включая запрещенные к просмотру у данного пользователя.
У меня в запросе собираются документы Реализация по отбору, причём часть из этих документов закрыто по RLS для пользователя (Контрагент в недоступной ему группе доступа).
Так вот проблема была, когда обращаешься к реквизитам отобранных документов, если документ для данного пользователя запрещен для просмотра ... выходит ошибка.
Через Попытку я проверяю возможность прочитать реквизит:
* если не читаемо, то я НЕ делаю обращение к реквизитам, но сам документ вывожу в отчет (это даёт сделать),
* если читаемо - то дополнительно реквизиты вывожу в отчет
Меня это полностью устраивает )))
PS
в запросе мне не надо фильтровать "ТОЛЬКО РАЗРЕШЕННЫЕ", так как в отчет должны попасть все документы по отбору, включая запрещенные к просмотру у данного пользователя.
Ну... Лично я такого не знаю, но
РЛС пишется для Роли и решение МОЖНО/НЕЛЬЗЯ принимается в результате выполнения запроса,
так что в крайнем случае можно для определенных Ролей проанализировать результат аналогичного запроса...
РЛС пишется для Роли и решение МОЖНО/НЕЛЬЗЯ принимается в результате выполнения запроса,
так что в крайнем случае можно для определенных Ролей проанализировать результат аналогичного запроса...
(4) whilefor, (3) ZergKRSK,
"Право доступа" и "Выполнить проверку прав доступа" - судя по описанию - делают это с ОБЪЕКТОМ МЕТАДАННЫХ а не с ЭЛЕМЕНТОМ.
Т.е. можно проверить право на запись всего справочника (как задано в конфигураторе), а не к конкретной записи (элементу) данного справочника с учетом ограничений РЛС.
"Право доступа" и "Выполнить проверку прав доступа" - судя по описанию - делают это с ОБЪЕКТОМ МЕТАДАННЫХ а не с ЭЛЕМЕНТОМ.
Т.е. можно проверить право на запись всего справочника (как задано в конфигураторе), а не к конкретной записи (элементу) данного справочника с учетом ограничений РЛС.
Возникла аналогичная задача, нужно показать кнопку в зависимости от наличия права доступа к определенному документу. Кнопка позволяет добавлять связанные с этим документом документы. Использовать проверку через "Запись" - не вариант, т.к. просто так перезаписывать "объект проверки права" не желательно.
Решение не нашлось?
Решение не нашлось?
Так же есть потребность в этом. Я пока ничего не нашел штатного или в БСП хотя там есть интересная функция: УправлениеДоступом.ЕстьПраво()...
Но для того что бы ей пользоваться, нужно что то еще записывать в регистры.
Я думаю самый простой вариант, и без костылей, сделать запрос к объекту метаданных с "РАЗРЕШЕННЫЕ" и проверить результат на вхождение требуемой ссылки, если ее там нет, значит доступа нет, ну и наоборот!)
Но для того что бы ей пользоваться, нужно что то еще записывать в регистры.
Я думаю самый простой вариант, и без костылей, сделать запрос к объекту метаданных с "РАЗРЕШЕННЫЕ" и проверить результат на вхождение требуемой ссылки, если ее там нет, значит доступа нет, ну и наоборот!)
(12)
Наверно это сработает, если нет доступа на чтение. Как вариант действительно подойдет.
У меня доступ на чтение есть у всех, а на запись - по RLS. Получается никак не проверить, кроме как попыткой записи...
сделать запрос к объекту метаданных с "РАЗРЕШЕННЫЕ" и проверить результат
Наверно это сработает, если нет доступа на чтение. Как вариант действительно подойдет.
У меня доступ на чтение есть у всех, а на запись - по RLS. Получается никак не проверить, кроме как попыткой записи...
(12)
нашёл ещё пару интересных функций в УправлениеДоступом:
УправлениеДоступом.ЧтениеРазрешено(Ссылка);
УправлениеДоступом.ИзменениеРазрешено(Ссылка);
Может кому-то пригодится.
П.С. БСП версии 3.0.3.48
УправлениеДоступом
нашёл ещё пару интересных функций в УправлениеДоступом:
УправлениеДоступом.ЧтениеРазрешено(Ссылка);
УправлениеДоступом.ИзменениеРазрешено(Ссылка);
Может кому-то пригодится.
П.С. БСП версии 3.0.3.48
Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ &Ссылка";
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Если Запрос.Выполнить().Пустой() Тогда
//Нет прав на чтение
КонецЕсли;
С правами на запись сложнее, там надо будет анализировать сами RLS.
Вариант из предыдущего поста рабочий
УправлениеДоступом.ЧтениеРазрешено(Ссылка);
УправлениеДоступом.ИзменениеРазрешено(Ссылка);
УправлениеДоступом.ИзменениеРазрешено(Ссылка);
(18) Такой запрос не сработал, он возвращает строку со ссылкой "объект не найден..." и запрос уже получается не пустым.
Но, развивая эту мысль, накидал такую функцию:
Тестил на 8.3.17, скармливал ссылки на элементы справочников. Предположительно, она много чего жрать должна.
UPD: и да, это только проверка на чтение, не на запись, на вопрос ветки не отвечает.
Но, развивая эту мысль, накидал такую функцию:
&НаСервереБезКонтекста
Функция ЧтениеРазрешено(Ссылка)
Если НЕ ЗначениеЗаполнено(Ссылка) Тогда
Возврат Ложь;
КонецЕсли;
Запрос = Новый Запрос;
ТаблицаЗапрос = Метаданные.НайтиПоТипу(ТипЗнч(Ссылка)).ПолноеИмя();
ТаблицаИмя = СтрЗаменить(ТаблицаЗапрос, ".", "");
Запрос.Текст = Запрос.Текст +
"ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1
| " + ТаблицаИмя + ".Ссылка КАК Ссылка
|ИЗ
| " + ТаблицаЗапрос + " КАК " + ТаблицаИмя + "
|ГДЕ
| " + ТаблицаИмя + ".Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Если Запрос.Выполнить().Пустой() Тогда
Возврат Ложь;
Иначе
Возврат Истина;
КонецЕсли;
КонецФункции
ПоказатьТестил на 8.3.17, скармливал ссылки на элементы справочников. Предположительно, она много чего жрать должна.
UPD: и да, это только проверка на чтение, не на запись, на вопрос ветки не отвечает.
ВЫБРАТЬ ПЕРВЫЕ 1
ИСТИНА КАК ЗначениеИстина
ИЗ
РегистрСведений.КлючиДоступаКОбъектам КАК КлючиДоступаКОбъектам
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КлючиДоступаНаборовГруппДоступа КАК РазрешенныеКлючиДоступа
ПО (КлючиДоступаКОбъектам.Объект = &Объект)
И (РазрешенныеКлючиДоступа.КлючДоступа = КлючиДоступаКОбъектам.КлючДоступаПользователей)
И (РазрешенныеКлючиДоступа.НаборГруппДоступа В (&РазрешенныйНаборГруппДоступа, &РазрешенныйПустойНаборГруппДоступа))
И (РазрешенныеКлючиДоступа.Изменение)
ИСТИНА КАК ЗначениеИстина
ИЗ
РегистрСведений.КлючиДоступаКОбъектам КАК КлючиДоступаКОбъектам
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КлючиДоступаНаборовГруппДоступа КАК РазрешенныеКлючиДоступа
ПО (КлючиДоступаКОбъектам.Объект = &Объект)
И (РазрешенныеКлючиДоступа.КлючДоступа = КлючиДоступаКОбъектам.КлючДоступаПользователей)
И (РазрешенныеКлючиДоступа.НаборГруппДоступа В (&РазрешенныйНаборГруппДоступа, &РазрешенныйПустойНаборГруппДоступа))
И (РазрешенныеКлючиДоступа.Изменение)
Для обычных форм
// Для определения доступности формы на изменение с учетом РЛС, пробуем записать объект.
// Если запись не удаласть - значит доступа нет и нужно перевести форму в режим "Только просмотр"
// В любом случае, после выполнения операции отменяем транзакцию.
Процедура ОграничениеДоступаПоРЛС(Объект, Форма) Экспорт
Если ПараметрыСеанса.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей Тогда
Если НЕ Объект.Ссылка.Пустая() Тогда
НачатьТранзакцию();
Попытка
Объект.Записать();
Исключение
УстановитьНедоступностьФормы(Форма);
КонецПопытки;
ОтменитьТранзакцию();
Объект.Прочитать(); // для сбоса флага модифицированности объект нужно перечитать
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура УстановитьНедоступностьФормы(Форма) Экспорт
Форма.ТолькоПросмотр = Истина;
Для каждого ЭлементФормы Из Форма.ЭлементыФормы Цикл
ТипЭлемента = ТипЗнч(ЭлементФормы);
Если ТипЭлемента = Тип("ПолеВвода")
ИЛИ ТипЗнч(ЭлементФормы) = Тип("ТабличноеПоле")
ИЛИ ТипЗнч(ЭлементФормы) = Тип("ПолеТабличногоДокумента") Тогда
ЭлементФормы.ТолькоПросмотр = Истина;
ИначеЕсли ТипЭлемента = Тип("Кнопка") Тогда
ЭлементФормы.Доступность = Ложь;
ИначеЕсли ТипЭлемента = Тип("КоманднаяПанель") Тогда
ЭлементФормы.Доступность = Ложь;
УстановитьНедоступностьКнопкамКоманднойПанели(ЭлементФормы.Кнопки);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура УстановитьНедоступностьКнопкамКоманднойПанели(Кнопки)
Для каждого Кнопка Из Кнопки Цикл
Если Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Действие Тогда
Если Кнопка.ИзменяетДанные Тогда
Кнопка.Доступность = Ложь;
КонецЕсли;
ДействиеСтрокой = Строка(Кнопка.Действие);
Если ДействиеСтрокой = "Записать" ИЛИ ДействиеСтрокой = "Записать и закрыть" Тогда
Кнопка.Доступность = Ложь;
КонецЕсли;
ИначеЕсли Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю Тогда
УстановитьНедоступностьКнопкамКоманднойПанели(Кнопка.Кнопки);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Показать
По мотивам обсуждения написал вот такое (делюсь - пользуйтесь).
*Писал и тестил на 8.3.22.2501.
// Назаренко_СВ 2024-08-24
//
// Проверяет доступен ли указанный объект БД для изменения текущему пользователю (с учетом РЛС).
// Если нет права на чтение, то считаем, что и на изменение права нет.
//
//Параметры:
// Ссылка – ЛюбаяСсылка – Ссылка на проверяемый объект БД (Справочник, Документ и т.п.).
//
//Возвращаемое значение:
// Булево – Признак того, что с учетом РЛС данный объект доступен пользователю для изменения.
//
Функция ОбъектДоступенДляИзменения(Ссылка) Экспорт
ВозвращаемоеЗначение = Истина;
Если ЗначениеЗаполнено(Ссылка) Тогда
НачатьТранзакцию();
Попытка
Объект = Ссылка.ПолучитьОбъект();
Объект.ОбменДанными.Загрузка = Истина;
Объект.Записать();
Исключение
Информация = ИнформацияОбОшибке();
Если ОбработкаОшибок.КатегорияОшибкиДляПользователя(Информация) = КатегорияОшибки.НарушениеПравДоступа Тогда
ВозвращаемоеЗначение = Ложь;
Иначе
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
ОтменитьТранзакцию();
Иначе
// Т.к. РЛС не распространяется на еще не записанные объекты, то к пустой ссылке доступ есть всегда.
КонецЕсли;
Возврат ВозвращаемоеЗначение;
КонецФункции
Показать*Писал и тестил на 8.3.22.2501.
(27)
(27)
Так я. вроде, ОбменДанными.Загрузка.Истина установил, чтоб оно в обработчиках не бродило.
Если конфа в целом кривая, то тут уже ничего не поделать (хуже уже не будет).
Можешь предложить альтернативу для конфигураций без БСП и без того, чтобы перегонять все метаданные в справочники?
(27)
оно начинает отрабатывать цепочку подписок на запись
Так я. вроде, ОбменДанными.Загрузка.Истина установил, чтоб оно в обработчиках не бродило.
Если конфа в целом кривая, то тут уже ничего не поделать (хуже уже не будет).
Можешь предложить альтернативу для конфигураций без БСП и без того, чтобы перегонять все метаданные в справочники?
(31)
Если ты об этом
(29)
то я думал, что это пример кода, который будет глючить, т.к. ему пофиг на ОбменДанными.Загрузка.
А там есть пример, как определить доступно ли по РЛС пользователю изменение документа, версия которого записывается?
Или ты о каком примере кода?
Ты пример кода-то посмотрел?
Если ты об этом
(29)
Ну открой и посмотри, например, БСПшный обработчик ЗаписатьВерсиюДокумента.
то я думал, что это пример кода, который будет глючить, т.к. ему пофиг на ОбменДанными.Загрузка.
А там есть пример, как определить доступно ли по РЛС пользователю изменение документа, версия которого записывается?
Или ты о каком примере кода?
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот