eric6/WebBrowser/WebBrowserPage.py

changeset 7766
0af772bc14c4
parent 7759
51aa6c6b66f7
child 7923
91e843545d9a
diff -r 72ea8b7452a4 -r 0af772bc14c4 eric6/WebBrowser/WebBrowserPage.py
--- a/eric6/WebBrowser/WebBrowserPage.py	Wed Oct 07 17:58:51 2020 +0200
+++ b/eric6/WebBrowser/WebBrowserPage.py	Wed Oct 07 19:14:36 2020 +0200
@@ -23,6 +23,12 @@
     PYQT_WEBENGINE_VERSION = QT_VERSION
 from PyQt5.QtWebChannel import QWebChannel
 
+try:
+    from PyQt5.QtNetwork import QSslConfiguration, QSslCertificate
+    SSL_AVAILABLE = True
+except ImportError:
+    SSL_AVAILABLE = False
+
 from E5Gui import E5MessageBox
 
 from WebBrowser.WebBrowserWindow import WebBrowserWindow
@@ -33,6 +39,7 @@
 from .Tools import Scripts
 
 import Preferences
+import Globals
 
 
 class WebBrowserPage(QWebEnginePage):
@@ -47,6 +54,8 @@
         shown web page
     @signal navigationRequestAccepted(url, navigation type, main frame) emitted
         to signal an accepted navigation request
+    @signal sslConfigurationChanged() emitted to indicate a change of the
+        stored SSL configuration data
     """
     SafeJsWorld = QWebEngineScript.ApplicationWorld
     UnsafeJsWorld = QWebEngineScript.MainWorld
@@ -58,6 +67,8 @@
     navigationRequestAccepted = pyqtSignal(QUrl, QWebEnginePage.NavigationType,
                                            bool)
     
+    sslConfigurationChanged = pyqtSignal()
+    
     def __init__(self, parent=None):
         """
         Constructor
@@ -89,6 +100,8 @@
             # defined for Qt >= 5.11
             pass
         
+        self.__sslConfiguration = None
+        
         # Workaround for changing webchannel world inside
         # acceptNavigationRequest not working
         self.__channelUrl = QUrl()
@@ -614,3 +627,107 @@
             return self.__registerProtocolHandlerRequest.scheme()
         else:
             return ""
+    
+    #############################################################
+    ## SSL configuration handling below
+    #############################################################
+    
+    def setSslConfiguration(self, sslConfiguration):
+        """
+        Public slot to set the SSL configuration data of the page.
+        
+        @param sslConfiguration SSL configuration to be set
+        @type QSslConfiguration
+        """
+        self.__sslConfiguration = QSslConfiguration(sslConfiguration)
+        self.__sslConfiguration.url = self.url()
+        self.sslConfigurationChanged.emit()
+    
+    def getSslConfiguration(self):
+        """
+        Public method to return a reference to the current SSL configuration.
+        
+        @return reference to the SSL configuration in use
+        @rtype QSslConfiguration
+        """
+        return self.__sslConfiguration
+    
+    def clearSslConfiguration(self):
+        """
+        Public slot to clear the stored SSL configuration data.
+        """
+        self.__sslConfiguration = None
+        self.sslConfigurationChanged.emit()
+    
+    def getSslCertificate(self):
+        """
+        Public method to get a reference to the SSL certificate.
+        
+        @return amended SSL certificate
+        @rtype QSslCertificate
+        """
+        if self.__sslConfiguration is None:
+            return None
+        
+        sslCertificate = self.__sslConfiguration.peerCertificate()
+        sslCertificate.url = QUrl(self.__sslConfiguration.url)
+        return sslCertificate
+    
+    def getSslCertificateChain(self):
+        """
+        Public method to get a reference to the SSL certificate chain.
+        
+        @return SSL certificate chain
+        @rtype list of QSslCertificate
+        """
+        if self.__sslConfiguration is None:
+            return []
+        
+        chain = self.__sslConfiguration.peerCertificateChain()
+        return chain
+    
+    def showSslInfo(self, pos):
+        """
+        Public slot to show some SSL information for the loaded page.
+        
+        @param pos position to show the info at
+        @type QPoint
+        """
+        if SSL_AVAILABLE and self.__sslConfiguration is not None:
+            from E5Network.E5SslInfoWidget import E5SslInfoWidget
+            widget = E5SslInfoWidget(self.url(), self.__sslConfiguration,
+                                     self.view())
+            widget.showAt(pos)
+        else:
+            E5MessageBox.warning(
+                self.view(),
+                self.tr("SSL Info"),
+                self.tr("""This site does not contain SSL information."""))
+    
+    def hasValidSslInfo(self):
+        """
+        Public method to check, if the page has a valid SSL certificate.
+        
+        @return flag indicating a valid SSL certificate
+        @rtype bool
+        """
+        if self.__sslConfiguration is None:
+            return False
+        
+        certList = self.__sslConfiguration.peerCertificateChain()
+        if not certList:
+            return False
+        
+        certificateDict = Globals.toDict(
+            Preferences.Prefs.settings.value("Ssl/CaCertificatesDict"))
+        for server in certificateDict:
+            localCAList = QSslCertificate.fromData(certificateDict[server])
+            for cert in certList:
+                if cert in localCAList:
+                    return True
+        
+        for cert in certList:
+            if cert.isBlacklisted():
+                return False
+        
+        return True

eric ide

mercurial