Prevent renewal of access token into older token

This commit is contained in:
David Kocik 2025-01-30 06:03:47 +01:00 committed by Lukas Matena
parent 88a08cd212
commit 003b0ad6e4
4 changed files with 40 additions and 4 deletions

View File

@ -300,7 +300,11 @@ void UserAccountCommunication::set_username(const std::string& username, bool st
return; return;
} }
{ {
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << " empty: " << username.empty(); //BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << " empty: " << username.empty();
std::string at = m_session->get_access_token();
if (!at.empty())
at = at.substr(0,5) + "..." + at.substr(at.size()-5);
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ <<" access_token: " << (username.empty() ? "" : at);
if (is_secret_store_ok()) { if (is_secret_store_ok()) {
std::string tokens = "|||"; std::string tokens = "|||";
if (m_remember_session && !username.empty()) { if (m_remember_session && !username.empty()) {
@ -667,9 +671,12 @@ void UserAccountCommunication::request_refresh()
return; return;
} }
// Here we need to count with situation when token was renewed in m_session but was not yet stored.
// Then store token is not valid - it should has erlier expiration
long long expires_in_second = stored_data.next_timeout.empty() ? 0 : std::stoll(stored_data.next_timeout) - std::time(nullptr); long long expires_in_second = stored_data.next_timeout.empty() ? 0 : std::stoll(stored_data.next_timeout) - std::time(nullptr);
if (stored_data.access_token != current_access_token && expires_in_second > 0) { BOOST_LOG_TRIVIAL(error) << "Compare " << expires_in_second << " vs " << m_next_token_refresh_at - std::time(nullptr) << (stored_data.access_token != current_access_token ? " not same" : " same");
BOOST_LOG_TRIVIAL(debug) << "Found usable token"; if (stored_data.access_token != current_access_token && expires_in_second > 0 && expires_in_second > m_next_token_refresh_at - std::time(nullptr)) {
BOOST_LOG_TRIVIAL(debug) << "Found usable token. Expires in " << expires_in_second;
set_tokens(stored_data); set_tokens(stored_data);
} else { } else {
BOOST_LOG_TRIVIAL(debug) << "No new token"; BOOST_LOG_TRIVIAL(debug) << "No new token";

View File

@ -195,10 +195,37 @@ void UserAccountSession::init_with_code(const std::string& code, const std::stri
} }
} }
void UserAccountSession::remove_from_queue(UserAccountActionID action_id)
{
{
std::lock_guard<std::mutex> lock(m_session_mutex);
auto it = std::find_if(
std::begin(m_priority_action_queue), std::end(m_priority_action_queue),
[action_id](const ActionQueueData& item) { return item.action_id == action_id; }
);
while (it != m_priority_action_queue.end())
{
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__;
m_priority_action_queue.erase(it);
it = std::find_if(
std::begin(m_priority_action_queue), std::end(m_priority_action_queue),
[action_id](const ActionQueueData& item) { return item.action_id == action_id; }
);
}
}
}
void UserAccountSession::token_success_callback(const std::string& body) void UserAccountSession::token_success_callback(const std::string& body)
{ {
// No need to use lock m_session_mutex here // No need to use lock m_session_mutex here
// This is here to prevent performing refresh again until USER_ACCOUNT_ACTION_USER_ID_AFTER_TOKEN_SUCCESS is performed.
// If refresh with stored token was enqueued during performing one we are in its success_callback,
// It would fail and prevent USER_ID to write this tokens to store.
remove_from_queue(UserAccountActionID::USER_ACCOUNT_ACTION_REFRESH_TOKEN);
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << " Access token refreshed"; BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << " Access token refreshed";
// Data we need // Data we need
std::string access_token, refresh_token, shared_session_key; std::string access_token, refresh_token, shared_session_key;

View File

@ -207,6 +207,8 @@ private:
std::string client_id() const { return Utils::ServiceConfig::instance().account_client_id(); } std::string client_id() const { return Utils::ServiceConfig::instance().account_client_id(); }
void process_action_queue_inner(); void process_action_queue_inner();
void remove_from_queue(UserAccountActionID action_id);
// called from m_session_mutex protected code only // called from m_session_mutex protected code only
void enqueue_action_inner(UserAccountActionID id, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input); void enqueue_action_inner(UserAccountActionID id, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input);

View File

@ -1413,7 +1413,7 @@ void PrintablesWebViewPanel::sys_color_changed()
void PrintablesWebViewPanel::on_printables_event_access_token_expired(const std::string& message_data) void PrintablesWebViewPanel::on_printables_event_access_token_expired(const std::string& message_data)
{ {
// { "event": "accessTokenExpired:) // { "event": "accessTokenExpired")
// There seems to be a situation where we get accessTokenExpired when there is active token from Slicer POW // There seems to be a situation where we get accessTokenExpired when there is active token from Slicer POW
// We need get new token and freeze webview until its not refreshed // We need get new token and freeze webview until its not refreshed
if (m_refreshing_token) { if (m_refreshing_token) {