Prusa Account communication changes after testing all possible error states.

This commit is contained in:
David Kocik 2024-01-24 17:23:36 +01:00
parent 5804d5aa71
commit c129340712
7 changed files with 217 additions and 281 deletions

View File

@ -146,12 +146,11 @@ PrusaAuthCommunication::PrusaAuthCommunication(wxEvtHandler* evt_handler, AppCon
refresh_token = m_app_config->get("refresh_token"); refresh_token = m_app_config->get("refresh_token");
shared_session_key = m_app_config->get("shared_session_key"); shared_session_key = m_app_config->get("shared_session_key");
} }
if (!access_token.empty() || !refresh_token.empty()) bool has_token = !access_token.empty() && !refresh_token.empty();
m_remember_session = true;
m_session = std::make_unique<AuthSession>(evt_handler, access_token, refresh_token, shared_session_key, m_app_config->get_bool("connect_polling")); m_session = std::make_unique<AuthSession>(evt_handler, access_token, refresh_token, shared_session_key, m_app_config->get_bool("connect_polling"));
init_session_thread(); init_session_thread();
// perform login at the start // perform login at the start, but only with tokens
if (m_remember_session) if (has_token)
do_login(); do_login();
} }
@ -234,8 +233,9 @@ void PrusaAuthCommunication::do_login()
std::lock_guard<std::mutex> lock(m_session_mutex); std::lock_guard<std::mutex> lock(m_session_mutex);
if (!m_session->is_initialized()) { if (!m_session->is_initialized()) {
login_redirect(); login_redirect();
} else {
m_session->enqueue_test_with_refresh();
} }
m_session->enqueue_action(UserActionID::LOGIN_USER_ID, nullptr, nullptr, {});
} }
wakeup_session_thread(); wakeup_session_thread();
} }
@ -289,7 +289,7 @@ void PrusaAuthCommunication::enqueue_connect_dummy_action()
} }
wakeup_session_thread(); wakeup_session_thread();
} }
#endif #endif 0
void PrusaAuthCommunication::enqueue_connect_printers_action() void PrusaAuthCommunication::enqueue_connect_printers_action()
{ {
@ -299,7 +299,19 @@ void PrusaAuthCommunication::enqueue_connect_printers_action()
BOOST_LOG_TRIVIAL(error) << "Connect Printers endpoint connection failed - Not Logged in."; BOOST_LOG_TRIVIAL(error) << "Connect Printers endpoint connection failed - Not Logged in.";
return; return;
} }
m_session->enqueue_action(UserActionID::CONNECT_PRINTERS, nullptr, nullptr, {}); m_session->enqueue_action(UserActionID::AUTH_ACTION_CONNECT_PRINTERS, nullptr, nullptr, {});
}
wakeup_session_thread();
}
void PrusaAuthCommunication::enqueue_test_connection()
{
{
std::lock_guard<std::mutex> lock(m_session_mutex);
if (!m_session->is_initialized()) {
BOOST_LOG_TRIVIAL(error) << "Connect Printers endpoint connection failed - Not Logged in.";
return;
}
m_session->enqueue_action(UserActionID::AUTH_ACTION_TEST_CONNECTION, nullptr, nullptr, {});
} }
wakeup_session_thread(); wakeup_session_thread();
} }
@ -312,7 +324,7 @@ void PrusaAuthCommunication::enqueue_avatar_action(const std::string url)
BOOST_LOG_TRIVIAL(error) << "Connect Printers endpoint connection failed - Not Logged in."; BOOST_LOG_TRIVIAL(error) << "Connect Printers endpoint connection failed - Not Logged in.";
return; return;
} }
m_session->enqueue_action(UserActionID::AVATAR, nullptr, nullptr, url); m_session->enqueue_action(UserActionID::AUTH_ACTION_AVATAR, nullptr, nullptr, url);
} }
wakeup_session_thread(); wakeup_session_thread();
} }

View File

@ -44,6 +44,7 @@ public:
#endif #endif
void enqueue_connect_printers_action(); void enqueue_connect_printers_action();
void enqueue_avatar_action(const std::string url); void enqueue_avatar_action(const std::string url);
void enqueue_test_connection();
// Callbacks - called from UI after receiving Event from Session thread. Some might use Session thread. // Callbacks - called from UI after receiving Event from Session thread. Some might use Session thread.
// //
@ -73,7 +74,7 @@ private:
AppConfig* m_app_config; AppConfig* m_app_config;
// if not empty - user is logged in // if not empty - user is logged in
std::string m_username; std::string m_username;
bool m_remember_session {true}; bool m_remember_session { true }; // if default is true, on every login Remember me will be checked.
void wakeup_session_thread(); void wakeup_session_thread();
void init_session_thread(); void init_session_thread();

View File

@ -26,74 +26,46 @@ wxDEFINE_EVENT(EVT_PRUSAAUTH_SUCCESS, PrusaAuthSuccessEvent);
wxDEFINE_EVENT(EVT_PRUSACONNECT_PRINTERS_SUCCESS, PrusaAuthSuccessEvent); wxDEFINE_EVENT(EVT_PRUSACONNECT_PRINTERS_SUCCESS, PrusaAuthSuccessEvent);
wxDEFINE_EVENT(EVT_PA_AVATAR_SUCCESS, PrusaAuthSuccessEvent); wxDEFINE_EVENT(EVT_PA_AVATAR_SUCCESS, PrusaAuthSuccessEvent);
wxDEFINE_EVENT(EVT_PRUSAAUTH_FAIL, PrusaAuthFailEvent); wxDEFINE_EVENT(EVT_PRUSAAUTH_FAIL, PrusaAuthFailEvent);
wxDEFINE_EVENT(EVT_PA_AVATAR_FAIL, PrusaAuthFailEvent);
wxDEFINE_EVENT(EVT_PRUSAAUTH_RESET, PrusaAuthFailEvent); wxDEFINE_EVENT(EVT_PRUSAAUTH_RESET, PrusaAuthFailEvent);
void UserActionPost::perform( /*UNUSED*/ const std::string& access_token, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input) void UserActionPost::perform(/*UNUSED*/ wxEvtHandler* evt_handler, /*UNUSED*/ const std::string& access_token, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input)
{ {
std::string url = m_url; std::string url = m_url;
//BOOST_LOG_TRIVIAL(info) << m_action_name <<" POST " << url << " body: " << input;
auto http = Http::post(std::move(url)); auto http = Http::post(std::move(url));
if (!input.empty()) if (!input.empty())
http.set_post_body(input); http.set_post_body(input);
http.header("Content-type", "application/x-www-form-urlencoded"); http.header("Content-type", "application/x-www-form-urlencoded");
http.on_error([&](std::string body, std::string error, unsigned status) { http.on_error([fail_callback](std::string body, std::string error, unsigned status) {
//BOOST_LOG_TRIVIAL(error) << m_action_name << " action failed. status: " << status << " Body: " << body;
if (fail_callback) if (fail_callback)
fail_callback(body); fail_callback(body);
}); });
http.on_complete([&, this](std::string body, unsigned status) { http.on_complete([success_callback](std::string body, unsigned status) {
//BOOST_LOG_TRIVIAL(info) << m_action_name << "action success. Status: " << status << " Body: " << body;
if (success_callback) if (success_callback)
success_callback(body); success_callback(body);
}); });
http.perform_sync(); http.perform_sync();
} }
void UserActionGetWithEvent::perform(const std::string& access_token, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, /*UNUSED*/ const std::string& input) void UserActionGetWithEvent::perform(wxEvtHandler* evt_handler, const std::string& access_token, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input)
{
std::string url = m_url;
//BOOST_LOG_TRIVIAL(info) << m_action_name << " GET " << url;
auto http = Http::get(url);
http.header("Authorization", "Bearer " + access_token);
http.on_error([&](std::string body, std::string error, unsigned status) {
//BOOST_LOG_TRIVIAL(error) << m_action_name << " action failed. status: " << status << " Body: " << body;
if (fail_callback)
fail_callback(body);
std::string message = GUI::format("%1% action failed (%2%): %3%", m_action_name, std::to_string(status), body);
if (m_succ_evt_type != wxEVT_NULL)
wxQueueEvent(m_evt_handler, new PrusaAuthFailEvent(m_fail_evt_type, std::move(message)));
});
http.on_complete([&, this](std::string body, unsigned status) {
//BOOST_LOG_TRIVIAL(info) << m_action_name << " action success. Status: " << status << " Body: " << body;
if (success_callback)
success_callback(body);
if (m_succ_evt_type != wxEVT_NULL)
wxQueueEvent(m_evt_handler, new PrusaAuthSuccessEvent(m_succ_evt_type, body));
});
http.perform_sync();
}
void UserActionNoAuthGetWithEvent::perform(/*UNUSED*/ const std::string& access_token, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input)
{ {
std::string url = m_url + input; std::string url = m_url + input;
//BOOST_LOG_TRIVIAL(info) << m_action_name << " GET " << url; auto http = Http::get(std::move(url));
auto http = Http::get(url); if (!access_token.empty())
http.on_error([&](std::string body, std::string error, unsigned status) { http.header("Authorization", "Bearer " + access_token);
//BOOST_LOG_TRIVIAL(error) << m_action_name << " action failed. status: " << status << " Body: " << body; http.on_error([evt_handler, fail_callback, action_name = &m_action_name, fail_evt_type = m_fail_evt_type](std::string body, std::string error, unsigned status) {
if (fail_callback) if (fail_callback)
fail_callback(body); fail_callback(body);
std::string message = GUI::format("%1% action failed (%2%): %3%", m_action_name, std::to_string(status), body); std::string message = GUI::format("%1% action failed (%2%): %3%", action_name, std::to_string(status), body);
if (m_succ_evt_type != wxEVT_NULL) if (fail_evt_type != wxEVT_NULL)
wxQueueEvent(m_evt_handler, new PrusaAuthFailEvent(m_fail_evt_type, std::move(message))); wxQueueEvent(evt_handler, new PrusaAuthFailEvent(fail_evt_type, std::move(message)));
}); });
http.on_complete([&, this](std::string body, unsigned status) { http.on_complete([evt_handler, success_callback, succ_evt_type = m_succ_evt_type](std::string body, unsigned status) {
//BOOST_LOG_TRIVIAL(info) << m_action_name << " action success. Status: " << status << " Body: " << body;
if (success_callback) if (success_callback)
success_callback(body); success_callback(body);
if (m_succ_evt_type != wxEVT_NULL) if (succ_evt_type != wxEVT_NULL)
wxQueueEvent(m_evt_handler, new PrusaAuthSuccessEvent(m_succ_evt_type, body)); wxQueueEvent(evt_handler, new PrusaAuthSuccessEvent(succ_evt_type, body));
}); });
http.perform_sync(); http.perform_sync();
@ -103,47 +75,36 @@ void AuthSession::process_action_queue()
{ {
if (!m_proccessing_enabled) if (!m_proccessing_enabled)
return; return;
//BOOST_LOG_TRIVIAL(debug) << "process_action_queue start";
if (m_priority_action_queue.empty() && m_action_queue.empty()) { if (m_priority_action_queue.empty() && m_action_queue.empty()) {
//BOOST_LOG_TRIVIAL(debug) << "process_action_queue queues empty";
// update printers on every periodic wakeup call // update printers on every periodic wakeup call
if (m_polling_enabled) if (m_polling_enabled)
enqueue_action(UserActionID::CONNECT_PRINTERS, nullptr, nullptr, {}); enqueue_action(UserActionID::AUTH_ACTION_CONNECT_PRINTERS, nullptr, nullptr, {});
else else
return; return;
} }
// priority queue works even when tokens are empty or broken
if (this->is_initialized()) {
// if priority queue already has some action f.e. to exchange tokens, the test should not be neccessary but also shouldn't be problem
enqueue_test_with_refresh();
}
while (!m_priority_action_queue.empty()) { while (!m_priority_action_queue.empty()) {
m_actions[m_priority_action_queue.front().action_id]->perform(m_access_token, m_priority_action_queue.front().success_callback, m_priority_action_queue.front().fail_callback, m_priority_action_queue.front().input); m_actions[m_priority_action_queue.front().action_id]->perform(p_evt_handler, m_access_token, m_priority_action_queue.front().success_callback, m_priority_action_queue.front().fail_callback, m_priority_action_queue.front().input);
if (!m_priority_action_queue.empty()) if (!m_priority_action_queue.empty())
m_priority_action_queue.pop(); m_priority_action_queue.pop();
} }
// regular queue has to wait until priority fills tokens
if (!this->is_initialized()) { if (!this->is_initialized())
//BOOST_LOG_TRIVIAL(debug) << "process_action_queue not initialized";
return; return;
}
while (!m_action_queue.empty()) { while (!m_action_queue.empty()) {
m_actions[m_action_queue.front().action_id]->perform(m_access_token, m_action_queue.front().success_callback, m_action_queue.front().fail_callback, m_action_queue.front().input); m_actions[m_action_queue.front().action_id]->perform(p_evt_handler, m_access_token, m_action_queue.front().success_callback, m_action_queue.front().fail_callback, m_action_queue.front().input);
if (!m_action_queue.empty()) if (!m_action_queue.empty())
m_action_queue.pop(); m_action_queue.pop();
} }
//BOOST_LOG_TRIVIAL(debug) << "process_action_queue end";
} }
void AuthSession::enqueue_action(UserActionID id, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input) void AuthSession::enqueue_action(UserActionID id, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input)
{ {
//BOOST_LOG_TRIVIAL(info) << "enqueue_action " << (int)id;
m_proccessing_enabled = true; m_proccessing_enabled = true;
m_action_queue.push({ id, success_callback, fail_callback, input }); m_action_queue.push({ id, success_callback, fail_callback, input });
} }
void AuthSession::init_with_code(const std::string& code, const std::string& code_verifier) void AuthSession::init_with_code(const std::string& code, const std::string& code_verifier)
{ {
// Data we have // Data we have
@ -154,7 +115,16 @@ void AuthSession::init_with_code(const std::string& code, const std::string& cod
"&redirect_uri=" + REDIRECT_URI + "&redirect_uri=" + REDIRECT_URI +
"&code_verifier="+ code_verifier; "&code_verifier="+ code_verifier;
auto succ_fn = [&](const std::string& body){ m_proccessing_enabled = true;
// fail fn might be cancel_queue here
m_priority_action_queue.push({ UserActionID::AUTH_ACTION_CODE_FOR_TOKEN
, std::bind(&AuthSession::token_success_callback, this, std::placeholders::_1)
, std::bind(&AuthSession::code_exchange_fail_callback, this, std::placeholders::_1)
, post_fields });
}
void AuthSession::token_success_callback(const std::string& body)
{
// Data we need // Data we need
std::string access_token, refresh_token, shared_session_key; std::string access_token, refresh_token, shared_session_key;
try { try {
@ -174,15 +144,18 @@ void AuthSession::init_with_code(const std::string& code, const std::string& cod
shared_session_key = *shared_session_key_optional; shared_session_key = *shared_session_key_optional;
} }
catch (const std::exception&) { catch (const std::exception&) {
BOOST_LOG_TRIVIAL(error) << "Auth::http_access Could not parse server response."; std::string msg = "Could not parse server response after code exchange.";
wxQueueEvent(p_evt_handler, new PrusaAuthFailEvent(EVT_PRUSAAUTH_RESET, std::move(msg)));
return;
} }
assert(!access_token.empty() && !refresh_token.empty() && !shared_session_key.empty());
if (access_token.empty() || refresh_token.empty() || shared_session_key.empty()) { if (access_token.empty() || refresh_token.empty() || shared_session_key.empty()) {
BOOST_LOG_TRIVIAL(error) << "Refreshing token has failed."; // just debug msg, no need to translate
std::string msg = GUI::format("Failed read tokens after POST.\nAccess token: %1%\nRefresh token: %2%\nShared session token: %3%\nbody: %4%", access_token, refresh_token, shared_session_key, body);
m_access_token = std::string(); m_access_token = std::string();
m_refresh_token = std::string(); m_refresh_token = std::string();
m_shared_session_key = std::string(); m_shared_session_key = std::string();
wxQueueEvent(p_evt_handler, new PrusaAuthFailEvent(EVT_PRUSAAUTH_RESET, std::move(msg)));
return; return;
} }
@ -193,76 +166,48 @@ void AuthSession::init_with_code(const std::string& code, const std::string& cod
m_access_token = access_token; m_access_token = access_token;
m_refresh_token = refresh_token; m_refresh_token = refresh_token;
m_shared_session_key = shared_session_key; m_shared_session_key = shared_session_key;
}; enqueue_action(UserActionID::AUTH_ACTION_USER_ID, nullptr, nullptr, {});
}
m_proccessing_enabled = true; void AuthSession::code_exchange_fail_callback(const std::string& body)
// fail fn might be cancel_queue here {
m_priority_action_queue.push({ UserActionID::CODE_FOR_TOKEN, succ_fn, std::bind(&AuthSession::enqueue_refresh, this, std::placeholders::_1), post_fields }); clear();
cancel_queue();
// Unlike refresh_fail_callback, no event was triggered so far, do it. (AUTH_ACTION_CODE_FOR_TOKEN does not send events)
wxQueueEvent(p_evt_handler, new PrusaAuthFailEvent(EVT_PRUSAAUTH_RESET, std::move(body)));
} }
void AuthSession::enqueue_test_with_refresh() void AuthSession::enqueue_test_with_refresh()
{ {
// on test fail - try refresh // on test fail - try refresh
m_priority_action_queue.push({ UserActionID::TEST_CONNECTION, nullptr, std::bind(&AuthSession::enqueue_refresh, this, std::placeholders::_1), {} }); m_proccessing_enabled = true;
m_priority_action_queue.push({ UserActionID::AUTH_ACTION_TEST_ACCESS_TOKEN, nullptr, std::bind(&AuthSession::enqueue_refresh, this, std::placeholders::_1), {} });
} }
void AuthSession::enqueue_refresh(const std::string& body) void AuthSession::enqueue_refresh(const std::string& body)
{ {
assert(!m_refresh_token.empty());
std::string post_fields = "grant_type=refresh_token" std::string post_fields = "grant_type=refresh_token"
"&client_id=" + client_id() + "&client_id=" + client_id() +
"&refresh_token=" + m_refresh_token; "&refresh_token=" + m_refresh_token;
auto succ_callback = [&](const std::string& body){ m_priority_action_queue.push({ UserActionID::AUTH_ACTION_REFRESH_TOKEN
std::string new_access_token; , std::bind(&AuthSession::token_success_callback, this, std::placeholders::_1)
std::string new_refresh_token; , std::bind(&AuthSession::refresh_fail_callback, this, std::placeholders::_1)
std::string new_shared_session_key; , post_fields });
try {
std::stringstream ss(body);
pt::ptree ptree;
pt::read_json(ss, ptree);
const auto access_token_optional = ptree.get_optional<std::string>("access_token");
const auto refresh_token_optional = ptree.get_optional<std::string>("refresh_token");
const auto shared_session_key_optional = ptree.get_optional<std::string>("shared_session_key");
if (access_token_optional)
new_access_token = *access_token_optional;
if (refresh_token_optional)
new_refresh_token = *refresh_token_optional;
if (shared_session_key_optional)
new_shared_session_key = *shared_session_key_optional;
}
catch (const std::exception&) {
BOOST_LOG_TRIVIAL(error) << "Could not parse server response.";
}
assert(!new_access_token.empty() && !new_refresh_token.empty() && !new_shared_session_key.empty());
if (new_access_token.empty() || new_refresh_token.empty() || new_shared_session_key.empty()) {
BOOST_LOG_TRIVIAL(error) << "Refreshing token has failed.";
m_access_token = std::string();
m_refresh_token = std::string();
m_shared_session_key = std::string();
// TODO: cancel following queue
}
BOOST_LOG_TRIVIAL(info) << "access_token: " << new_access_token;
BOOST_LOG_TRIVIAL(info) << "refresh_token: " << new_refresh_token;
BOOST_LOG_TRIVIAL(info) << "shared_session_key: " << new_shared_session_key;
m_access_token = new_access_token;
m_refresh_token = new_refresh_token;
m_shared_session_key = new_shared_session_key;
m_priority_action_queue.push({ UserActionID::TEST_CONNECTION, nullptr, std::bind(&AuthSession::refresh_failed_callback, this, std::placeholders::_1), {} });
};
m_priority_action_queue.push({ UserActionID::REFRESH_TOKEN, succ_callback, std::bind(&AuthSession::refresh_failed_callback, this, std::placeholders::_1), post_fields });
} }
void AuthSession::refresh_failed_callback(const std::string& body) void AuthSession::refresh_fail_callback(const std::string& body)
{ {
clear(); clear();
cancel_queue(); cancel_queue();
// No need to notify UI thread here
// backtrace: load tokens -> TEST_TOKEN fail (access token bad) -> REFRESH_TOKEN fail (refresh token bad)
// AUTH_ACTION_TEST_ACCESS_TOKEN triggers EVT_PRUSAAUTH_FAIL, we need also RESET
wxQueueEvent(p_evt_handler, new PrusaAuthFailEvent(EVT_PRUSAAUTH_RESET, std::move(body)));
} }
void AuthSession::cancel_queue() void AuthSession::cancel_queue()
{ {
while (!m_priority_action_queue.empty()) { while (!m_priority_action_queue.empty()) {

View File

@ -23,29 +23,31 @@ wxDECLARE_EVENT(EVT_PA_ID_USER_FAIL, PrusaAuthFailEvent);
wxDECLARE_EVENT(EVT_PRUSAAUTH_SUCCESS, PrusaAuthSuccessEvent); wxDECLARE_EVENT(EVT_PRUSAAUTH_SUCCESS, PrusaAuthSuccessEvent);
wxDECLARE_EVENT(EVT_PRUSACONNECT_PRINTERS_SUCCESS, PrusaAuthSuccessEvent); wxDECLARE_EVENT(EVT_PRUSACONNECT_PRINTERS_SUCCESS, PrusaAuthSuccessEvent);
wxDECLARE_EVENT(EVT_PA_AVATAR_SUCCESS, PrusaAuthSuccessEvent); wxDECLARE_EVENT(EVT_PA_AVATAR_SUCCESS, PrusaAuthSuccessEvent);
wxDECLARE_EVENT(EVT_PRUSAAUTH_FAIL, PrusaAuthFailEvent); wxDECLARE_EVENT(EVT_PRUSAAUTH_FAIL, PrusaAuthFailEvent); // Soft fail - clears only after some number of fails
wxDECLARE_EVENT(EVT_PRUSAAUTH_RESET, PrusaAuthFailEvent); wxDECLARE_EVENT(EVT_PA_AVATAR_FAIL, PrusaAuthFailEvent); // Soft fail - clears only after some number of fails
wxDECLARE_EVENT(EVT_PRUSAAUTH_RESET, PrusaAuthFailEvent); // Hard fail - clears all
typedef std::function<void(const std::string& body)> UserActionSuccessFn; typedef std::function<void(const std::string& body)> UserActionSuccessFn;
typedef std::function<void(const std::string& body)> UserActionFailFn; typedef std::function<void(const std::string& body)> UserActionFailFn;
// UserActions implements different operations via trigger() method. Stored in m_actions. // UserActions implements different operations via trigger() method. Stored in m_actions.
enum class UserActionID { enum class UserActionID {
DUMMY_ACTION, AUTH_ACTION_DUMMY,
REFRESH_TOKEN, AUTH_ACTION_REFRESH_TOKEN,
CODE_FOR_TOKEN, AUTH_ACTION_CODE_FOR_TOKEN,
TEST_CONNECTION, AUTH_ACTION_USER_ID,
LOGIN_USER_ID, AUTH_ACTION_TEST_ACCESS_TOKEN,
CONNECT_DUMMY, AUTH_ACTION_TEST_CONNECTION,
CONNECT_PRINTERS, AUTH_ACTION_CONNECT_DUMMY,
AVATAR, AUTH_ACTION_CONNECT_PRINTERS,
AUTH_ACTION_AVATAR,
}; };
class UserAction class UserAction
{ {
public: public:
UserAction(const std::string name, const std::string url) : m_action_name(name), m_url(url){} UserAction(const std::string name, const std::string url) : m_action_name(name), m_url(url){}
~UserAction() {} ~UserAction() {}
virtual void perform(const std::string& access_token, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input) = 0; virtual void perform(wxEvtHandler* evt_handler, const std::string& access_token, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input) = 0;
protected: protected:
std::string m_action_name; std::string m_action_name;
std::string m_url; std::string m_url;
@ -54,35 +56,16 @@ protected:
class UserActionGetWithEvent : public UserAction class UserActionGetWithEvent : public UserAction
{ {
public: public:
UserActionGetWithEvent(const std::string name, const std::string url, wxEvtHandler* evt_handler, wxEventType succ_event_type, wxEventType fail_event_type) UserActionGetWithEvent(const std::string name, const std::string url, wxEventType succ_event_type, wxEventType fail_event_type)
: m_succ_evt_type(succ_event_type) : m_succ_evt_type(succ_event_type)
, m_fail_evt_type(fail_event_type) , m_fail_evt_type(fail_event_type)
, m_evt_handler(evt_handler)
, UserAction(name, url) , UserAction(name, url)
{} {}
~UserActionGetWithEvent() {} ~UserActionGetWithEvent() {}
void perform(const std::string& access_token, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input) override; void perform(wxEvtHandler* evt_handler, const std::string& access_token, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input) override;
private: private:
wxEventType m_succ_evt_type; wxEventType m_succ_evt_type;
wxEventType m_fail_evt_type; wxEventType m_fail_evt_type;
wxEvtHandler* m_evt_handler;
};
class UserActionNoAuthGetWithEvent : public UserAction
{
public:
UserActionNoAuthGetWithEvent(const std::string name, const std::string url, wxEvtHandler* evt_handler, wxEventType succ_event_type, wxEventType fail_event_type)
: m_succ_evt_type(succ_event_type)
, m_fail_evt_type(fail_event_type)
, m_evt_handler(evt_handler)
, UserAction(name, url)
{}
~UserActionNoAuthGetWithEvent() {}
void perform(const std::string& access_token, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input) override;
private:
wxEventType m_succ_evt_type;
wxEventType m_fail_evt_type;
wxEvtHandler* m_evt_handler;
}; };
class UserActionPost : public UserAction class UserActionPost : public UserAction
@ -90,7 +73,7 @@ class UserActionPost : public UserAction
public: public:
UserActionPost(const std::string name, const std::string url) : UserAction(name, url) {} UserActionPost(const std::string name, const std::string url) : UserAction(name, url) {}
~UserActionPost() {} ~UserActionPost() {}
void perform(const std::string& access_token, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input) override; void perform(wxEvtHandler* evt_handler, const std::string& access_token, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input) override;
}; };
class DummyUserAction : public UserAction class DummyUserAction : public UserAction
@ -98,7 +81,7 @@ class DummyUserAction : public UserAction
public: public:
DummyUserAction() : UserAction("Dummy", {}) {} DummyUserAction() : UserAction("Dummy", {}) {}
~DummyUserAction() {} ~DummyUserAction() {}
void perform(const std::string& access_token, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input) override { } void perform(wxEvtHandler* evt_handler, const std::string& access_token, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input) override { }
}; };
struct ActionQueueData struct ActionQueueData
@ -113,31 +96,36 @@ class AuthSession
{ {
public: public:
AuthSession(wxEvtHandler* evt_handler, const std::string& access_token, const std::string& refresh_token, const std::string& shared_session_key, bool polling_enabled) AuthSession(wxEvtHandler* evt_handler, const std::string& access_token, const std::string& refresh_token, const std::string& shared_session_key, bool polling_enabled)
: m_access_token(access_token) : p_evt_handler(evt_handler)
, m_access_token(access_token)
, m_refresh_token(refresh_token) , m_refresh_token(refresh_token)
, m_shared_session_key(shared_session_key) , m_shared_session_key(shared_session_key)
, m_polling_enabled(polling_enabled) , m_polling_enabled(polling_enabled)
{ {
// do not forget to add delete to destructor // do not forget to add delete to destructor
m_actions[UserActionID::DUMMY_ACTION] = std::make_unique<DummyUserAction>(); m_actions[UserActionID::AUTH_ACTION_DUMMY] = std::make_unique<DummyUserAction>();
m_actions[UserActionID::REFRESH_TOKEN] = std::make_unique<UserActionPost>("EXCHANGE_TOKENS", "https://test-account.prusa3d.com/o/token/"); m_actions[UserActionID::AUTH_ACTION_REFRESH_TOKEN] = std::make_unique<UserActionPost>("EXCHANGE_TOKENS", "https://test-account.prusa3d.com/o/token/");
m_actions[UserActionID::CODE_FOR_TOKEN] = std::make_unique<UserActionPost>("EXCHANGE_TOKENS", "https://test-account.prusa3d.com/o/token/"); m_actions[UserActionID::AUTH_ACTION_CODE_FOR_TOKEN] = std::make_unique<UserActionPost>("EXCHANGE_TOKENS", "https://test-account.prusa3d.com/o/token/");
m_actions[UserActionID::TEST_CONNECTION] = std::make_unique<UserActionGetWithEvent>("TEST_CONNECTION", "https://test-account.prusa3d.com/api/v1/me/", evt_handler, wxEVT_NULL, EVT_PRUSAAUTH_FAIL); m_actions[UserActionID::AUTH_ACTION_USER_ID] = std::make_unique<UserActionGetWithEvent>("USER_ID", "https://test-account.prusa3d.com/api/v1/me/", EVT_PA_ID_USER_SUCCESS, EVT_PRUSAAUTH_RESET);
m_actions[UserActionID::LOGIN_USER_ID] = std::make_unique<UserActionGetWithEvent>("USER_ID", "https://test-account.prusa3d.com/api/v1/me/", evt_handler, EVT_PA_ID_USER_SUCCESS, EVT_PRUSAAUTH_FAIL); m_actions[UserActionID::AUTH_ACTION_TEST_ACCESS_TOKEN] = std::make_unique<UserActionGetWithEvent>("TEST_ACCESS_TOKEN", "https://test-account.prusa3d.com/api/v1/me/", EVT_PA_ID_USER_SUCCESS, EVT_PRUSAAUTH_FAIL);
m_actions[UserActionID::CONNECT_DUMMY] = std::make_unique<UserActionGetWithEvent>("CONNECT_DUMMY", "https://dev.connect.prusa3d.com/slicer/dummy"/*"dev.connect.prusa:8000/slicer/dummy"*/, evt_handler, EVT_PRUSAAUTH_SUCCESS, EVT_PRUSAAUTH_FAIL); m_actions[UserActionID::AUTH_ACTION_TEST_CONNECTION] = std::make_unique<UserActionGetWithEvent>("TEST_CONNECTION", "https://test-account.prusa3d.com/api/v1/me/", wxEVT_NULL, EVT_PRUSAAUTH_RESET);
m_actions[UserActionID::CONNECT_PRINTERS] = std::make_unique<UserActionGetWithEvent>("CONNECT_PRINTERS", "https://dev.connect.prusa3d.com/slicer/printers"/*"dev.connect.prusa:8000/slicer/printers"*/, evt_handler, EVT_PRUSACONNECT_PRINTERS_SUCCESS, EVT_PRUSAAUTH_FAIL); m_actions[UserActionID::AUTH_ACTION_CONNECT_DUMMY] = std::make_unique<UserActionGetWithEvent>("CONNECT_DUMMY", "https://dev.connect.prusa3d.com/slicer/dummy"/*"dev.connect.prusa:8000/slicer/dummy"*/, EVT_PRUSAAUTH_SUCCESS, EVT_PRUSAAUTH_FAIL);
m_actions[UserActionID::AVATAR] = std::make_unique<UserActionNoAuthGetWithEvent>("AVATAR", "https://test-media.printables.com/media/", evt_handler, EVT_PA_AVATAR_SUCCESS, EVT_PRUSAAUTH_FAIL); m_actions[UserActionID::AUTH_ACTION_CONNECT_PRINTERS] = std::make_unique<UserActionGetWithEvent>("CONNECT_PRINTERS", "https://dev.connect.prusa3d.com/slicer/printers"/*"dev.connect.prusa:8000/slicer/printers"*/, EVT_PRUSACONNECT_PRINTERS_SUCCESS, EVT_PRUSAAUTH_FAIL);
m_actions[UserActionID::AUTH_ACTION_AVATAR] = std::make_unique<UserActionGetWithEvent>("AVATAR", "https://test-media.printables.com/media/", EVT_PA_AVATAR_SUCCESS, EVT_PA_AVATAR_FAIL);
} }
~AuthSession() ~AuthSession()
{ {
m_actions[UserActionID::DUMMY_ACTION].reset(nullptr); m_actions[UserActionID::AUTH_ACTION_DUMMY].reset(nullptr);
m_actions[UserActionID::REFRESH_TOKEN].reset(nullptr); m_actions[UserActionID::AUTH_ACTION_REFRESH_TOKEN].reset(nullptr);
m_actions[UserActionID::CODE_FOR_TOKEN].reset(nullptr); m_actions[UserActionID::AUTH_ACTION_CODE_FOR_TOKEN].reset(nullptr);
m_actions[UserActionID::TEST_CONNECTION].reset(nullptr); m_actions[UserActionID::AUTH_ACTION_USER_ID].reset(nullptr);
m_actions[UserActionID::LOGIN_USER_ID].reset(nullptr); m_actions[UserActionID::AUTH_ACTION_TEST_ACCESS_TOKEN].reset(nullptr);
m_actions[UserActionID::CONNECT_DUMMY].reset(nullptr); m_actions[UserActionID::AUTH_ACTION_TEST_CONNECTION].reset(nullptr);
m_actions[UserActionID::CONNECT_PRINTERS].reset(nullptr); m_actions[UserActionID::AUTH_ACTION_CONNECT_DUMMY].reset(nullptr);
m_actions[UserActionID::AVATAR].reset(nullptr); m_actions[UserActionID::AUTH_ACTION_CONNECT_PRINTERS].reset(nullptr);
m_actions[UserActionID::AUTH_ACTION_AVATAR].reset(nullptr);
//assert(m_actions.empty()); //assert(m_actions.empty());
} }
void clear() { void clear() {
@ -150,6 +138,8 @@ public:
// Functions that automatically enable action queu processing // Functions that automatically enable action queu processing
void init_with_code(const std::string& code, const std::string& code_verifier); void init_with_code(const std::string& code, const std::string& code_verifier);
void enqueue_action(UserActionID id, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input); void enqueue_action(UserActionID id, UserActionSuccessFn success_callback, UserActionFailFn fail_callback, const std::string& input);
// Special enques, that sets callbacks.
void enqueue_test_with_refresh();
void process_action_queue(); void process_action_queue();
bool is_initialized() { return !m_access_token.empty() || !m_refresh_token.empty(); } bool is_initialized() { return !m_access_token.empty() || !m_refresh_token.empty(); }
@ -159,10 +149,12 @@ public:
void set_polling_enabled(bool enabled) {m_polling_enabled = enabled; } void set_polling_enabled(bool enabled) {m_polling_enabled = enabled; }
private: private:
void enqueue_test_with_refresh();
void enqueue_refresh(const std::string& body); void enqueue_refresh(const std::string& body);
void refresh_failed_callback(const std::string& body); void refresh_fail_callback(const std::string& body);
void cancel_queue(); void cancel_queue();
void code_exchange_fail_callback(const std::string& body);
void token_success_callback(const std::string& body);
std::string client_id() const { return "UfTRUm5QjWwaQEGpWQBHGHO3reAyuzgOdBaiqO52"; } std::string client_id() const { return "UfTRUm5QjWwaQEGpWQBHGHO3reAyuzgOdBaiqO52"; }
// false prevents action queu to be processed - no communication is done // false prevents action queu to be processed - no communication is done
@ -178,6 +170,8 @@ private:
std::queue<ActionQueueData> m_action_queue; std::queue<ActionQueueData> m_action_queue;
std::queue<ActionQueueData> m_priority_action_queue; std::queue<ActionQueueData> m_priority_action_queue;
std::map<UserActionID, std::unique_ptr<UserAction>> m_actions; std::map<UserActionID, std::unique_ptr<UserAction>> m_actions;
wxEvtHandler* p_evt_handler;
}; };
} }

View File

@ -884,42 +884,52 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
}); });
this->q->Bind(EVT_LOGGEDOUT_PRUSAAUTH, [this](PrusaAuthSuccessEvent& evt) { this->q->Bind(EVT_LOGGEDOUT_PRUSAAUTH, [this](PrusaAuthSuccessEvent& evt) {
user_account->on_logout(wxGetApp().app_config); user_account->clear();
this->main_frame->disable_connect_tab(); std::string text = _u8L("Logged out from Prusa Account.");
std::string text = _u8L("Logged out.");
this->notification_manager->close_notification_of_type(NotificationType::PrusaAuthUserID); this->notification_manager->close_notification_of_type(NotificationType::PrusaAuthUserID);
this->notification_manager->push_notification(NotificationType::PrusaAuthUserID, NotificationManager::NotificationLevel::ImportantNotificationLevel, text); this->notification_manager->push_notification(NotificationType::PrusaAuthUserID, NotificationManager::NotificationLevel::ImportantNotificationLevel, text);
this->main_frame->disable_connect_tab();
this->main_frame->refresh_auth_menu();
}); });
this->q->Bind(EVT_PA_ID_USER_SUCCESS, [this](PrusaAuthSuccessEvent& evt) { this->q->Bind(EVT_PA_ID_USER_SUCCESS, [this](PrusaAuthSuccessEvent& evt) {
std::string username; std::string username;
bool succ = user_account->on_user_id_success(evt.data, username); if (user_account->on_user_id_success(evt.data, username)) {
if (succ) {
// show connect tab
this->main_frame->enable_connect_tab();
// login notification // login notification
std::string text = format(_u8L("Logged as %1%."), username); std::string text = format(_u8L("Logged to Prusa Account as %1%."), username);
this->notification_manager->close_notification_of_type(NotificationType::PrusaAuthUserID); this->notification_manager->close_notification_of_type(NotificationType::PrusaAuthUserID);
this->notification_manager->push_notification(NotificationType::PrusaAuthUserID, NotificationManager::NotificationLevel::ImportantNotificationLevel, text); this->notification_manager->push_notification(NotificationType::PrusaAuthUserID, NotificationManager::NotificationLevel::ImportantNotificationLevel, text);
// show connect tab
this->main_frame->enable_connect_tab();
// Update User name in TopBar // Update User name in TopBar
this->main_frame->refresh_auth_menu(); this->main_frame->refresh_auth_menu();
} else { } else {
// TODO // data were corrupt and username was not retrieved
// procced as if EVT_PRUSAAUTH_RESET was recieved
BOOST_LOG_TRIVIAL(error) << "Reseting Prusa Account communication. Recieved data were corrupt.";
user_account->clear();
this->notification_manager->close_notification_of_type(NotificationType::PrusaAuthUserID);
this->notification_manager->push_notification(NotificationType::PrusaAuthUserID, NotificationManager::NotificationLevel::WarningNotificationLevel, _u8L("Failed to connect to Prusa Account."));
// Update User name in TopBar
this->main_frame->refresh_auth_menu();
// Update sidebar printer status
sidebar->update_printer_presets_combobox();
} }
}); });
this->q->Bind(EVT_PRUSAAUTH_RESET, [this](PrusaAuthFailEvent& evt) { this->q->Bind(EVT_PRUSAAUTH_RESET, [this](PrusaAuthFailEvent& evt) {
BOOST_LOG_TRIVIAL(error) << "Network error message: " << evt.data; BOOST_LOG_TRIVIAL(error) << "Reseting Prusa Account communication. Error message: " << evt.data;
user_account->on_communication_fail(evt.data, wxGetApp().app_config); user_account->clear();
this->notification_manager->close_notification_of_type(NotificationType::PrusaAuthUserID); this->notification_manager->close_notification_of_type(NotificationType::PrusaAuthUserID);
this->notification_manager->push_notification(NotificationType::PrusaAuthUserID, NotificationManager::NotificationLevel::WarningNotificationLevel, _u8L("Connection to PrusaConnect has failed.")); this->notification_manager->push_notification(NotificationType::PrusaAuthUserID, NotificationManager::NotificationLevel::WarningNotificationLevel, _u8L("Failed to connect to Prusa Account."));
// Update User name in TopBar
this->main_frame->refresh_auth_menu();
// Update sidebar printer status
sidebar->update_printer_presets_combobox();
}); });
this->q->Bind(EVT_PRUSAAUTH_FAIL, [this](PrusaAuthFailEvent& evt) { this->q->Bind(EVT_PRUSAAUTH_FAIL, [this](PrusaAuthFailEvent& evt) {
BOOST_LOG_TRIVIAL(error) << "Network error message: " << evt.data; BOOST_LOG_TRIVIAL(error) << "Failed communication with Prusa Account: " << evt.data;
user_account->on_communication_fail(evt.data, wxGetApp().app_config); user_account->on_communication_fail();
this->notification_manager->close_notification_of_type(NotificationType::PrusaAuthUserID);
this->notification_manager->push_notification(NotificationType::PrusaAuthUserID, NotificationManager::NotificationLevel::WarningNotificationLevel, _u8L("Connection to PrusaConnect has failed."));
}); });
this->q->Bind(EVT_PRUSAAUTH_SUCCESS, [this](PrusaAuthSuccessEvent& evt) { this->q->Bind(EVT_PRUSAAUTH_SUCCESS, [this](PrusaAuthSuccessEvent& evt) {
this->notification_manager->close_notification_of_type(NotificationType::PrusaAuthUserID); this->notification_manager->close_notification_of_type(NotificationType::PrusaAuthUserID);
@ -928,19 +938,13 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
this->q->Bind(EVT_PRUSACONNECT_PRINTERS_SUCCESS, [this](PrusaAuthSuccessEvent& evt) { this->q->Bind(EVT_PRUSACONNECT_PRINTERS_SUCCESS, [this](PrusaAuthSuccessEvent& evt) {
std::string text; std::string text;
bool printers_changed = false; bool printers_changed = false;
bool succ = user_account->on_connect_printers_success(evt.data, wxGetApp().app_config, printers_changed, text); if (user_account->on_connect_printers_success(evt.data, wxGetApp().app_config, printers_changed)) {
if (succ) { if (printers_changed) {
if (printers_changed)
{
//std::string out = GUI::format("Printers in your PrusaConnect team %1%:\n%2%", (printers_changed ? "changed" : "didn't changed"), text);
//std::string out = GUI::format("Printers in your PrusaConnect team:\n%1%", text);
//this->notification_manager->close_notification_of_type(NotificationType::PrusaConnectPrinters);
//this->notification_manager->push_notification(NotificationType::PrusaConnectPrinters, NotificationManager::NotificationLevel::ImportantNotificationLevel, out);
sidebar->update_printer_presets_combobox(); sidebar->update_printer_presets_combobox();
} }
} else { } else {
// TODO // message was corrupt, procceed like EVT_PRUSAAUTH_FAIL
user_account->on_communication_fail();
} }
}); });
this->q->Bind(EVT_PA_AVATAR_SUCCESS, [this](PrusaAuthSuccessEvent& evt) { this->q->Bind(EVT_PA_AVATAR_SUCCESS, [this](PrusaAuthSuccessEvent& evt) {

View File

@ -25,7 +25,7 @@ void UserAccount::set_username(const std::string& username)
m_auth_communication->set_username(username); m_auth_communication->set_username(username);
} }
void UserAccount::reset() void UserAccount::clear()
{ {
m_username = {}; m_username = {};
m_user_data.clear(); m_user_data.clear();
@ -79,10 +79,9 @@ void UserAccount::enqueue_connect_printers_action()
{ {
m_auth_communication->enqueue_connect_printers_action(); m_auth_communication->enqueue_connect_printers_action();
} }
void UserAccount::enqueue_avatar_action()
void UserAccount::enqueue_avatar_action(const std::string& url)
{ {
m_auth_communication->enqueue_avatar_action(url); m_auth_communication->enqueue_avatar_action(m_user_data["avatar"]);
} }
bool UserAccount::on_login_code_recieved(const std::string& url_message) bool UserAccount::on_login_code_recieved(const std::string& url_message)
@ -111,7 +110,6 @@ bool UserAccount::on_user_id_success(const std::string data, std::string& out_us
} }
} }
assert(m_user_data.find("public_username") != m_user_data.end());
if (m_user_data.find("public_username") == m_user_data.end()) { if (m_user_data.find("public_username") == m_user_data.end()) {
BOOST_LOG_TRIVIAL(error) << "User ID message from PrusaAuth did not contain public_username. Login failed. Message data: " << data; BOOST_LOG_TRIVIAL(error) << "User ID message from PrusaAuth did not contain public_username. Login failed. Message data: " << data;
return false; return false;
@ -121,33 +119,24 @@ bool UserAccount::on_user_id_success(const std::string data, std::string& out_us
out_username = public_username; out_username = public_username;
// equeue GET with avatar url // equeue GET with avatar url
if (m_user_data.find("avatar") != m_user_data.end()) { if (m_user_data.find("avatar") != m_user_data.end()) {
enqueue_avatar_action(m_user_data["avatar"]); enqueue_avatar_action();
} }
else { else {
BOOST_LOG_TRIVIAL(warning) << "User ID message from PrusaAcuth did not contain avatar."; BOOST_LOG_TRIVIAL(error) << "User ID message from PrusaAuth did not contain avatar.";
} }
// update printers list // update printers list
enqueue_connect_printers_action(); enqueue_connect_printers_action();
return true; return true;
} }
bool UserAccount::on_communication_fail(const std::string data, AppConfig* app_config) void UserAccount::on_communication_fail()
{ {
// TODO: should we just declare disconnect on every fail? m_fail_counter++;
//set_username({}, app_config); if (m_fail_counter > 5) // there is no deeper reason why 5
return true; {
} m_auth_communication->enqueue_test_connection();
m_fail_counter = 0;
bool UserAccount::on_communication_reset(const std::string data, AppConfig* app_config) }
{
set_username({});
return true;
}
bool UserAccount::on_logout( AppConfig* app_config)
{
set_username({});
return true;
} }
namespace { namespace {
@ -166,7 +155,7 @@ namespace {
} }
} }
bool UserAccount::on_connect_printers_success(const std::string data, AppConfig* app_config, bool& out_printers_changed, std::string& out_message) bool UserAccount::on_connect_printers_success(const std::string data, AppConfig* app_config, bool& out_printers_changed)
{ {
BOOST_LOG_TRIVIAL(debug) << "PrusaConnect printers message: " << data; BOOST_LOG_TRIVIAL(debug) << "PrusaConnect printers message: " << data;
pt::ptree ptree; pt::ptree ptree;
@ -238,17 +227,6 @@ bool UserAccount::on_connect_printers_success(const std::string data, AppConfig*
} }
} }
} }
std::string out;
for (const auto& it : m_printer_map)
{
out_message += GUI::format("%1%: O%2% I%3% P%4% F%5% \n"
, it.first
, std::to_string(it.second[static_cast<size_t>(ConnectPrinterState::CONNECT_PRINTER_OFFLINE)])
, std::to_string(it.second[static_cast<size_t>(ConnectPrinterState::CONNECT_PRINTER_IDLE)])
, std::to_string(it.second[static_cast<size_t>(ConnectPrinterState::CONNECT_PRINTER_PRINTING)])
, std::to_string(it.second[static_cast<size_t>(ConnectPrinterState::CONNECT_PRINTER_FINISHED)]));
}
return true; return true;
} }

View File

@ -42,16 +42,17 @@ public:
void enqueue_connect_dummy_action(); void enqueue_connect_dummy_action();
#endif #endif
void enqueue_connect_printers_action(); void enqueue_connect_printers_action();
void enqueue_avatar_action(const std::string& url); void enqueue_avatar_action();
// Functions called from UI where events emmited from AuthSession are binded // Functions called from UI where events emmited from AuthSession are binded
// Returns bool if data were correctly proccessed // Returns bool if data were correctly proccessed
bool on_login_code_recieved(const std::string& url_message); bool on_login_code_recieved(const std::string& url_message);
bool on_user_id_success(const std::string data, std::string& out_username); bool on_user_id_success(const std::string data, std::string& out_username);
bool on_communication_fail(const std::string data, AppConfig* app_config); // Called on EVT_PRUSAAUTH_FAIL, triggers test after several calls
bool on_communication_reset(const std::string data, AppConfig* app_config); void on_communication_fail();
bool on_logout(AppConfig* app_config); // Clears all data and connections, called on logout or EVT_PRUSAAUTH_RESET
bool on_connect_printers_success(const std::string data, AppConfig* app_config, bool& out_printers_changed, std::string& out_message); void clear();
bool on_connect_printers_success(const std::string data, AppConfig* app_config, bool& out_printers_changed);
std::string get_username() const { return m_username; } std::string get_username() const { return m_username; }
std::string get_access_token(); std::string get_access_token();
@ -65,13 +66,14 @@ public:
std::string get_apikey_from_json(const std::string& message) const; std::string get_apikey_from_json(const std::string& message) const;
private: private:
void set_username(const std::string& username); void set_username(const std::string& username);
void reset();
std::unique_ptr<Slic3r::GUI::PrusaAuthCommunication> m_auth_communication; std::unique_ptr<Slic3r::GUI::PrusaAuthCommunication> m_auth_communication;
ConnectPrinterStateMap m_printer_map; ConnectPrinterStateMap m_printer_map;
std::map<std::string, std::string> m_user_data; std::map<std::string, std::string> m_user_data;
std::string m_username; std::string m_username;
size_t m_fail_counter { 0 };
// first string is "printer_type" code from Connect edpoints // first string is "printer_type" code from Connect edpoints
const std::map<std::string, std::string> printer_type_and_name_table = { const std::map<std::string, std::string> printer_type_and_name_table = {