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")
|
||||
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_REQUIRED ON)
|
||||
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(back/include)
|
||||
include_directories(generated-client/include)
|
||||
include_directories(generated-client-auth/include)
|
||||
if (CURL_FOUND)
|
||||
include_directories(${CURL_INCLUDE_DIRS})
|
||||
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 <boost/optional.hpp>
|
||||
|
||||
#include "AuthImpersonation.hpp"
|
||||
|
||||
using namespace org::openapitools::client::api;
|
||||
|
||||
class BotToServer {
|
||||
|
|
@ -28,4 +30,6 @@ private:
|
|||
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::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) {
|
||||
utility::string_t userIdW = utility::conversions::to_string_t(userId);
|
||||
int32_t limit = static_cast<int32_t>(BotConstants::DISP_TITLES_NUM);
|
||||
// Шаг 1: Получаем impersonation-токен
|
||||
auto impersonationTask = authClient.getImpersonationToken(std::stoi(userId));
|
||||
|
||||
auto responseTask = 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
|
||||
);
|
||||
|
||||
return responseTask.then([=](pplx::task<std::shared_ptr<org::openapitools::client::model::GetUserTitles_200_response>> task) {
|
||||
// Шаг 2: После получения токена — делаем запрос getUserTitles с этим токеном
|
||||
return impersonationTask.then([=](pplx::task<std::shared_ptr<nyanimed::meow::auth::model::GetImpersonationToken_200_response>> tokenTask) {
|
||||
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) {
|
||||
throw std::runtime_error("Null response from getUserTitles");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ void BotHandlers::renderCurrent(TgBot::CallbackQuery::Ptr query) {
|
|||
editMessage(chatId, messageId, showMainMenu());
|
||||
return;
|
||||
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) {
|
||||
try {
|
||||
auto titles = t.get();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue