diff --git a/examples/webengine/quicknanobrowser/BrowserWindow.qml b/examples/webengine/quicknanobrowser/BrowserWindow.qml index 3465e0da6ad5d5fe07b9914944718db5351df1e0..f451c8c07c182cfa048e65154343677d56fc931b 100644 --- a/examples/webengine/quicknanobrowser/BrowserWindow.qml +++ b/examples/webengine/quicknanobrowser/BrowserWindow.qml @@ -290,10 +290,8 @@ ApplicationWindow { } onCertificateError: { - sslDialog.certError = error - sslDialog.text = "Certificate Error: " + error.description - sslDialog.visible = true error.defer() + sslDialog.enqueue(error) } onNewViewRequested: { @@ -316,14 +314,33 @@ ApplicationWindow { MessageDialog { id: sslDialog - property var certError - - standardButtons: StandardButton.Cancel | StandardButton.Ok - visible: false - title: "Do you want to accept this certificate?" + property var certErrors: [] + icon: StandardIcon.Warning + standardButtons: StandardButton.No | StandardButton.Yes + title: "Server's certificate not trusted" + text: "Do you wish to continue?" + detailedText: "If you wish so, you may continue with an unverified certificate. " + + "Accepting an unverified certificate means " + + "you may not be connected with the host you tried to connect to.\n" + + "Do you wish to override the security check and continue?" + onYes: { + certErrors.shift().ignoreCertificateError() + presentError() + } + onNo: reject() + onRejected: reject() - onAccepted: certError.ignoreCertificateError() - onRejected: certError.rejectCertificate() + function reject(){ + certErrors.shift().rejectCertificate() + presentError() + } + function enqueue(error){ + certErrors.push(error) + presentError() + } + function presentError(){ + visible = certErrors.length > 0 + } } DownloadView { id: downloadView diff --git a/src/webengine/api/qquickwebenginecertificateerror.cpp b/src/webengine/api/qquickwebenginecertificateerror.cpp index ba22bf1f07aaa804bb95e03a8a6e3b566281ad5f..a39bbfb84e09a20356a8816169339c915c8d7e3e 100644 --- a/src/webengine/api/qquickwebenginecertificateerror.cpp +++ b/src/webengine/api/qquickwebenginecertificateerror.cpp @@ -45,7 +45,8 @@ public: error(static_cast<QQuickWebEngineCertificateError::Error>(static_cast<int>(controller->error()))), description(controller->errorString()), overridable(controller->overridable()), - async(false) + async(false), + answered(false) { } @@ -54,6 +55,7 @@ public: QString description; bool overridable; bool async; + bool answered; }; @@ -102,7 +104,9 @@ void QQuickWebEngineCertificateError::defer() */ void QQuickWebEngineCertificateError::ignoreCertificateError() { - Q_D(const QQuickWebEngineCertificateError); + Q_D(QQuickWebEngineCertificateError); + + d->answered = true; QSharedPointer<CertificateErrorController> strongRefCert = d->weakRefCertErrorController.toStrongRef(); if (strongRefCert) @@ -116,7 +120,9 @@ void QQuickWebEngineCertificateError::ignoreCertificateError() */ void QQuickWebEngineCertificateError::rejectCertificate() { - Q_D(const QQuickWebEngineCertificateError); + Q_D(QQuickWebEngineCertificateError); + + d->answered = true; QSharedPointer<CertificateErrorController> strongRefCert = d->weakRefCertErrorController.toStrongRef(); if (strongRefCert) @@ -169,5 +175,11 @@ bool QQuickWebEngineCertificateError::deferred() const return d->async; } +bool QQuickWebEngineCertificateError::answered() const +{ + Q_D(const QQuickWebEngineCertificateError); + return d->answered; +} + QT_END_NAMESPACE diff --git a/src/webengine/api/qquickwebenginecertificateerror_p.h b/src/webengine/api/qquickwebenginecertificateerror_p.h index 08ebc83b6b6ec526598ca80a2ae1ac8517984632..18a1f90e50cc8baf7c00f0b1e34df0b85134b8a9 100644 --- a/src/webengine/api/qquickwebenginecertificateerror_p.h +++ b/src/webengine/api/qquickwebenginecertificateerror_p.h @@ -83,6 +83,7 @@ public: QString description() const; bool overridable() const; bool deferred() const; + bool answered() const; private: Q_DISABLE_COPY(QQuickWebEngineCertificateError) diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 1430d72b31e48da975b2892e5ae6b69bcf94ece9..c1d2ac2b6c1c16ddfd626874be39ba2a0f1c2e1c 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -228,12 +228,13 @@ void QQuickWebEngineViewPrivate::allowCertificateError(const QSharedPointer<Cert { Q_Q(QQuickWebEngineView); - m_certificateErrorController = errorController; QQuickWebEngineCertificateError *quickController = new QQuickWebEngineCertificateError(errorController); QQmlEngine::setObjectOwnership(quickController, QQmlEngine::JavaScriptOwnership); Q_EMIT q->certificateError(quickController); - if (!quickController->deferred()) + if (!quickController->deferred() && !quickController->answered()) quickController->rejectCertificate(); + else + m_certificateErrorControllers.append(errorController); } void QQuickWebEngineViewPrivate::runGeolocationPermissionRequest(const QUrl &url) @@ -305,6 +306,7 @@ void QQuickWebEngineViewPrivate::loadStarted(const QUrl &provisionalUrl) Q_Q(QQuickWebEngineView); isLoading = true; m_history->reset(); + m_certificateErrorControllers.clear(); QQuickWebEngineLoadRequest loadRequest(provisionalUrl, QQuickWebEngineView::LoadStartedStatus); Q_EMIT q->loadingChanged(&loadRequest); } diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 0111d4be40fbc7135bf4bad2117f1a8875f186d3..377dcc91f2885119ed05f6f923c53b2c2eaaf0f9 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -202,7 +202,7 @@ public: bool isLoading; qreal devicePixelRatio; QMap<quint64, QJSValue> m_callbacks; - QSharedPointer<CertificateErrorController> m_certificateErrorController; + QList<QSharedPointer<CertificateErrorController> > m_certificateErrorControllers; private: QScopedPointer<QtWebEngineCore::UIDelegatesManager> m_uIDelegatesManager; diff --git a/tests/quicktestbrowser/BrowserWindow.qml b/tests/quicktestbrowser/BrowserWindow.qml index 2c8e9e1ea111f606f788da1d15c00418edc4a4d1..b111edb6c11a8650456a30f4e29eeef5f399ddca 100644 --- a/tests/quicktestbrowser/BrowserWindow.qml +++ b/tests/quicktestbrowser/BrowserWindow.qml @@ -357,10 +357,12 @@ ApplicationWindow { ] onCertificateError: { - sslDialog.certError = error - sslDialog.text = "Certificate Error: " + error.description - sslDialog.visible = true - error.defer() + if (!acceptedCertificates.shouldAutoAccept(error)){ + error.defer() + sslDialog.enqueue(error) + } else{ + error.ignoreCertificateError() + } } onNewViewRequested: { @@ -440,17 +442,50 @@ ApplicationWindow { } } + QtObject{ + id:acceptedCertificates + + property var acceptedUrls : [] + + function shouldAutoAccept(certificateError){ + var domain = utils.domainFromString(certificateError.url) + return acceptedUrls.indexOf(domain) >= 0 + } + } + MessageDialog { id: sslDialog - property var certError - - standardButtons: StandardButton.Cancel | StandardButton.Ok - visible: false - title: "Do you want to accept this certificate?" + property var certErrors: [] + icon: StandardIcon.Warning + standardButtons: StandardButton.No | StandardButton.Yes + title: "Server's certificate not trusted" + text: "Do you wish to continue?" + detailedText: "If you wish so, you may continue with an unverified certificate. " + + "Accepting an unverified certificate means " + + "you may not be connected with the host you tried to connect to.\n" + + "Do you wish to override the security check and continue?" + onYes: { + var cert = certErrors.shift() + var domain = utils.domainFromString(cert.url) + acceptedCertificates.acceptedUrls.push(domain) + cert.ignoreCertificateError() + presentError() + } + onNo: reject() + onRejected: reject() - onAccepted: certError.ignoreCertificateError() - onRejected: certError.rejectCertificate() + function reject(){ + certErrors.shift().rejectCertificate() + presentError() + } + function enqueue(error){ + certErrors.push(error) + presentError() + } + function presentError(){ + visible = certErrors.length > 0 + } } DownloadView { diff --git a/tests/quicktestbrowser/utils.h b/tests/quicktestbrowser/utils.h index 0f4460dfea76fe8a58e7870af12b0444fbb481f8..52025b7e43433dcdb2792de839c468cd42c4f356 100644 --- a/tests/quicktestbrowser/utils.h +++ b/tests/quicktestbrowser/utils.h @@ -48,6 +48,7 @@ class Utils : public QObject { Q_OBJECT public: Q_INVOKABLE static QUrl fromUserInput(const QString& userInput); + Q_INVOKABLE static QString domainFromString(const QString& urlString); }; inline QUrl Utils::fromUserInput(const QString& userInput) @@ -58,4 +59,9 @@ inline QUrl Utils::fromUserInput(const QString& userInput) return QUrl::fromUserInput(userInput); } +inline QString Utils::domainFromString(const QString& urlString) +{ + return QUrl::fromUserInput(urlString).host(); +} + #endif // UTILS_H