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

10.04.15

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

См. также

SALE! 15%

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

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

10000 руб.

02.09.2020    159437    872    399    

861

Инструменты администратора БД Роли и права Системный администратор Программист Пользователь 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, пытаясь понять какими правами они обладают? Вы все время смотрите права в конфигураторе или отчетах чтоб создать нормальные профили доступа? Вы хотите наглядно видеть какие права дает профиль и редактировать все в простом виде? А может хотите просто указать подсистему и дать права на просмотр и добавление на объекты и не лезть в дебри прав и чтоб обработка сама подобрала нужные роли? Все это теперь стало возможно! Обновление от 18.09.2024, версия 1.2

16800 руб.

06.12.2023    8844    42    5    

73

SALE! 15%

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

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

10000 8500 руб.

10.11.2023    10429    36    24    

61

SALE! 20%

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

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

5940 4752 руб.

27.05.2021    37567    264    92    

205

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

Расширение для 1С:Бухгалтерия 3.0, которое позволяет использовать отдельные роли для доступа к складским документам, для доступа к документам раздела "Производство" и для доступа к документам раздела "Покупки".

4560 руб.

21.05.2019    1694764    570    194    

137

Ценообразование, анализ цен Роли и права Системный администратор Платформа 1С v8.3 Управление правами 1С:Управление нашей фирмой 1.6 1С:Управление нашей фирмой 3.0 Россия Платные (руб)

Расширение возможностей программы 1С УНФ. Функционал расширения - разграничение всевозможных прав пользователей и контроль при совершении различных действий.

3000 руб.

23.02.2018    58454    160    261    

152

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

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

19200 руб.

29.11.2019    25657    16    8    

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

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

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


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

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


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

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


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

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


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

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

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

Скоро напишу "серьезную" статью по РЛС, а тут - извиняйте, ежели чего...
9. karpik666 3851 10.04.15 12:26 Сейчас в теме
(8) ну так форум что ли отменили?
10. cargobird 308 10.04.15 12:33 Сейчас в теме
(9) karpik666, точно, как-то об этом не подумал)
13. vasyak319 152 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 152 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 308 10.04.15 22:08 Сейчас в теме
(11) Templ, как минимум, если конфигурация нетиповая,
Если РольДоступна("ИвановаСвета") Тогда ... КонецЕсли;

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

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

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