summaryrefslogtreecommitdiff
path: root/battleNetApi/src/token.cpp
diff options
context:
space:
mode:
authorAotrix <[email protected]>2026-01-01 03:35:41 +0100
committerAotrix <[email protected]>2026-01-01 03:35:41 +0100
commitc05901c38c6a77779807a6b224b9b624bfcaa5d3 (patch)
treefb8d212cd9995e4eecd351de352ea6aab2295924 /battleNetApi/src/token.cpp
parenta56ae1a7ad5f624b05570965bed76e928bbd945c (diff)
removed useless files
Diffstat (limited to 'battleNetApi/src/token.cpp')
-rw-r--r--battleNetApi/src/token.cpp105
1 files changed, 105 insertions, 0 deletions
diff --git a/battleNetApi/src/token.cpp b/battleNetApi/src/token.cpp
new file mode 100644
index 0000000..89f0d2a
--- /dev/null
+++ b/battleNetApi/src/token.cpp
@@ -0,0 +1,105 @@
+#include "token.hpp"
+#include <charconv>
+#include <chrono>
+#include <curl/curl.h>
+#include <format>
+#include <fstream>
+#include <iostream>
+#include <regex>
+#include <system_error>
+
+Token::Token(const std::string &iTokenFilePath, const std::string &iUsername, const std::string &iPassword)
+ : mFilePath{iTokenFilePath}, mUsername{iUsername}, mPassword{iPassword}, mToken{getValidToken()} {}
+
+std::string Token::toString() const { return mToken; }
+
+std::string Token::getValidToken() const {
+ refreshToken();
+ std::ifstream aTokenFile{mFilePath};
+ std::string aLine;
+ std::getline(aTokenFile, aLine);
+ const std::string kToken{aLine.substr(0, aLine.find(" "))};
+ return kToken;
+}
+
+void Token::refreshToken() const {
+ std::ifstream aTokenFile{mFilePath};
+ std::string aLine;
+ std::getline(aTokenFile, aLine);
+ if (aLine.empty()) {
+ writeNewTokenToFile();
+ } else {
+ const std::string kTimeLimitText{aLine.substr(aLine.find(" ") + 1)};
+ long int aTimeLimit;
+ const auto kConversionStatus{
+ std::from_chars(kTimeLimitText.data(), kTimeLimitText.data() + kTimeLimitText.size(), aTimeLimit)};
+ if (kConversionStatus.ec == std::errc{}) {
+ const bool kTokenExpired{
+ std::chrono::duration_cast<std::chrono::seconds>(std::chrono::utc_clock::now().time_since_epoch())
+ .count() >= aTimeLimit};
+ if (kTokenExpired) {
+ writeNewTokenToFile();
+ }
+ }
+ }
+}
+
+void Token::writeNewTokenToFile() const {
+ const std::string kToken{getValidTokenWithApi()};
+ if (not kToken.empty()) {
+ writeTokenToFile(kToken);
+ }
+}
+
+void Token::writeTokenToFile(const std::string &iToken) const {
+ std::ofstream aTokenFile{mFilePath};
+ std::chrono::seconds aExpiresAt{getCurrentTime() + std::chrono::hours(24)};
+ aTokenFile << iToken << " " << aExpiresAt.count() << '\n';
+}
+
+std::string Token::getValidTokenWithApi() const {
+ CURL *aCurl{curl_easy_init()};
+ std::string aTokenInfo;
+ if (aCurl) {
+ 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("{}:{}", mUsername, mPassword).data());
+ curl_easy_setopt(aCurl, CURLOPT_POSTFIELDS, "grant_type=client_credentials");
+ CURLcode result_code{curl_easy_perform(aCurl)};
+ curl_easy_cleanup(aCurl);
+ if (result_code != CURLE_OK) {
+ std::cerr << "ERROR: token request failed" << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ }
+
+ return extractTokenWithRegex(aTokenInfo, "\"access_token\":\"(\\w+)\"");
+}
+
+std::chrono::seconds Token::getCurrentTime() const {
+ return std::chrono::duration_cast<std::chrono::seconds>(std::chrono::utc_clock::now().time_since_epoch());
+}
+
+std::string Token::extractTokenWithRegex(const std::string &iText, const std::string &iRegex) const {
+ const std::regex kRegex{iRegex};
+ std::smatch aMatches;
+ if (std::regex_search(iText, aMatches, kRegex)) {
+ return aMatches[1].str();
+ }
+ std::cerr << std::format("Unable to retrieve token with regex '{}'", iRegex);
+ return "";
+}
+
+size_t Token::curlCallbackStringOutput(void *iPtr, size_t iSize, size_t iNmemb, std::string *iUserData) {
+ size_t newLength{iSize * iNmemb};
+ try {
+ iUserData->append(static_cast<char *>(iPtr), newLength);
+ } catch (std::bad_alloc &e) {
+ // handle memory problem
+ return 0;
+ }
+ return newLength;
+}