mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-13 07:39:05 +08:00
WebView: handling authentication challenge (passing user credentials) for OSX (working) and Linux (WIP)
This commit is contained in:
parent
b4fadc102d
commit
c953dd9eea
@ -29,6 +29,7 @@ set(SLIC3R_GUI_SOURCES
|
||||
GUI/WebViewDialog.hpp
|
||||
GUI/WebView.cpp
|
||||
GUI/WebView.hpp
|
||||
GUI/WebViewPlatformUtils.hpp
|
||||
GUI/SysInfoDialog.cpp
|
||||
GUI/SysInfoDialog.hpp
|
||||
GUI/KBShortcutsDialog.cpp
|
||||
@ -389,9 +390,19 @@ if (APPLE)
|
||||
GUI/Mouse3DHandlerMac.mm
|
||||
GUI/InstanceCheckMac.mm
|
||||
GUI/InstanceCheckMac.h
|
||||
)
|
||||
GUI/WebViewPlatformUtilsMac.mm
|
||||
|
||||
)
|
||||
FIND_LIBRARY(DISKARBITRATION_LIBRARY DiskArbitration)
|
||||
FIND_LIBRARY(COREWLAN_LIBRARY CoreWLAN)
|
||||
elseif (WIN32)
|
||||
list(APPEND SLIC3R_GUI_SOURCES
|
||||
GUI/WebViewPlatformUtilsWin32.cpp
|
||||
)
|
||||
else() # Linux
|
||||
list(APPEND SLIC3R_GUI_SOURCES
|
||||
GUI/WebViewPlatformUtilsLinux.cpp
|
||||
)
|
||||
endif ()
|
||||
|
||||
add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES})
|
||||
|
@ -855,11 +855,9 @@ void MainFrame::show_printer_webview_tab(DynamicPrintConfig* dpc)
|
||||
if (dynamic_cast<const ConfigOptionEnum<AuthorizationType>*>(dpc->option("printhost_authorization_type"))->value == AuthorizationType::atKeyPassword) {
|
||||
set_printer_webview_api_key(dpc->opt_string("printhost_apikey"));
|
||||
}
|
||||
#if 0 // The user password authentication is not working in prusa link as of now.
|
||||
else {
|
||||
mset_printer_webview_credentials(dpc->opt_string("printhost_user"), dpc->opt_string("printhost_password"));
|
||||
set_printer_webview_credentials(dpc->opt_string("printhost_user"), dpc->opt_string("printhost_password"));
|
||||
}
|
||||
#endif // 0
|
||||
// add printer or change url
|
||||
if (get_printer_webview_tab_added()) {
|
||||
set_printer_webview_tab_url(from_u8(url));
|
||||
@ -903,7 +901,9 @@ void MainFrame::set_printer_webview_tab_url(const wxString& url)
|
||||
add_printer_webview_tab(url);
|
||||
return;
|
||||
}
|
||||
m_printer_webview->clear();
|
||||
// TODO: this will reset already filled credential when bundle loaded,
|
||||
// what's the reason of clearing credentials here?
|
||||
//m_printer_webview->clear();
|
||||
m_printer_webview->set_default_url(url);
|
||||
|
||||
if (m_tabpanel->GetSelection() == m_tabpanel->FindPage(m_printer_webview)) {
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include "slic3r/GUI/UserAccount.hpp"
|
||||
#include "slic3r/GUI/format.hpp"
|
||||
#include "slic3r/GUI/WebView.hpp"
|
||||
#include "slic3r/GUI/WebViewPlatformUtils.hpp"
|
||||
|
||||
#include "slic3r/GUI/MsgDialog.hpp"
|
||||
#include "slic3r/GUI/Field.hpp"
|
||||
|
||||
@ -775,10 +777,12 @@ void PrinterWebViewPanel::send_api_key()
|
||||
wxString script = wxString::Format(R"(
|
||||
// Check if window.fetch exists before overriding
|
||||
if (window.fetch) {
|
||||
console.log('Patching fetch with API key');
|
||||
const originalFetch = window.fetch;
|
||||
window.fetch = function(input, init = {}) {
|
||||
init.headers = init.headers || {};
|
||||
init.headers['X-API-Key'] = '%s';
|
||||
init.headers['X-Api-Key'] = '%s';
|
||||
console.log('Patched fetch', input, init);
|
||||
return originalFetch(input, init);
|
||||
};
|
||||
}
|
||||
@ -797,26 +801,7 @@ void PrinterWebViewPanel::send_credentials()
|
||||
if (!m_browser || m_api_key_sent)
|
||||
return;
|
||||
m_api_key_sent = true;
|
||||
wxString usr = from_u8(m_usr);
|
||||
wxString psk = from_u8(m_psk);
|
||||
wxString script = wxString::Format(R"(
|
||||
// Check if window.fetch exists before overriding
|
||||
if (window.fetch) {
|
||||
const originalFetch = window.fetch;
|
||||
window.fetch = function(input, init = {}) {
|
||||
init.headers = init.headers || {};
|
||||
init.headers['X-API-Key'] = 'Basic ' + btoa(`%s:%s`);
|
||||
return originalFetch(input, init);
|
||||
};
|
||||
}
|
||||
)", usr, psk);
|
||||
|
||||
m_browser->RemoveAllUserScripts();
|
||||
BOOST_LOG_TRIVIAL(debug) << "RunScript " << script << "\n";
|
||||
m_browser->AddUserScript(script);
|
||||
|
||||
m_browser->Reload();
|
||||
|
||||
setup_webview_with_credentials(m_browser, m_usr, m_psk);
|
||||
}
|
||||
|
||||
void PrinterWebViewPanel::sys_color_changed()
|
||||
@ -1006,7 +991,7 @@ void WebViewDialog::on_reload_button(wxCommandEvent& WXUNUSED(evt))
|
||||
}
|
||||
|
||||
|
||||
void WebViewDialog::on_navigation_request(wxWebViewEvent &evt)
|
||||
void WebViewDialog::on_navigation_request(wxWebViewEvent &evt)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1319,7 +1304,7 @@ void PrinterPickWebViewDialog::request_compatible_printers_SLA()
|
||||
wxString script = GUI::format_wxstr("window._prusaConnect_v1.requestCompatiblePrinter(%1%)", request);
|
||||
run_script(script);
|
||||
}
|
||||
void PrinterPickWebViewDialog::on_dpi_changed(const wxRect &suggested_rect)
|
||||
void PrinterPickWebViewDialog::on_dpi_changed(const wxRect &suggested_rect)
|
||||
{
|
||||
wxWindow *parent = GetParent();
|
||||
const wxSize &size = wxSize(
|
||||
@ -1331,7 +1316,7 @@ void PrinterPickWebViewDialog::on_dpi_changed(const wxRect &suggested_rect)
|
||||
Refresh();
|
||||
}
|
||||
|
||||
LoginWebViewDialog::LoginWebViewDialog(wxWindow *parent, std::string &ret_val, const wxString& url)
|
||||
LoginWebViewDialog::LoginWebViewDialog(wxWindow *parent, std::string &ret_val, const wxString& url)
|
||||
: WebViewDialog(parent
|
||||
, url
|
||||
, _L("Log in dialog"),
|
||||
@ -1350,7 +1335,7 @@ void LoginWebViewDialog::on_navigation_request(wxWebViewEvent &evt)
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
}
|
||||
void LoginWebViewDialog::on_dpi_changed(const wxRect &suggested_rect)
|
||||
void LoginWebViewDialog::on_dpi_changed(const wxRect &suggested_rect)
|
||||
{
|
||||
const wxSize &size = wxSize(50 * wxGetApp().em_unit(), 80 * wxGetApp().em_unit());
|
||||
SetMinSize(size);
|
||||
|
8
src/slic3r/GUI/WebViewPlatformUtils.hpp
Normal file
8
src/slic3r/GUI/WebViewPlatformUtils.hpp
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <wx/webview.h>
|
||||
#include <string>
|
||||
|
||||
namespace Slic3r::GUI {
|
||||
void setup_webview_with_credentials(wxWebView* web_view, const std::string& username, const std::string& password);
|
||||
}
|
32
src/slic3r/GUI/WebViewPlatformUtilsLinux.cpp
Normal file
32
src/slic3r/GUI/WebViewPlatformUtilsLinux.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
#include "WebViewPlatformUtils.hpp"
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <webkit2/webkit2.h>
|
||||
|
||||
|
||||
namespace Slic3r::GUI {
|
||||
|
||||
struct Credentials {
|
||||
std::string username;
|
||||
std::string password;
|
||||
};
|
||||
|
||||
using WebViewCredentialsMap = std::unordered_map<void*, std::unique_ptr<Credentials>>;
|
||||
WebViewCredentialsMap g_credentials;
|
||||
|
||||
gboolean webkit_authorize_handler(WebKitWebView *web_view, WebKitAuthenticationRequest *request, gpointer user_data)
|
||||
{
|
||||
const Credentials& creds = *static_cast<const Credentials*>(user_data);
|
||||
webkit_authentication_request_authenticate(request, webkit_credential_new(creds.username.c_str(), creds.password.c_str()));
|
||||
}
|
||||
|
||||
void setup_webview_with_credentials(wxWebView* web_view, const std::string& username, const std::string& password)
|
||||
{
|
||||
std::unique_ptr<Credentials> ptr(new Credentials{username, password});
|
||||
g_credentials[web_view->GetNativeBackend()] = std::move(ptr);
|
||||
g_signal_connect(web_view, "authorize",
|
||||
G_CALLBACK(webkit_authorize_handler), g_credentials[web_view].get());
|
||||
|
||||
}
|
||||
|
||||
}
|
134
src/slic3r/GUI/WebViewPlatformUtilsMac.mm
Normal file
134
src/slic3r/GUI/WebViewPlatformUtilsMac.mm
Normal file
@ -0,0 +1,134 @@
|
||||
#include "WebViewPlatformUtils.hpp"
|
||||
|
||||
#import <WebKit/WKWebView.h>
|
||||
#import <WebKit/WKNavigationDelegate.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Foundation/NSURLSession.h>
|
||||
|
||||
@interface MyNavigationDelegate: NSObject<WKNavigationDelegate> {
|
||||
id<WKNavigationDelegate> _delegate;
|
||||
NSString* _username;
|
||||
NSString* _passwd;
|
||||
}
|
||||
- (id) initWithOriginalDelegate: (id<WKNavigationDelegate>) delegate userName: (const char*) username password: (const char*) password;
|
||||
@end
|
||||
|
||||
@implementation MyNavigationDelegate
|
||||
- (id) initWithOriginalDelegate: (id<WKNavigationDelegate>) delegate userName: (const char*) username password: (const char*) password {
|
||||
if (self = [super init]) {
|
||||
_delegate = delegate;
|
||||
_username = [[NSString alloc] initWithFormat:@"%s", username];
|
||||
_passwd = [[NSString alloc] initWithFormat:@"%s", password];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler WK_SWIFT_ASYNC(3) {
|
||||
if ([_delegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) {
|
||||
[_delegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
|
||||
} else {
|
||||
decisionHandler(WKNavigationActionPolicyAllow);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction preferences:(WKWebpagePreferences *)preferences decisionHandler:(void (^)(WKNavigationActionPolicy, WKWebpagePreferences *))decisionHandler WK_SWIFT_ASYNC(4) API_AVAILABLE(macos(10.15), ios(13.0)) {
|
||||
if ([_delegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:preferences:decisionHandler:)]) {
|
||||
[_delegate webView:webView decidePolicyForNavigationAction:navigationAction preferences:preferences decisionHandler:decisionHandler];
|
||||
} else {
|
||||
decisionHandler(WKNavigationActionPolicyAllow, preferences);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler WK_SWIFT_ASYNC(3) {
|
||||
if ([_delegate respondsToSelector:@selector(webView:decidePolicyForNavigationResponse:decisionHandler:)]) {
|
||||
[_delegate webView:webView decidePolicyForNavigationResponse: navigationResponse decisionHandler: decisionHandler];
|
||||
} else {
|
||||
decisionHandler(WKNavigationResponsePolicyAllow);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation {
|
||||
if ([_delegate respondsToSelector:@selector(webView:didStartProvisionalNavigation:)]) {
|
||||
[_delegate webView:webView didStartProvisionalNavigation:navigation];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation {
|
||||
if ([_delegate respondsToSelector:@selector(webView:didReceiveServerRedirectForProvisionalNavigation:)]) {
|
||||
[_delegate webView:webView didReceiveServerRedirectForProvisionalNavigation:navigation];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
|
||||
if ([_delegate respondsToSelector:@selector(webView:didFailProvisionalNavigation:withError:)]) {
|
||||
[_delegate webView:webView didFailProvisionalNavigation:navigation withError:error];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation {
|
||||
if ([_delegate respondsToSelector:@selector(webView:didCommitNavigation:)]) {
|
||||
[_delegate webView:webView didCommitNavigation:navigation];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation {
|
||||
if ([_delegate respondsToSelector:@selector(webView:didFinishNavigation:)]) {
|
||||
[_delegate webView:webView didFinishNavigation:navigation];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
|
||||
if ([_delegate respondsToSelector:@selector(webView:didFailNavigation:withError:)]) {
|
||||
[_delegate webView:webView didFailNavigation:navigation withError:error];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler WK_SWIFT_ASYNC_NAME(webView(_:respondTo:)) {
|
||||
//challenge.protectionSpace.realm
|
||||
completionHandler(
|
||||
NSURLSessionAuthChallengeUseCredential,
|
||||
[NSURLCredential credentialWithUser: _username password: _passwd persistence: NSURLCredentialPersistenceForSession]
|
||||
);
|
||||
}
|
||||
|
||||
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView API_AVAILABLE(macos(10.11), ios(9.0)) {
|
||||
if ([_delegate respondsToSelector:@selector(webViewWebContentProcessDidTerminate:)]) {
|
||||
[_delegate webViewWebContentProcessDidTerminate:webView];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView authenticationChallenge:(NSURLAuthenticationChallenge *)challenge shouldAllowDeprecatedTLS:(void (^)(BOOL))decisionHandler WK_SWIFT_ASYNC_NAME(webView(_:shouldAllowDeprecatedTLSFor:)) WK_SWIFT_ASYNC(3) API_AVAILABLE(macos(11.0), ios(14.0)) {
|
||||
if ([_delegate respondsToSelector:@selector(webView:authenticationChallenge:shouldAllowDeprecatedTLS:)]) {
|
||||
[_delegate webView:webView authenticationChallenge:challenge shouldAllowDeprecatedTLS:decisionHandler];
|
||||
} else {
|
||||
decisionHandler(YES);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView navigationAction:(WKNavigationAction *)navigationAction didBecomeDownload:(WKDownload *)download API_AVAILABLE(macos(11.3), ios(14.5)) {
|
||||
if ([_delegate respondsToSelector:@selector(webView:navigationAction:didBecomeDownload:)]) {
|
||||
[_delegate webView:webView navigationAction:navigationAction didBecomeDownload:download];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView navigationResponse:(WKNavigationResponse *)navigationResponse didBecomeDownload:(WKDownload *)download API_AVAILABLE(macos(11.3), ios(14.5)) {
|
||||
if ([_delegate respondsToSelector:@selector(webView:navigationResponse:didBecomeDownload:)]) {
|
||||
[_delegate webView:webView navigationResponse:navigationResponse didBecomeDownload:download];
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
namespace Slic3r::GUI {
|
||||
void setup_webview_with_credentials(wxWebView* web_view, const std::string& username, const std::string& password)
|
||||
{
|
||||
WKWebView* backend = static_cast<WKWebView*>(web_view->GetNativeBackend());
|
||||
if (![backend.navigationDelegate isKindOfClass:MyNavigationDelegate.class]) {
|
||||
backend.navigationDelegate = [[MyNavigationDelegate alloc]
|
||||
initWithOriginalDelegate:backend.navigationDelegate
|
||||
userName:username.c_str()
|
||||
password:password.c_str()];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
10
src/slic3r/GUI/WebViewPlatformUtilsWin32.cpp
Normal file
10
src/slic3r/GUI/WebViewPlatformUtilsWin32.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
#include "WebViewPlatformUtils.hpp"
|
||||
|
||||
namespace Slic3r::GUI {
|
||||
|
||||
void setup_webview_with_credentials(wxWebView* web_view, const std::string& username, const std::string& password)
|
||||
{
|
||||
// TODO: fill IE/Edge implementation here
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user