16 |
16 |
17 class SslErrorExceptionsDialog(QDialog, Ui_SslErrorExceptionsDialog): |
17 class SslErrorExceptionsDialog(QDialog, Ui_SslErrorExceptionsDialog): |
18 """ |
18 """ |
19 Class implementing a dialog to edit the SSL error exceptions. |
19 Class implementing a dialog to edit the SSL error exceptions. |
20 """ |
20 """ |
|
21 |
21 def __init__(self, errorsDict, parent=None): |
22 def __init__(self, errorsDict, parent=None): |
22 """ |
23 """ |
23 Constructor |
24 Constructor |
24 |
25 |
25 @param errorsDict error exceptions |
26 @param errorsDict error exceptions |
26 @type dict of list of int |
27 @type dict of list of int |
27 @param parent reference to the parent widget |
28 @param parent reference to the parent widget |
28 @type QWidget |
29 @type QWidget |
29 """ |
30 """ |
30 super().__init__(parent) |
31 super().__init__(parent) |
31 self.setupUi(self) |
32 self.setupUi(self) |
32 |
33 |
33 self.__errorDescriptions = { |
34 self.__errorDescriptions = { |
34 QWebEngineCertificateError.Type.SslPinnedKeyNotInCertificateChain: |
35 QWebEngineCertificateError.Type.SslPinnedKeyNotInCertificateChain: self.tr( |
35 self.tr("The certificate did not match the built-in public" |
36 "The certificate did not match the built-in public" |
36 " keys pinned for the host name."), |
37 " keys pinned for the host name." |
37 QWebEngineCertificateError.Type.CertificateCommonNameInvalid: |
38 ), |
38 self.tr("The certificate's common name did not match the" |
39 QWebEngineCertificateError.Type.CertificateCommonNameInvalid: self.tr( |
39 " host name."), |
40 "The certificate's common name did not match the" " host name." |
40 QWebEngineCertificateError.Type.CertificateDateInvalid: |
41 ), |
41 self.tr("The certificate is not valid at the current date" |
42 QWebEngineCertificateError.Type.CertificateDateInvalid: self.tr( |
42 " and time."), |
43 "The certificate is not valid at the current date" " and time." |
43 QWebEngineCertificateError.Type.CertificateAuthorityInvalid: |
44 ), |
44 self.tr("The certificate is not signed by a trusted" |
45 QWebEngineCertificateError.Type.CertificateAuthorityInvalid: self.tr( |
45 " authority."), |
46 "The certificate is not signed by a trusted" " authority." |
46 QWebEngineCertificateError.Type.CertificateContainsErrors: |
47 ), |
47 self.tr("The certificate contains errors."), |
48 QWebEngineCertificateError.Type.CertificateContainsErrors: self.tr( |
48 QWebEngineCertificateError.Type.CertificateNoRevocationMechanism: |
49 "The certificate contains errors." |
49 self.tr("The certificate has no mechanism for determining if" |
50 ), |
50 " it has been revoked."), |
51 QWebEngineCertificateError.Type.CertificateNoRevocationMechanism: self.tr( |
51 QWebEngineCertificateError.Type |
52 "The certificate has no mechanism for determining if" |
52 .CertificateUnableToCheckRevocation: |
53 " it has been revoked." |
53 self.tr("Revocation information for the certificate is" |
54 ), |
54 " not available."), |
55 QWebEngineCertificateError.Type.CertificateUnableToCheckRevocation: self.tr( |
55 QWebEngineCertificateError.Type.CertificateRevoked: |
56 "Revocation information for the certificate is" " not available." |
56 self.tr("The certificate has been revoked."), |
57 ), |
57 QWebEngineCertificateError.Type.CertificateInvalid: |
58 QWebEngineCertificateError.Type.CertificateRevoked: self.tr( |
58 self.tr("The certificate is invalid."), |
59 "The certificate has been revoked." |
59 QWebEngineCertificateError.Type.CertificateWeakSignatureAlgorithm: |
60 ), |
60 self.tr("The certificate is signed using a weak signature" |
61 QWebEngineCertificateError.Type.CertificateInvalid: self.tr( |
61 " algorithm."), |
62 "The certificate is invalid." |
62 QWebEngineCertificateError.Type.CertificateNonUniqueName: |
63 ), |
63 self.tr("The host name specified in the certificate is" |
64 QWebEngineCertificateError.Type.CertificateWeakSignatureAlgorithm: self.tr( |
64 " not unique."), |
65 "The certificate is signed using a weak signature" " algorithm." |
65 QWebEngineCertificateError.Type.CertificateWeakKey: |
66 ), |
66 self.tr("The certificate contains a weak key."), |
67 QWebEngineCertificateError.Type.CertificateNonUniqueName: self.tr( |
67 QWebEngineCertificateError.Type |
68 "The host name specified in the certificate is" " not unique." |
68 .CertificateNameConstraintViolation: |
69 ), |
69 self.tr("The certificate claimed DNS names that are in" |
70 QWebEngineCertificateError.Type.CertificateWeakKey: self.tr( |
70 " violation of name constraints."), |
71 "The certificate contains a weak key." |
71 QWebEngineCertificateError.Type.CertificateValidityTooLong: |
72 ), |
72 self.tr("The certificate has a validity period that is" |
73 QWebEngineCertificateError.Type.CertificateNameConstraintViolation: self.tr( |
73 " too long."), |
74 "The certificate claimed DNS names that are in" |
74 QWebEngineCertificateError.Type.CertificateTransparencyRequired: |
75 " violation of name constraints." |
75 self.tr("Certificate Transparency was required for this" |
76 ), |
76 " connection, but the server did not provide" |
77 QWebEngineCertificateError.Type.CertificateValidityTooLong: self.tr( |
77 " information that complied with the policy."), |
78 "The certificate has a validity period that is" " too long." |
78 QWebEngineCertificateError.Type |
79 ), |
79 .CertificateKnownInterceptionBlocked: |
80 QWebEngineCertificateError.Type.CertificateTransparencyRequired: self.tr( |
80 self.tr("The certificate is known to be used for interception" |
81 "Certificate Transparency was required for this" |
81 " by an entity other than the device owner."), |
82 " connection, but the server did not provide" |
82 QWebEngineCertificateError.Type.SslObsoleteVersion: |
83 " information that complied with the policy." |
83 self.tr("The connection uses an obsolete version of SSL/TLS."), |
84 ), |
84 QWebEngineCertificateError.Type.CertificateSymantecLegacy: |
85 QWebEngineCertificateError.Type.CertificateKnownInterceptionBlocked: ( |
85 self.tr("The certificate is a legacy Symantec one that's no" |
86 self.tr( |
86 " longer valid."), |
87 "The certificate is known to be used for interception" |
|
88 " by an entity other than the device owner." |
|
89 ) |
|
90 ), |
|
91 QWebEngineCertificateError.Type.SslObsoleteVersion: self.tr( |
|
92 "The connection uses an obsolete version of SSL/TLS." |
|
93 ), |
|
94 QWebEngineCertificateError.Type.CertificateSymantecLegacy: self.tr( |
|
95 "The certificate is a legacy Symantec one that's no" " longer valid." |
|
96 ), |
87 } |
97 } |
88 |
98 |
89 for host, errors in errorsDict.items(): |
99 for host, errors in errorsDict.items(): |
90 itm = QTreeWidgetItem(self.errorsTree, [host]) |
100 itm = QTreeWidgetItem(self.errorsTree, [host]) |
91 self.errorsTree.setFirstItemColumnSpanned(itm, True) |
101 self.errorsTree.setFirstItemColumnSpanned(itm, True) |
92 for error in errors: |
102 for error in errors: |
93 try: |
103 try: |
94 errorDesc = self.__errorDescriptions[error] |
104 errorDesc = self.__errorDescriptions[error] |
95 except KeyError: |
105 except KeyError: |
96 errorDesc = self.tr("No error description available.") |
106 errorDesc = self.tr("No error description available.") |
97 QTreeWidgetItem(itm, [str(error), errorDesc]) |
107 QTreeWidgetItem(itm, [str(error), errorDesc]) |
98 |
108 |
99 self.errorsTree.expandAll() |
109 self.errorsTree.expandAll() |
100 for i in range(self.errorsTree.columnCount()): |
110 for i in range(self.errorsTree.columnCount()): |
101 self.errorsTree.resizeColumnToContents(i) |
111 self.errorsTree.resizeColumnToContents(i) |
102 self.errorsTree.sortItems(0, Qt.SortOrder.AscendingOrder) |
112 self.errorsTree.sortItems(0, Qt.SortOrder.AscendingOrder) |
103 |
113 |
104 self.__setRemoveButtons() |
114 self.__setRemoveButtons() |
105 |
115 |
106 def __setRemoveButtons(self): |
116 def __setRemoveButtons(self): |
107 """ |
117 """ |
108 Private method to set the state of the 'remove' buttons. |
118 Private method to set the state of the 'remove' buttons. |
109 """ |
119 """ |
110 if self.errorsTree.topLevelItemCount() == 0: |
120 if self.errorsTree.topLevelItemCount() == 0: |
111 self.removeButton.setEnabled(False) |
121 self.removeButton.setEnabled(False) |
112 self.removeAllButton.setEnabled(False) |
122 self.removeAllButton.setEnabled(False) |
113 else: |
123 else: |
114 self.removeAllButton.setEnabled(True) |
124 self.removeAllButton.setEnabled(True) |
115 self.removeButton.setEnabled( |
125 self.removeButton.setEnabled(len(self.errorsTree.selectedItems()) > 0) |
116 len(self.errorsTree.selectedItems()) > 0) |
126 |
117 |
|
118 @pyqtSlot(QPoint) |
127 @pyqtSlot(QPoint) |
119 def on_errorsTree_customContextMenuRequested(self, pos): |
128 def on_errorsTree_customContextMenuRequested(self, pos): |
120 """ |
129 """ |
121 Private slot to show the context menu. |
130 Private slot to show the context menu. |
122 |
131 |
123 @param pos cursor position |
132 @param pos cursor position |
124 @type QPoint |
133 @type QPoint |
125 """ |
134 """ |
126 menu = QMenu() |
135 menu = QMenu() |
127 menu.addAction( |
136 menu.addAction( |
128 self.tr("Remove Selected"), |
137 self.tr("Remove Selected"), self.on_removeButton_clicked |
129 self.on_removeButton_clicked).setEnabled( |
138 ).setEnabled( |
130 self.errorsTree.topLevelItemCount() > 0 and |
139 self.errorsTree.topLevelItemCount() > 0 |
131 len(self.errorsTree.selectedItems()) > 0) |
140 and len(self.errorsTree.selectedItems()) > 0 |
|
141 ) |
132 menu.addAction( |
142 menu.addAction( |
133 self.tr("Remove All"), |
143 self.tr("Remove All"), self.on_removeAllButton_clicked |
134 self.on_removeAllButton_clicked).setEnabled( |
144 ).setEnabled(self.errorsTree.topLevelItemCount() > 0) |
135 self.errorsTree.topLevelItemCount() > 0) |
145 |
136 |
|
137 menu.exec(self.errorsTree.mapToGlobal(pos)) |
146 menu.exec(self.errorsTree.mapToGlobal(pos)) |
138 |
147 |
139 @pyqtSlot() |
148 @pyqtSlot() |
140 def on_errorsTree_itemSelectionChanged(self): |
149 def on_errorsTree_itemSelectionChanged(self): |
141 """ |
150 """ |
142 Private slot handling the selection of entries. |
151 Private slot handling the selection of entries. |
143 """ |
152 """ |
144 self.__setRemoveButtons() |
153 self.__setRemoveButtons() |
145 |
154 |
146 @pyqtSlot() |
155 @pyqtSlot() |
147 def on_removeButton_clicked(self): |
156 def on_removeButton_clicked(self): |
148 """ |
157 """ |
149 Private slot to remove the selected items. |
158 Private slot to remove the selected items. |
150 """ |
159 """ |
154 pitm.removeChild(itm) |
163 pitm.removeChild(itm) |
155 else: |
164 else: |
156 index = self.errorsTree.indexOfTopLevelItem(itm) |
165 index = self.errorsTree.indexOfTopLevelItem(itm) |
157 self.errorsTree.takeTopLevelItem(index) |
166 self.errorsTree.takeTopLevelItem(index) |
158 del itm |
167 del itm |
159 |
168 |
160 # remove all hosts without an exception |
169 # remove all hosts without an exception |
161 for index in range(self.errorsTree.topLevelItemCount() - 1, -1, -1): |
170 for index in range(self.errorsTree.topLevelItemCount() - 1, -1, -1): |
162 itm = self.errorsTree.topLevelItem(index) |
171 itm = self.errorsTree.topLevelItem(index) |
163 if itm.childCount() == 0: |
172 if itm.childCount() == 0: |
164 self.errorsTree.takeTopLevelItem(index) |
173 self.errorsTree.takeTopLevelItem(index) |
165 del itm |
174 del itm |
166 |
175 |
167 @pyqtSlot() |
176 @pyqtSlot() |
168 def on_removeAllButton_clicked(self): |
177 def on_removeAllButton_clicked(self): |
169 """ |
178 """ |
170 Private slot to remove all entries. |
179 Private slot to remove all entries. |
171 """ |
180 """ |
172 self.errorsTree.clear() |
181 self.errorsTree.clear() |
173 |
182 |
174 def getSslErrorExceptions(self): |
183 def getSslErrorExceptions(self): |
175 """ |
184 """ |
176 Public method to retrieve the list of SSL error exceptions. |
185 Public method to retrieve the list of SSL error exceptions. |
177 |
186 |
178 @return error exceptions |
187 @return error exceptions |
179 @rtype dict of list of int |
188 @rtype dict of list of int |
180 """ |
189 """ |
181 errors = {} |
190 errors = {} |
182 |
191 |
183 for index in range(self.errorsTree.topLevelItemCount()): |
192 for index in range(self.errorsTree.topLevelItemCount()): |
184 itm = self.errorsTree.topLevelItem(index) |
193 itm = self.errorsTree.topLevelItem(index) |
185 host = itm.text(0) |
194 host = itm.text(0) |
186 errors[host] = [] |
195 errors[host] = [] |
187 for cindex in range(itm.childCount()): |
196 for cindex in range(itm.childCount()): |
188 citm = itm.child(cindex) |
197 citm = itm.child(cindex) |
189 errors[host].append(int(citm.text(0))) |
198 errors[host].append(int(citm.text(0))) |
190 |
199 |
191 return errors |
200 return errors |