add netrc support for webengine. resolves #2785.

This commit is contained in:
Marc Jauvin 2018-01-18 18:06:47 -05:00
parent cb2cd615e0
commit a2ca59b822
4 changed files with 46 additions and 30 deletions

View File

@ -99,6 +99,7 @@ class TabData:
Only used for QtWebKit.
pinned: Flag to pin the tab.
fullscreen: Whether the tab has a video shown fullscreen currently.
netrc_used: flag to avoid endless loop when using netrc
"""
keep_icon = attr.ib(False)
@ -107,6 +108,7 @@ class TabData:
override_target = attr.ib(None)
pinned = attr.ib(False)
fullscreen = attr.ib(False)
netrc_used = False
class AbstractAction:
@ -724,6 +726,7 @@ class AbstractTab(QWidget):
self._progress = 0
self._has_ssl_errors = False
self.data.viewing_source = False
self.data.netrc_used = False
self._set_load_status(usertypes.LoadStatus.loading)
self.load_started.emit()
@ -764,7 +767,6 @@ class AbstractTab(QWidget):
self.load_finished.emit(ok)
if not self.title():
self.title_changed.emit(self.url().toDisplayString())
self.zoom.set_current()
@pyqtSlot()

View File

@ -19,7 +19,9 @@
"""Various utilities shared between webpage/webview subclasses."""
import os
import html
import netrc
from qutebrowser.config import config
from qutebrowser.utils import usertypes, message, log, objreg, jinja, utils
@ -260,3 +262,29 @@ def get_user_stylesheet():
css += '\nhtml > ::-webkit-scrollbar { width: 0px; height: 0px; }'
return css
def netrc_authentication(url, authenticator):
"""performs authorization using netrc."""
if 'HOME' in os.environ:
# We'll get an OSError by netrc if 'HOME' isn't available in
# os.environ. We don't want to log that, so we prevent it
# altogether.
user, password = None, None
try:
net = netrc.netrc(config.val.content.netrc_file)
authenticators = net.authenticators(url.host())
if authenticators is not None:
(user, _account, password) = authenticators
except FileNotFoundError:
log.misc.debug("No .netrc file found")
except OSError:
log.misc.exception("Unable to read the netrc file")
except netrc.NetrcParseError:
log.misc.exception("Error when parsing the netrc file")
if user is not None:
authenticator.setUser(user)
authenticator.setPassword(password)
return True
return False

View File

@ -19,6 +19,7 @@
"""Wrapper over a QWebEngineView."""
import os
import math
import functools
import html as html_utils
@ -739,11 +740,15 @@ class WebEngineTab(browsertab.AbstractTab):
@pyqtSlot(QUrl, 'QAuthenticator*')
def _on_authentication_required(self, url, authenticator):
# FIXME:qtwebengine support .netrc
answer = shared.authentication_required(
url, authenticator, abort_on=[self.shutting_down,
self.load_started])
if answer is None:
netrc = None
if not self.data.netrc_used and 'HOME' in os.environ:
self.data.netrc_used = True
netrc = shared.netrc_authentication(url, authenticator)
if not netrc:
abort_on = [self.shutting_down, self.load_started]
answer = shared.authentication_required(url, authenticator,
abort_on)
if not netrc and answer is None:
try:
# pylint: disable=no-member, useless-suppression
sip.assign(authenticator, QAuthenticator())

View File

@ -19,9 +19,7 @@
"""Our own QNetworkAccessManager."""
import os
import collections
import netrc
import html
import attr
@ -270,28 +268,11 @@ class NetworkManager(QNetworkAccessManager):
@pyqtSlot('QNetworkReply*', 'QAuthenticator*')
def on_authentication_required(self, reply, authenticator):
"""Called when a website needs authentication."""
user, password = None, None
if not hasattr(reply, "netrc_used") and 'HOME' in os.environ:
# We'll get an OSError by netrc if 'HOME' isn't available in
# os.environ. We don't want to log that, so we prevent it
# altogether.
reply.netrc_used = True
try:
net = netrc.netrc(config.val.content.netrc_file)
authenticators = net.authenticators(reply.url().host())
if authenticators is not None:
(user, _account, password) = authenticators
except FileNotFoundError:
log.misc.debug("No .netrc file found")
except OSError:
log.misc.exception("Unable to read the netrc file")
except netrc.NetrcParseError:
log.misc.exception("Error when parsing the netrc file")
if user is not None:
authenticator.setUser(user)
authenticator.setPassword(password)
else:
netrc = False
if not hasattr(reply, "netrc_used"):
setattr(reply, "netrc_used", True)
netrc = shared.netrc_authentication(reply.url(), authenticator)
if not netrc:
abort_on = self._get_abort_signals(reply)
shared.authentication_required(reply.url(), authenticator,
abort_on=abort_on)