WebBrowser/Network/NetworkManager.py

branch
QtWebEngine
changeset 4817
0a4e2fb0e93c
parent 4786
b149def67c6e
child 4819
cb0672f0fc15
equal deleted inserted replaced
4816:4f5ca06fa93a 4817:0a4e2fb0e93c
7 Module implementing a network manager class. 7 Module implementing a network manager class.
8 """ 8 """
9 9
10 from __future__ import unicode_literals 10 from __future__ import unicode_literals
11 11
12 import json
13
14 from PyQt5.QtCore import pyqtSignal
12 from PyQt5.QtWidgets import QDialog 15 from PyQt5.QtWidgets import QDialog
13 from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkProxy 16 from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkProxy
14 17
15 from E5Gui import E5MessageBox 18 from E5Gui import E5MessageBox
16 19
21 except ImportError: 24 except ImportError:
22 SSL_AVAILABLE = False 25 SSL_AVAILABLE = False
23 26
24 from WebBrowser.WebBrowserWindow import WebBrowserWindow 27 from WebBrowser.WebBrowserWindow import WebBrowserWindow
25 28
29 from Utilities.AutoSaver import AutoSaver
26 import Preferences 30 import Preferences
27 31
28 32
29 class NetworkManager(QNetworkAccessManager): 33 class NetworkManager(QNetworkAccessManager):
30 """ 34 """
31 Class implementing a network manager. 35 Class implementing a network manager.
36
37 @signal changed() emitted to indicate a change
32 """ 38 """
39 changed = pyqtSignal()
40
33 def __init__(self, parent=None): 41 def __init__(self, parent=None):
34 """ 42 """
35 Constructor 43 Constructor
36 44
37 @param parent reference to the parent object (QObject) 45 @param parent reference to the parent object (QObject)
50 58
51 if SSL_AVAILABLE: 59 if SSL_AVAILABLE:
52 self.__sslErrorHandler = E5SslErrorHandler(self) 60 self.__sslErrorHandler = E5SslErrorHandler(self)
53 self.sslErrors.connect(self.__sslErrorHandler.sslErrorsReplySlot) 61 self.sslErrors.connect(self.__sslErrorHandler.sslErrorsReplySlot)
54 62
55 self.__ignoredSslErrors = {} 63 self.__temporarilyIgnoredSslErrors = {}
56 # dictionary of temporarily ignored SSL errors 64 self.__permanentlyIgnoredSslErrors = {}
57 65 # dictionaries of permanently and temporarily ignored SSL errors
66
67 self.__loaded = False
68 self.__saveTimer = AutoSaver(self, self.__save)
69
70 self.changed.connect(self.__saveTimer.changeOccurred)
58 self.proxyAuthenticationRequired.connect(proxyAuthenticationRequired) 71 self.proxyAuthenticationRequired.connect(proxyAuthenticationRequired)
59 self.authenticationRequired.connect( 72 self.authenticationRequired.connect(
60 lambda reply, auth: self.authentication(reply.url(), auth)) 73 lambda reply, auth: self.authentication(reply.url(), auth))
74
75 def __save(self):
76 """
77 Private slot to save the permanent SSL error exceptions.
78 """
79 if not self.__loaded:
80 return
81
82 from WebBrowser.WebBrowserWindow import WebBrowserWindow
83 if not WebBrowserWindow.isPrivate():
84 dbString = json.dumps(self.__permanentlyIgnoredSslErrors)
85 Preferences.setWebBrowser("SslExceptionsDB", dbString)
86
87 def __load(self):
88 """
89 Private method to load the permanent SSL error exceptions.
90 """
91 if self.__loaded:
92 return
93
94 dbString = Preferences.getWebBrowser("SslExceptionsDB")
95 if dbString:
96 try:
97 db = json.loads(dbString)
98 self.__permanentlyIgnoredSslErrors = db
99 except ValueError:
100 # ignore silently
101 pass
102
103 self.__loaded = True
104
105 def showSslErrorExceptionsDialog(self):
106 """
107 Public method to show the SSL error exceptions dialog.
108 """
109 self.__load()
110
111 from .SslErrorExceptionsDialog import SslErrorExceptionsDialog
112 dlg = SslErrorExceptionsDialog(self.__permanentlyIgnoredSslErrors)
113 if dlg.exec_() == QDialog.Accepted:
114 self.__permanentlyIgnoredSslErrors = dlg.getSslErrorExceptions()
115 self.changed.emit()
61 116
62 def certificateError(self, error, view): 117 def certificateError(self, error, view):
63 """ 118 """
64 Public method to handle SSL certificate errors. 119 Public method to handle SSL certificate errors.
65 120
68 @param view reference to a view to be used as parent for the dialog 123 @param view reference to a view to be used as parent for the dialog
69 @type QWidget 124 @type QWidget
70 @return flag indicating to ignore this error 125 @return flag indicating to ignore this error
71 @rtype bool 126 @rtype bool
72 """ 127 """
73 # TODO: permanent SSL certificate error exceptions 128 self.__load()
129
74 host = error.url().host() 130 host = error.url().host()
75 131
76 if host in self.__ignoredSslErrors and \ 132 if host in self.__temporarilyIgnoredSslErrors and \
77 self.__ignoredSslErrors[host] == error.error(): 133 error.error() in self.__temporarilyIgnoredSslErrors[host]:
134 return True
135
136 if host in self.__permanentlyIgnoredSslErrors and \
137 error.error() in self.__permanentlyIgnoredSslErrors[host]:
78 return True 138 return True
79 139
80 title = self.tr("SSL Certificate Error") 140 title = self.tr("SSL Certificate Error")
81 accept = E5MessageBox.yesNo( 141 msgBox = E5MessageBox.E5MessageBox(
82 view, 142 E5MessageBox.Warning,
83 title, 143 title,
84 self.tr("""<b>{0}</b>""" 144 self.tr("""<b>{0}</b>"""
85 """<p>The page you are trying to access has errors""" 145 """<p>The page you are trying to access has errors"""
86 """ in the SSL certificate.</p>""" 146 """ in the SSL certificate.</p>"""
87 """<ul><li>{1}</li></ul>""" 147 """<ul><li>{1}</li></ul>"""
88 """<p>Would you like to make an exception?</p>""") 148 """<p>Would you like to make an exception?</p>""")
89 .format(title, error.errorDescription()), 149 .format(title, error.errorDescription()),
90 icon=E5MessageBox.Warning) 150 modal=True, parent=view)
91 if accept: 151 permButton = msgBox.addButton(self.tr("&Permanent accept"),
92 self.__ignoredSslErrors[error.url().host()] = error.error() 152 E5MessageBox.AcceptRole)
93 return True 153 tempButton = msgBox.addButton(self.tr("&Temporary accept"),
94 154 E5MessageBox.AcceptRole)
95 return False 155 msgBox.addButton(self.tr("&Reject"), E5MessageBox.RejectRole)
156 msgBox.exec_()
157 if msgBox.clickedButton() == permButton:
158 if host not in self.__permanentlyIgnoredSslErrors:
159 self.__permanentlyIgnoredSslErrors[host] = []
160 self.__permanentlyIgnoredSslErrors[host].append(error.error())
161 self.changed.emit()
162 return True
163 elif msgBox.clickedButton() == tempButton:
164 if host not in self.__temporarilyIgnoredSslErrors:
165 self.__temporarilyIgnoredSslErrors[host] = []
166 self.__temporarilyIgnoredSslErrors[host].append(error.error())
167 return True
168 else:
169 return False
96 170
97 def authentication(self, url, auth): 171 def authentication(self, url, auth):
98 """ 172 """
99 Public slot to handle an authentication request. 173 Public slot to handle an authentication request.
100 174

eric ide

mercurial