PrinterWebViewPanel: fixed passing API Key when uploading gcode, fixed passing API key via session storage, improved cleaning up credential infra on printer change (removing API key from storage or deregistering delegate/event for HTTP digest auth)

This commit is contained in:
Jan Bařtipán 2024-08-01 15:16:48 +02:00 committed by Lukas Matena
parent f46916681b
commit 7fb3638d46
5 changed files with 65 additions and 8 deletions

View File

@ -755,6 +755,10 @@ PrinterWebViewPanel::PrinterWebViewPanel(wxWindow* parent, const wxString& defau
return; return;
m_browser->Bind(wxEVT_WEBVIEW_LOADED, &PrinterWebViewPanel::on_loaded, this); m_browser->Bind(wxEVT_WEBVIEW_LOADED, &PrinterWebViewPanel::on_loaded, this);
#ifndef NDEBUG
m_browser->EnableAccessToDevTools();
m_browser->EnableContextMenu();
#endif
} }
void PrinterWebViewPanel::on_loaded(wxWebViewEvent& evt) void PrinterWebViewPanel::on_loaded(wxWebViewEvent& evt)
@ -776,16 +780,18 @@ void PrinterWebViewPanel::send_api_key()
wxString key = from_u8(m_api_key); wxString key = from_u8(m_api_key);
wxString script = wxString::Format(R"( wxString script = wxString::Format(R"(
// Check if window.fetch exists before overriding // Check if window.fetch exists before overriding
if (window.fetch) { if (window.originalFetch === undefined) {
console.log('Patching fetch with API key'); console.log('Patching fetch with API key');
const originalFetch = window.fetch; window.originalFetch = window.fetch;
window.fetch = function(input, init = {}) { window.fetch = function(input, init = {}) {
init.headers = init.headers || {}; init.headers = init.headers || {};
init.headers['X-Api-Key'] = '%s'; init.headers['X-Api-Key'] = sessionStorage.getItem('apiKey');
console.log('Patched fetch', input, init); console.log('Patched fetch', input, init);
return originalFetch(input, init); return window.originalFetch(input, init);
}; };
} }
sessionStorage.setItem('authType', 'ApiKey');
sessionStorage.setItem('apiKey', '%s');
)", )",
key); key);
@ -793,13 +799,16 @@ void PrinterWebViewPanel::send_api_key()
BOOST_LOG_TRIVIAL(debug) << "RunScript " << script << "\n"; BOOST_LOG_TRIVIAL(debug) << "RunScript " << script << "\n";
m_browser->AddUserScript(script); m_browser->AddUserScript(script);
m_browser->Reload(); m_browser->Reload();
remove_webview_credentials(m_browser);
} }
void PrinterWebViewPanel::send_credentials() void PrinterWebViewPanel::send_credentials()
{ {
if (!m_browser || m_api_key_sent) if (!m_browser || m_api_key_sent)
return; return;
m_browser->RemoveAllUserScripts();
m_browser->AddUserScript("sessionStorage.removeItem('authType'); sessionStorage.removeItem('apiKey'); console.log('Session Storage cleared');");
m_browser->Reload();
m_api_key_sent = true; m_api_key_sent = true;
setup_webview_with_credentials(m_browser, m_usr, m_psk); setup_webview_with_credentials(m_browser, m_usr, m_psk);
} }

View File

@ -5,4 +5,5 @@
namespace Slic3r::GUI { namespace Slic3r::GUI {
void setup_webview_with_credentials(wxWebView* web_view, const std::string& username, const std::string& password); void setup_webview_with_credentials(wxWebView* web_view, const std::string& username, const std::string& password);
void remove_webview_credentials(wxWebView* web_view);
} }

View File

@ -37,7 +37,12 @@ void setup_webview_with_credentials(wxWebView* web_view, const std::string& user
&free_credentials, &free_credentials,
static_cast<GConnectFlags>(0) static_cast<GConnectFlags>(0)
); );
}
void remove_webview_credentials(wxWebView* web_view)
{
WebKitWebView* native_backend = static_cast<WebKitWebView *>(web_view->GetNativeBackend());
g_object_disconnect(native_backend, "authenticate");
} }
} }

View File

@ -10,7 +10,11 @@
NSString* _username; NSString* _username;
NSString* _passwd; NSString* _passwd;
} }
- (id) initWithOriginalDelegate: (id<WKNavigationDelegate>) delegate userName: (const char*) username password: (const char*) password; - (id) initWithOriginalDelegate: (id<WKNavigationDelegate>) delegate userName: (const char*) username password: (const char*) password;
- (id<WKNavigationDelegate>) wrapped_delegate;
@end @end
@implementation MyNavigationDelegate @implementation MyNavigationDelegate
@ -23,6 +27,10 @@
return self; return self;
} }
- (id<WKNavigationDelegate>) wrapped_delegate {
return _delegate;
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
if ([_delegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) { if ([_delegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) {
[_delegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler]; [_delegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
@ -118,5 +126,15 @@ void setup_webview_with_credentials(wxWebView* web_view, const std::string& user
password:password.c_str()]; password:password.c_str()];
} }
} }
void remove_webview_credentials(wxWebView* web_view)
{
WKWebView* backend = static_cast<WKWebView*>(web_view->GetNativeBackend());
if ([backend.navigationDelegate isKindOfClass:MyNavigationDelegate.class]) {
MyNavigationDelegate* my_delegate = backend.navigationDelegate;
backend.navigationDelegate = my_delegate.wrapped_delegate;
}
}
} }

View File

@ -5,6 +5,7 @@
#include <wrl.h> #include <wrl.h>
#include <atlbase.h> #include <atlbase.h>
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
#include <unordered_map>
#include "wx/msw/private/comptr.h" #include "wx/msw/private/comptr.h"
@ -14,11 +15,11 @@
namespace Slic3r::GUI { namespace Slic3r::GUI {
std::unordered_map<ICoreWebView2*,EventRegistrationToken> g_basic_auth_handler_tokens;
void setup_webview_with_credentials(wxWebView* webview, const std::string& username, const std::string& password) void setup_webview_with_credentials(wxWebView* webview, const std::string& username, const std::string& password)
{ {
ICoreWebView2 *webView2 = static_cast<ICoreWebView2 *>(webview->GetNativeBackend()); ICoreWebView2 *webView2 = static_cast<ICoreWebView2 *>(webview->GetNativeBackend());
wxCOMPtr<ICoreWebView2_10> wv2_10; wxCOMPtr<ICoreWebView2_10> wv2_10;
HRESULT hr = webView2->QueryInterface(IID_PPV_ARGS(&wv2_10)); HRESULT hr = webView2->QueryInterface(IID_PPV_ARGS(&wv2_10));
if (FAILED(hr)) { if (FAILED(hr)) {
@ -48,8 +49,31 @@ void setup_webview_with_credentials(wxWebView* webview, const std::string& usern
))) { ))) {
BOOST_LOG_TRIVIAL(error) << "WebView: Cannot register authentication request handler"; BOOST_LOG_TRIVIAL(error) << "WebView: Cannot register authentication request handler";
} else {
g_basic_auth_handler_tokens[webView2] = basicAuthenticationRequestedToken;
} }
} }
#endif
void remove_webview_credentials(wxWebView* webview)
{
ICoreWebView2 *webView2 = static_cast<ICoreWebView2 *>(webview->GetNativeBackend());
wxCOMPtr<ICoreWebView2_10> wv2_10;
HRESULT hr = webView2->QueryInterface(IID_PPV_ARGS(&wv2_10));
if (FAILED(hr)) {
return;
}
auto it = g_basic_auth_handler_tokens.find(webView2);
if (it != g_basic_auth_handler_tokens.end()) {
if (FAILED(wv2_10->remove_BasicAuthenticationRequested(it->second))) {
BOOST_LOG_TRIVIAL(error) << "WebView: Unregistering authentication request handler failed";
}
} else {
BOOST_LOG_TRIVIAL(error) << "WebView: Cannot unregister authentication request handler";
}
} }
} // namespace Slic3r::GUI
#endif // WIN32