From 506ee571b1015b2210673b9fd47e442cfbbeebf1 Mon Sep 17 00:00:00 2001 From: Ian Walker Date: Fri, 15 Sep 2017 08:36:59 +0900 Subject: [PATCH 1/8] Add handler for proxyAuthenticationRequired() --- qutebrowser/browser/webengine/webview.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/qutebrowser/browser/webengine/webview.py b/qutebrowser/browser/webengine/webview.py index fd6fc99cb..8a69b4e35 100644 --- a/qutebrowser/browser/webengine/webview.py +++ b/qutebrowser/browser/webengine/webview.py @@ -24,6 +24,7 @@ import functools from PyQt5.QtCore import pyqtSignal, pyqtSlot, QUrl, PYQT_VERSION from PyQt5.QtGui import QPalette from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage +from PyQt5.QtNetwork import QAuthenticator from qutebrowser.browser import shared from qutebrowser.browser.webengine import certificateerror, webenginesettings @@ -133,6 +134,8 @@ class WebEnginePage(QWebEnginePage): self._is_shutting_down = False self.featurePermissionRequested.connect( self._on_feature_permission_requested) + self.proxyAuthenticationRequired.connect( + self._on_proxy_authentication_required) self._theme_color = theme_color self._set_bg_color() objreg.get('config').changed.connect(self._set_bg_color) @@ -144,6 +147,11 @@ class WebEnginePage(QWebEnginePage): col = self._theme_color self.setBackgroundColor(col) + @pyqtSlot(QUrl, 'QAuthenticator*', 'QString') + def _on_proxy_authentication_required(self, url, authenticator, proxyHost): + log.webview.debug("Proxy authentication required for URL: %s"%url.toString()) + shared.authentication_required(url, authenticator, [self.shutting_down, self.loadStarted]) + @pyqtSlot(QUrl, 'QWebEnginePage::Feature') def _on_feature_permission_requested(self, url, feature): """Ask the user for approval for geolocation/media/etc..""" From 9face7567ca9fe0a8970509ddf9b3bd83a39ac56 Mon Sep 17 00:00:00 2001 From: Ian Walker Date: Sat, 16 Sep 2017 17:01:18 +0900 Subject: [PATCH 2/8] Removed QAuthenticator import --- qutebrowser/browser/webengine/webview.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/qutebrowser/browser/webengine/webview.py b/qutebrowser/browser/webengine/webview.py index 8a69b4e35..12f658be8 100644 --- a/qutebrowser/browser/webengine/webview.py +++ b/qutebrowser/browser/webengine/webview.py @@ -24,7 +24,6 @@ import functools from PyQt5.QtCore import pyqtSignal, pyqtSlot, QUrl, PYQT_VERSION from PyQt5.QtGui import QPalette from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage -from PyQt5.QtNetwork import QAuthenticator from qutebrowser.browser import shared from qutebrowser.browser.webengine import certificateerror, webenginesettings @@ -149,7 +148,6 @@ class WebEnginePage(QWebEnginePage): @pyqtSlot(QUrl, 'QAuthenticator*', 'QString') def _on_proxy_authentication_required(self, url, authenticator, proxyHost): - log.webview.debug("Proxy authentication required for URL: %s"%url.toString()) shared.authentication_required(url, authenticator, [self.shutting_down, self.loadStarted]) @pyqtSlot(QUrl, 'QWebEnginePage::Feature') From eaa1bdcddb42b35dafb6436440e71b2f43254996 Mon Sep 17 00:00:00 2001 From: Ian Walker Date: Sat, 16 Sep 2017 17:13:16 +0900 Subject: [PATCH 3/8] Show error page when user cancels proxy authentication dialog --- qutebrowser/browser/webengine/webview.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/qutebrowser/browser/webengine/webview.py b/qutebrowser/browser/webengine/webview.py index 12f658be8..ee28ab2da 100644 --- a/qutebrowser/browser/webengine/webview.py +++ b/qutebrowser/browser/webengine/webview.py @@ -148,7 +148,15 @@ class WebEnginePage(QWebEnginePage): @pyqtSlot(QUrl, 'QAuthenticator*', 'QString') def _on_proxy_authentication_required(self, url, authenticator, proxyHost): - shared.authentication_required(url, authenticator, [self.shutting_down, self.loadStarted]) + answer = shared.authentication_required(url, authenticator, [self.shutting_down, self.loadStarted]) + if answer is None: + authenticator.setUser(None) + authenticator.setPassword(None) + url_string = url.toDisplayString() + error_page = jinja.render( + 'error.html', title="Error loading page: {}".format(url_string), + url=url_string, error="Proxy authentication required.", icon='') + self.setHtml(error_page) @pyqtSlot(QUrl, 'QWebEnginePage::Feature') def _on_feature_permission_requested(self, url, feature): From 9867200c380db8e1d4044fe8bf406410eb821edb Mon Sep 17 00:00:00 2001 From: Ian Walker Date: Mon, 18 Sep 2017 15:55:44 +0900 Subject: [PATCH 4/8] Change username/password prompt for proxyAuthenticationRequired Update webview.py to more closely follow the webkit/networkmanager.py on_proxy_authentication_required(). --- qutebrowser/browser/webengine/webview.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/qutebrowser/browser/webengine/webview.py b/qutebrowser/browser/webengine/webview.py index ee28ab2da..c99271494 100644 --- a/qutebrowser/browser/webengine/webview.py +++ b/qutebrowser/browser/webengine/webview.py @@ -20,6 +20,7 @@ """The main browser widget for QtWebEngine.""" import functools +import html from PyQt5.QtCore import pyqtSignal, pyqtSlot, QUrl, PYQT_VERSION from PyQt5.QtGui import QPalette @@ -147,16 +148,18 @@ class WebEnginePage(QWebEnginePage): self.setBackgroundColor(col) @pyqtSlot(QUrl, 'QAuthenticator*', 'QString') - def _on_proxy_authentication_required(self, url, authenticator, proxyHost): - answer = shared.authentication_required(url, authenticator, [self.shutting_down, self.loadStarted]) - if answer is None: - authenticator.setUser(None) - authenticator.setPassword(None) - url_string = url.toDisplayString() - error_page = jinja.render( - 'error.html', title="Error loading page: {}".format(url_string), - url=url_string, error="Proxy authentication required.", icon='') - self.setHtml(error_page) + def _on_proxy_authentication_required(self, url, authenticator, + proxy_host): + """Called when a proxy needs authentication.""" + msg = "{} requires a username and password.".format( + html.escape(proxy_host)) + answer = message.ask( + title="Proxy authentication required", text=msg, + mode=usertypes.PromptMode.user_pwd, + abort_on=[self.loadStarted, self.shutting_down]) + if answer is not None: + authenticator.setUser(answer.user) + authenticator.setPassword(answer.password) @pyqtSlot(QUrl, 'QWebEnginePage::Feature') def _on_feature_permission_requested(self, url, feature): From a3456c41e43d351e0b1fd44a1bb1013d8ab515b7 Mon Sep 17 00:00:00 2001 From: Ian Walker Date: Wed, 20 Sep 2017 12:51:38 +0900 Subject: [PATCH 5/8] Mark url argument as unused --- qutebrowser/browser/webengine/webview.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/browser/webengine/webview.py b/qutebrowser/browser/webengine/webview.py index c99271494..665d3f80a 100644 --- a/qutebrowser/browser/webengine/webview.py +++ b/qutebrowser/browser/webengine/webview.py @@ -148,7 +148,7 @@ class WebEnginePage(QWebEnginePage): self.setBackgroundColor(col) @pyqtSlot(QUrl, 'QAuthenticator*', 'QString') - def _on_proxy_authentication_required(self, url, authenticator, + def _on_proxy_authentication_required(self, _url, authenticator, proxy_host): """Called when a proxy needs authentication.""" msg = "{} requires a username and password.".format( From e2e9bbacce1d77941ef35757d40ddbb6113cef29 Mon Sep 17 00:00:00 2001 From: Ian Walker Date: Sat, 23 Sep 2017 17:26:41 +0900 Subject: [PATCH 6/8] Move _on_proxy_authentication_required to WebEngineTab --- qutebrowser/browser/webengine/webenginetab.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py index 8d328f5e8..a4ad1f3be 100644 --- a/qutebrowser/browser/webengine/webenginetab.py +++ b/qutebrowser/browser/webengine/webenginetab.py @@ -22,6 +22,7 @@ import os import math import functools +import html import sip from PyQt5.QtCore import pyqtSlot, Qt, QEvent, QPoint, QUrl, QTimer @@ -37,7 +38,7 @@ from qutebrowser.browser.webengine import (webview, webengineelem, tabhistory, webenginesettings) from qutebrowser.misc import miscwidgets from qutebrowser.utils import (usertypes, qtutils, log, javascript, utils, - objreg, jinja, debug, version) + message, objreg, jinja, debug, version) _qute_scheme_handler = None @@ -682,6 +683,20 @@ class WebEngineTab(browsertab.AbstractTab): self.add_history_item.emit(url, requested_url, title) + @pyqtSlot(QUrl, 'QAuthenticator*', 'QString') + def _on_proxy_authentication_required(self, _url, authenticator, + proxy_host): + """Called when a proxy needs authentication.""" + msg = "{} requires a username and password.".format( + html.escape(proxy_host)) + answer = message.ask( + title="Proxy authentication required", text=msg, + mode=usertypes.PromptMode.user_pwd, + abort_on=[self.shutting_down, self.load_started]) + if answer is not None: + authenticator.setUser(answer.user) + authenticator.setPassword(answer.password) + @pyqtSlot(QUrl, 'QAuthenticator*') def _on_authentication_required(self, url, authenticator): # FIXME:qtwebengine support .netrc @@ -759,6 +774,8 @@ class WebEngineTab(browsertab.AbstractTab): page.loadFinished.connect(self._on_load_finished) page.certificate_error.connect(self._on_ssl_errors) page.authenticationRequired.connect(self._on_authentication_required) + page.proxyAuthenticationRequired.connect( + self._on_proxy_authentication_required) page.fullScreenRequested.connect(self._on_fullscreen_requested) page.contentsSizeChanged.connect(self.contents_size_changed) From 78bddaefe61c8fefb79203a0d6383bb0c8c22684 Mon Sep 17 00:00:00 2001 From: Ian Walker Date: Mon, 25 Sep 2017 14:47:54 +0900 Subject: [PATCH 7/8] Move _on_proxy_authentication_required to WebEngineTab --- qutebrowser/browser/webengine/webview.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/qutebrowser/browser/webengine/webview.py b/qutebrowser/browser/webengine/webview.py index 665d3f80a..fd6fc99cb 100644 --- a/qutebrowser/browser/webengine/webview.py +++ b/qutebrowser/browser/webengine/webview.py @@ -20,7 +20,6 @@ """The main browser widget for QtWebEngine.""" import functools -import html from PyQt5.QtCore import pyqtSignal, pyqtSlot, QUrl, PYQT_VERSION from PyQt5.QtGui import QPalette @@ -134,8 +133,6 @@ class WebEnginePage(QWebEnginePage): self._is_shutting_down = False self.featurePermissionRequested.connect( self._on_feature_permission_requested) - self.proxyAuthenticationRequired.connect( - self._on_proxy_authentication_required) self._theme_color = theme_color self._set_bg_color() objreg.get('config').changed.connect(self._set_bg_color) @@ -147,20 +144,6 @@ class WebEnginePage(QWebEnginePage): col = self._theme_color self.setBackgroundColor(col) - @pyqtSlot(QUrl, 'QAuthenticator*', 'QString') - def _on_proxy_authentication_required(self, _url, authenticator, - proxy_host): - """Called when a proxy needs authentication.""" - msg = "{} requires a username and password.".format( - html.escape(proxy_host)) - answer = message.ask( - title="Proxy authentication required", text=msg, - mode=usertypes.PromptMode.user_pwd, - abort_on=[self.loadStarted, self.shutting_down]) - if answer is not None: - authenticator.setUser(answer.user) - authenticator.setPassword(answer.password) - @pyqtSlot(QUrl, 'QWebEnginePage::Feature') def _on_feature_permission_requested(self, url, feature): """Ask the user for approval for geolocation/media/etc..""" From ad2bb454460af1185652c1a7409a2990661ea135 Mon Sep 17 00:00:00 2001 From: Ian Walker Date: Mon, 25 Sep 2017 14:48:54 +0900 Subject: [PATCH 8/8] Allow user to cancel proxy authentication request --- qutebrowser/browser/webengine/webenginetab.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py index a4ad1f3be..43e682c07 100644 --- a/qutebrowser/browser/webengine/webenginetab.py +++ b/qutebrowser/browser/webengine/webenginetab.py @@ -22,7 +22,7 @@ import os import math import functools -import html +import html as html_utils import sip from PyQt5.QtCore import pyqtSlot, Qt, QEvent, QPoint, QUrl, QTimer @@ -684,11 +684,11 @@ class WebEngineTab(browsertab.AbstractTab): self.add_history_item.emit(url, requested_url, title) @pyqtSlot(QUrl, 'QAuthenticator*', 'QString') - def _on_proxy_authentication_required(self, _url, authenticator, + def _on_proxy_authentication_required(self, url, authenticator, proxy_host): """Called when a proxy needs authentication.""" msg = "{} requires a username and password.".format( - html.escape(proxy_host)) + html_utils.escape(proxy_host)) answer = message.ask( title="Proxy authentication required", text=msg, mode=usertypes.PromptMode.user_pwd, @@ -696,6 +696,18 @@ class WebEngineTab(browsertab.AbstractTab): if answer is not None: authenticator.setUser(answer.user) authenticator.setPassword(answer.password) + else: + try: + # pylint: disable=no-member, useless-suppression + sip.assign(authenticator, QAuthenticator()) + except AttributeError: + url_string = url.toDisplayString() + error_page = jinja.render( + 'error.html', + title="Error loading page: {}".format(url_string), + url=url_string, error="Proxy authentication required", + icon='') + self.set_html(error_page) @pyqtSlot(QUrl, 'QAuthenticator*') def _on_authentication_required(self, url, authenticator):