diff options
| author | Aotrix <[email protected]> | 2026-07-29 18:31:43 +0200 |
|---|---|---|
| committer | Aotrix <[email protected]> | 2026-07-29 18:31:43 +0200 |
| commit | 1fbfd13f5d7220122b2a127627cc9105013b4893 (patch) | |
| tree | 0ca51f463996ea96eddc5b8939c07d3ef207a311 /battleNetApi/src/hearthstoneTokenBuilder.cpp | |
| parent | 2c286a812a3bdaa2531e8f87f5503988bb331a78 (diff) | |
Add tests for HearthstoneTokenBuilder
Diffstat (limited to 'battleNetApi/src/hearthstoneTokenBuilder.cpp')
| -rw-r--r-- | battleNetApi/src/hearthstoneTokenBuilder.cpp | 122 |
1 files changed, 71 insertions, 51 deletions
diff --git a/battleNetApi/src/hearthstoneTokenBuilder.cpp b/battleNetApi/src/hearthstoneTokenBuilder.cpp index 89466a5..668aaa5 100644 --- a/battleNetApi/src/hearthstoneTokenBuilder.cpp +++ b/battleNetApi/src/hearthstoneTokenBuilder.cpp @@ -1,46 +1,69 @@ -#include <algorithm> #include <curl/curl.h> #include <fstream> #include <hearthstoneTokenBuilder.hpp> #include <iostream> #include <memory> +namespace bnet { HearthstoneTokenBuilder::HearthstoneTokenBuilder(const std::span<std::string> &iJsonPaths) { _credentialJsonPaths.append_range(iJsonPaths); } HearthstoneTokenBuilder &HearthstoneTokenBuilder::buildToken() { - std::ranges::find_if(_credentialJsonPaths, - [](const std::string &iCredentialJsonPath) { return true; }); - if (hasExpired()) { - if (isUpdateSourceFileAllowed()) { + for (const std::string &aCredentialJsonPath : _credentialJsonPaths) { + std::ifstream aCredentialJsonFile{aCredentialJsonPath}; + json aCredentialJson = json::parse(aCredentialJsonFile); + if (isTokenValid(aCredentialJson)) { + _currentToken = std::make_shared<Token>(); + _currentToken->setText(aCredentialJson["Token"]["Content"]); + _currentToken->setExpirationTime( + std::chrono::seconds(aCredentialJson["Token"]["ExpirationTime"])); + return *this; } - const std::pair<std::string, std::uint64_t> kTokenContent{getTokenWithApi()}; - writeTokenToLocalFile(kTokenContent); } - // return getTokenFromLocalFile(); - if (aTokenContainer.empty()) { - return std::nullopt; + + if (!_allowBattleNetApiCall) { + return *this; + } + + for (const std::string &aCredentialJsonPath : _credentialJsonPaths) { + std::ifstream aCredentialJsonFile{aCredentialJsonPath}; + json aCredentialJson = json::parse(aCredentialJsonFile); + _currentToken = std::make_shared<Token>(getTokenWithApi(aCredentialJson)); + if (_currentToken) { + if (_allowUpdateSourceFile) { + writeTokenToLocalFile(_currentToken, aCredentialJsonPath); + } + break; + } } - Token aOutputToken{aTokenContainer.front()}; - aTokenContainer.pop(); - // mCurrentToken = std::make_unique<Token>(...); return *this; } -std::shared_ptr<Token> HearthstoneTokenBuilder::getToken() { return mCurrentToken; } +std::shared_ptr<Token> HearthstoneTokenBuilder::getToken() { return _currentToken; } +HearthstoneTokenBuilder &HearthstoneTokenBuilder::allowBattleNetApiCall() { + _allowBattleNetApiCall = true; + return *this; +} HearthstoneTokenBuilder &HearthstoneTokenBuilder::allowUpdateSourceFile() { - mUpdateSourceFile = true; + _allowUpdateSourceFile = true; + return *this; +} +HearthstoneTokenBuilder &HearthstoneTokenBuilder::allowExpiredToken() { + _allowExpiredToken = true; return *this; } -bool HearthstoneTokenBuilder::isUpdateSourceFileAllowed() const { return mUpdateSourceFile; } +bool HearthstoneTokenBuilder::isUpdateSourceFileAllowed() const { return _allowUpdateSourceFile; } -const bool HearthstoneTokenBuilder::hasExpired(json iTokenJson) const { +bool HearthstoneTokenBuilder::isTokenValid(const json &iTokenJson) const { if (not iTokenJson.contains("Token") or not iTokenJson["Token"].contains("ExpirationTime") or not iTokenJson["Token"].contains("Content")) { - return true; + return false; } if (iTokenJson["Token"]["Content"].dump().length() < kTOKEN_CONTENT_MIN_LENGTH) { + return false; + } + if (_allowExpiredToken) { return true; } const std::uint64_t kExpirationTime{iTokenJson["Token"]["ExpirationTime"]}; @@ -48,7 +71,18 @@ const bool HearthstoneTokenBuilder::hasExpired(json iTokenJson) const { static_cast<std::uint64_t>(std::chrono::duration_cast<std::chrono::seconds>( std::chrono::high_resolution_clock::now().time_since_epoch()) .count())}; - return kCurrentTime >= kExpirationTime; + return kCurrentTime <= kExpirationTime; +} + +std::chrono::seconds HearthstoneTokenBuilder::getCurrentTime() const { + return std::chrono::duration_cast<std::chrono::seconds>( + std::chrono::utc_clock::now().time_since_epoch()); +} + +Token HearthstoneTokenBuilder::getTokenWithApi(const std::string &iCredentialsJsonFilePath) const { + std::ifstream aAgentJsonFile{iCredentialsJsonFilePath}; + json aCredentials = json::parse(aAgentJsonFile); + return getTokenWithApi(aCredentials); } size_t HearthstoneTokenBuilder::curlCallbackStringOutput(void *iPtr, size_t iSize, size_t iNmemb, @@ -63,33 +97,25 @@ size_t HearthstoneTokenBuilder::curlCallbackStringOutput(void *iPtr, size_t iSiz return newLength; } -std::chrono::seconds HearthstoneTokenBuilder::getCurrentTime() const { - return std::chrono::duration_cast<std::chrono::seconds>( - std::chrono::utc_clock::now().time_since_epoch()); -} - -std::pair<std::string, std::uint64_t> -HearthstoneTokenBuilder::getTokenWithApi(const std::string &iAgentJsonFilePath) const { - std::ifstream aAgentJsonFile{iAgentJsonFilePath}; - json aCredentials = json::parse(aAgentJsonFile); - if (not aCredentials.contains("Agent") or not aCredentials["Agent"].contains("Username") or - not aCredentials["Agent"].contains("Password")) { +Token HearthstoneTokenBuilder::getTokenWithApi(const json &iCredentials) const { + if (not iCredentials.contains("Agent") or not iCredentials["Agent"].contains("Username") or + not iCredentials["Agent"].contains("Password")) { std::cerr << "Please define Agent/Username and Agent/Password in the " "JSON credentials file\n"; std::exit(EXIT_FAILURE); } - const std::string kAgentUsername{aCredentials["Agent"]["Username"]}; - const std::string kAgentPassword{aCredentials["Agent"]["Password"]}; + const std::string aAgentUsername{iCredentials["Agent"]["Username"]}; + const std::string aAgentPassword{iCredentials["Agent"]["Password"]}; CURL *aCurl{curl_easy_init()}; std::string aTokenInfo; - if (aCurl and not kAgentUsername.empty() and not kAgentPassword.empty()) { + if (aCurl and not aAgentUsername.empty() and not aAgentPassword.empty()) { curl_easy_setopt(aCurl, CURLOPT_URL, "https://oauth.battle.net/token"); curl_easy_setopt(aCurl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(aCurl, CURLOPT_SSL_VERIFYHOST, 0L); curl_easy_setopt(aCurl, CURLOPT_WRITEFUNCTION, curlCallbackStringOutput); curl_easy_setopt(aCurl, CURLOPT_WRITEDATA, &aTokenInfo); curl_easy_setopt(aCurl, CURLOPT_USERPWD, - std::format("{}:{}", kAgentUsername, kAgentPassword).data()); + std::format("{}:{}", aAgentUsername, aAgentPassword).data()); curl_easy_setopt(aCurl, CURLOPT_POSTFIELDS, "grant_type=client_credentials"); CURLcode result_code{curl_easy_perform(aCurl)}; curl_easy_cleanup(aCurl); @@ -99,24 +125,18 @@ HearthstoneTokenBuilder::getTokenWithApi(const std::string &iAgentJsonFilePath) } } json aTokenJson = json::parse(aTokenInfo); - return std::make_pair(aTokenJson["access_token"], aTokenJson["expires_in"]); + return Token{} + .setText(aTokenJson["access_token"]) + .setLifetime(std::chrono::seconds{aTokenJson["expires_in"]}); } -std::string HearthstoneTokenBuilder::getTokenFromLocalFile() const { - std::ifstream aTokenFile{mFilePath}; - return json::parse(aTokenFile)["Token"]["Content"]; -} - -void HearthstoneTokenBuilder::writeTokenToLocalFile( - const std::pair<std::string, std::uint64_t> &iToken) const { - std::ifstream aTokenFileInput{mFilePath}; - json aCredentialsFile = json::parse(aTokenFileInput); - aCredentialsFile["Token"]["Content"] = iToken.first; - aCredentialsFile["Token"]["ExpirationTime"] = - std::chrono::duration_cast<std::chrono::seconds>(getCurrentTime() + - std::chrono::seconds(iToken.second)) - .count(); - - std::ofstream aTokenFileOutput{mFilePath}; +void HearthstoneTokenBuilder::writeTokenToLocalFile(std::shared_ptr<Token> &iToken, + const std::string &iTokenFileOutputPath) const { + std::ifstream aTokenFile{iTokenFileOutputPath}; + json aCredentialsFile = json::parse(aTokenFile); + aCredentialsFile["Token"]["Content"] = iToken->text(); + aCredentialsFile["Token"]["ExpirationTime"] = iToken->expirationTime()->count(); + std::ofstream aTokenFileOutput{iTokenFileOutputPath}; aTokenFileOutput << std::setw(4) << aCredentialsFile; } +} // namespace bnet |
