1
0
mirror of https://github.com/Bayselonarrend/OpenIntegrations.git synced 2025-03-25 21:39:21 +02:00

S3: Шифрование бакета

This commit is contained in:
Anton Titovets 2024-11-14 17:19:43 +03:00
parent 32d63f9ed2
commit 0a3980c4d5
11 changed files with 6188 additions and 5753 deletions

File diff suppressed because it is too large Load Diff

View File

@ -81,29 +81,28 @@
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - сериализованный JSON ответа от хранилища
Функция ОтправитьЗапросБезТела(Знач Метод, Знач ОсновныеДанные, Знач Заголовки = Неопределено) Экспорт
ПроверитьОсновныеДанные(ОсновныеДанные);
URL = ОсновныеДанные["URL"];
СтруктураURL = OPI_Инструменты.РазбитьURL(URL);
Сервер = СтруктураURL["Сервер"];
Адрес = СтруктураURL["Адрес"];
Защищенное = СтруктураURL["Защищенное"];
Запрос = OPI_Инструменты.СоздатьЗапрос(Адрес);
Соединение = OPI_Инструменты.СоздатьСоединение(Сервер, Защищенное);
ДобавитьДополнительныеЗаголовки(Запрос, Заголовки);
ЗаголовокАвторизации = СоздатьЗаголовокАвторизации(ОсновныеДанные, Запрос, Соединение, Метод);
Запрос.Заголовки.Вставить("Authorization", ЗаголовокАвторизации);
Ответ = OPI_Инструменты.ВыполнитьЗапрос(Запрос, Соединение, Метод, , Истина);
Ответ = ОформитьОтвет(Ответ);
Ответ = ОтправитьЗапрос(Метод, ОсновныеДанные, , Заголовки);
Возврат Ответ;
КонецФункции
// Отправить запрос с телом
// Отправляет http запрос с телом
//
// Параметры:
// Метод - Строка - HTTP метод - method
// ОсновныеДанные - Структура Из КлючИЗначение - Основные данные запроса (c полным URL). См. ПолучитьСтруктуруДанных - data
// Тело - Строка, ДвоичныеДанные - Двоичное тело запроса или путь к файлу - body
// Заголовки - Соответствие Из КлючИЗначение - Дополнительные заголовки запроса, если необходимо - headers
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - сериализованный JSON ответа от хранилища
Функция ОтправитьЗапросСТелом(Знач Метод, Знач ОсновныеДанные, Знач Тело, Знач Заголовки = Неопределено) Экспорт
Ответ = ОтправитьЗапрос(Метод, ОсновныеДанные, Тело, Заголовки);
Возврат Ответ;
КонецФункции
#КонецОбласти
@ -186,6 +185,73 @@
КонецФункции
// Установить шифрование бакета
// Устанавлиает шифрование бакета по дайджесту
//
// Примечание:
// Метод в документации AWS: [PutBucketEncryption](@docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html)
//
// Параметры:
// Наименование - Строка - Наименование бакета - name
// ОсновныеДанные - Структура Из КлючИЗначение - Основные данные запроса. См. ПолучитьСтруктуруДанных - data
// XMLКонфигурация - Строка - XML строка или файл конфигурации шифрования - conf
// Каталог - Булево - Истина > Directory Bucket, Ложь > General Purpose Bucket - dir
// Заголовки - Соответствие Из КлючИЗначение - Дополнительные заголовки запроса, если необходимо - headers
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - сериализованный JSON ответа от хранилища
Функция УстановитьШифрованиеБакета(Знач Наименование
, Знач ОсновныеДанные
, Знач XMLКонфигурация
, Знач Каталог = Истина
, Знач Заголовки = Неопределено) Экспорт
OPI_ПреобразованиеТипов.ПолучитьСтроку(XMLКонфигурация, Истина);
XMLКонфигурация = ПолучитьДвоичныеДанныеИзСтроки(XMLКонфигурация);
URL = ПолучитьURLСервиса(ОсновныеДанные);
URL = СформироватьURLБакета(URL, Наименование, Каталог);
URL = URL + "?encryption";
ОсновныеДанные.Вставить("URL", URL);
Ответ = ОтправитьЗапросСТелом("PUT", ОсновныеДанные, XMLКонфигурация, Заголовки);
Возврат Ответ;
КонецФункции
// Получить шифрование бакета
// Получает установленную ранее конфигурацию шифрования бакета
//
// Примечание:
// Метод в документации AWS: [GetBucketEncryption](@docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html)
//
// Параметры:
// Наименование - Строка - Наименование бакета - name
// ОсновныеДанные - Структура Из КлючИЗначение - Основные данные запроса. См. ПолучитьСтруктуруДанных - data
// Каталог - Булево - Истина > Directory Bucket, Ложь > General Purpose Bucket - dir
// Заголовки - Соответствие Из КлючИЗначение - Дополнительные заголовки запроса, если необходимо - headers
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - сериализованный JSON ответа от хранилища
Функция ПолучитьШифрованиеБакета(Знач Наименование
, Знач ОсновныеДанные
, Знач Каталог = Истина
, Знач Заголовки = Неопределено) Экспорт
URL = ПолучитьURLСервиса(ОсновныеДанные);
URL = СформироватьURLБакета(URL, Наименование, Каталог);
URL = URL + "?encryption";
ОсновныеДанные.Вставить("URL", URL);
Ответ = ОтправитьЗапросБезТела("GET", ОсновныеДанные, Заголовки);
Возврат Ответ;
КонецФункции
// Получить список бакетов
// Получает список бакетов. Возможно использование отборов, если они поддерживаются сервисом
//
@ -370,26 +436,23 @@
КонецФункции
Функция ПолучитьСтрокуПараметров(Знач Запрос)
Функция ПолучитьСтрокуПараметров(Запрос)
URI = Запрос.АдресРесурса;
НачалоПараметров = СтрНайти(URI, "?");
Если НачалоПараметров = 0 Тогда
Если НачалоПараметров = 0 Тогда
СтрокаПараметров = "";
Иначе
ДлинаURI = СтрДлина(URI);
СтрокаПараметров = Прав(URI, ДлинаURI - НачалоПараметров);
ДлинаURI = СтрДлина(URI);
СтрокаПараметров = Прав(URI, ДлинаURI - НачалоПараметров);
ОбработатьСтрокуПараметровЗапроса(СтрокаПараметров);
КонецЕсли;
МассивПараметров = СтрРазделить(СтрокаПараметров, "&");
СписокПараметров = Новый СписокЗначений();
СписокПараметров.ЗагрузитьЗначения(МассивПараметров);
СписокПараметров.СортироватьПоЗначению();
СтрокаПараметров = СтрСоединить(СписокПараметров.ВыгрузитьЗначения(), "&");
Возврат СтрокаПараметров;
КонецФункции
@ -482,28 +545,69 @@
КонецФункции
Процедура ОбработатьСтрокуПараметровЗапроса(СтрокаПараметров)
МассивПараметров = СтрРазделить(СтрокаПараметров, "&");
СписокПараметров = Новый СписокЗначений();
СписокПараметров.ЗагрузитьЗначения(МассивПараметров);
СписокПараметров.СортироватьПоЗначению();
МассивПараметров = СписокПараметров.ВыгрузитьЗначения();
КонечныйМассивПараметров = Новый Массив;
Для Н = 0 По МассивПараметров.ВГраница() Цикл
ПараметрЗапроса = МассивПараметров[Н];
Если СтрНайти(ПараметрЗапроса, "=") = 0 Тогда
МассивПараметров[Н] = ПараметрЗапроса + "=";
КонецЕсли;
КонецЦикла;
СтрокаПараметров = СтрСоединить(МассивПараметров, "&");
КонецПроцедуры
#КонецОбласти
#Область Прочее
Функция ОтправитьЗапрос(Знач Метод, Знач ОсновныеДанные, Знач Тело = Неопределено, Знач Заголовки = Неопределено)
ПроверитьОсновныеДанные(ОсновныеДанные);
URL = ОсновныеДанные["URL"];
СтруктураURL = OPI_Инструменты.РазбитьURL(URL);
Сервер = СтруктураURL["Сервер"];
Адрес = СтруктураURL["Адрес"];
Защищенное = СтруктураURL["Защищенное"];
Запрос = OPI_Инструменты.СоздатьЗапрос(Адрес);
Соединение = OPI_Инструменты.СоздатьСоединение(Сервер, Защищенное);
Если ЗначениеЗаполнено(Тело) Тогда
УстановитьТелоЗапроса(Запрос, Тело);
КонецЕсли;
ДобавитьДополнительныеЗаголовки(Запрос, Заголовки);
ЗаголовокАвторизации = СоздатьЗаголовокАвторизации(ОсновныеДанные, Запрос, Соединение, Метод);
Запрос.Заголовки.Вставить("Authorization", ЗаголовокАвторизации);
Ответ = OPI_Инструменты.ВыполнитьЗапрос(Запрос, Соединение, Метод, , Истина);
Ответ = ОформитьОтвет(Ответ);
Возврат Ответ;
КонецФункции
Функция УправлениеБакетом(Знач Имя, Знач ОсновныеДанные, Знач Каталог, Знач Метод, Знач Заголовки)
OPI_ПреобразованиеТипов.ПолучитьСтроку(Имя);
OPI_ПреобразованиеТипов.ПолучитьБулево(Каталог);
URL = ПолучитьURLСервиса(ОсновныеДанные);
Если Каталог Тогда
URL = URL + Имя;
Иначе
Если СтрНайти(URL, "://") Тогда
URL = СтрЗаменить(URL, "://", "://" + Имя + ".");
Иначе
URL = Имя + "." + URL;
КонецЕсли;
КонецЕсли;
URL = ПолучитьURLСервиса(ОсновныеДанные);
URL = СформироватьURLБакета(URL, Имя, Каталог);
ОсновныеДанные.Вставить("URL", URL);
@ -518,6 +622,9 @@
Статус = Ответ.КодСостояния;
Если Не ОжидаютсяДвоичные Или Статус > 299 Тогда
ДанныеОтвета = Новый Соответствие;
ДанныеТела = Новый Соответствие;
ТелоОтвета = Ответ.ПолучитьТелоКакСтроку();
ТелоОтвета = СокрЛП(ТелоОтвета);
@ -525,16 +632,16 @@
Если ЗначениеЗаполнено(ТелоОтвета) Тогда
Попытка
ДанныеОтвета = OPI_Инструменты.ОбработатьXML(ТелоОтвета);
ДанныеТела = OPI_Инструменты.ОбработатьXML(ТелоОтвета);
Исключение
ДанныеОтвета = Новый Структура("notXMLMessage", ТелоОтвета);
ДанныеТела.Вставить("notValidXMLMessage", ТелоОтвета);
КонецПопытки;
Иначе
ДанныеОтвета = Новый Структура;
КонецЕсли;
ДанныеОтвета = Новый Структура("status,response", Статус, ДанныеОтвета);
ДанныеОтвета = Новый Соответствие;
ДанныеОтвета.Вставить("status" , Статус);
ДанныеОтвета.Вставить("response", ДанныеТела);
Иначе
ДанныеОтвета = Ответ.ПолучитьТелоКакДвоичныеДанные();
@ -596,6 +703,38 @@
КонецПроцедуры
Процедура УстановитьТелоЗапроса(Запрос, Тело)
OPI_ПреобразованиеТипов.ПолучитьДвоичныеДанные(Тело);
Запрос.УстановитьТелоИзДвоичныхДанных(Тело);
КонецПроцедуры
Функция СформироватьURLБакета(Знач URL, Знач Имя, Знач Каталог)
OPI_ПреобразованиеТипов.ПолучитьСтроку(Имя);
OPI_ПреобразованиеТипов.ПолучитьБулево(Каталог);
Если Каталог Тогда
URL = URL + Имя;
Иначе
Если СтрНайти(URL, "://") Тогда
URL = СтрЗаменить(URL, "://", "://" + Имя + ".");
Иначе
URL = Имя + "." + URL;
КонецЕсли;
КонецЕсли;
Если Не СтрЗаканчиваетсяНа(URL, "/") Тогда
URL = URL + "/";
КонецЕсли;
Возврат URL;
КонецФункции
#КонецОбласти
#КонецОбласти

View File

@ -2113,6 +2113,8 @@
S3_СоздатьБакет(ПараметрыТеста);
S3_ПолучитьСписокБакетов(ПараметрыТеста);
S3_ПроверитьДоступностьБакета(ПараметрыТеста);
S3_УстановитьШифрованиеБакета(ПараметрыТеста);
S3_ПолучитьШифрованиеБакета(ПараметрыТеста);
S3_УдалитьБакет(ПараметрыТеста);
КонецПроцедуры
@ -14621,7 +14623,7 @@
// Directory bucket
Наименование = "opi-dirbucket1";
Наименование = "opi-dirbucket3";
Результат = OPI_S3.СоздатьБакет(Наименование, ОсновныеДанные);
@ -14631,7 +14633,7 @@
// General purpose bucket
Наименование = "opi-gpbucket1";
Наименование = "opi-gpbucket3";
Результат = OPI_S3.СоздатьБакет(Наименование, ОсновныеДанные, Ложь);
@ -14653,16 +14655,17 @@
// Directory bucket
Имя = "opi-dirbucket1";
Имя = "opi-dirbucket3";
Результат = OPI_S3.УдалитьБакет(Имя, ОсновныеДанные);
OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "УдалитьБакет (DB)", "S3"); // SKIP
OPI_ПолучениеДанныхТестов.Проверка_S3Успех(Результат); // SKIP
ОсновныеДанные.Вставить("URL", ПараметрыФункции["S3_URL"]); // SKIP
// General purpose bucket
Имя = "opi-gpbucket1";
Имя = "opi-gpbucket3";
Результат = OPI_S3.УдалитьБакет(Имя, ОсновныеДанные, Ложь);
@ -14693,13 +14696,13 @@
Процедура S3_ПроверитьДоступностьБакета(ПараметрыФункции)
URL = ПараметрыФункции["S3_URL"];
URL = ПараметрыФункции["S3_URL"];
AccessKey = ПараметрыФункции["S3_AccessKey"];
SecretKey = ПараметрыФункции["S3_SecretKey"];
Region = "BTC";
ОсновныеДанные = OPI_S3.ПолучитьСтруктуруДанных(URL, AccessKey, SecretKey, Region);
Наименование = "opi-dirbucket1";
Наименование = "opi-dirbucket3";
Результат = OPI_S3.ПроверитьДоступностьБакета(Наименование, ОсновныеДанные, Истина);
@ -14715,6 +14718,56 @@
КонецПроцедуры
Процедура S3_ПолучитьШифрованиеБакета(ПараметрыФункции)
URL = ПараметрыФункции["S3_URL"];
AccessKey = ПараметрыФункции["S3_AccessKey"];
SecretKey = ПараметрыФункции["S3_SecretKey"];
Region = "BTC";
ОсновныеДанные = OPI_S3.ПолучитьСтруктуруДанных(URL, AccessKey, SecretKey, Region);
Имя = "opi-newbucket2";
Результат = OPI_S3.ПолучитьШифрованиеБакета(Имя, ОсновныеДанные, Ложь);
// END
OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ПолучитьШифрованиеБакета", "S3");
OPI_ПолучениеДанныхТестов.Проверка_Соответствие(Результат);
OPI_ПолучениеДанныхТестов.ЗаписатьФайлЛога("", "ПолучитьШифрованиеБакета", "S3");
КонецПроцедуры
Процедура S3_УстановитьШифрованиеБакета(ПараметрыФункции)
URL = ПараметрыФункции["S3_URL"];
AccessKey = ПараметрыФункции["S3_AccessKey"];
SecretKey = ПараметрыФункции["S3_SecretKey"];
Region = "BTC";
ОсновныеДанные = OPI_S3.ПолучитьСтруктуруДанных(URL, AccessKey, SecretKey, Region);
Имя = "opi-newbucket2";
КонфигурацияXML = "<ServerSideEncryptionConfiguration xmlns=""http://s3.amazonaws.com/doc/2006-03-01/"">
| <Rule>
| <ApplyServerSideEncryptionByDefault>
| <SSEAlgorithm>AES256</SSEAlgorithm>
| </ApplyServerSideEncryptionByDefault>
| </Rule>
|</ServerSideEncryptionConfiguration>";
Результат = OPI_S3.УстановитьШифрованиеБакета(Имя, ОсновныеДанные, КонфигурацияXML, Ложь);
// END
OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "УстановитьШифрованиеБакета", "S3");
OPI_ПолучениеДанныхТестов.Проверка_S3НеПоддерживается(Результат);
OPI_ПолучениеДанныхТестов.ЗаписатьФайлЛога("", "УстановитьШифрованиеБакета", "S3");
КонецПроцедуры
#КонецОбласти
#КонецОбласти

View File

@ -443,6 +443,40 @@
КонецПроцедуры
Процедура ЗаписатьФайлЛога(Знач Данные, Знач Метод, Знач Библиотека) Экспорт
Попытка
ПутьЛогов = "./docs/ru/results";
ПутьЛоговБиблиотеки = ПутьЛогов + "/" + Библиотека;
КаталогЛогов = Новый Файл(ПутьЛогов);
Если Не КаталогЛогов.Существует() Тогда
СоздатьКаталог(ПутьЛогов);
КонецЕсли;
КаталогЛоговБиблиотеки = Новый Файл(ПутьЛоговБиблиотеки);
Если Не КаталогЛоговБиблиотеки.Существует() Тогда
СоздатьКаталог(ПутьЛоговБиблиотеки);
КонецЕсли;
ПутьКФайлу = ПутьЛоговБиблиотеки + "/" + Метод + ".log";
ФайлЛога = Новый Файл(ПутьКФайлу);
Если Не ФайлЛога.Существует() Тогда
ДокументЛога = Новый ТекстовыйДокумент;
ДокументЛога.УстановитьТекст(Данные);
ДокументЛога.Записать(ПутьКФайлу);
КонецЕсли;
Исключение
Сообщить("Не удалось записать файл лога!: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Процедура ЗаписатьЛогCLI(Знач Результат, Знач Метод, Знач Библиотека = "") Экспорт
ЗаписатьЛог(Результат, Метод + " (CLI)");
@ -1961,6 +1995,13 @@
КонецПроцедуры
Процедура Проверка_S3НеПоддерживается(Знач Результат) Экспорт
Успех = Результат["status"] = 501;
ОжидаетЧто(Успех).Равно(Истина);
КонецПроцедуры
#КонецОбласти
#КонецОбласти
@ -1997,9 +2038,9 @@
КонецФункции
Функция ПолучитьОбщийМодуль(Знач Имя)
Модуль = Вычислить(Имя);
Возврат Модуль;
КонецФункции
@ -2147,40 +2188,6 @@
КонецПроцедуры
Процедура ЗаписатьФайлЛога(Знач Данные, Знач Метод, Знач Библиотека)
Попытка
ПутьЛогов = "./docs/ru/results";
ПутьЛоговБиблиотеки = ПутьЛогов + "/" + Библиотека;
КаталогЛогов = Новый Файл(ПутьЛогов);
Если Не КаталогЛогов.Существует() Тогда
СоздатьКаталог(ПутьЛогов);
КонецЕсли;
КаталогЛоговБиблиотеки = Новый Файл(ПутьЛоговБиблиотеки);
Если Не КаталогЛоговБиблиотеки.Существует() Тогда
СоздатьКаталог(ПутьЛоговБиблиотеки);
КонецЕсли;
ПутьКФайлу = ПутьЛоговБиблиотеки + "/" + Метод + ".log";
ФайлЛога = Новый Файл(ПутьКФайлу);
Если Не ФайлЛога.Существует() Тогда
ДокументЛога = Новый ТекстовыйДокумент;
ДокументЛога.УстановитьТекст(Данные);
ДокументЛога.Записать(ПутьКФайлу);
КонецЕсли;
Исключение
Сообщить("Не удалось записать файл лога!: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Процедура ЗаписатьВызовCLI(Знач Библиотека, Знач Метод, Знач Опции)
Если Не OPI_Инструменты.ЭтоOneScript() Тогда

View File

@ -52,11 +52,18 @@
Файл = Новый Файл(Значение);
Если Файл.Существует() Тогда
Значение = Новый ДвоичныеДанные(Значение);
ИначеЕсли СтрНайти(Значение, "//") Тогда
ИначеЕсли СтрНачинаетсяС(СокрЛ(Значение), "http://")
Или СтрНачинаетсяС(СокрЛ(Значение), "https://") Тогда
Значение = OPI_Инструменты.Get(Значение);
Иначе
Значение = Base64Значение(Значение);
КонецЕсли;
КонецЕсли;
@ -243,20 +250,15 @@
Значение = ЧтениеТекста.Прочитать();
ЧтениеТекста.Закрыть();
ИначеЕсли СтрНачинаетсяС(нРег(Значение), "http") Тогда
ИВФ = ПолучитьИмяВременногоФайла();
КопироватьФайл(Значение, ИВФ);
ЧтениеТекста = Новый ЧтениеТекста(ИВФ);
Значение = ЧтениеТекста.Прочитать();
ЧтениеТекста.Закрыть();
УдалитьФайлы(ИВФ);
ИначеЕсли СтрНачинаетсяС(СокрЛ(Значение), "http://")
Или СтрНачинаетсяС(СокрЛ(Значение), "https://") Тогда
Значение = OPI_Инструменты.Get(Значение);
ПолучитьСтроку(Значение);
Иначе
Возврат;
Значение = OPI_Инструменты.ЧислоВСтроку(Значение);
КонецЕсли;
@ -267,7 +269,11 @@
ИначеЕсли ЭтоКоллекция(Значение) Тогда
Значение = OPI_Инструменты.JSONСтрокой(Значение);
ИначеЕсли ТипЗнч(Значение) = Тип("ЗаписьXML") Тогда
Значение = Значение.Закрыть();
Иначе
Возврат;
КонецЕсли;

View File

@ -483,6 +483,8 @@
Если МассивКлючЗначение.Количество() = КоличествоЧастей Тогда
СоответствиеВозврата.Вставить(МассивКлючЗначение[0], МассивКлючЗначение[1]);
Иначе
СоответствиеВозврата.Вставить(МассивКлючЗначение[0], Неопределено);
КонецЕсли;
КонецЦикла;

View File

@ -1,4 +1,4 @@
// OneScript: ./OInt/core/Modules/OPI_S3.os
// OneScript: ./OInt/core/Modules/OPI_S3.os
// Lib: S3
// CLI: s3
@ -81,29 +81,28 @@
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - сериализованный JSON ответа от хранилища
Функция ОтправитьЗапросБезТела(Знач Метод, Знач ОсновныеДанные, Знач Заголовки = Неопределено) Экспорт
ПроверитьОсновныеДанные(ОсновныеДанные);
URL = ОсновныеДанные["URL"];
СтруктураURL = OPI_Инструменты.РазбитьURL(URL);
Сервер = СтруктураURL["Сервер"];
Адрес = СтруктураURL["Адрес"];
Защищенное = СтруктураURL["Защищенное"];
Запрос = OPI_Инструменты.СоздатьЗапрос(Адрес);
Соединение = OPI_Инструменты.СоздатьСоединение(Сервер, Защищенное);
ДобавитьДополнительныеЗаголовки(Запрос, Заголовки);
ЗаголовокАвторизации = СоздатьЗаголовокАвторизации(ОсновныеДанные, Запрос, Соединение, Метод);
Запрос.Заголовки.Вставить("Authorization", ЗаголовокАвторизации);
Ответ = OPI_Инструменты.ВыполнитьЗапрос(Запрос, Соединение, Метод, , Истина);
Ответ = ОформитьОтвет(Ответ);
Ответ = ОтправитьЗапрос(Метод, ОсновныеДанные, , Заголовки);
Возврат Ответ;
КонецФункции
// Отправить запрос с телом
// Отправляет http запрос с телом
//
// Параметры:
// Метод - Строка - HTTP метод - method
// ОсновныеДанные - Структура Из КлючИЗначение - Основные данные запроса (c полным URL). См. ПолучитьСтруктуруДанных - data
// Тело - Строка, ДвоичныеДанные - Двоичное тело запроса или путь к файлу - body
// Заголовки - Соответствие Из КлючИЗначение - Дополнительные заголовки запроса, если необходимо - headers
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - сериализованный JSON ответа от хранилища
Функция ОтправитьЗапросСТелом(Знач Метод, Знач ОсновныеДанные, Знач Тело, Знач Заголовки = Неопределено) Экспорт
Ответ = ОтправитьЗапрос(Метод, ОсновныеДанные, Тело, Заголовки);
Возврат Ответ;
КонецФункции
#КонецОбласти
@ -186,6 +185,73 @@
КонецФункции
// Установить шифрование бакета
// Устанавлиает шифрование бакета по XML конфигурации
//
// Примечание:
// Метод в документации AWS: [PutBucketEncryption](@docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html)
//
// Параметры:
// Наименование - Строка - Наименование бакета - name
// ОсновныеДанные - Структура Из КлючИЗначение - Основные данные запроса. См. ПолучитьСтруктуруДанных - data
// XMLКонфигурация - Строка - XML строка или файл конфигурации шифрования - conf
// Каталог - Булево - Истина > Directory Bucket, Ложь > General Purpose Bucket - dir
// Заголовки - Соответствие Из КлючИЗначение - Дополнительные заголовки запроса, если необходимо - headers
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - сериализованный JSON ответа от хранилища
Функция УстановитьШифрованиеБакета(Знач Наименование
, Знач ОсновныеДанные
, Знач XMLКонфигурация
, Знач Каталог = Истина
, Знач Заголовки = Неопределено) Экспорт
OPI_ПреобразованиеТипов.ПолучитьСтроку(XMLКонфигурация, Истина);
XMLКонфигурация = ПолучитьДвоичныеДанныеИзСтроки(XMLКонфигурация);
URL = ПолучитьURLСервиса(ОсновныеДанные);
URL = СформироватьURLБакета(URL, Наименование, Каталог);
URL = URL + "?encryption";
ОсновныеДанные.Вставить("URL", URL);
Ответ = ОтправитьЗапросСТелом("PUT", ОсновныеДанные, XMLКонфигурация, Заголовки);
Возврат Ответ;
КонецФункции
// Получить шифрование бакета
// Получает установленную ранее конфигурацию шифрования бакета
//
// Примечание:
// Метод в документации AWS: [GetBucketEncryption](@docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html)
//
// Параметры:
// Наименование - Строка - Наименование бакета - name
// ОсновныеДанные - Структура Из КлючИЗначение - Основные данные запроса. См. ПолучитьСтруктуруДанных - data
// Каталог - Булево - Истина > Directory Bucket, Ложь > General Purpose Bucket - dir
// Заголовки - Соответствие Из КлючИЗначение - Дополнительные заголовки запроса, если необходимо - headers
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - сериализованный JSON ответа от хранилища
Функция ПолучитьШифрованиеБакета(Знач Наименование
, Знач ОсновныеДанные
, Знач Каталог = Истина
, Знач Заголовки = Неопределено) Экспорт
URL = ПолучитьURLСервиса(ОсновныеДанные);
URL = СформироватьURLБакета(URL, Наименование, Каталог);
URL = URL + "?encryption";
ОсновныеДанные.Вставить("URL", URL);
Ответ = ОтправитьЗапросБезТела("GET", ОсновныеДанные, Заголовки);
Возврат Ответ;
КонецФункции
// Получить список бакетов
// Получает список бакетов. Возможно использование отборов, если они поддерживаются сервисом
//
@ -370,26 +436,23 @@
КонецФункции
Функция ПолучитьСтрокуПараметров(Знач Запрос)
Функция ПолучитьСтрокуПараметров(Запрос)
URI = Запрос.АдресРесурса;
НачалоПараметров = СтрНайти(URI, "?");
Если НачалоПараметров = 0 Тогда
Если НачалоПараметров = 0 Тогда
СтрокаПараметров = "";
Иначе
ДлинаURI = СтрДлина(URI);
СтрокаПараметров = Прав(URI, ДлинаURI - НачалоПараметров);
ДлинаURI = СтрДлина(URI);
СтрокаПараметров = Прав(URI, ДлинаURI - НачалоПараметров);
ОбработатьСтрокуПараметровЗапроса(СтрокаПараметров);
КонецЕсли;
МассивПараметров = СтрРазделить(СтрокаПараметров, "&");
СписокПараметров = Новый СписокЗначений();
СписокПараметров.ЗагрузитьЗначения(МассивПараметров);
СписокПараметров.СортироватьПоЗначению();
СтрокаПараметров = СтрСоединить(СписокПараметров.ВыгрузитьЗначения(), "&");
Возврат СтрокаПараметров;
КонецФункции
@ -482,28 +545,69 @@
КонецФункции
Процедура ОбработатьСтрокуПараметровЗапроса(СтрокаПараметров)
МассивПараметров = СтрРазделить(СтрокаПараметров, "&");
СписокПараметров = Новый СписокЗначений();
СписокПараметров.ЗагрузитьЗначения(МассивПараметров);
СписокПараметров.СортироватьПоЗначению();
МассивПараметров = СписокПараметров.ВыгрузитьЗначения();
КонечныйМассивПараметров = Новый Массив;
Для Н = 0 По МассивПараметров.ВГраница() Цикл
ПараметрЗапроса = МассивПараметров[Н];
Если СтрНайти(ПараметрЗапроса, "=") = 0 Тогда
МассивПараметров[Н] = ПараметрЗапроса + "=";
КонецЕсли;
КонецЦикла;
СтрокаПараметров = СтрСоединить(МассивПараметров, "&");
КонецПроцедуры
#КонецОбласти
#Область Прочее
Функция ОтправитьЗапрос(Знач Метод, Знач ОсновныеДанные, Знач Тело = Неопределено, Знач Заголовки = Неопределено)
ПроверитьОсновныеДанные(ОсновныеДанные);
URL = ОсновныеДанные["URL"];
СтруктураURL = OPI_Инструменты.РазбитьURL(URL);
Сервер = СтруктураURL["Сервер"];
Адрес = СтруктураURL["Адрес"];
Защищенное = СтруктураURL["Защищенное"];
Запрос = OPI_Инструменты.СоздатьЗапрос(Адрес);
Соединение = OPI_Инструменты.СоздатьСоединение(Сервер, Защищенное);
Если ЗначениеЗаполнено(Тело) Тогда
УстановитьТелоЗапроса(Запрос, Тело);
КонецЕсли;
ДобавитьДополнительныеЗаголовки(Запрос, Заголовки);
ЗаголовокАвторизации = СоздатьЗаголовокАвторизации(ОсновныеДанные, Запрос, Соединение, Метод);
Запрос.Заголовки.Вставить("Authorization", ЗаголовокАвторизации);
Ответ = OPI_Инструменты.ВыполнитьЗапрос(Запрос, Соединение, Метод, , Истина);
Ответ = ОформитьОтвет(Ответ);
Возврат Ответ;
КонецФункции
Функция УправлениеБакетом(Знач Имя, Знач ОсновныеДанные, Знач Каталог, Знач Метод, Знач Заголовки)
OPI_ПреобразованиеТипов.ПолучитьСтроку(Имя);
OPI_ПреобразованиеТипов.ПолучитьБулево(Каталог);
URL = ПолучитьURLСервиса(ОсновныеДанные);
Если Каталог Тогда
URL = URL + Имя;
Иначе
Если СтрНайти(URL, "://") Тогда
URL = СтрЗаменить(URL, "://", "://" + Имя + ".");
Иначе
URL = Имя + "." + URL;
КонецЕсли;
КонецЕсли;
URL = ПолучитьURLСервиса(ОсновныеДанные);
URL = СформироватьURLБакета(URL, Имя, Каталог);
ОсновныеДанные.Вставить("URL", URL);
@ -518,6 +622,9 @@
Статус = Ответ.КодСостояния;
Если Не ОжидаютсяДвоичные Или Статус > 299 Тогда
ДанныеОтвета = Новый Соответствие;
ДанныеТела = Новый Соответствие;
ТелоОтвета = Ответ.ПолучитьТелоКакСтроку();
ТелоОтвета = СокрЛП(ТелоОтвета);
@ -525,16 +632,16 @@
Если ЗначениеЗаполнено(ТелоОтвета) Тогда
Попытка
ДанныеОтвета = OPI_Инструменты.ОбработатьXML(ТелоОтвета);
ДанныеТела = OPI_Инструменты.ОбработатьXML(ТелоОтвета);
Исключение
ДанныеОтвета = Новый Структура("notXMLMessage", ТелоОтвета);
ДанныеТела.Вставить("notValidXMLMessage", ТелоОтвета);
КонецПопытки;
Иначе
ДанныеОтвета = Новый Структура;
КонецЕсли;
ДанныеОтвета = Новый Структура("status,response", Статус, ДанныеОтвета);
ДанныеОтвета = Новый Соответствие;
ДанныеОтвета.Вставить("status" , Статус);
ДанныеОтвета.Вставить("response", ДанныеТела);
Иначе
ДанныеОтвета = Ответ.ПолучитьТелоКакДвоичныеДанные();
@ -596,6 +703,38 @@
КонецПроцедуры
Процедура УстановитьТелоЗапроса(Запрос, Тело)
OPI_ПреобразованиеТипов.ПолучитьДвоичныеДанные(Тело);
Запрос.УстановитьТелоИзДвоичныхДанных(Тело);
КонецПроцедуры
Функция СформироватьURLБакета(Знач URL, Знач Имя, Знач Каталог)
OPI_ПреобразованиеТипов.ПолучитьСтроку(Имя);
OPI_ПреобразованиеТипов.ПолучитьБулево(Каталог);
Если Каталог Тогда
URL = URL + Имя;
Иначе
Если СтрНайти(URL, "://") Тогда
URL = СтрЗаменить(URL, "://", "://" + Имя + ".");
Иначе
URL = Имя + "." + URL;
КонецЕсли;
КонецЕсли;
Если Не СтрЗаканчиваетсяНа(URL, "/") Тогда
URL = URL + "/";
КонецЕсли;
Возврат URL;
КонецФункции
#КонецОбласти
#КонецОбласти

View File

@ -1,4 +1,4 @@
// OneScript: ./OInt/tools/Modules/internal/Modules/OPI_Инструменты.os
// OneScript: ./OInt/tools/Modules/internal/Modules/OPI_Инструменты.os
// MIT License
@ -483,6 +483,8 @@
Если МассивКлючЗначение.Количество() = КоличествоЧастей Тогда
СоответствиеВозврата.Вставить(МассивКлючЗначение[0], МассивКлючЗначение[1]);
Иначе
СоответствиеВозврата.Вставить(МассивКлючЗначение[0], Неопределено);
КонецЕсли;
КонецЦикла;

View File

@ -1,4 +1,4 @@
// OneScript: ./OInt/tools/Modules/OPI_ПолучениеДанныхТестов.os
// OneScript: ./OInt/tools/Modules/OPI_ПолучениеДанныхТестов.os
// MIT License
@ -443,6 +443,40 @@
КонецПроцедуры
Процедура ЗаписатьФайлЛога(Знач Данные, Знач Метод, Знач Библиотека) Экспорт
Попытка
ПутьЛогов = "./docs/ru/results";
ПутьЛоговБиблиотеки = ПутьЛогов + "/" + Библиотека;
КаталогЛогов = Новый Файл(ПутьЛогов);
Если Не КаталогЛогов.Существует() Тогда
СоздатьКаталог(ПутьЛогов);
КонецЕсли;
КаталогЛоговБиблиотеки = Новый Файл(ПутьЛоговБиблиотеки);
Если Не КаталогЛоговБиблиотеки.Существует() Тогда
СоздатьКаталог(ПутьЛоговБиблиотеки);
КонецЕсли;
ПутьКФайлу = ПутьЛоговБиблиотеки + "/" + Метод + ".log";
ФайлЛога = Новый Файл(ПутьКФайлу);
Если Не ФайлЛога.Существует() Тогда
ДокументЛога = Новый ТекстовыйДокумент;
ДокументЛога.УстановитьТекст(Данные);
ДокументЛога.Записать(ПутьКФайлу);
КонецЕсли;
Исключение
Сообщить("Не удалось записать файл лога!: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Процедура ЗаписатьЛогCLI(Знач Результат, Знач Метод, Знач Библиотека = "") Экспорт
ЗаписатьЛог(Результат, Метод + " (CLI)");
@ -1961,6 +1995,13 @@
КонецПроцедуры
Процедура Проверка_S3НеПоддерживается(Знач Результат) Экспорт
Успех = Результат["status"] = 501;
ОжидаетЧто(Успех).Равно(Истина);
КонецПроцедуры
#КонецОбласти
#КонецОбласти
@ -2147,40 +2188,6 @@
КонецПроцедуры
Процедура ЗаписатьФайлЛога(Знач Данные, Знач Метод, Знач Библиотека)
Попытка
ПутьЛогов = "./docs/ru/results";
ПутьЛоговБиблиотеки = ПутьЛогов + "/" + Библиотека;
КаталогЛогов = Новый Файл(ПутьЛогов);
Если Не КаталогЛогов.Существует() Тогда
СоздатьКаталог(ПутьЛогов);
КонецЕсли;
КаталогЛоговБиблиотеки = Новый Файл(ПутьЛоговБиблиотеки);
Если Не КаталогЛоговБиблиотеки.Существует() Тогда
СоздатьКаталог(ПутьЛоговБиблиотеки);
КонецЕсли;
ПутьКФайлу = ПутьЛоговБиблиотеки + "/" + Метод + ".log";
ФайлЛога = Новый Файл(ПутьКФайлу);
Если Не ФайлЛога.Существует() Тогда
ДокументЛога = Новый ТекстовыйДокумент;
ДокументЛога.УстановитьТекст(Данные);
ДокументЛога.Записать(ПутьКФайлу);
КонецЕсли;
Исключение
Сообщить("Не удалось записать файл лога!: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Процедура ЗаписатьВызовCLI(Знач Библиотека, Знач Метод, Знач Опции)
Если Не OPI_Инструменты.ЭтоOneScript() Тогда

View File

@ -1,4 +1,4 @@
// OneScript: ./OInt/tools/Modules/OPI_ПреобразованиеТипов.os
// OneScript: ./OInt/tools/Modules/OPI_ПреобразованиеТипов.os
// MIT License
@ -52,11 +52,18 @@
Файл = Новый Файл(Значение);
Если Файл.Существует() Тогда
Значение = Новый ДвоичныеДанные(Значение);
ИначеЕсли СтрНайти(Значение, "//") Тогда
ИначеЕсли СтрНачинаетсяС(СокрЛ(Значение), "http://")
Или СтрНачинаетсяС(СокрЛ(Значение), "https://") Тогда
Значение = OPI_Инструменты.Get(Значение);
Иначе
Значение = Base64Значение(Значение);
КонецЕсли;
КонецЕсли;
@ -243,20 +250,15 @@
Значение = ЧтениеТекста.Прочитать();
ЧтениеТекста.Закрыть();
ИначеЕсли СтрНачинаетсяС(нРег(Значение), "http") Тогда
ИВФ = ПолучитьИмяВременногоФайла();
КопироватьФайл(Значение, ИВФ);
ЧтениеТекста = Новый ЧтениеТекста(ИВФ);
Значение = ЧтениеТекста.Прочитать();
ЧтениеТекста.Закрыть();
УдалитьФайлы(ИВФ);
ИначеЕсли СтрНачинаетсяС(СокрЛ(Значение), "http://")
Или СтрНачинаетсяС(СокрЛ(Значение), "https://") Тогда
Значение = OPI_Инструменты.Get(Значение);
ПолучитьСтроку(Значение);
Иначе
Возврат;
Значение = OPI_Инструменты.ЧислоВСтроку(Значение);
КонецЕсли;
@ -267,7 +269,11 @@
ИначеЕсли ЭтоКоллекция(Значение) Тогда
Значение = OPI_Инструменты.JSONСтрокой(Значение);
ИначеЕсли ТипЗнч(Значение) = Тип("ЗаписьXML") Тогда
Значение = Значение.Закрыть();
Иначе
Возврат;
КонецЕсли;

View File

@ -1,4 +1,4 @@
// OneScript: ./OInt/tests/Modules/internal/OPI_Тесты.os
// OneScript: ./OInt/tests/Modules/internal/OPI_Тесты.os
// MIT License
@ -2113,6 +2113,8 @@
S3_СоздатьБакет(ПараметрыТеста);
S3_ПолучитьСписокБакетов(ПараметрыТеста);
S3_ПроверитьДоступностьБакета(ПараметрыТеста);
S3_УстановитьШифрованиеБакета(ПараметрыТеста);
S3_ПолучитьШифрованиеБакета(ПараметрыТеста);
S3_УдалитьБакет(ПараметрыТеста);
КонецПроцедуры
@ -14621,7 +14623,7 @@
// Directory bucket
Наименование = "opi-dirbucket1";
Наименование = "opi-dirbucket3";
Результат = OPI_S3.СоздатьБакет(Наименование, ОсновныеДанные);
@ -14631,7 +14633,7 @@
// General purpose bucket
Наименование = "opi-gpbucket1";
Наименование = "opi-gpbucket3";
Результат = OPI_S3.СоздатьБакет(Наименование, ОсновныеДанные, Ложь);
@ -14653,16 +14655,17 @@
// Directory bucket
Имя = "opi-dirbucket1";
Имя = "opi-dirbucket3";
Результат = OPI_S3.УдалитьБакет(Имя, ОсновныеДанные);
OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "УдалитьБакет (DB)", "S3"); // SKIP
OPI_ПолучениеДанныхТестов.Проверка_S3Успех(Результат); // SKIP
ОсновныеДанные.Вставить("URL", ПараметрыФункции["S3_URL"]); // SKIP
// General purpose bucket
Имя = "opi-gpbucket1";
Имя = "opi-gpbucket3";
Результат = OPI_S3.УдалитьБакет(Имя, ОсновныеДанные, Ложь);
@ -14693,13 +14696,13 @@
Процедура S3_ПроверитьДоступностьБакета(ПараметрыФункции)
URL = ПараметрыФункции["S3_URL"];
URL = ПараметрыФункции["S3_URL"];
AccessKey = ПараметрыФункции["S3_AccessKey"];
SecretKey = ПараметрыФункции["S3_SecretKey"];
Region = "BTC";
ОсновныеДанные = OPI_S3.ПолучитьСтруктуруДанных(URL, AccessKey, SecretKey, Region);
Наименование = "opi-dirbucket1";
Наименование = "opi-dirbucket3";
Результат = OPI_S3.ПроверитьДоступностьБакета(Наименование, ОсновныеДанные, Истина);
@ -14715,6 +14718,56 @@
КонецПроцедуры
Процедура S3_ПолучитьШифрованиеБакета(ПараметрыФункции)
URL = ПараметрыФункции["S3_URL"];
AccessKey = ПараметрыФункции["S3_AccessKey"];
SecretKey = ПараметрыФункции["S3_SecretKey"];
Region = "BTC";
ОсновныеДанные = OPI_S3.ПолучитьСтруктуруДанных(URL, AccessKey, SecretKey, Region);
Имя = "opi-newbucket2";
Результат = OPI_S3.ПолучитьШифрованиеБакета(Имя, ОсновныеДанные, Ложь);
// END
OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ПолучитьШифрованиеБакета", "S3");
OPI_ПолучениеДанныхТестов.Проверка_Соответствие(Результат);
OPI_ПолучениеДанныхТестов.ЗаписатьФайлЛога("", "ПолучитьШифрованиеБакета", "S3");
КонецПроцедуры
Процедура S3_УстановитьШифрованиеБакета(ПараметрыФункции)
URL = ПараметрыФункции["S3_URL"];
AccessKey = ПараметрыФункции["S3_AccessKey"];
SecretKey = ПараметрыФункции["S3_SecretKey"];
Region = "BTC";
ОсновныеДанные = OPI_S3.ПолучитьСтруктуруДанных(URL, AccessKey, SecretKey, Region);
Имя = "opi-newbucket2";
XMLКонфигурация = "<ServerSideEncryptionConfiguration xmlns=""http://s3.amazonaws.com/doc/2006-03-01/"">
| <Rule>
| <ApplyServerSideEncryptionByDefault>
| <SSEAlgorithm>AES256</SSEAlgorithm>
| </ApplyServerSideEncryptionByDefault>
| </Rule>
|</ServerSideEncryptionConfiguration>";
Результат = OPI_S3.УстановитьШифрованиеБакета(Имя, ОсновныеДанные, XMLКонфигурация, Ложь);
// END
OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "УстановитьШифрованиеБакета", "S3");
OPI_ПолучениеДанныхТестов.Проверка_S3НеПоддерживается(Результат);
OPI_ПолучениеДанныхТестов.ЗаписатьФайлЛога("", "УстановитьШифрованиеБакета", "S3");
КонецПроцедуры
#КонецОбласти
#КонецОбласти