--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/E5Network/E5SslCertificateSelectionDialog.py Sat Jan 19 14:31:48 2019 +0100 @@ -0,0 +1,149 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2019 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to select a SSL certificate. +""" + +from __future__ import unicode_literals + +from PyQt5.QtCore import pyqtSlot, Qt +from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QTreeWidgetItem +try: + from PyQt5.QtNetwork import QSslCertificate +except ImportError: + pass + +from .Ui_E5SslCertificateSelectionDialog import \ + Ui_E5SslCertificateSelectionDialog + +import Utilities +import UI.PixmapCache +from Globals import qVersionTuple + + +class E5SslCertificateSelectionDialog(QDialog, + Ui_E5SslCertificateSelectionDialog): + """ + Class implementing a dialog to select a SSL certificate. + """ + CertRole = Qt.UserRole + 1 + + def __init__(self, certificates, parent=None): + """ + Constructor + + @param certificates list of SSL certificates to select from + @type list of QSslCertificate + @param parent reference to the parent widget + @type QWidget + """ + super(E5SslCertificateSelectionDialog, self).__init__(parent) + self.setupUi(self) + + self.viewButton.setIcon( + UI.PixmapCache.getIcon("certificates.png")) + + self.buttonBox.button(QDialogButtonBox.OK).setEnabled(False) + self.viewButton.setEnabled(False) + + self.__populateCertificatesTree(certificates) + + def __populateCertificatesTree(self, certificates): + """ + Private slot to populate the certificates tree. + + @param certificates list of SSL certificates to select from + @type list of QSslCertificate + """ + for cert in certificates(): + self.__createCertificateEntry(cert) + + self.certificatesTree.expandAll() + for i in range(self.certificatesTree.columnCount()): + self.certificatesTree.resizeColumnToContents(i) + self.certificatesTree.sortItems(0, Qt.AscendingOrder) + + def __createCaCertificateEntry(self, cert): + """ + Private method to create a certificate entry. + + @param cert certificate to insert + @type QSslCertificate + """ + # step 1: extract the info to be shown + if qVersionTuple() >= (5, 0, 0): + organisation = Utilities.decodeString( + ", ".join(cert.subjectInfo(QSslCertificate.Organization))) + commonName = Utilities.decodeString( + ", ".join(cert.subjectInfo(QSslCertificate.CommonName))) + else: + organisation = Utilities.decodeString( + cert.subjectInfo(QSslCertificate.Organization)) + commonName = Utilities.decodeString( + cert.subjectInfo(QSslCertificate.CommonName)) + if organisation is None or organisation == "": + organisation = self.tr("(Unknown)") + if commonName is None or commonName == "": + commonName = self.tr("(Unknown common name)") + expiryDate = cert.expiryDate().toString("yyyy-MM-dd") + + # step 2: create the entry + items = self.certificatesTree.findItems( + organisation, + Qt.MatchFixedString | Qt.MatchCaseSensitive) + if len(items) == 0: + parent = QTreeWidgetItem(self.certificatesTree, [organisation]) + parent.setFirstColumnSpanned(True) + else: + parent = items[0] + + itm = QTreeWidgetItem(parent, [commonName, expiryDate]) + itm.setData(0, self.CertRole, cert.toPem()) + + @pyqtSlot() + def on_certificatesTree_itemSelectionChanged(self): + """ + Private slot to handle the selection of an item. + """ + enable = len(self.certificatesTree.selectedItems()) > 0 and \ + self.certificatesTree.selectedItems()[0].parent() is not None + self.buttonBox.button(QDialogButtonBox.OK).setEnabled(enable) + self.viewButton.setEnabled(enable) + + @pyqtSlot() + def on_viewButton_clicked(self): + """ + Private slot to show data of the selected certificate. + """ + try: + from E5Network.E5SslCertificatesInfoDialog import \ + E5SslCertificatesInfoDialog + cert = QSslCertificate.fromData( + self.certificatesTree.selectedItems()[0].data( + 0, self.CertRole)) + dlg = E5SslCertificatesInfoDialog(cert, self) + dlg.exec_() + except ImportError: + pass + + def getSelectedCertificate(self): + """ + Public method to get the selected certificate. + + @return selected certificate + @rtype QSslCertificate + """ + valid = len(self.certificatesTree.selectedItems()) > 0 and \ + self.certificatesTree.selectedItems()[0].parent() is not None + + if valid: + certificate = QSslCertificate.fromData( + self.certificatesTree.selectedItems()[0].data( + 0, self.CertRole)) + else: + certificate = None + + return certificate