From 4858107fc0b87b18ce74cda4e91766323146aea4 Mon Sep 17 00:00:00 2001 From: Sebastian Ratz Date: Mon, 4 Nov 2024 15:21:02 +0100 Subject: [PATCH] Edge: Implement AuthenticationListener handling for BasicAuth Differences to IE engine: - Location attribute: - IE does not provide the 'location' for the callback, so this has to be guessed from lastNavigateURL which does not work consistently, e.g. after an immediate Browser.setUrl(); - Edge does provide the 'location' information consistently - When returning invalid credentials - IE does not call the authentication handler again for further attempts - Edge calls the authentication handler again and again. Keeping track of this is out-of-scope for SWT. There is no retryCount field or similar in the event. AuthenticationHandler implementations need to account for unbounded repetitive calls in case the server does not bail out. Resolves #730. --- .../win32/org/eclipse/swt/browser/Edge.java | 57 +++++++++++++++++++ .../eclipse/swt/internal/ole/win32/COM.java | 1 + ...BasicAuthenticationRequestedEventArgs.java | 48 ++++++++++++++++ ...reWebView2BasicAuthenticationResponse.java | 38 +++++++++++++ .../internal/ole/win32/ICoreWebView2_10.java | 30 ++++++++++ .../internal/ole/win32/ICoreWebView2_11.java | 2 +- 6 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2BasicAuthenticationRequestedEventArgs.java create mode 100644 bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2BasicAuthenticationResponse.java create mode 100644 bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2_10.java diff --git a/bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java b/bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java index beeff7d7d95..9d696e06a6f 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java @@ -289,6 +289,7 @@ class WebViewProvider { private CompletableFuture webViewFuture = new CompletableFuture<>(); private CompletableFuture webView_2Future = new CompletableFuture<>(); + private CompletableFuture webView_10Future = new CompletableFuture<>(); private CompletableFuture webView_11Future = new CompletableFuture<>(); private CompletableFuture webView_12Future = new CompletableFuture<>(); private CompletableFuture webView_13Future = new CompletableFuture<>(); @@ -300,6 +301,7 @@ ICoreWebView2 initializeWebView(ICoreWebView2Controller controller) { controller.get_CoreWebView2(ppv); final ICoreWebView2 webView = new ICoreWebView2(ppv[0]); initializeWebView_2(webView); + initializeWebView_10(webView); initializeWebView_11(webView); initializeWebView_12(webView); initializeWebView_13(webView); @@ -317,6 +319,16 @@ private void initializeWebView_2(ICoreWebView2 webView) { } } + private void initializeWebView_10(ICoreWebView2 webView) { + long[] ppv = new long[1]; + int hr = webView.QueryInterface(COM.IID_ICoreWebView2_10, ppv); + if (hr == COM.S_OK) { + webView_10Future.complete(new ICoreWebView2_10(ppv[0])); + } else { + webView_10Future.cancel(true); + } + } + private void initializeWebView_11(ICoreWebView2 webView) { long[] ppv = new long[1]; int hr = webView.QueryInterface(COM.IID_ICoreWebView2_11, ppv); @@ -366,6 +378,18 @@ boolean isWebView_2Available() { return !webView_2Future.isCancelled(); } + ICoreWebView2_10 getWebView_10(boolean waitForPendingWebviewTasksToFinish) { + if(waitForPendingWebviewTasksToFinish) { + waitForFutureToFinish(lastWebViewTask); + } + return webView_10Future.join(); + } + + boolean isWebView_10Available() { + waitForFutureToFinish(webView_10Future); + return !webView_10Future.isCancelled(); + } + ICoreWebView2_11 getWebView_11(boolean waitForPendingWebviewTasksToFinish) { if(waitForPendingWebviewTasksToFinish) { waitForFutureToFinish(lastWebViewTask); @@ -637,6 +661,11 @@ void setupBrowser(int hr, long pv) { webViewProvider.getWebView_2(false).add_DOMContentLoaded(handler, token); handler.Release(); } + if (webViewProvider.isWebView_10Available()) { + handler = newCallback(this::handleBasicAuthenticationRequested); + webViewProvider.getWebView_10(false).add_BasicAuthenticationRequested(handler, token); + handler.Release(); + } if (webViewProvider.isWebView_11Available()) { handler = newCallback(this::handleContextMenuRequested); webViewProvider.getWebView_11(false).add_ContextMenuRequested(handler, token); @@ -971,6 +1000,34 @@ private static String escapeForSingleQuotedJSString(String str) { .replace("\n", "\\n"); } +int handleBasicAuthenticationRequested(long pView, long pArgs) { + ICoreWebView2BasicAuthenticationRequestedEventArgs args = new ICoreWebView2BasicAuthenticationRequestedEventArgs(pArgs); + + long[] ppv = new long[1]; + + args.get_Uri(ppv); + String uri = wstrToString(ppv[0], true); + + for (AuthenticationListener authenticationListener : this.authenticationListeners) { + AuthenticationEvent event = new AuthenticationEvent (browser); + event.location = uri; + authenticationListener.authenticate (event); + if (!event.doit) { + args.put_Cancel(true); + return COM.S_OK; + } + if (event.user != null && event.password != null) { + args.get_Response(ppv); + ICoreWebView2BasicAuthenticationResponse response = new ICoreWebView2BasicAuthenticationResponse(ppv[0]); + response.put_UserName(stringToWstr(event.user)); + response.put_Password(stringToWstr(event.password)); + return COM.S_OK; + } + } + + return COM.S_OK; +} + int handleContextMenuRequested(long pView, long pArgs) { ICoreWebView2ContextMenuRequestedEventArgs args = new ICoreWebView2ContextMenuRequestedEventArgs(pArgs); diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/COM.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/COM.java index 08a7ad0e08c..d2cbc3c7a5c 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/COM.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/COM.java @@ -86,6 +86,7 @@ public class COM extends OS { public static final GUID CGID_Explorer = IIDFromString("{000214D0-0000-0000-C000-000000000046}"); //$NON-NLS-1$ public static final GUID IID_ICoreWebView2Environment2 = IIDFromString("{41F3632B-5EF4-404F-AD82-2D606C5A9A21}"); //$NON-NLS-1$ public static final GUID IID_ICoreWebView2_2 = IIDFromString("{9E8F0CF8-E670-4B5E-B2BC-73E061E3184C}"); //$NON-NLS-1$ + public static final GUID IID_ICoreWebView2_10 = IIDFromString("{B1690564-6F5A-4983-8E48-31D1143FECDB}"); //$NON-NLS-1$ public static final GUID IID_ICoreWebView2_11 = IIDFromString("{0BE78E56-C193-4051-B943-23B460C08BDB}"); //$NON-NLS-1$ public static final GUID IID_ICoreWebView2_12 = IIDFromString("{35D69927-BCFA-4566-9349-6B3E0D154CAC}"); //$NON-NLS-1$ public static final GUID IID_ICoreWebView2_13 = IIDFromString("{F75F09A8-667E-4983-88D6-C8773F315E84}"); //$NON-NLS-1$ diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2BasicAuthenticationRequestedEventArgs.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2BasicAuthenticationRequestedEventArgs.java new file mode 100644 index 00000000000..9316030b790 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2BasicAuthenticationRequestedEventArgs.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2024 SAP SE and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * SAP SE - initial implementation + *******************************************************************************/ +package org.eclipse.swt.internal.ole.win32; + +public class ICoreWebView2BasicAuthenticationRequestedEventArgs extends IUnknown { + + public ICoreWebView2BasicAuthenticationRequestedEventArgs(long address) { + super(address); + } + + public int get_Uri(long[] value) { + return COM.VtblCall(3, address, value); + } + + public int get_Challenge(long[] challenge) { + return COM.VtblCall(4, address, challenge); + } + + public int get_Response(long[] response) { + return COM.VtblCall(5, address, response); + } + + public int get_Cancel(int[] cancel) { + return COM.VtblCall(6, address, cancel); + } + + public int put_Cancel(boolean cancel) { + return COM.VtblCall(7, address, cancel ? 1 : 0); + } + + /* 8: + DECLSPEC_XFGVIRT(ICoreWebView2BasicAuthenticationRequestedEventArgs, GetDeferral) + HRESULT ( STDMETHODCALLTYPE *GetDeferral )( + ICoreWebView2BasicAuthenticationRequestedEventArgs * This, + ICoreWebView2Deferral **deferral); + */ +} \ No newline at end of file diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2BasicAuthenticationResponse.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2BasicAuthenticationResponse.java new file mode 100644 index 00000000000..64ef450dae0 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2BasicAuthenticationResponse.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2024 SAP SE and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * SAP SE - initial implementation + *******************************************************************************/ +package org.eclipse.swt.internal.ole.win32; + +public class ICoreWebView2BasicAuthenticationResponse extends IUnknown { + + public ICoreWebView2BasicAuthenticationResponse(long address) { + super(address); + } + + public int get_UserName(long[] userName) { + return COM.VtblCall(3, address, userName); + } + + public int put_UserName(char[] userName) { + return COM.VtblCall(4, address, userName); + } + + public int get_Password(long[] password) { + return COM.VtblCall(5, address, password); + } + + public int put_Password(char[] password) { + return COM.VtblCall(6, address, password); + } + +} \ No newline at end of file diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2_10.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2_10.java new file mode 100644 index 00000000000..259d3ce046c --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2_10.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2024 SAP SE and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * SAP SE - initial implementation + *******************************************************************************/ +package org.eclipse.swt.internal.ole.win32; + +public class ICoreWebView2_10 extends ICoreWebView2_2 { + +public ICoreWebView2_10(long address) { + super(address); +} + +public int add_BasicAuthenticationRequested(IUnknown eventHandler, long[] token) { + return COM.VtblCall(97, address, eventHandler.getAddress(), token); +} + +public int remove_BasicAuthenticationRequested(long[] token) { + return COM.VtblCall(98, address, token); +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2_11.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2_11.java index 97d8e76cddf..1460557fcff 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2_11.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2_11.java @@ -13,7 +13,7 @@ *******************************************************************************/ package org.eclipse.swt.internal.ole.win32; -public class ICoreWebView2_11 extends ICoreWebView2_2 { +public class ICoreWebView2_11 extends ICoreWebView2_10 { public ICoreWebView2_11(long address) { super(address);