From 590d6308aa21f1a47b91d809faa3992607cd41df Mon Sep 17 00:00:00 2001 From: Moss Date: Wed, 8 Feb 2023 11:34:49 -0800 Subject: [PATCH] Login: Added Caching Session Token --- src/login.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/login.h | 3 +- src/util.cpp | 60 ++++++++++++++++++++++++++++++++++++++- src/util.h | 21 ++++++++++++-- 4 files changed, 153 insertions(+), 8 deletions(-) diff --git a/src/login.cpp b/src/login.cpp index ab0aa2a..71d464c 100644 --- a/src/login.cpp +++ b/src/login.cpp @@ -5,6 +5,56 @@ void dropout_dl::login::get_cookies(std::string& session) { std::string email; std::string password; + const std::string home = getenv("HOME"); + const std::string cache_directory = home + "/.cache/dropout-dl/"; + const std::string cache_file_path = home + "/.cache/dropout-dl/token-cache"; + std::fstream cache_file(cache_file_path); + + /// check if file exist + if(!cache_file.fail()) { + std::cout << GREEN << "Using cached tokens from " << cache_file_path << RESET << "\n"; + std::string cached_session_token; + std::string expiration_date; + std::getline(cache_file, cached_session_token); + std::getline(cache_file, expiration_date); + + int day_of_the_month_index = 0; + int day_of_the_month = get_int_in_string(expiration_date, day_of_the_month_index); + + std::string month = expiration_date.substr(day_of_the_month_index + 1, 3); + int month_as_int = get_month_string_as_int(month); + + int year_index = day_of_the_month_index + 4; + int year = get_int_in_string(expiration_date, year_index); + + time_t now = time(0); + + tm *ltm = localtime(&now); + + // If the expiration year is larger than current year. + if (year > (1900 + ltm->tm_year)) { + session = cached_session_token; + return; + } + + if (year == (1900 + ltm->tm_year)) { + // If the year is the same and the expiration month is larger + if (month_as_int > ltm->tm_mon) { + session = cached_session_token; + return; + } + + if (month_as_int == ltm->tm_mon) { + if (day_of_the_month > ltm->tm_mday) { + session = cached_session_token; + return; + } + } + } + + std::cout << YELLOW << "Cached tokens expired" << RESET << "\n"; + } + std::cout << "Logging in...\n"; get_login_info_from_file("login", email, password); @@ -12,14 +62,29 @@ void dropout_dl::login::get_cookies(std::string& session) { /// Needed to login properly std::string authentication; std::string cf_bm; - get_login_tokens(session, cf_bm, authentication); + // Needed for caching + std::string session_expiration; + get_login_tokens(session, cf_bm, authentication, session_expiration); if (!login_with_tokens(email, password, session, cf_bm, authentication)) { - std::cerr << RED << "ERROR: Could not login. Check your login. If you are certain your information is correct please report this issue\n"; + std::cerr << RED << "ERROR: Could not login. Check your login. If you are certain your information is correct please report this issue.\n"; exit(1); } std::cout << GREEN << "Successfully logged in.\n" << RESET; + + std::cout << "Caching tokens...\r"; + + + if (!std::filesystem::is_directory(cache_directory)) { + std::filesystem::create_directories(cache_directory); + } + + cache_file.open(cache_file_path, std::ios_base::in | std::ios_base::out | std::ios_base::trunc); + + cache_file << session << "\n" << session_expiration << "\n"; + + std::cout << GREEN "Cached tokens to " << cache_file_path << "\n" << RESET; } void dropout_dl::login::get_login_info_from_file(const std::string& filename, std::string& email, std::string& password) { @@ -45,14 +110,18 @@ void dropout_dl::login::get_login_info_from_file(const std::string& filename, st } } -void dropout_dl::login::get_login_tokens(std::string& session_token, std::string& cf_bm_token, std::string& authentication_token) { +void dropout_dl::login::get_login_tokens(std::string& session_token, std::string& cf_bm_token, std::string& authentication_token, std::string& session_expiration) { std::string login_page_url = "https://www.dropout.tv/login"; std::string header_string = ""; std::string login_page_data = get_generic_page(login_page_url, false, &header_string); + size_t set_cookie_index = header_string.find("set-cookie: _session="); - session_token = get_substring_in(header_string, "set-cookie: _session=", ";"); + if (set_cookie_index != std::string::npos) { + session_token = get_substring_in(header_string, "set-cookie: _session=", ";"); + session_expiration = get_substring_in(header_string, "expires=", ";", set_cookie_index); + } cf_bm_token = get_substring_in(header_string, "set-cookie: __cf_bm=", ";"); diff --git a/src/login.h b/src/login.h index 3d50db7..cc403f0 100644 --- a/src/login.h +++ b/src/login.h @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -17,7 +18,7 @@ namespace dropout_dl { void get_login_info_from_file(const std::string& filename, std::string& email, std::string& password); - void get_login_tokens(std::string& session_token, std::string& cf_bm_token, std::string& authentication_token); + void get_login_tokens(std::string& session_token, std::string& cf_bm_token, std::string& authentication_token, std::string& session_expiration); /** * diff --git a/src/util.cpp b/src/util.cpp index 2ed4ab6..3218607 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -277,8 +277,12 @@ namespace dropout_dl { return result; } + int get_int_in_string(const std::string& string) { + int tmp = 0; + return get_int_in_string(string, tmp); + } - int get_int_in_string(const std::string& string, uint32_t starting_index) { + int get_int_in_string(const std::string& string, int& starting_index) { int out = 0; int negative = 1; bool found_number = false; @@ -293,10 +297,64 @@ namespace dropout_dl { out += string[i] - '0'; } else if (found_number) { + starting_index = i; return out * negative; } } + starting_index = string.length(); return out * negative; } + int get_month_string_as_int(const std::string& month) { + if (month == "Jan") { + return 0; + } + + if (month == "Feb") { + return 1; + } + + if (month == "Mar") { + return 2; + } + + if (month == "Apr") { + return 3; + } + + if (month == "May") { + return 4; + } + + if (month == "Jun") { + return 5; + } + + if (month == "Jul") { + return 6; + } + + if (month == "Aug") { + return 7; + } + + if (month == "Sep") { + return 8; + } + + if (month == "Oct") { + return 9; + } + + if (month == "Nov") { + return 10; + } + + if (month == "Dec") { + return 11; + } + + return -1; + } + } diff --git a/src/util.h b/src/util.h index 4679d03..fc34735 100644 --- a/src/util.h +++ b/src/util.h @@ -131,15 +131,25 @@ namespace dropout_dl { std::string get_substring_in(const std::string& string, const std::string& begin, const std::string& end, int staring_index = 0); + /** * * @param string - the string that contains an integer. - * @param starting_index - the index within the string to start at. * @return the int within string * * Gets the first int in string after starting_index. The first non number character will cause the function to stop parsing the int */ - int get_int_in_string(const std::string& string, uint32_t starting_index = 0); + int get_int_in_string(const std::string& string); + + /** + * + * @param string - the string that contains an integer. + * @param starting_index - the index within the string to start at. this will be set to the end index of the int + * @return the int within string + * + * Gets the first int in string after starting_index. The first non number character will cause the function to stop parsing the int + */ + int get_int_in_string(const std::string& string, int& starting_index); /** @@ -148,4 +158,11 @@ namespace dropout_dl { * @return 'value' with values escaped. e.g. "&" -> %26 */ std::string url_encode(const std::string &value); + + /** + * + * @param string - the month as a 3 char string. e.g. "Feb" + * @return an integer between 0 and 11 for the month e.g. "Feb" -> 1. Or -1 if invalid. + */ + int get_month_string_as_int(const std::string& month); }