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;
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)
@ -776,16 +780,18 @@ void PrinterWebViewPanel::send_api_key()
wxString key = from_u8(m_api_key);
wxString script = wxString::Format(R"(
// Check if window.fetch exists before overriding
if (window.fetch) {
if (window.originalFetch === undefined) {
console.log('Patching fetch with API key');
const originalFetch = window.fetch;
window.originalFetch = window.fetch;
window.fetch = function(input, init = {}) {
init.headers = init.headers || {};
init.headers['X-Api-Key'] = '%s';
init.headers['X-Api-Key'] = sessionStorage.getItem('apiKey');
console.log('Patched fetch', input, init);
return originalFetch(input, init);
return window.originalFetch(input, init);
};
}
sessionStorage.setItem('authType', 'ApiKey');
sessionStorage.setItem('apiKey', '%s');
)",
key);
@ -793,13 +799,16 @@ void PrinterWebViewPanel::send_api_key()
BOOST_LOG_TRIVIAL(debug) << "RunScript " << script << "\n";
m_browser->AddUserScript(script);
m_browser->Reload();
remove_webview_credentials(m_browser);
}
void PrinterWebViewPanel::send_credentials()
{
if (!m_browser || m_api_key_sent)
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;
setup_webview_with_credentials(m_browser, m_usr, m_psk);
}

View File

@ -5,4 +5,5 @@
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);
}

View File

@ -37,7 +37,12 @@ void setup_webview_with_credentials(wxWebView* web_view, const std::string& user
&free_credentials,
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* _passwd;
}
- (id) initWithOriginalDelegate: (id<WKNavigationDelegate>) delegate userName: (const char*) username password: (const char*) password;
- (id<WKNavigationDelegate>) wrapped_delegate;
@end
@implementation MyNavigationDelegate
@ -23,6 +27,10 @@
return self;
}
- (id<WKNavigationDelegate>) wrapped_delegate {
return _delegate;
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
if ([_delegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction: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()];
}
}
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 <atlbase.h>
#include <boost/log/trivial.hpp>
#include <unordered_map>
#include "wx/msw/private/comptr.h"
@ -14,11 +15,11 @@
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)
{
ICoreWebView2 *webView2 = static_cast<ICoreWebView2 *>(webview->GetNativeBackend());
wxCOMPtr<ICoreWebView2_10> wv2_10;
HRESULT hr = webView2->QueryInterface(IID_PPV_ARGS(&wv2_10));
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";
} 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