SPE-2567: Deleting cookies with counter

Timer to prevent fail in asynchronous deletion
This commit is contained in:
David Kocik 2025-01-09 14:06:06 +01:00 committed by Lukas Matena
parent bd19f11919
commit 3c377a435e
6 changed files with 142 additions and 8 deletions

View File

@ -693,19 +693,28 @@ LoginWebViewDialog::LoginWebViewDialog(wxWindow *parent, std::string &ret_val, c
, m_ret_val(ret_val)
, p_evt_handler(evt_handler)
{
m_force_quit_timer.SetOwner(this, 0);
Bind(wxEVT_TIMER, [this](wxTimerEvent &evt)
{
m_force_quit = true;
});
Centre();
}
void LoginWebViewDialog::on_navigation_request(wxWebViewEvent &evt)
{
wxString url = evt.GetURL();
if (url.starts_with(L"prusaslicer")) {
delete_cookies(m_browser, Utils::ServiceConfig::instance().account_url());
delete_cookies(m_browser, "https://accounts.google.com");
delete_cookies(m_browser, "https://appleid.apple.com");
delete_cookies(m_browser, "https://facebook.com");
m_waiting_for_counters = true;
m_atomic_counter = 0;
m_counter_to_match = 4;
delete_cookies_with_counter(m_browser, Utils::ServiceConfig::instance().account_url(), m_atomic_counter);
delete_cookies_with_counter(m_browser, "https://accounts.google.com", m_atomic_counter);
delete_cookies_with_counter(m_browser, "https://appleid.apple.com", m_atomic_counter);
delete_cookies_with_counter(m_browser, "https://facebook.com", m_atomic_counter);
evt.Veto();
m_ret_val = into_u8(url);
EndModal(wxID_OK);
m_force_quit_timer.Start(2000, wxTIMER_ONE_SHOT);
// End modal is moved to on_idle
} else if (url.Find(L"accounts.google.com") != wxNOT_FOUND
|| url.Find(L"appleid.apple.com") != wxNOT_FOUND
|| url.Find(L"facebook.com") != wxNOT_FOUND) {
@ -726,5 +735,36 @@ void LoginWebViewDialog::on_dpi_changed(const wxRect &suggested_rect)
Fit();
Refresh();
}
void LoginWebViewDialog::on_idle(wxIdleEvent& WXUNUSED(evt))
{
if (!m_browser)
return;
if (m_browser->IsBusy()) {
if constexpr (!is_linux) {
wxSetCursor(wxCURSOR_ARROWWAIT);
}
} else {
if constexpr (!is_linux) {
wxSetCursor(wxNullCursor);
}
if (m_load_error_page) {
m_load_error_page = false;
m_browser->LoadURL(GUI::format_wxstr("file://%1%/web/error_no_reload.html", boost::filesystem::path(resources_dir()).generic_string()));
}
if (m_waiting_for_counters && m_atomic_counter == m_counter_to_match)
{
EndModal(wxID_OK);
}
if (m_force_quit)
{
EndModal(wxID_OK);
}
}
#ifdef DEBUG_URL_PANEL
m_button_stop->Enable(m_browser->IsBusy());
#endif
}
} // GUI
} // Slic3r

View File

@ -13,6 +13,8 @@
#include <wx/infobar.h>
#endif
#include <atomic>
class wxWebView;
class wxWebViewEvent;
@ -30,7 +32,7 @@ public:
virtual void on_show(wxShowEvent& evt) {};
virtual void on_script_message(wxWebViewEvent& evt);
void on_idle(wxIdleEvent& evt);
virtual void on_idle(wxIdleEvent& evt);
void on_url(wxCommandEvent& evt);
void on_back_button(wxCommandEvent& evt);
void on_forward_button(wxCommandEvent& evt);
@ -124,7 +126,7 @@ protected:
void on_reload_event(const std::string& message_data) override;
void run_script_bridge(const wxString &script) override { run_script(script); }
void on_connect_action_close_dialog(const std::string& message_data) override;
};
};
class LoginWebViewDialog : public WebViewDialog
{
@ -132,10 +134,17 @@ public:
LoginWebViewDialog(wxWindow *parent, std::string &ret_val, const wxString& url, wxEvtHandler* evt_handler);
void on_navigation_request(wxWebViewEvent &evt) override;
void on_dpi_changed(const wxRect &suggested_rect) override;
void on_idle(wxIdleEvent& evt) override;
private:
std::string& m_ret_val;
wxEvtHandler* p_evt_handler;
bool m_evt_sent{ false };
bool m_waiting_for_counters {false};
std::atomic<size_t> m_atomic_counter;
size_t m_counter_to_match;
wxTimer m_force_quit_timer;
bool m_force_quit{false};
};
} // GUI

View File

@ -2,11 +2,12 @@
#include <wx/webview.h>
#include <string>
#include <atomic>
namespace Slic3r::GUI {
void setup_webview_with_credentials(wxWebView* web_view, const std::string& username, const std::string& password);
void remove_webview_credentials(wxWebView* web_view);
void delete_cookies(wxWebView* web_view, const std::string& url);
void delete_cookies_with_counter(wxWebView* web_view, const std::string& url, std::atomic<size_t>& counter);
void add_request_authorization(wxWebView* web_view, const wxString& address, const std::string& token);
void remove_request_authorization(wxWebView* web_view);
void load_request(wxWebView* web_view, const std::string& address, const std::string& token);

View File

@ -109,6 +109,12 @@ void delete_cookies(wxWebView* web_view, const std::string& url)
webkit_cookie_manager_get_cookies(cookieManager, uri, nullptr, (GAsyncReadyCallback)Slic3r::GUI::get_cookie_callback, nullptr);
}
void delete_cookies_with_counter(wxWebView* web_view, const std::string& url, std::atomic<size_t>& counter)
{
delete_cookies(web_view, url);
counter++;
}
void add_request_authorization(wxWebView* web_view, const wxString& address, const std::string& token)
{
// unused on Linux

View File

@ -156,6 +156,13 @@ void delete_cookies(wxWebView* web_view, const std::string& url)
}
}];
}
void delete_cookies_with_counter(wxWebView* web_view, const std::string& url, std::atomic<size_t>& counter)
{
delete_cookies(web_view, url);
counter++;
}
void add_request_authorization(wxWebView* web_view, const wxString& address, const std::string& token)
{
// unused on MacOS

View File

@ -150,7 +150,78 @@ void delete_cookies(wxWebView* webview, const std::string& url)
).Get());
}
void delete_cookies_with_counter(wxWebView* webview, const std::string& url, std::atomic<size_t>& counter)
{
ICoreWebView2 *webView2 = static_cast<ICoreWebView2 *>(webview->GetNativeBackend());
if (!webView2) {
BOOST_LOG_TRIVIAL(error) << "delete_cookies Failed: webView2 is null.";
return;
}
/*
"cookies": [{
"domain": ".google.com",
"expires": 1756464458.304917,
"httpOnly": true,
"name": "__Secure-1PSIDCC",
"path": "/",
"priority": "High",
"sameParty": false,
"secure": true,
"session": false,
"size": 90,
"sourcePort": 443,
"sourceScheme": "Secure",
"value": "AKEyXzUvV_KBqM4aOlsudROI_VZ-ToIH41LRbYJFtFjmKq_rOmx1owoyUGvQHbwr5be380fKuQ"
},...]}
*/
wxString parameters = GUI::format_wxstr(L"{\"urls\": [\"%1%\"]}", url);
webView2->CallDevToolsProtocolMethod(L"Network.getCookies", parameters.c_str(),
Microsoft::WRL::Callback<ICoreWebView2CallDevToolsProtocolMethodCompletedHandler>(
[webView2, url, &counter](HRESULT errorCode, LPCWSTR resultJson) -> HRESULT {
if (FAILED(errorCode)) {
return S_OK;
}
// Handle successful call (resultJson contains the list of cookies)
pt::ptree ptree;
try {
std::stringstream ss(GUI::into_u8(resultJson));
pt::read_json(ss, ptree);
}
catch (const std::exception& e) {
BOOST_LOG_TRIVIAL(error) << "Failed to parse cookies json: " << e.what();
return S_OK;
}
auto& cookies = ptree.get_child("cookies");
if (cookies.size() == 0) {
counter++;
return S_OK;
}
for (auto it = cookies.begin(); it != cookies.end(); ++it) {
const auto& cookie = *it;
std::string name = cookie.second.get<std::string>("name");
std::string domain = cookie.second.get<std::string>("domain");
// Delete cookie by name and domain
wxString name_and_domain = GUI::format_wxstr(L"{\"name\": \"%1%\", \"domain\": \"%2%\"}", name, domain);
BOOST_LOG_TRIVIAL(debug) << "Deleting cookie: " << name_and_domain;
bool last = false;
if (std::next(it) == cookies.end()) {
last = true;
}
webView2->CallDevToolsProtocolMethod(L"Network.deleteCookies", name_and_domain.c_str(),
Microsoft::WRL::Callback<ICoreWebView2CallDevToolsProtocolMethodCompletedHandler>(
[last, &counter](HRESULT errorCode, LPCWSTR resultJson) -> HRESULT {
if (last) {
counter++;
}
return S_OK;
}).Get());
}
return S_OK;
}
).Get());
}
static EventRegistrationToken m_webResourceRequestedTokenForImageBlocking = {};
static wxString filter_patern;
namespace {