feat(tgbot-back): Add functions for processing user authentication
This commit is contained in:
parent
d6194ec8be
commit
f045eb22b2
6 changed files with 122 additions and 21 deletions
|
|
@ -11,6 +11,9 @@ list(APPEND SOURCES ${SRC_BACK})
|
||||||
file(GLOB_RECURSE SRC_API "generated-client/src/*.cpp")
|
file(GLOB_RECURSE SRC_API "generated-client/src/*.cpp")
|
||||||
list(APPEND SOURCES ${SRC_API})
|
list(APPEND SOURCES ${SRC_API})
|
||||||
|
|
||||||
|
file(GLOB_RECURSE SRC_AUTH "generated-client-auth/src/*.cpp")
|
||||||
|
list(APPEND SOURCES ${SRC_AUTH})
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||||
|
|
@ -26,6 +29,7 @@ include_directories(/usr/local/include ${OPENSSL_INCLUDE_DIR} ${Boost_INCLUDE_DI
|
||||||
include_directories(front/include/)
|
include_directories(front/include/)
|
||||||
include_directories(back/include)
|
include_directories(back/include)
|
||||||
include_directories(generated-client/include)
|
include_directories(generated-client/include)
|
||||||
|
include_directories(generated-client-auth/include)
|
||||||
if (CURL_FOUND)
|
if (CURL_FOUND)
|
||||||
include_directories(${CURL_INCLUDE_DIRS})
|
include_directories(${CURL_INCLUDE_DIRS})
|
||||||
add_definitions(-DHAVE_CURL)
|
add_definitions(-DHAVE_CURL)
|
||||||
|
|
|
||||||
35
modules/bot/back/include/AuthImpersonation.hpp
Normal file
35
modules/bot/back/include/AuthImpersonation.hpp
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
// AuthImpersonationClient.hpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <map>
|
||||||
|
#include <cpprest/asyncrt_utils.h>
|
||||||
|
#include "AuthClient/ApiClient.h"
|
||||||
|
#include "AuthClient/ApiConfiguration.h"
|
||||||
|
#include "AuthClient/api/AuthApi.h"
|
||||||
|
#include "AuthClient/model/GetImpersonationToken_request.h"
|
||||||
|
#include "AuthClient/model/GetImpersonationToken_200_response.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace nyanimed {
|
||||||
|
|
||||||
|
class AuthImpersonationClient {
|
||||||
|
public:
|
||||||
|
AuthImpersonationClient();
|
||||||
|
|
||||||
|
// Потокобезопасный вызов — не модифицирует состояние
|
||||||
|
pplx::task<std::shared_ptr<nyanimed::meow::auth::model::GetImpersonationToken_200_response>>
|
||||||
|
getImpersonationToken(int64_t userId) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_baseUrl;
|
||||||
|
std::string m_authToken;
|
||||||
|
std::shared_ptr<nyanimed::meow::auth::api::ApiClient> m_apiClient;
|
||||||
|
std::shared_ptr<nyanimed::meow::auth::api::AuthApi> m_authApi;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace nyanimed
|
||||||
|
|
@ -15,6 +15,8 @@
|
||||||
#include <cpprest/asyncrt_utils.h>
|
#include <cpprest/asyncrt_utils.h>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
#include "AuthImpersonation.hpp"
|
||||||
|
|
||||||
using namespace org::openapitools::client::api;
|
using namespace org::openapitools::client::api;
|
||||||
|
|
||||||
class BotToServer {
|
class BotToServer {
|
||||||
|
|
@ -28,4 +30,6 @@ private:
|
||||||
std::shared_ptr<org::openapitools::client::api::ApiConfiguration> apiconfiguration;
|
std::shared_ptr<org::openapitools::client::api::ApiConfiguration> apiconfiguration;
|
||||||
std::shared_ptr<org::openapitools::client::api::ApiClient> apiclient;
|
std::shared_ptr<org::openapitools::client::api::ApiClient> apiclient;
|
||||||
std::shared_ptr<org::openapitools::client::api::DefaultApi> api;
|
std::shared_ptr<org::openapitools::client::api::DefaultApi> api;
|
||||||
|
|
||||||
|
nyanimed::AuthImpersonationClient authClient;
|
||||||
};
|
};
|
||||||
34
modules/bot/back/src/AuthImpersonation.cpp
Normal file
34
modules/bot/back/src/AuthImpersonation.cpp
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include "AuthImpersonation.hpp"
|
||||||
|
|
||||||
|
nyanimed::AuthImpersonationClient::AuthImpersonationClient() {
|
||||||
|
const char* baseUrlEnv = std::getenv("NYANIMEDBAUTHURL");
|
||||||
|
const char* tokenEnv = std::getenv("NYANIMEDBAUTHTOKEN");
|
||||||
|
|
||||||
|
if (!baseUrlEnv || std::string(baseUrlEnv).empty()) {
|
||||||
|
throw std::runtime_error("Missing required environment variable: NYANIMEDBAUTHURL");
|
||||||
|
}
|
||||||
|
if (!tokenEnv || std::string(tokenEnv).empty()) {
|
||||||
|
throw std::runtime_error("Missing required environment variable: NYANIMEDBAUTHTOKEN");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_baseUrl = baseUrlEnv;
|
||||||
|
m_authToken = tokenEnv;
|
||||||
|
|
||||||
|
auto config = std::make_shared<nyanimed::meow::auth::api::ApiConfiguration>();
|
||||||
|
config->setBaseUrl(utility::conversions::to_string_t(m_baseUrl));
|
||||||
|
|
||||||
|
m_apiClient = std::make_shared<nyanimed::meow::auth::api::ApiClient>(config);
|
||||||
|
m_authApi = std::make_shared<nyanimed::meow::auth::api::AuthApi>(m_apiClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
pplx::task<std::shared_ptr<nyanimed::meow::auth::model::GetImpersonationToken_200_response>>
|
||||||
|
nyanimed::AuthImpersonationClient::getImpersonationToken(int64_t userId) const {
|
||||||
|
auto request = std::make_shared<nyanimed::meow::auth::model::GetImpersonationToken_request>();
|
||||||
|
request->setUserId(userId);
|
||||||
|
//request->setExternalId(externalId);
|
||||||
|
|
||||||
|
std::map<utility::string_t, utility::string_t> headers;
|
||||||
|
headers[U("Authorization")] = U("Bearer ") + utility::conversions::to_string_t(m_authToken);
|
||||||
|
|
||||||
|
return m_authApi->getImpersonationToken(request, headers);
|
||||||
|
}
|
||||||
|
|
@ -45,28 +45,52 @@ static BotStructs::Title mapUserTitleToBotTitle(
|
||||||
}
|
}
|
||||||
|
|
||||||
pplx::task<std::vector<BotStructs::Title>> BotToServer::fetchUserTitlesAsync(const std::string& userId) {
|
pplx::task<std::vector<BotStructs::Title>> BotToServer::fetchUserTitlesAsync(const std::string& userId) {
|
||||||
utility::string_t userIdW = utility::conversions::to_string_t(userId);
|
// Шаг 1: Получаем impersonation-токен
|
||||||
int32_t limit = static_cast<int32_t>(BotConstants::DISP_TITLES_NUM);
|
auto impersonationTask = authClient.getImpersonationToken(std::stoi(userId));
|
||||||
|
|
||||||
auto responseTask = api->getUserTitles(
|
// Шаг 2: После получения токена — делаем запрос getUserTitles с этим токеном
|
||||||
userIdW,
|
return impersonationTask.then([=](pplx::task<std::shared_ptr<nyanimed::meow::auth::model::GetImpersonationToken_200_response>> tokenTask) {
|
||||||
boost::none, // cursor
|
|
||||||
boost::none, // sort
|
|
||||||
boost::none, // sortForward
|
|
||||||
boost::none, // word
|
|
||||||
boost::none, // status
|
|
||||||
boost::none, // watchStatus
|
|
||||||
boost::none, // rating
|
|
||||||
boost::none, // myRate
|
|
||||||
boost::none, // releaseYear
|
|
||||||
boost::none, // releaseSeason
|
|
||||||
limit,
|
|
||||||
boost::none // fields
|
|
||||||
);
|
|
||||||
|
|
||||||
return responseTask.then([=](pplx::task<std::shared_ptr<org::openapitools::client::model::GetUserTitles_200_response>> task) {
|
|
||||||
try {
|
try {
|
||||||
auto response = task.get();
|
auto tokenResponse = tokenTask.get();
|
||||||
|
if (!tokenResponse) {
|
||||||
|
throw std::runtime_error("Null response from getImpersonationToken");
|
||||||
|
}
|
||||||
|
|
||||||
|
utility::string_t accessToken = utility::conversions::to_string_t(tokenResponse->getAccessToken());
|
||||||
|
|
||||||
|
// Формируем заголовки с токеном
|
||||||
|
std::map<utility::string_t, utility::string_t> customHeaders;
|
||||||
|
customHeaders[U("Cookie")] = U("access_token=") + accessToken;
|
||||||
|
|
||||||
|
// Подготавливаем параметры запроса
|
||||||
|
utility::string_t userIdW = utility::conversions::to_string_t(userId);
|
||||||
|
int32_t limit = static_cast<int32_t>(BotConstants::DISP_TITLES_NUM);
|
||||||
|
|
||||||
|
// Шаг 3: Выполняем getUserTitles с кастомными заголовками
|
||||||
|
return api->getUserTitles(
|
||||||
|
userIdW,
|
||||||
|
boost::none, // cursor
|
||||||
|
boost::none, // sort
|
||||||
|
boost::none, // sortForward
|
||||||
|
boost::none, // word
|
||||||
|
boost::none, // status
|
||||||
|
boost::none, // watchStatus
|
||||||
|
boost::none, // rating
|
||||||
|
boost::none, // myRate
|
||||||
|
boost::none, // releaseYear
|
||||||
|
boost::none, // releaseSeason
|
||||||
|
limit,
|
||||||
|
boost::none, // fields
|
||||||
|
customHeaders
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
std::cerr << "Error obtaining impersonation token: " << e.what() << std::endl;
|
||||||
|
throw; // Пробрасываем, чтобы цепочка task.then завершилась с ошибкой
|
||||||
|
}
|
||||||
|
}).then([=](pplx::task<std::shared_ptr<org::openapitools::client::model::GetUserTitles_200_response>> responseTask) {
|
||||||
|
try {
|
||||||
|
auto response = responseTask.get();
|
||||||
if (!response) {
|
if (!response) {
|
||||||
throw std::runtime_error("Null response from getUserTitles");
|
throw std::runtime_error("Null response from getUserTitles");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ void BotHandlers::renderCurrent(TgBot::CallbackQuery::Ptr query) {
|
||||||
editMessage(chatId, messageId, showMainMenu());
|
editMessage(chatId, messageId, showMainMenu());
|
||||||
return;
|
return;
|
||||||
case UserState::VIEWING_MY_TITLES:
|
case UserState::VIEWING_MY_TITLES:
|
||||||
server_.fetchUserTitlesAsync(std::to_string(2)) // ALARM: тестовое значение вместо userId
|
server_.fetchUserTitlesAsync(std::to_string(22)) // ALARM: тестовое значение вместо userId
|
||||||
.then([this, chatId, messageId](pplx::task<std::vector<BotStructs::Title>> t) {
|
.then([this, chatId, messageId](pplx::task<std::vector<BotStructs::Title>> t) {
|
||||||
try {
|
try {
|
||||||
auto titles = t.get();
|
auto titles = t.get();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue