Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Настройки отбора компоновки данных #50

Merged
merged 11 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
462 changes: 462 additions & 0 deletions src/Catalogs/__НастройкиОтбораОбъектов.xml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@

#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

#Область ПрограммныйИнтерфейс

// Процедура заполняет компоновщик настроек для выбранного объекта метаданных
//
// Параметры:
// КомпоновщикНастроек - КомпоновщикНастроекКомпоновкиДанных
// ОбъектМетаданных - Строка - Строковое представление объекта метаданных (пример - Документ.ПоступлениеТоваровУслуг)
//
Процедура ИнициализироватьКомпоновщик(КомпоновщикНастроек, Знач ОбъектМетаданных) Экспорт

ТекстЗапроса =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ " + ОбъектМетаданных;

Check warning on line 15 in src/Catalogs/__НастройкиОтбораОбъектов/Ext/ManagerModule.bsl

View check run for this annotation

sonar.openbsl.ru qa-bot / 1C: Project SubSystems Library Sonarqube Results

src/Catalogs/__НастройкиОтбораОбъектов/Ext/ManagerModule.bsl#L15

Текст запроса должен быть корректным и открываться конструктором запросов

Comment on lines +14 to +16
Copy link

@coderabbitai coderabbitai bot Apr 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The query text should be constructed safely to prevent SQL injection. Use parameterized queries or query builders.

- ТекстЗапроса = "ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ " + ОбъектМетаданных;
+ ТекстЗапроса = СтроковыйКонструкторЗапроса("ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ ", ОбъектМетаданных);

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
ТекстЗапроса =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ " + ОбъектМетаданных;
ТекстЗапроса = СтроковыйКонструкторЗапроса("ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ ", ОбъектМетаданных);

Copy link
Contributor Author

@perlusha perlusha Apr 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, i'm not familiar with this function СтроковыйКонструкторЗапроса, are you sure it exists?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I apologize for the confusion, СтроковыйКонструкторЗапроса is not a standard function in BSL. It seems I made an error in suggesting it. In BSL, to safely construct SQL queries and prevent SQL injection, you should use parameterized queries or the query builder provided by the platform.

Here's an example of how you can modify the query construction to use parameterized queries:

Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ &ОбъектМетаданных";
Запрос.УстановитьПараметр("ОбъектМетаданных", ОбъектМетаданных);
ТекстЗапроса = Запрос.Текст;

This method uses the Запрос object to set up a query with parameters, which helps in preventing SQL injection by separating the data (parameter values) from the code (SQL query). Please let me know if you need further assistance with this!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So sorry, but it doesn't work like that, the name of the table can't be a parameter.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@perlusha, you are absolutely right; the table name cannot be parameterized in SQL queries, which is a common limitation. To ensure the safety of dynamically constructed SQL queries where the table name is variable, you can implement a validation step against a predefined list of allowed table names. Here's how you could modify the procedure to include this safety check:

// Предполагаем, что у нас есть функция, которая возвращает разрешенные имена таблиц
Функция ПолучитьРазрешенныеИменаТаблиц() Экспорт
    Возврат Новый Массив Из {"Документ.ПоступлениеТоваровУслуг", "Документ.ВыпискаБанка"}; // Пример
КонецФункции

Процедура ИнициализироватьКомпоновщик(КомпоновщикНастроек, Знач ОбъектМетаданных) Экспорт
    Если Не ПолучитьРазрешенныеИменаТаблиц().Содержит(ОбъектМетаданных) Тогда
        ВызватьИсключение "Недопустимое имя объекта метаданных";
    КонецЕсли;
    
    ТекстЗапроса = "ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ " + ОбъектМетаданных;
КонецПроцедуры

This approach checks if the metadata object name is in the list of allowed names before constructing the query. It helps prevent SQL injection by ensuring that only valid, expected table names are used in the query. Please let me know if this solution works for you or if you need further modifications!

СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных.Добавить();
ИсточникДанных.Имя = "ИсточникДанных1";
ИсточникДанных.ТипИсточникаДанных = "Local";

НаборДанных = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
НаборДанных.Имя = "НаборДанных1";
НаборДанных.ИсточникДанных = ИсточникДанных.Имя;
НаборДанных.Запрос = ТекстЗапроса;

АдресКомпоновки = ПоместитьВоВременноеХранилище(СхемаКомпоновкиДанных, Новый УникальныйИдентификатор);
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресКомпоновки));
КомпоновщикНастроек.ЗагрузитьНастройки(СхемаКомпоновкиДанных.НастройкиПоУмолчанию);

КонецПроцедуры

// Процедура используется для копирования элементов отбора из пользовательского компоновщика
//
// Параметры:
// НовыйОтбор - ОтборКомпоновкиДанных
// СтарыйОтбор - ОтборКомпоновкиДанных
//
Процедура СкопироватьЭлементыОтбора(НовыйОтбор, СтарыйОтбор) Экспорт

Для Каждого Элемент Из СтарыйОтбор.Элементы Цикл
Если ТипЗнч(Элемент) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
НовыйЭлемент = НовыйОтбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
ЗаполнитьЗначенияСвойств(НовыйЭлемент, Элемент);
СкопироватьЭлементыОтбора(НовыйЭлемент, Элемент);
Иначе
НовыйЭлемент = НовыйОтбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЗаполнитьЗначенияСвойств(НовыйЭлемент, Элемент);
КонецЕсли;
КонецЦикла;

КонецПроцедуры

// По заданной настройке отбора функция возвращает таблицу значений с ссылками, соответствующими условиям отбора
//
// Параметры:
// Настройка - СправочникСсылка.__НастройкиОтбораОбъектов
//
// Возвращаемое значение:
// - ТаблицаЗначений с колонкой Ссылка
//
Функция ПолучитьДанныеПоНастройкеОтбора(Настройка) Экспорт

Check warning on line 62 in src/Catalogs/__НастройкиОтбораОбъектов/Ext/ManagerModule.bsl

View check run for this annotation

sonar.openbsl.ru qa-bot / 1C: Project SubSystems Library Sonarqube Results

src/Catalogs/__НастройкиОтбораОбъектов/Ext/ManagerModule.bsl#L62

Добавьте описание возвращаемого значения функции

МодульОбщегоНазначения = __ОбщегоНазначенияСервер.ОбщийМодуль("ОбщегоНазначения", "__ОбщегоНазначенияСервер");

ОбъектМетаданных = МодульОбщегоНазначения.ЗначениеРеквизитаОбъекта(Настройка, "ОбъектМетаданных");
Отбор = МодульОбщегоНазначения.ЗначениеРеквизитаОбъекта(Настройка, "Отбор");

КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
ТекстЗапроса = "ВЫБРАТЬ * ИЗ " + ОбъектМетаданных;

Check warning on line 70 in src/Catalogs/__НастройкиОтбораОбъектов/Ext/ManagerModule.bsl

View check run for this annotation

sonar.openbsl.ru qa-bot / 1C: Project SubSystems Library Sonarqube Results

src/Catalogs/__НастройкиОтбораОбъектов/Ext/ManagerModule.bsl#L70

Текст запроса должен быть корректным и открываться конструктором запросов

СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных.Добавить();
ИсточникДанных.Имя = "ИсточникДанных1";
ИсточникДанных.ТипИсточникаДанных = "Local";

НаборДанных = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
НаборДанных.Имя = "НаборДанных1";
НаборДанных.ИсточникДанных = ИсточникДанных.Имя;
НаборДанных.Запрос = ТекстЗапроса;

АдресКомпоновки = ПоместитьВоВременноеХранилище(СхемаКомпоновкиДанных, Новый УникальныйИдентификатор);
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресКомпоновки));
КомпоновщикНастроек.ЗагрузитьНастройки(СхемаКомпоновкиДанных.НастройкиПоУмолчанию);

ДетальныеЗаписи = КомпоновщикНастроек.Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
ДетальныеЗаписи.Имя = "Детальные";
ДетальныеЗаписи.Использование = Истина;
ВыбранноеПоле = ДетальныеЗаписи.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
ВыбранноеПоле.Поле = Новый ПолеКомпоновкиДанных("Ссылка");

Отбор = МодульОбщегоНазначения.ЗначениеИзСтрокиXML(Отбор);
СкопироватьЭлементыОтбора(КомпоновщикНастроек.Настройки.Отбор, Отбор);

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Попытка
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.Настройки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));

Check warning on line 97 in src/Catalogs/__НастройкиОтбораОбъектов/Ext/ManagerModule.bsl

View check run for this annotation

sonar.openbsl.ru qa-bot / 1C: Project SubSystems Library Sonarqube Results

src/Catalogs/__НастройкиОтбораОбъектов/Ext/ManagerModule.bsl#L97

Длина строки 166 превышает максимально допустимую 120
Исключение
СообщениеОбОшибке = ОписаниеОшибки();
__ОбщегоНазначенияСервер.СообщитьПользователю(СообщениеОбОшибке);
КонецПопытки;

ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки);

ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;

Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("Ссылка");

ПроцессорВывода.УстановитьОбъект(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);

Возврат Результат;

КонецФункции

#КонецОбласти

#КонецЕсли
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.16">
<Form uuid="1b463292-adbe-4510-8686-82c974fb20da">
<Properties>
<Name>ФормаВыбораОбъектаМетаданных</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Форма выбора объекта метаданных</v8:content>
</v8:item>
</Synonym>
<Comment/>
<FormType>Managed</FormType>
<IncludeHelpInContents>false</IncludeHelpInContents>
<UsePurposes>
<v8:Value xsi:type="app:ApplicationUsePurpose">PlatformApplication</v8:Value>
<v8:Value xsi:type="app:ApplicationUsePurpose">MobilePlatformApplication</v8:Value>
</UsePurposes>
</Properties>
</Form>
</MetaDataObject>
Loading
Loading