Апрельские "нешутки", записанные в пятницу не 13-го (продолжение)

10.04.15

Администрирование - Роли и права

Еще одна байка про незадачливого кодера:
Загадочный РЛС или почему не могут работать "ПолныеПрава"

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

Но... По субъективным ощущениям (это которые без замеров) все стало чуть-чуть медленнее работать.

Кодер знал, что за кажущейся простотой ограничения доступа вроде

ОрганизацияВШапке("Организация")

скрывается подобный монстр-запрос:

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

От такого все что угодно можно ожидать, подумал кодер и решил придумать способ оптимизации.

"Сформировать бы перед запуском системы список доступных организаций, да и передать в шаблон ограничений, чтобы запрос был как можно меньше", рассуждал кодер, и стал искать способы. Создавать регистр сведений - масло масляное, передавать таблицу значений нельзя, список значений тоже, и массив нельзя... Ага, а фиксированный массив можно. Сказано - сделано. Перед началом работы системы был вставлен следующий код:

Если НЕ РольДоступна("ПолныеПрава") Тогда
	Если Константы.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей.Получить() Тогда
		Запрос = Новый Запрос("ВЫБРАТЬ
		                      |	ГруппыПользователейПользователиГруппы.Ссылка
		                      |ПОМЕСТИТЬ ВТ_ГП
		                      |ИЗ
		                      |	Справочник.ГруппыПользователей.ПользователиГруппы КАК ГруппыПользователейПользователиГруппы
		                      |ГДЕ
		                      |	ГруппыПользователейПользователиГруппы.Пользователь = &Пользователь
		                      |;
		                      |
		                      |////////////////////////////////////////////////////////////////////////////////
		                      |ВЫБРАТЬ РАЗРЕШЕННЫЕ
		                      |	&Пользователь КАК Пользователь,
		                      |	НастройкиПравДоступаПользователей.ОбъектДоступа КАК Организация,
		                      |	НастройкиПравДоступаПользователей.Запись,
		                      |	НастройкиПравДоступаПользователей.Отчеты
		                      |ПОМЕСТИТЬ ВТ_Доступ
		                      |ИЗ
		                      |	РегистрСведений.НастройкиПравДоступаПользователей КАК НастройкиПравДоступаПользователей
		                      |ГДЕ
		                      |	НастройкиПравДоступаПользователей.Пользователь В
		                      |			(ВЫБРАТЬ
		                      |				ВТ_ГП.Ссылка
		                      |			ИЗ
		                      |				ВТ_ГП КАК ВТ_ГП)
		                      |		КОНЕЦ
		                      |
		                      |СГРУППИРОВАТЬ ПО
		                      |	НастройкиПравДоступаПользователей.ОбъектДоступа,
		                      |	НастройкиПравДоступаПользователей.Запись
		                      |;
		                      |
		                      |////////////////////////////////////////////////////////////////////////////////
		                      |ВЫБРАТЬ
		                      |	ВТ_Доступ.Пользователь,
		                      |	ВТ_Доступ.Организация
		                      |ИЗ
		                      |	ВТ_Доступ КАК ВТ_Доступ
		                      |;
		                      |
		                      |////////////////////////////////////////////////////////////////////////////////
		                      |ВЫБРАТЬ
		                      |	ВТ_Доступ.Пользователь,
		                      |	ВТ_Доступ.Организация
		                      |ИЗ
		                      |	ВТ_Доступ КАК ВТ_Доступ
		                      |ГДЕ
		                      |	ВТ_Доступ.Запись");
		ТекущийПользователь = ПараметрыСеанса.ТекущийПользователь;
		Запрос.УстановитьПараметр("Пользователь", ТекущийПользователь);
		МассивРезультатов = Запрос.ВыполнитьПакет();
		РезультатЗапросаЧтение = МассивРезультатов[2].Выгрузить();
		РезультатЗапросаЗапись = МассивРезультатов[3].Выгрузить();
		
		МассивОрганизацийДоступныхДляЧтения = РезультатЗапросаЧтение.ВыгрузитьКолонку("Организация");
		ПараметрыСеанса.СписокОрганизацийДоступныхДляЧтения = Новый ФиксированныйМассив(МассивОрганизацийДоступныхДляЧтения);
		МассивОрганизацийДоступныхДляЗаписи = РезультатЗапросаЗапись.ВыгрузитьКолонку("Организация");
		ПараметрыСеанса.СписокОрганизацийДоступныхДляЗаписи = Новый ФиксированныйМассив(МассивОрганизацийДоступныхДляЗаписи);		
	КонецЕсли;	
КонецЕсли; 

И монстр-запрос для чтения превратился во вполне компактный:

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

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

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

Наступило утро. Обычные пользователи без полных прав вошли в программу и стали работать как обычно.

Пользователи же с полными правами стали натыкаться в разных местах на непонятное сообщение: "Попытка получить неинициализированное значение параметра сеанса".

Анализ ситуации показал, что приведенный код выполнял инициализацию параметров сеанса только для неполноправных пользователей.

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

Система была давняя, кодер - не первый ее доработчик и исследователь, и на наборы ролей пользователей особого внимания не обращал.

А зря. У пользователей с полными правами, (наверное для большей полноты прав) были добавлены еще по нескольку ролей, эти роли и пытались получить список доступных организаций через неинициализированный параметр сеанса.

Попытка снять "лишние" роли привела к отключению у полноправных пользователей некоторых возможностей. Это, в свою очередь, произошло от того, что часть из этих "лишних" ролей использовалась только в коде для включения определенного функционала (речь идет об УТ 10.3, функциональные опции еще только снятся), но поскольку роли были скопированы с типовых ролей, то и потянули за собой и шаблоны ограничений доступа, и ограничения доступа к метаданным.

Финал оптимистичный, в стиле анекдота про отца-программиста и сына: "Знаешь что, сынок! Не трогай-ка ты работающую систему!" - наборы ролей пользователей были восстановлены в прежнем состоянии, над условием "Если не РольДоступна("ПолныеПрава")..." появилась пара строк инициализации параметров сеанса пустыми фиксированными массивами и все продолжили спокойно работать до следущего внедрения...

РЛС шаблоны ограничений доступа

См. также

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

13000 руб.

02.09.2020    119908    656    389    

701

Запрет доступа к данным по зарплате для БП 3.0 и КА 2.5

Зарплата Роли и права Платформа 1С v8.3 Бухгалтерский учет Управление правами 1С:Бухгалтерия 3.0 1С:Комплексная автоматизация 2.х Молдова Россия Казахстан Бухгалтерский учет Платные (руб)

Расширение позволяет максимально полно ограничить доступ пользователей к данным по заработной плате, а именно закрывает доступ к документам начисления и выплаты заработной платы, не позволяет просматривать бухгалтерские отчеты по счету учета зарплаты а также убирает зарплатные проводки из журнала проводок. Расширение запрещает просматривать платежные документы на выплату зарплаты, так же не доступны регламентные отчеты в ПФР и ИФНС. Расширение предлагает готовые настроенные профили "Бухгалтер без зарплаты", "Только просмотр без зарплаты".

5700 руб.

27.05.2021    32518    202    89    

162

Автоподбор ролей для профилей и групп доступа в любых типовых базах 1С УТ 11, КА 2, ERP2, Розница 2/3, УНФ 16/3, БП 3, ЗУП 3 и подобных (УФ, Платформа 8.3.14+)

Инструменты администратора БД Роли и права 8.3.14 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Документооборот 1С:Зарплата и кадры государственного учреждения 3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Платные (руб)

Роли… Вы тратите много времени и сил на подбор ролей среди около 2400 в ERP или 1500 в Рознице 2, пытаясь понять какими правами они обладают? Вы все время смотрите права в конфигураторе или отчетах чтоб создать нормальные профили доступа? Вы хотите наглядно видеть какие права дает профиль и редактировать все в простом виде? А может хотите просто указать подсистему и дать права на просмотр и добавление на объекты и не лезть в дебри прав и чтоб обработка сама подобрала нужные роли? Все это теперь стало возможно! Обновление от 15.12.2023, версия 1.1.

12000 руб.

06.12.2023    2756    11    1    

30

Infostart УДиФ: Управление данными и формами

Инструменты администратора БД Инструментарий разработчика Роли и права Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

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

10000 руб.

10.11.2023    3244    10    1    

31

Роли для кладовщика

Логистика, склад и ТМЦ Роли и права Платформа 1С v8.3 Бухгалтерский учет Управление правами 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Управленческий учет Платные (руб)

Расширение, которое позволяет использовать отдельные роли для доступа к складским документам, для доступа к документам раздела "Производство" и для доступа к документам раздела "Покупки".

2520 руб.

21.05.2019    1692147    551    192    

131

Расширение для разграничения доступа к контрагентам и обработка для группового назначения доступа для Бухгалтерии (RLS) 3.0.143.42

Роли и права Платформа 1С v8.3 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Платные (руб)

Расширение предназначено для Бухгалтерии предприятия (версии ПРОФ и КОРП). Типовая конфигурация остается на поддержке. С помощью расширения менеджер по продажам будет иметь доступ к контрагентам и списку их документов только в случае, если он является для них ответственным. Пользователю с полными правами также доступна обработка «Назначение ответственных» для группового добавления/удаления ответственного в карточке контрагента. Есть версия данного расширения для клиентов Fresh - в магазине расширений (Fresh)

9360 руб.

14.09.2022    5732    6    4    

8

Универсальная система оповещений в базе или по почте по произвольным условиям, расписанием, ролям и пользователям (Расширение / конфигурация для платформ 8.3.6+, для ЛЮБЫХ баз)

Роли и права Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 11 Платные (руб)

Данная система разработана как альтернатива стандартной системе напоминаний. Но имеет ряд существенных преимуществ: отображение в базе или с отправкой по почте, свое расписание, возможность фильтрации по ролям и пользователям, формирование своих запросов и макетов, шаблоны писем, работа в фоне. А также может блокировать работу пользователей при заданных условиях. Может работать в составе любой конфигурации. Имеется справка с описанием возможностей. (Обновление от 20.02.2024, версия 2.2, расширение)

18000 руб.

29.11.2019    24657    13    8    

33
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. karpik666 3759 10.04.15 09:12 Сейчас в теме
Хм, А просто условие убрать на полные права и в "иначе" записать
ПараметрыСеанса.СписокОрганизацийДоступныхДляЧтения = Новый ФиксированныйМассив();
        ПараметрыСеанса.СписокОрганизацийДоступныхДляЗаписи = Новый ФиксированныйМассив();    

На самом деле не очень страшная история, глядя на название хотелось таких ужасов, чтобы мороз по коже=)
По мне мораль, что все нужно тестировать, прежде чем накатывать.
2. cargobird 306 10.04.15 09:44 Сейчас в теме
(1) karpik666

не очень страшная история


Как посмотреть, если пользователь под полными правами не может зайти ни в один журнал документов, ни провести документ из списка....

все нужно тестировать


Так все и было протестировано, только под неполными правами) Что так будут вести себя "полные права" ожидалось меньше всего)

просто условие убрать на полные права


В итоге да, было убрано условие на полные права ..
3. necropunk 9 10.04.15 10:58 Сейчас в теме
Да-да-да, знакомый до боли затык. Влипал я так с полными правами тоже...
cargobird; +1 Ответить
4. vasyak319 150 10.04.15 11:03 Сейчас в теме
История на тему "какие траблы могут случиться, если дорабатывать систему, уже доработанную рукожопами". Да, в общем, любые.
А можно вообще про каждую обнаруженную ошибку статью писать (в принципе, эта статья как раз такая и есть). А можно анекдоты постить. А почему нет, если начисляют по 10 СМ за каждую?
alest; wolfsoft; +2 Ответить
5. cargobird 306 10.04.15 11:55 Сейчас в теме
(4) vasyak319, в этой статье кроме обнаруженной ошибки (достаточно серьезной, и, наверное, стоящей того, чтобы поделиться), приведен скромный опыт сокращения запроса РЛС путем передачи фиксированного массива в параметр сеанса и кроме того, нашелся сотоварищ по влипанию в подобную ситуацию. А 10 стартмани это скорее приятный бонус, а не цель...
6. vasyak319 150 10.04.15 12:15 Сейчас в теме
(5) да все влипали. В кучу разных ситуаций, ибо не оскудела земля русская рукожопами. Мне как-то вообще попалась конфа (КАТАП), доработанная платиново-иридиевым эталоном рукожопа.
Чувак писал что-то вроде:

Процедура ПриОткрытии()
	ВыбКлиент.Очистить();
	ВЫбКлиент=ВосстановитьЗначение("Выбклиент_ОтчетПоКлиентам");
	ВыбКлиент.Очистить();
	Номенклатура=Справочники.ОсобКлиенты.Выбрать(,,,"Наименование УБЫВ");
	Пока Номенклатура.Следующий() Цикл
		Объект=Номенклатура.Ссылка;
		Клиент=Объект.ПолучитьОбъект();
		Попытка
			ВыбКлиент.Добавить(Клиент.Поставщик);
		Исключение
		КонецПопытки
	КонецЦикла;
...
Показать


ВыбКлиент-список значений на форме отчёта. Уродливые кнопки для его редактирования - всё, как положено. При этом первое, что делала процедура Сформировать - очищала ВыбКлиент и заполняла заново примерно таким же алгоритмом.
В некоторых документах был булевый реквизит, который на форме документа выглядел флажком с заголовком "Орехова Т.". В процедурах ПередЗаписью проверки типа
Если ТекущийПользователь.Наименование="Иванова Света"
Итэде итэпэ. И что?

А вы приводите пример заурядной проблемы, причины которой очевидны, способ выяснения проблемных мест очевиден и способ исправления тоже очевиден.
cargobird; +1 Ответить
7. karpik666 3759 10.04.15 12:24 Сейчас в теме
(6) vasyak319,
Если ТекущийПользователь.Наименование="Иванова Света"
Видимо в этой организации Иванова Светлана будет работать до победного, а если и уволиться, то в вакансии на ее место будет обязательное требование: Требуется человек с именем "Иванова Света" или изменить на соответствующее в ЗАГС=)
alest; odin777; +2 Ответить
8. cargobird 306 10.04.15 12:24 Сейчас в теме
(6) vasyak319, боюсь показаться нудным, но способ сокращения запроса РЛС вроде ничего себе так, хотя и не протестирован на производительность)

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

Скоро напишу "серьезную" статью по РЛС, а тут - извиняйте, ежели чего...
9. karpik666 3759 10.04.15 12:26 Сейчас в теме
(8) ну так форум что ли отменили?
10. cargobird 306 10.04.15 12:33 Сейчас в теме
(9) karpik666, точно, как-то об этом не подумал)
13. vasyak319 150 11.04.15 01:18 Сейчас в теме
(8)
способ сокращения запроса РЛС вроде ничего себе так
таки да.

(11) Templ, зависит от ситуации. В том конкретном случае годилось:
Если ЭтоРуководительОтделаПродаж() Тогда...

или:
Если ОбщегоНазначения.ЕстьПраво(ПланыВидовХарактеристик.ДополнительныеПраваПользователей.ПравоТворитьСЗаказомПокупателяЛюбоеНепотребство) Тогда...

или даже:
Если ТекущийПользователь=Константы.ТотЕдинственныйПользовательКоторомуМыРазрешаемУродоватьЗаказКакБогЧерепаху.Получить() Тогда...


Запомни, Templ, никаких констант в коде! Никогда! Или я приду за тобой... Не, ну почему в этом форуме нет зловещих смайликов? Вообще никаких нету :(
Chif13; odin777; charushkin; dmpas; karpik666; cargobird; +6 Ответить
15. alyaev.a.v 12.04.15 11:09 Сейчас в теме
(13) vasyak319, А чем так страшны константы в коде,особенно вне транзакций?
16. vasyak319 150 12.04.15 14:38 Сейчас в теме
(15) alyaev.a.v, по-моему вы путаете прикладные объекты Константы с термином "константы в коде".
17. alyaev.a.v 12.04.15 23:46 Сейчас в теме
(16) vasyak319, Возможно, я просто подумал коммент про константы относился к "ТекущийПользователь=Константы.ТотЕдинственныйПользовательКоторомуМыРазрешаемУродоватьЗаказ­КакБогЧерепаху.Получить()"

а похоже он относился "Если ТекущийПользователь.Наименование="Иванова Света"",

попутал :)
11. Templ 10.04.15 21:04 Сейчас в теме
(6) vasyak319, (7) karpik666,
Если ТекущийПользователь.Наименование="Иванова Света"
Видимо в этой организации Иванова Светлана будет работать до победного, а если и уволиться, то в вакансии на ее место будет обязательное требование: Требуется человек с именем "Иванова Света" или изменить на соответствующее в ЗАГС=)

А как надо писать?
12. cargobird 306 10.04.15 22:08 Сейчас в теме
(11) Templ, как минимум, если конфигурация нетиповая,
Если РольДоступна("ИвановаСвета") Тогда ... КонецЕсли;

Тогда пользователю с любым именем можно назначить функционал Светы Ивановой)
18. Allexe8.1 15.04.15 20:21 Сейчас в теме
(5)
опыт сокращения запроса РЛС путем передачи фиксированного массива в параметр сеанса
Опасная штука. Если массив будет большим, условие (IN) будет выполняться через построчное создание ВТ (сколько элементов массива - столько insert-ов) и левое соединение с ней.
19. cargobird 306 15.04.15 21:17 Сейчас в теме
(18) Allexe8.1, спасибо за предупреждение, протестирую.

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

Скорость выполнения сложных самописных отчетов увеличивается путем заполнения массива перед формированием отчета теми организациями, по которым установлен отбор, а не всеми доступными. После формирования массив снова заполняется разрешенными организациями.
14. Templ 11.04.15 22:37 Сейчас в теме
У нас есть вещи и пострашнее констант. Например Запросы в цикле. Соответсвенно тормоза не хилые. (но это не я)
Оставьте свое сообщение