You've already forked OpenIntegrations
mirror of
https://github.com/Bayselonarrend/OpenIntegrations.git
synced 2025-11-23 22:05:15 +02:00
Функция создания токена для Service аккаунта Google
This commit is contained in:
BIN
data.json.gpg
BIN
data.json.gpg
Binary file not shown.
BIN
docs/docusaurus/static/img/Docs/GoogleCalendar/13.png
vendored
Normal file
BIN
docs/docusaurus/static/img/Docs/GoogleCalendar/13.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 92 KiB |
BIN
docs/docusaurus/static/img/Docs/GoogleCalendar/14.png
vendored
Normal file
BIN
docs/docusaurus/static/img/Docs/GoogleCalendar/14.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
BIN
docs/docusaurus/static/img/Docs/GoogleCalendar/15.png
vendored
Normal file
BIN
docs/docusaurus/static/img/Docs/GoogleCalendar/15.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
BIN
docs/docusaurus/static/img/Docs/GoogleCalendar/16.png
vendored
Normal file
BIN
docs/docusaurus/static/img/Docs/GoogleCalendar/16.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
BIN
docs/docusaurus/static/img/Docs/GoogleCalendar/17.png
vendored
Normal file
BIN
docs/docusaurus/static/img/Docs/GoogleCalendar/17.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
@@ -16,7 +16,7 @@ opt-level = "z"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
addin1c = "0.5.0"
|
addin1c = "0.5.0"
|
||||||
hmac = "0.12"
|
hmac = "0.12"
|
||||||
sha1 = "0.10"
|
sha1 = { version = "0.10", features = ["oid"] }
|
||||||
sha2 = "0.10"
|
sha2 = { version = "0.10", features = ["oid"] }
|
||||||
rsa = "0.9"
|
rsa = "0.9"
|
||||||
digest = "0.10.7"
|
digest = "0.10.7"
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
"MAIN ---"
|
"MAIN ---"
|
||||||
linux-vdso.so.1 (0x00007ffd2bba8000)
|
linux-vdso.so.1 (0x00007fff64dcd000)
|
||||||
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f8e3f32c000)
|
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f075273c000)
|
||||||
libc.so.6 => /lib64/libc.so.6 (0x00007f8e3ef55000)
|
libc.so.6 => /lib64/libc.so.6 (0x00007f0752365000)
|
||||||
libdl.so.2 => /lib64/libdl.so.2 (0x00007f8e3ed51000)
|
libdl.so.2 => /lib64/libdl.so.2 (0x00007f0752161000)
|
||||||
/lib64/ld-linux-x86-64.so.2 (0x00007f8e3f54c000)
|
/lib64/ld-linux-x86-64.so.2 (0x00007f075295c000)
|
||||||
GLIBC_2.2.5
|
GLIBC_2.2.5
|
||||||
GLIBC_2.3
|
GLIBC_2.3
|
||||||
GLIBC_2.14
|
GLIBC_2.14
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
use hmac::{Hmac, Mac};
|
use hmac::{Hmac, Mac};
|
||||||
use sha1::Sha1;
|
use sha1::Sha1;
|
||||||
use sha2::{Sha256};
|
use sha2::Sha256;
|
||||||
use rsa::{RsaPrivateKey, pkcs1::DecodeRsaPrivateKey};
|
use rsa::{RsaPrivateKey, pkcs1::DecodeRsaPrivateKey, pkcs8::DecodePrivateKey};
|
||||||
use rsa::pkcs1v15::SigningKey;
|
use rsa::pkcs1v15::{Pkcs1v15Sign};
|
||||||
use rsa::signature::digest::{Digest, FixedOutput};
|
use rsa::signature::digest::{Digest, FixedOutput};
|
||||||
use rsa::signature::{Signer, SignatureEncoding};
|
|
||||||
|
|
||||||
// ===== HMAC ===== //
|
// ===== HMAC ===== //
|
||||||
|
|
||||||
@@ -30,45 +29,49 @@ pub fn hmac_sha256(key: &[u8], data: &[u8]) -> Result<Vec<u8>, String> {
|
|||||||
|
|
||||||
// ===== RSA ===== //
|
// ===== RSA ===== //
|
||||||
|
|
||||||
fn load_rsa_key(key: &[u8]) -> Result<RsaPrivateKey, String> {
|
pub fn load_rsa_key(key_data: &[u8]) -> Result<RsaPrivateKey, String> {
|
||||||
|
if let Ok(key) = RsaPrivateKey::from_pkcs1_der(key_data) {
|
||||||
|
return Ok(key);
|
||||||
|
}
|
||||||
|
|
||||||
match RsaPrivateKey::from_pkcs1_der(key){
|
if let Ok(key) = RsaPrivateKey::from_pkcs8_der(key_data) {
|
||||||
Ok(v) => Ok(v),
|
return Ok(key);
|
||||||
Err(_) => {
|
}
|
||||||
|
|
||||||
let pem_string = match std::str::from_utf8(key){
|
let pem_str = match std::str::from_utf8(key_data) {
|
||||||
Ok(pem_str) => pem_str,
|
Ok(s) => s,
|
||||||
Err(_) => return Err("Invalid RSA key format".to_string()),
|
Err(_) => return Err("Invalid key format: not DER or PEM".to_string()),
|
||||||
};
|
};
|
||||||
|
|
||||||
match RsaPrivateKey::from_pkcs1_pem(pem_string){
|
if let Ok(key) = RsaPrivateKey::from_pkcs1_pem(pem_str) {
|
||||||
Ok(v) => Ok(v),
|
return Ok(key);
|
||||||
Err(_) => Err("Invalid RSA key format".to_string()),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Ok(key) = RsaPrivateKey::from_pkcs8_pem(pem_str) {
|
||||||
|
return Ok(key);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Err("Invalid RSA key format. Expected: PKCS#1/8 PEM or DER".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rsa_sign<D>(key: &RsaPrivateKey, data: &[u8]) -> Result<Vec<u8>, String>
|
fn rsa_sign<D>(key: &RsaPrivateKey, data: &[u8]) -> Result<Vec<u8>, String>
|
||||||
where
|
where
|
||||||
D: Digest + FixedOutput,
|
D: Digest + FixedOutput + rsa::pkcs8::AssociatedOid,
|
||||||
SigningKey<D>: From<RsaPrivateKey>,
|
|
||||||
{
|
{
|
||||||
let signing_key = SigningKey::<D>::new_unprefixed(key.clone());
|
// Создаем схему подписи с указанием хеш-алгоритма
|
||||||
|
let scheme = Pkcs1v15Sign::new::<D>();
|
||||||
|
|
||||||
|
// Хешируем данные
|
||||||
let mut hasher = D::new();
|
let mut hasher = D::new();
|
||||||
Digest::update(&mut hasher, data);
|
Digest::update(&mut hasher, data);
|
||||||
let digest = hasher.finalize();
|
let digest = hasher.finalize();
|
||||||
|
|
||||||
let sign_result = signing_key.try_sign(&digest);
|
// Подписываем хеш
|
||||||
|
let signature = key.sign(scheme, &digest).map_err(|e| format!("RSA signing error: {}", e))?;
|
||||||
|
|
||||||
match sign_result {
|
Ok(signature)
|
||||||
Ok(signature) => Ok(signature.to_vec()),
|
|
||||||
Err(e) => Err(format!("RSA signing error: {}", e)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Подписывает данные с помощью RSA-SHA1
|
/// Подписывает данные с помощью RSA-SHA1
|
||||||
pub fn rsa_sha1(key: &[u8], data: &[u8]) -> Result<Vec<u8>, String> {
|
pub fn rsa_sha1(key: &[u8], data: &[u8]) -> Result<Vec<u8>, String> {
|
||||||
let key = load_rsa_key(key)?;
|
let key = load_rsa_key(key)?;
|
||||||
|
|||||||
BIN
src/en/OInt/addins/OPI_Cryptography.zip
vendored
BIN
src/en/OInt/addins/OPI_Cryptography.zip
vendored
Binary file not shown.
Binary file not shown.
BIN
src/ru/OInt/addins/OPI_Cryptography.zip
vendored
BIN
src/ru/OInt/addins/OPI_Cryptography.zip
vendored
Binary file not shown.
@@ -1,4 +1,4 @@
|
|||||||
// OneScript: ./OInt/core/Modules/OPI_GoogleWorkspace.os
|
// OneScript: ./OInt/core/Modules/OPI_GoogleWorkspace.os
|
||||||
// Lib: Google Workspace
|
// Lib: Google Workspace
|
||||||
// CLI: google
|
// CLI: google
|
||||||
|
|
||||||
@@ -136,6 +136,73 @@
|
|||||||
|
|
||||||
КонецФункции
|
КонецФункции
|
||||||
|
|
||||||
|
// Получить токен service аккаунта
|
||||||
|
// Получает токен авторизации по данным service аккаунта
|
||||||
|
//
|
||||||
|
// Примечание:
|
||||||
|
// Список доступных областей действия: [developers.google.com](https://developers.google.com/identity/protocols/oauth2/scopes)
|
||||||
|
//
|
||||||
|
// Параметры:
|
||||||
|
// Данные - Произвольный - JSON данные авторизации как файл, коллекция или двоичные данные - auth
|
||||||
|
// ОбластиДействия - Массив Из Строка - Область действия (scope) или массив областей - scope
|
||||||
|
// ВремяЖизни - Число - Время жизни токена в секундах - exp
|
||||||
|
//
|
||||||
|
// Возвращаемое значение:
|
||||||
|
// Соответствие Из КлючИЗначение - сериализованный JSON ответа от Google
|
||||||
|
Функция ПолучитьТокенServiceАккаунта(Знач Данные, Знач ОбластиДействия, Знач ВремяЖизни = 3600) Экспорт
|
||||||
|
|
||||||
|
ТекстОшибки = "Переданные данные service аккаунта не являются валидным JSON";
|
||||||
|
OPI_ПреобразованиеТипов.ПолучитьКоллекциюКлючИЗначение(Данные, ТекстОшибки);
|
||||||
|
OPI_ПреобразованиеТипов.ПолучитьЧисло(ВремяЖизни);
|
||||||
|
OPI_ПреобразованиеТипов.ПолучитьМассив(ОбластиДействия);
|
||||||
|
|
||||||
|
МассивОбязательныхПолей = Новый Массив;
|
||||||
|
МассивОбязательныхПолей.Добавить("token_uri");
|
||||||
|
МассивОбязательныхПолей.Добавить("client_email");
|
||||||
|
МассивОбязательныхПолей.Добавить("private_key");
|
||||||
|
МассивОбязательныхПолей.Добавить("private_key_id");
|
||||||
|
|
||||||
|
ОтсутствующиеПоля = OPI_Инструменты.НайтиОтсутствующиеПоляКоллекции(Данные, МассивОбязательныхПолей);
|
||||||
|
|
||||||
|
Если ЗначениеЗаполнено(ОтсутствующиеПоля) Тогда
|
||||||
|
|
||||||
|
ШаблонОшибкиПолей = "В данных service аккаунта отсутствуют обязательные поля: %1";
|
||||||
|
ТекстОшибкиПолей = СтрШаблон(ШаблонОшибкиПолей, СтрСоединить(ОтсутствующиеПоля, ", "));
|
||||||
|
ВызватьИсключение ТекстОшибкиПолей;
|
||||||
|
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
ОбластиДействияСтрокой = СтрСоединить(ОбластиДействия, " ");
|
||||||
|
КлючПодписи = Данные["private_key"];
|
||||||
|
URL = Данные["token_uri"];
|
||||||
|
|
||||||
|
ТекущаяДата = ТекущаяУниверсальнаяДата();
|
||||||
|
ДатаСгорания = ТекущаяДата + ВремяЖизни;
|
||||||
|
|
||||||
|
UnixTime = OPI_Инструменты.UnixTime(ТекущаяДата);
|
||||||
|
ExpTime = OPI_Инструменты.UnixTime(ДатаСгорания);
|
||||||
|
|
||||||
|
Payload = Новый Структура;
|
||||||
|
|
||||||
|
Payload.Вставить("iss" , Данные["client_email"]);
|
||||||
|
Payload.Вставить("scope", ОбластиДействияСтрокой);
|
||||||
|
Payload.Вставить("aud" , URL);
|
||||||
|
Payload.Вставить("exp" , Число(ExpTime));
|
||||||
|
Payload.Вставить("iat" , Число(UnixTime));
|
||||||
|
|
||||||
|
ДопЗаголовки = Новый Структура("kid", Данные["private_key_id"]);
|
||||||
|
|
||||||
|
JWT = OPI_Криптография.JWT(Payload, КлючПодписи, "RS256", ДопЗаголовки);
|
||||||
|
|
||||||
|
Грант = "urn:ietf:params:oauth:grant-type:jwt-bearer";
|
||||||
|
СтруктураТела = Новый Структура("grant_type,assertion", Грант, JWT);
|
||||||
|
|
||||||
|
Ответ = OPI_ЗапросыHTTP.PostСТелом(URL, СтруктураТела, , Ложь);
|
||||||
|
|
||||||
|
Возврат Ответ;
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
#КонецОбласти
|
#КонецОбласти
|
||||||
|
|
||||||
#Область СлужебныйПрограммныйИнтерфейс
|
#Область СлужебныйПрограммныйИнтерфейс
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// OneScript: ./OInt/tools/Modules/internal/Modules/OPI_Криптография.os
|
// OneScript: ./OInt/tools/Modules/internal/Modules/OPI_Криптография.os
|
||||||
|
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
@@ -76,8 +76,62 @@
|
|||||||
|
|
||||||
КонецФункции
|
КонецФункции
|
||||||
|
|
||||||
|
Функция JWT(Знач Payload, Знач КлючПодписи, Знач Метод, Знач ДопЗаголовки = "") Экспорт
|
||||||
|
|
||||||
#Область БСП
|
OPI_ПреобразованиеТипов.ПолучитьСтроку(Метод);
|
||||||
|
OPI_ПреобразованиеТипов.ПолучитьКоллекциюКлючИЗначение(Payload);
|
||||||
|
OPI_ПреобразованиеТипов.ПолучитьДвоичныеДанные(КлючПодписи, Истина, Ложь);
|
||||||
|
|
||||||
|
Метод = вРег(Метод);
|
||||||
|
|
||||||
|
Если Метод = "HS256" Тогда
|
||||||
|
|
||||||
|
Алгоритм = "HMAC";
|
||||||
|
ФункцияХеша = "SHA256";
|
||||||
|
|
||||||
|
ИначеЕсли Метод = "RS256" Тогда
|
||||||
|
|
||||||
|
Алгоритм = "RSA";
|
||||||
|
ФункцияХеша = "SHA256";
|
||||||
|
|
||||||
|
Иначе
|
||||||
|
ВызватьИсключение "JWT: Неподдерживаемый метод";
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Заголовки = Новый Структура("alg,typ", Метод, "JWT");
|
||||||
|
|
||||||
|
Если ЗначениеЗаполнено(ДопЗаголовки) Тогда
|
||||||
|
|
||||||
|
OPI_ПреобразованиеТипов.ПолучитьКоллекциюКлючИЗначение(ДопЗаголовки);
|
||||||
|
|
||||||
|
Для Каждого КлючЗначение Из ДопЗаголовки Цикл
|
||||||
|
Заголовки.Вставить(КлючЗначение.Ключ, КлючЗначение.Значение);
|
||||||
|
КонецЦикла;
|
||||||
|
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
PayloadСтрокой = OPI_Инструменты.JSONСтрокой(Payload, , Ложь);
|
||||||
|
ЗаголовкиСтркой = OPI_Инструменты.JSONСтрокой(Заголовки, , Ложь);
|
||||||
|
|
||||||
|
PayloadДвоичные = ПолучитьДвоичныеДанныеИзСтроки(PayloadСтрокой);
|
||||||
|
ЗаголовкиДвоичные = ПолучитьДвоичныеДанныеИзСтроки(ЗаголовкиСтркой);
|
||||||
|
|
||||||
|
PayloadBase64 = Base64UrlEncode(PayloadДвоичные);
|
||||||
|
ЗаголовкиBase64 = Base64UrlEncode(ЗаголовкиДвоичные);
|
||||||
|
|
||||||
|
Токен = СтрШаблон("%1.%2", ЗаголовкиBase64, PayloadBase64);
|
||||||
|
ТокенДвоичные = ПолучитьДвоичныеДанныеИзСтроки(Токен);
|
||||||
|
|
||||||
|
Подпись = СоздатьПодпись(КлючПодписи, ТокенДвоичные, Алгоритм, ФункцияХеша);
|
||||||
|
ПодписьBase64 = Base64UrlEncode(Подпись);
|
||||||
|
|
||||||
|
Токен = СтрШаблон("%1.%2", Токен, ПодписьBase64);
|
||||||
|
|
||||||
|
Возврат Токен;
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
#Область Заимстованные
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Copyright (c) 2019, ООО 1С-Софт
|
// Copyright (c) 2019, ООО 1С-Софт
|
||||||
@@ -148,6 +202,41 @@
|
|||||||
|
|
||||||
КонецФункции
|
КонецФункции
|
||||||
|
|
||||||
|
// The MIT License (MIT)
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017 Vasily Pintov
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
// https://github.com/pintov/1c-jwt
|
||||||
|
|
||||||
|
Функция Base64UrlEncode(Знач Значение)
|
||||||
|
|
||||||
|
Вывод = Base64Строка(Значение);
|
||||||
|
Вывод = СтрРазделить(Вывод, "=")[0];
|
||||||
|
Вывод = СтрЗаменить(Вывод, Символы.ВК + Символы.ПС, "");
|
||||||
|
Вывод = СтрЗаменить(Вывод, "+", "-");
|
||||||
|
Вывод = СтрЗаменить(Вывод, "/", "_");
|
||||||
|
Возврат Вывод;
|
||||||
|
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
#КонецОбласти
|
#КонецОбласти
|
||||||
|
|
||||||
#КонецОбласти
|
#КонецОбласти
|
||||||
|
|||||||
@@ -841,10 +841,13 @@
|
|||||||
OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("Google_ClientSecret", ПараметрыТеста);
|
OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("Google_ClientSecret", ПараметрыТеста);
|
||||||
OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("Google_Code" , ПараметрыТеста);
|
OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("Google_Code" , ПараметрыТеста);
|
||||||
OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("Google_Refresh" , ПараметрыТеста);
|
OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("Google_Refresh" , ПараметрыТеста);
|
||||||
|
OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("Google_ServiceData" , ПараметрыТеста);
|
||||||
|
OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("Access_Token" , ПараметрыТеста);
|
||||||
|
|
||||||
GoogleWorkspace_СформироватьСсылкуПолученияКода(ПараметрыТеста);
|
GoogleWorkspace_СформироватьСсылкуПолученияКода(ПараметрыТеста);
|
||||||
GoogleWorkspace_ПолучитьТокенПоКоду(ПараметрыТеста);
|
GoogleWorkspace_ПолучитьТокенПоКоду(ПараметрыТеста);
|
||||||
GoogleWorkspace_ОбновитьТокен(ПараметрыТеста);
|
GoogleWorkspace_ОбновитьТокен(ПараметрыТеста);
|
||||||
|
GoogleWorkspace_ПолучитьТокенServiceАккаунта(ПараметрыТеста);
|
||||||
|
|
||||||
КонецПроцедуры
|
КонецПроцедуры
|
||||||
|
|
||||||
@@ -5416,13 +5419,38 @@
|
|||||||
// END
|
// END
|
||||||
|
|
||||||
OPI_ПолучениеДанныхТестов.Проверка_ГуглТокен(Результат);
|
OPI_ПолучениеДанныхТестов.Проверка_ГуглТокен(Результат);
|
||||||
|
|
||||||
OPI_ПолучениеДанныхТестов.ЗаписатьПараметр("Google_Token", Результат["access_token"]);
|
OPI_ПолучениеДанныхТестов.ЗаписатьПараметр("Google_Token", Результат["access_token"]);
|
||||||
|
|
||||||
OPI_Инструменты.Пауза(5);
|
OPI_Инструменты.Пауза(5);
|
||||||
|
|
||||||
КонецПроцедуры
|
КонецПроцедуры
|
||||||
|
|
||||||
|
Процедура GoogleWorkspace_ПолучитьТокенServiceАккаунта(ПараметрыФункции)
|
||||||
|
|
||||||
|
Данные = ПараметрыФункции["Google_ServiceData"]; // URL, двоичные данные, файл или коллекция
|
||||||
|
|
||||||
|
Токен = ПараметрыФункции["Access_Token"]; // SKIP
|
||||||
|
Данные = OPI_ЗапросыHTTP // SKIP
|
||||||
|
.НовыйЗапрос() // SKIP
|
||||||
|
.Инициализировать(Данные) // SKIP
|
||||||
|
.ДобавитьBearerАвторизацию(Токен) // SKIP
|
||||||
|
.ОбработатьЗапрос("GET") // SKIP
|
||||||
|
.ВернутьОтветКакДвоичныеДанные(); // SKIP
|
||||||
|
|
||||||
|
ОбластиДействия = Новый Массив;
|
||||||
|
ОбластиДействия.Добавить("https://www.googleapis.com/auth/calendar");
|
||||||
|
ОбластиДействия.Добавить("https://www.googleapis.com/auth/drive");
|
||||||
|
ОбластиДействия.Добавить("https://www.googleapis.com/auth/spreadsheets");
|
||||||
|
|
||||||
|
Результат = OPI_GoogleWorkspace.ПолучитьТокенServiceАккаунта(Данные, ОбластиДействия);
|
||||||
|
|
||||||
|
// END
|
||||||
|
|
||||||
|
OPI_ПолучениеДанныхТестов.Проверка_ГуглТокен(Результат);
|
||||||
|
OPI_ПолучениеДанныхТестов.ЗаписатьПараметр("Google_ServiceToken", Результат["access_token"]);
|
||||||
|
|
||||||
|
КонецПроцедуры
|
||||||
|
|
||||||
#КонецОбласти
|
#КонецОбласти
|
||||||
|
|
||||||
#Область GoogleCalendar
|
#Область GoogleCalendar
|
||||||
|
|||||||
Binary file not shown.
@@ -1104,6 +1104,7 @@
|
|||||||
ДобавитьЛог("ОбработатьЗапрос: перенос тела в объект HTTPЗапроса");
|
ДобавитьЛог("ОбработатьЗапрос: перенос тела в объект HTTPЗапроса");
|
||||||
Если УстановитьТелоЗапроса().Ошибка Тогда Возврат ЭтотОбъект; КонецЕсли;
|
Если УстановитьТелоЗапроса().Ошибка Тогда Возврат ЭтотОбъект; КонецЕсли;
|
||||||
|
|
||||||
|
ГарантироватьТелоКоллекцию();
|
||||||
ДополнитьЗаголовки();
|
ДополнитьЗаголовки();
|
||||||
|
|
||||||
Если ВыполнитьСразу Тогда
|
Если ВыполнитьСразу Тогда
|
||||||
@@ -2430,18 +2431,6 @@
|
|||||||
ТаблицаПараметров.Колонки.Добавить("Ключ");
|
ТаблицаПараметров.Колонки.Добавить("Ключ");
|
||||||
ТаблицаПараметров.Колонки.Добавить("Значение");
|
ТаблицаПараметров.Колонки.Добавить("Значение");
|
||||||
|
|
||||||
Если Не ЗначениеЗаполнено(ЗапросТелоКоллекция)
|
|
||||||
Или Не OPI_Инструменты.ЭтоКоллекция(ЗапросТелоКоллекция, Истина) Тогда
|
|
||||||
|
|
||||||
Попытка
|
|
||||||
ЗапросТелоКоллекция = ЗапросТело;
|
|
||||||
OPI_ПреобразованиеТипов.ПолучитьКоллекциюКлючИЗначение(ЗапросТелоКоллекция);
|
|
||||||
Исключение
|
|
||||||
ЗапросТелоКоллекция = Новый Структура;
|
|
||||||
КонецПопытки;
|
|
||||||
|
|
||||||
КонецЕсли;
|
|
||||||
|
|
||||||
Если ПолучитьНастройку("MultipartВOAuth") Или Не Multipart Тогда
|
Если ПолучитьНастройку("MultipartВOAuth") Или Не Multipart Тогда
|
||||||
Для Каждого Поле Из ЗапросТелоКоллекция Цикл
|
Для Каждого Поле Из ЗапросТелоКоллекция Цикл
|
||||||
|
|
||||||
@@ -2630,6 +2619,24 @@
|
|||||||
|
|
||||||
КонецПроцедуры
|
КонецПроцедуры
|
||||||
|
|
||||||
|
Процедура ГарантироватьТелоКоллекцию()
|
||||||
|
|
||||||
|
Если Не ЗначениеЗаполнено(ЗапросТелоКоллекция)
|
||||||
|
Или Не OPI_Инструменты.ЭтоКоллекция(ЗапросТелоКоллекция, Истина) Тогда
|
||||||
|
|
||||||
|
Попытка
|
||||||
|
ЗапросТелоКоллекция = ЗапросТело;
|
||||||
|
OPI_ПреобразованиеТипов.ПолучитьКоллекциюКлючИЗначение(ЗапросТелоКоллекция);
|
||||||
|
Исключение
|
||||||
|
ЗапросТелоКоллекция = Новый Структура;
|
||||||
|
КонецПопытки;
|
||||||
|
|
||||||
|
ЗапросТелоКоллекция = ?(ЗначениеЗаполнено(ЗапросТелоКоллекция), ЗапросТелоКоллекция, Новый Структура);
|
||||||
|
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
КонецПроцедуры
|
||||||
|
|
||||||
#КонецОбласти
|
#КонецОбласти
|
||||||
|
|
||||||
#КонецОбласти
|
#КонецОбласти
|
||||||
|
|||||||
Reference in New Issue
Block a user