From 2d67036e6eede970efb0db5f9793de95093599cd Mon Sep 17 00:00:00 2001 From: Aotrix <9aotrix@protonmail.com> Date: Sat, 1 Nov 2025 19:29:44 +0100 Subject: refactoring Token class --- .gitignore | 1 + .../battleNetApi/include/hearthstoneApi.hpp | 19 +--- subprojects/battleNetApi/include/token.hpp | 6 +- subprojects/battleNetApi/src/hearthstoneApi.cpp | 100 +++------------------ subprojects/battleNetApi/src/token.cpp | 8 +- subprojects/battleNetApi/tests/tests.cpp | 8 +- 6 files changed, 28 insertions(+), 114 deletions(-) diff --git a/.gitignore b/.gitignore index b83f9dc..88e3f02 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ compile_commands.json .cache build resources/token_info.txt +subprojects/battleNetApi/resources/ diff --git a/subprojects/battleNetApi/include/hearthstoneApi.hpp b/subprojects/battleNetApi/include/hearthstoneApi.hpp index fcd84c0..88d48ef 100644 --- a/subprojects/battleNetApi/include/hearthstoneApi.hpp +++ b/subprojects/battleNetApi/include/hearthstoneApi.hpp @@ -1,6 +1,5 @@ #pragma once #include "token.hpp" -#include #include class HearthstoneApi { @@ -11,27 +10,13 @@ class HearthstoneApi { friend class HearthstoneApiTests; private: - /** - * @brief Get a valid token to call Battle.net API - * @return A valid token - */ - std::string getValidTokenWithApi() const; - static size_t curlCallbackStringOutput(void *t_contents, size_t t_size, size_t t_nmemb, std::string *t_s); - std::chrono::seconds getCurrentTime() const; - std::string extractStringWithRegex(const std::string &t_str, const std::string t_regex) const; - void writeTokenToFile(const std::string &iToken) const; - void writeNewTokenToFile() const; - void refreshToken(); - std::string getValidToken(); std::string generateRequestHeader(); const std::string getUrl(const std::string &t_parameters); const std::string getSetOfCardsUrl(const std::string &t_card_parameters); std::string makeApiRequest(const char *t_url, const char *t_header); std::string makeApiRequest(const std::string &t_url, const std::string &t_header); + static size_t curlCallbackStringOutput(void *t_contents, size_t t_size, size_t t_nmemb, std::string *t_s); - // TODO: add Token object - // Token mToken; - std::string mTokenFilePath; - std::string mToken; + Token mToken; std::string m_header; }; diff --git a/subprojects/battleNetApi/include/token.hpp b/subprojects/battleNetApi/include/token.hpp index 9c1eb18..e135d3f 100644 --- a/subprojects/battleNetApi/include/token.hpp +++ b/subprojects/battleNetApi/include/token.hpp @@ -4,11 +4,13 @@ class Token { public: Token(const std::string &iTokenFilePath); - std::string getValidToken() const; + std::string toString() const; private: - std::string mFilePath; //!< Path to the token file + const std::string mFilePath; //!< Path to the token file + const std::string mToken; //!< Token value + std::string getValidToken() const; void refreshToken() const; void writeNewTokenToFile() const; void writeTokenToFile(const std::string &iToken) const; diff --git a/subprojects/battleNetApi/src/hearthstoneApi.cpp b/subprojects/battleNetApi/src/hearthstoneApi.cpp index 706906a..d5b9aad 100644 --- a/subprojects/battleNetApi/src/hearthstoneApi.cpp +++ b/subprojects/battleNetApi/src/hearthstoneApi.cpp @@ -1,14 +1,21 @@ #include "hearthstoneApi.hpp" -#include #include #include -#include -#include -#include HearthstoneApi::HearthstoneApi() - : mTokenFilePath(std::format("{}/resources/token_info.txt", SOURCE_DIR_PATH)), mToken(getValidToken()), - m_header(generateRequestHeader()) {} + : mToken(std::format("{}/resources/token_info.txt", SOURCE_DIR_PATH)), m_header(generateRequestHeader()) {} + +std::string HearthstoneApi::generateRequestHeader() { + return std::format("Authorization: Bearer {}", mToken.toString()); +} + +const std::string HearthstoneApi::getUrl(const std::string &t_parameters) { + return std::format("https://eu.api.blizzard.com/hearthstone/{}", t_parameters); +} + +const std::string HearthstoneApi::getSetOfCardsUrl(const std::string &t_card_parameters) { + return getUrl(std::format("cards{}", t_card_parameters)); +} size_t HearthstoneApi::curlCallbackStringOutput(void *t_contents, size_t t_size, size_t t_nmemb, std::string *t_s) { size_t newLength = t_size * t_nmemb; @@ -21,87 +28,6 @@ size_t HearthstoneApi::curlCallbackStringOutput(void *t_contents, size_t t_size, return newLength; } -std::chrono::seconds HearthstoneApi::getCurrentTime() const { - return std::chrono::duration_cast(std::chrono::utc_clock::now().time_since_epoch()); -} - -std::string HearthstoneApi::extractStringWithRegex(const std::string &t_str, const std::string t_regex) const { - std::regex regex(t_regex); - auto it = std::sregex_iterator(t_str.begin(), t_str.end(), regex); - std::smatch match = *it; - return match[1].str(); -} - -std::string HearthstoneApi::getValidTokenWithApi() const { - CURL *curl = curl_easy_init(); - std::string token_info; - if (curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://oauth.battle.net/token"); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlCallbackStringOutput); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &token_info); - curl_easy_setopt(curl, CURLOPT_USERPWD, - "2b50f1123b424d5e9c21971a110fdd04:" - "MrMkhVMNdOeqPL4Q4XVQAsRPR14J7Yq6"); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "grant_type=client_credentials"); - CURLcode result_code; - result_code = curl_easy_perform(curl); - curl_easy_cleanup(curl); - if (result_code != CURLE_OK) { - std::cerr << "ERROR: token request failed" << std::endl; - std::exit(EXIT_FAILURE); - } - } - - return extractStringWithRegex(token_info, "\"access_token\":\"(\\w+)\""); -} - -void HearthstoneApi::writeNewTokenToFile() const { - std::string aToken{getValidTokenWithApi()}; - writeTokenToFile(aToken); -} - -void HearthstoneApi::writeTokenToFile(const std::string &iToken) const { - std::ofstream token_file(mTokenFilePath); - std::chrono::seconds expires_at = getCurrentTime() + std::chrono::hours(24); - token_file << iToken << " " << expires_at.count() << '\n'; -} - -void HearthstoneApi::refreshToken() { - std::string file_path = std::format("{}/resources/token_info.txt", SOURCE_DIR_PATH); - std::ifstream token_file(file_path); - std::string line; - std::getline(token_file, line); - if (line.empty()) { - writeNewTokenToFile(); - } else { - long expire_at = std::stoull(line.substr(line.find(" ") + 1)); - if (std::chrono::duration_cast(std::chrono::utc_clock::now().time_since_epoch()) - .count() >= expire_at) { - writeNewTokenToFile(); - } - } -} -std::string HearthstoneApi::getValidToken() { - refreshToken(); - std::ifstream token_file(mTokenFilePath); - std::string line; - std::getline(token_file, line); - std::string token = line.substr(0, line.find(" ")); - return token; -} - -std::string HearthstoneApi::generateRequestHeader() { return std::format("Authorization: Bearer {}", mToken); } - -const std::string HearthstoneApi::getUrl(const std::string &t_parameters) { - return std::format("https://eu.api.blizzard.com/hearthstone/{}", t_parameters); -} - -const std::string HearthstoneApi::getSetOfCardsUrl(const std::string &t_card_parameters) { - return getUrl(std::format("cards{}", t_card_parameters)); -} - std::string HearthstoneApi::makeApiRequest(const char *t_url, const char *t_header) { CURL *curl = curl_easy_init(); std::string request_output; diff --git a/subprojects/battleNetApi/src/token.cpp b/subprojects/battleNetApi/src/token.cpp index 7d2e20e..b1ec5bf 100644 --- a/subprojects/battleNetApi/src/token.cpp +++ b/subprojects/battleNetApi/src/token.cpp @@ -1,12 +1,13 @@ #include "token.hpp" #include #include -#include #include #include #include -Token::Token(const std::string &iTokenFilePath) : mFilePath{iTokenFilePath} {} +Token::Token(const std::string &iTokenFilePath) : mFilePath{iTokenFilePath}, mToken{getValidToken()} {} + +std::string Token::toString() const { return mToken; } std::string Token::getValidToken() const { refreshToken(); @@ -18,8 +19,7 @@ std::string Token::getValidToken() const { } void Token::refreshToken() const { - std::string file_path = std::format("{}/resources/token_info.txt", SOURCE_DIR_PATH); - std::ifstream token_file(file_path); + std::ifstream token_file{mFilePath}; std::string line; std::getline(token_file, line); if (line.empty()) { diff --git a/subprojects/battleNetApi/tests/tests.cpp b/subprojects/battleNetApi/tests/tests.cpp index 1790f88..f964ee4 100644 --- a/subprojects/battleNetApi/tests/tests.cpp +++ b/subprojects/battleNetApi/tests/tests.cpp @@ -4,16 +4,16 @@ class TokenTests { public: - std::string getValidTokenWithApi() const { - const std::string aTokenFilePath{""}; + std::string toString() const { + const std::string aTokenFilePath{"resources/token_info"}; const Token aToken(aTokenFilePath); - return aToken.getValidTokenWithApi(); + return aToken.toString(); } }; TEST_CASE("API Token retrieval", "[getApiToken]") { TokenTests aToken; - const std::string kToken{aToken.getValidTokenWithApi()}; + const std::string kToken{aToken.toString()}; std::cout << kToken << '\n'; REQUIRE(kToken == ""); } -- cgit v1.2.3