diff -r 9ee960bceb51 -r 2e046f1818ed Plugins/VcsPlugins/vcsMercurial/HgUserConfigDialog.py --- a/Plugins/VcsPlugins/vcsMercurial/HgUserConfigDialog.py Mon Mar 20 18:50:25 2017 +0100 +++ b/Plugins/VcsPlugins/vcsMercurial/HgUserConfigDialog.py Mon Mar 20 19:31:22 2017 +0100 @@ -47,6 +47,12 @@ self.__version = version + self.__minimumProtocols = { + "tls1.0": self.tr("TLS 1.0"), + "tls1.1": self.tr("TLS 1.1"), + "tls1.2": self.tr("TLS 1.2"), + } + self.lfUserCachePicker.setMode(E5PathPickerModes.DirectoryMode) if Globals.isLinuxPlatform(): self.lfUserCachePicker.setDefaultDirectory(os.path.expanduser( @@ -66,10 +72,15 @@ self.protocolDeleteButton.setIcon(UI.PixmapCache.getIcon("minus.png")) self.protocolEditButton.setIcon(UI.PixmapCache.getIcon("edit.png")) - self.minimumProtocolComboBox.addItem("", "") - self.minimumProtocolComboBox.addItem(self.tr("TLS 1.0"), "tls1.0") - self.minimumProtocolComboBox.addItem(self.tr("TLS 1.1"), "tls1.1") - self.minimumProtocolComboBox.addItem(self.tr("TLS 1.2"), "tls1.2") + self.minimumProtocolComboBox.addItem(self.tr("Default"), "") + for protocol in sorted(self.__minimumProtocols.keys()): + self.minimumProtocolComboBox.addItem( + self.__minimumProtocols[protocol], protocol) + + self.fingerprintsList.headerItem().setText( + self.fingerprintsList.columnCount(), "") + self.protocolsList.headerItem().setText( + self.protocolsList.columnCount(), "") if self.__version < (3, 9, 0): self.disableTls10WarningCheckBox.setEnabled(False) @@ -82,8 +93,9 @@ self.__config = None self.readUserConfig() - + self.__updateFingerprintsButtons() + self.__updateProtocolsButtons() def writeUserConfig(self): """ @@ -226,10 +238,6 @@ if "hostfingerprints" in self.__config: del self.__config["hostfingerprints"] else: - # TODO: add support for disabletls10warning = true - # TODO: add support for minimumprotocol = (tls1.0, tls1.1, tls1.2) - # TODO: add support for <hostname>:minimumprotocol = ... - # # delete hostfingerprints section # @@ -239,9 +247,10 @@ # # hostsecurity section # + if "hostsecurity" not in self.__config: + self.__config["hostsecurity"] = {} + if self.fingerprintsList.topLevelItemCount() > 0: - if "hostsecurity" not in self.__config: - self.__config["hostsecurity"] = {} self.__clearFingerprints() fingerprints = self.__assembleFingerprints() for host in fingerprints: @@ -249,43 +258,40 @@ self.__config["hostsecurity"][key] = \ ", ".join(fingerprints[host]) else: - if "hostsecurity" in self.__config: - self.__clearFingerprints() - if len(self.__config.options("hostsecurity")) == 0: - del self.__config["hostsecurity"] + self.__clearFingerprints() + + if self.disableTls10WarningCheckBox.isChecked(): + disabletls10warning = "true" + else: + disabletls10warning = "false" + self.__config["hostsecurity"]["disabletls10warning"] = \ + disabletls10warning + + if self.minimumProtocolComboBox.currentIndex() == 0: + self.__config.remove_option("hostsecurity", "minimumprotocol") + else: + minimumProtocol = self.minimumProtocolComboBox.itemData( + self.minimumProtocolComboBox.currentIndex()) + self.__config["hostsecurity"]["minimumprotocol"] = \ + minimumProtocol + + if self.protocolsList.topLevelItemCount() > 0: + self.__clearMinimumProtocols() + minimumProtocols = self.__assembleMinimumProtocols() + for host in minimumProtocols: + key = "{0}:minimumprotocol".format(host) + self.__config["hostsecurity"][key] = minimumProtocols[host] + else: + self.__clearMinimumProtocols() + + if len(self.__config.options("hostsecurity")) == 0: + del self.__config["hostsecurity"] ################################################################### cfgFile = getConfigPath() with open(cfgFile, "w") as configFile: self.__config.write(configFile) - def __clearFingerprints(self): - """ - Private method to clear the fingerprints from the hostsecurity section. - """ - if "hostsecurity" in self.__config: - for key in self.__config.options("hostsecurity"): - if key.endswith(":fingerprints"): - self.__config.remove_option("hostsecurity", key) - - def __assembleFingerprints(self): - """ - Private method to assemble a list of host fingerprints. - - @return dictionary with list of fingerprints per host - @rtype dict with str as key and list of str as value - """ - hostFingerprints = {} - for row in range(self.fingerprintsList.topLevelItemCount()): - itm = self.fingerprintsList.topLevelItem(row) - host = itm.text(0) - fingerprint = itm.text(1) - if host in hostFingerprints: - hostFingerprints[host].append(fingerprint) - else: - hostFingerprints[host] = [fingerprint] - return hostFingerprints - def readUserConfig(self): """ Public method to read the user configuration file. @@ -369,7 +375,6 @@ host, "sha1:" + self.__config["hostfingerprints"][host] ]) - self.__finalizeFingerprintsColumns() # step 5b: extract hostsecurity fingerprints if "hostsecurity" in self.__config: @@ -391,10 +396,32 @@ host, fingerprint.replace("\\", "").strip() ]) - self.__finalizeFingerprintsColumns() - # TODO: add support for disabletls10warning = true - # TODO: add support for minimumprotocol = (tls1.0, tls1.1, tls1.2) - # TODO: add support for <hostname>:minimumprotocol = ... + + elif key == "disabletls10warning": + self.disableTls10WarningCheckBox.setChecked( + self.__config.getboolean( + "hostsecurity", "disabletls10warning")) + + elif key == "minimumprotocol": + minimumProtocol = self.__config["hostsecurity"][key] + index = self.minimumProtocolComboBox.findData( + minimumProtocol) + if index == -1: + index = 0 + self.minimumProtocolComboBox.setCurrentIndex(index) + + elif key.endswith(":minimumprotocol"): + host = key.replace(":minimumprotocol", "") + protocol = self.__config["hostsecurity"][key].strip() + if protocol in self.__minimumProtocols: + itm = QTreeWidgetItem(self.protocolsList, [ + host, + self.__minimumProtocols[protocol] + ]) + itm.setData(1, Qt.UserRole, protocol) + + self.__finalizeFingerprintsColumns() + self.__finalizeProtocolsColumns() @pyqtSlot() def accept(self): @@ -431,11 +458,41 @@ self.fingerprintsList.clear() self.__updateFingerprintsButtons() + + self.protocolsList.clear() + self.__updateProtocolsButtons() ####################################################################### ## Methods and slots for the host fingerprint handling below ####################################################################### + def __clearFingerprints(self): + """ + Private method to clear the fingerprints from the hostsecurity section. + """ + if "hostsecurity" in self.__config: + for key in self.__config.options("hostsecurity"): + if key.endswith(":fingerprints"): + self.__config.remove_option("hostsecurity", key) + + def __assembleFingerprints(self): + """ + Private method to assemble a list of host fingerprints. + + @return dictionary with list of fingerprints per host + @rtype dict with str as key and list of str as value + """ + hostFingerprints = {} + for row in range(self.fingerprintsList.topLevelItemCount()): + itm = self.fingerprintsList.topLevelItem(row) + host = itm.text(0) + fingerprint = itm.text(1) + if host in hostFingerprints: + hostFingerprints[host].append(fingerprint) + else: + hostFingerprints[host] = [fingerprint] + return hostFingerprints + @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) def on_fingerprintsList_currentItemChanged(self, current, previous): """ @@ -514,6 +571,87 @@ self.fpEditButton.setEnabled(enable) ####################################################################### + ## Methods and slots for the host minimum protocol handling below + ####################################################################### + + def __clearMinimumProtocols(self): + """ + Private method to clear the minimum protocols from the hostsecurity + section. + """ + if "hostsecurity" in self.__config: + for key in self.__config.options("hostsecurity"): + if key.endswith(":minimumprotocol"): + self.__config.remove_option("hostsecurity", key) + + def __assembleMinimumProtocols(self): + """ + Private method to assemble a list of host minimum protocols. + + @return dictionary with list of minimum protocol per host + @rtype dict with str as key and str as value + """ + minimumProtocols = {} + for row in range(self.protocolsList.topLevelItemCount()): + itm = self.protocolsList.topLevelItem(row) + host = itm.text(0) + minimumProtocol = itm.data(1, Qt.UserRole) + minimumProtocols[host] = minimumProtocol + return minimumProtocols + + @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) + def on_protocolsList_currentItemChanged(self, current, previous): + """ + Private slot handling a change of the current minimum protocol item. + + @param current reference to the current item + @type QTreeWidgetItem + @param previous reference to the previous current item + @type QTreeWidgetItem + """ + self.__updateProtocolsButtons() + + @pyqtSlot() + def on_protocolAddButton_clicked(self): + """ + Slot documentation goes here. + """ + # TODO: not implemented yet + raise NotImplementedError + + @pyqtSlot() + def on_protocolDeleteButton_clicked(self): + """ + Slot documentation goes here. + """ + # TODO: not implemented yet + raise NotImplementedError + + @pyqtSlot() + def on_protocolEditButton_clicked(self): + """ + Slot documentation goes here. + """ + # TODO: not implemented yet + raise NotImplementedError + + def __finalizeProtocolsColumns(self): + """ + Private method to resize and sort the host fingerprints columns. + """ + for col in range(self.protocolsList.columnCount()): + self.protocolsList.resizeColumnToContents(col) + self.protocolsList.sortItems(0, Qt.AscendingOrder) + + def __updateProtocolsButtons(self): + """ + Private slot to update the host minimum protocol edit buttons. + """ + enable = self.protocolsList.currentItem() is not None + self.protocolDeleteButton.setEnabled(enable) + self.protocolEditButton.setEnabled(enable) + + ####################################################################### ## Slot to edit the user configuration in an editor below ####################################################################### @@ -559,40 +697,3 @@ return True return False - - @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) - def on_protocolsList_currentItemChanged(self, current, previous): - """ - Slot documentation goes here. - - @param current DESCRIPTION - @type QTreeWidgetItem - @param previous DESCRIPTION - @type QTreeWidgetItem - """ - # TODO: not implemented yet - return - - @pyqtSlot() - def on_protocolAddButton_clicked(self): - """ - Slot documentation goes here. - """ - # TODO: not implemented yet - raise NotImplementedError - - @pyqtSlot() - def on_protocolDeleteButton_clicked(self): - """ - Slot documentation goes here. - """ - # TODO: not implemented yet - raise NotImplementedError - - @pyqtSlot() - def on_protocolEditButton_clicked(self): - """ - Slot documentation goes here. - """ - # TODO: not implemented yet - raise NotImplementedError