mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 07:05:57 +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/WebViewDialog.hpp
|
||||||
GUI/WebView.cpp
|
GUI/WebView.cpp
|
||||||
GUI/WebView.hpp
|
GUI/WebView.hpp
|
||||||
|
GUI/WebViewPlatformUtils.hpp
|
||||||
GUI/SysInfoDialog.cpp
|
GUI/SysInfoDialog.cpp
|
||||||
GUI/SysInfoDialog.hpp
|
GUI/SysInfoDialog.hpp
|
||||||
GUI/KBShortcutsDialog.cpp
|
GUI/KBShortcutsDialog.cpp
|
||||||
@ -389,9 +390,19 @@ if (APPLE)
|
|||||||
GUI/Mouse3DHandlerMac.mm
|
GUI/Mouse3DHandlerMac.mm
|
||||||
GUI/InstanceCheckMac.mm
|
GUI/InstanceCheckMac.mm
|
||||||
GUI/InstanceCheckMac.h
|
GUI/InstanceCheckMac.h
|
||||||
)
|
GUI/WebViewPlatformUtilsMac.mm
|
||||||
|
|
||||||
|
)
|
||||||
FIND_LIBRARY(DISKARBITRATION_LIBRARY DiskArbitration)
|
FIND_LIBRARY(DISKARBITRATION_LIBRARY DiskArbitration)
|
||||||
FIND_LIBRARY(COREWLAN_LIBRARY CoreWLAN)
|
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 ()
|
endif ()
|
||||||
|
|
||||||
add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES})
|
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) {
|
if (dynamic_cast<const ConfigOptionEnum<AuthorizationType>*>(dpc->option("printhost_authorization_type"))->value == AuthorizationType::atKeyPassword) {
|
||||||
set_printer_webview_api_key(dpc->opt_string("printhost_apikey"));
|
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 {
|
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
|
// add printer or change url
|
||||||
if (get_printer_webview_tab_added()) {
|
if (get_printer_webview_tab_added()) {
|
||||||
set_printer_webview_tab_url(from_u8(url));
|
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);
|
add_printer_webview_tab(url);
|
||||||
return;
|
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);
|
m_printer_webview->set_default_url(url);
|
||||||
|
|
||||||
if (m_tabpanel->GetSelection() == m_tabpanel->FindPage(m_printer_webview)) {
|
if (m_tabpanel->GetSelection() == m_tabpanel->FindPage(m_printer_webview)) {
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#include "slic3r/GUI/UserAccount.hpp"
|
#include "slic3r/GUI/UserAccount.hpp"
|
||||||
#include "slic3r/GUI/format.hpp"
|
#include "slic3r/GUI/format.hpp"
|
||||||
#include "slic3r/GUI/WebView.hpp"
|
#include "slic3r/GUI/WebView.hpp"
|
||||||
|
#include "slic3r/GUI/WebViewPlatformUtils.hpp"
|
||||||
|
|
||||||
#include "slic3r/GUI/MsgDialog.hpp"
|
#include "slic3r/GUI/MsgDialog.hpp"
|
||||||
#include "slic3r/GUI/Field.hpp"
|
#include "slic3r/GUI/Field.hpp"
|
||||||
|
|
||||||
@ -775,10 +777,12 @@ void PrinterWebViewPanel::send_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.fetch) {
|
||||||
|
console.log('Patching fetch with API key');
|
||||||
const originalFetch = window.fetch;
|
const 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'] = '%s';
|
||||||
|
console.log('Patched fetch', input, init);
|
||||||
return originalFetch(input, init);
|
return originalFetch(input, init);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -797,26 +801,7 @@ void PrinterWebViewPanel::send_credentials()
|
|||||||
if (!m_browser || m_api_key_sent)
|
if (!m_browser || m_api_key_sent)
|
||||||
return;
|
return;
|
||||||
m_api_key_sent = true;
|
m_api_key_sent = true;
|
||||||
wxString usr = from_u8(m_usr);
|
setup_webview_with_credentials(m_browser, m_usr, m_psk);
|
||||||
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();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrinterWebViewPanel::sys_color_changed()
|
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);
|
wxString script = GUI::format_wxstr("window._prusaConnect_v1.requestCompatiblePrinter(%1%)", request);
|
||||||
run_script(script);
|
run_script(script);
|
||||||
}
|
}
|
||||||
void PrinterPickWebViewDialog::on_dpi_changed(const wxRect &suggested_rect)
|
void PrinterPickWebViewDialog::on_dpi_changed(const wxRect &suggested_rect)
|
||||||
{
|
{
|
||||||
wxWindow *parent = GetParent();
|
wxWindow *parent = GetParent();
|
||||||
const wxSize &size = wxSize(
|
const wxSize &size = wxSize(
|
||||||
@ -1331,7 +1316,7 @@ void PrinterPickWebViewDialog::on_dpi_changed(const wxRect &suggested_rect)
|
|||||||
Refresh();
|
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
|
: WebViewDialog(parent
|
||||||
, url
|
, url
|
||||||
, _L("Log in dialog"),
|
, _L("Log in dialog"),
|
||||||
@ -1350,7 +1335,7 @@ void LoginWebViewDialog::on_navigation_request(wxWebViewEvent &evt)
|
|||||||
EndModal(wxID_OK);
|
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());
|
const wxSize &size = wxSize(50 * wxGetApp().em_unit(), 80 * wxGetApp().em_unit());
|
||||||
SetMinSize(size);
|
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