[frameworks/kdav] src: Add a DavSslUiProxy to allow plugging user interaction for SSL errors

Kevin Ottens <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 50def044d22898ad63ba6f0c972cd76648c0f5ef by Kevin Ottens, on behalf of Kevin Ottens.
Committed on 28/07/2026 at 19:53.
Pushed by ervin into branch 'master'.

Add a DavSslUiProxy to allow plugging user interaction for SSL errors

M  +3    -0    src/CMakeLists.txt
M  +16   -0    src/common/davmanager.cpp
M  +7    -0    src/common/davmanager_p.h
A  +16   -0    src/common/davssluiproxy.cpp     [License: LGPL(v2.0+)]
A  +74   -0    src/common/davssluiproxy.h     [License: LGPL(v2.0+)]

https://invent.kde.org/frameworks/kdav/-/commit/50def044d22898ad63ba6f0c972cd76648c0f5ef

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 49fbd48..f72fc60 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -55,6 +55,8 @@ target_sources(KF6DAV PRIVATE
     common/davprincipalsearchjob.h
     common/davprotocolbase.cpp
     common/davprotocolbase_p.h
+    common/davssluiproxy.cpp
+    common/davssluiproxy.h
     common/davurl.cpp
     common/davurl.h
     common/enums.h
@@ -98,6 +100,7 @@ ecm_generate_headers(KDAV_Camelcase_HEADERS
     DavItemsListJob
     DavPrincipalHomesetsFetchJob
     DavPrincipalSearchJob
+    DavSslUiProxy
     DavUrl
     Enums
     EtagCache
diff --git a/src/common/davmanager.cpp b/src/common/davmanager.cpp
index 822403a..67e9d5b 100644
--- a/src/common/davmanager.cpp
+++ b/src/common/davmanager.cpp
@@ -6,6 +6,7 @@
 
 #include "davmanager_p.h"
 
+#include "davssluiproxy.h"
 #include "protocols/caldavprotocol_p.h"
 #include "protocols/carddavprotocol_p.h"
 #include "protocols/groupdavprotocol_p.h"
@@ -37,6 +38,16 @@ DavManager::DavManager()
             auth->setPassword(url.password());
         }
     });
+
+    QObject::connect(mNam.get(), &QNetworkAccessManager::sslErrors, [this](QNetworkReply *reply, const QList<QSslError> &sslErrors) {
+        if (!mSslUiProxy) {
+            return;
+        }
+
+        if (mSslUiProxy->ignoreSslErrors(reply, sslErrors)) {
+            reply->ignoreSslErrors();
+        }
+    });
 }
 
 DavManager::~DavManager() = default;
@@ -72,6 +83,11 @@ QNetworkAccessManager *DavManager::networkAccessManager() const
     return mNam.get();
 }
 
+void DavManager::setSslUiProxy(std::unique_ptr<DavSslUiProxy> &&proxy)
+{
+    mSslUiProxy = std::move(proxy);
+}
+
 QNetworkReply *DavManager::sendDavRequest(const QByteArray &method, const QUrl &url, const QString &document, const QString &depth) const
 {
     QNetworkRequest request(url);
diff --git a/src/common/davmanager_p.h b/src/common/davmanager_p.h
index 211517b..0e67474 100644
--- a/src/common/davmanager_p.h
+++ b/src/common/davmanager_p.h
@@ -20,6 +20,7 @@ class QUrl;
 namespace KDAV
 {
 class DavProtocolBase;
+class DavSslUiProxy;
 
 /*!
  * \internal
@@ -84,6 +85,11 @@ public:
      */
     QNetworkAccessManager *networkAccessManager() const;
 
+    /*!
+     * Sets the DavSslUiProxy used to handle SSL errors coming from the QNetworkAccessManager.
+     */
+    void setSslUiProxy(std::unique_ptr<DavSslUiProxy> &&proxy);
+
     /*!
      * Returns the user agent.
      */
@@ -103,6 +109,7 @@ private:
     QNetworkReply *sendDavRequest(const QByteArray &method, const QUrl &url, const QString &document, const QString &depth = {}) const;
 
     mutable std::unique_ptr<QNetworkAccessManager> mNam;
+    std::unique_ptr<DavSslUiProxy> mSslUiProxy;
     std::unique_ptr<DavProtocolBase> mProtocols[3];
 };
 }
diff --git a/src/common/davssluiproxy.cpp b/src/common/davssluiproxy.cpp
new file mode 100644
index 0000000..02e6b19
--- /dev/null
+++ b/src/common/davssluiproxy.cpp
@@ -0,0 +1,16 @@
+/*
+    SPDX-FileCopyrightText: 2026 Kevin Ottens <[email protected]>
+
+    SPDX-License-Identifier: LGPL-2.0-or-later
+*/
+
+#include "davssluiproxy.h"
+
+#include "davmanager_p.h"
+
+void KDAV::DavSslUiProxy::setDefaultProxy(std::unique_ptr<DavSslUiProxy> &&proxy)
+{
+    KDAV::DavManager::self()->setSslUiProxy(std::move(proxy));
+}
+
+KDAV::DavSslUiProxy::~DavSslUiProxy() = default;
diff --git a/src/common/davssluiproxy.h b/src/common/davssluiproxy.h
new file mode 100644
index 0000000..d3752a9
--- /dev/null
+++ b/src/common/davssluiproxy.h
@@ -0,0 +1,74 @@
+/*
+    SPDX-FileCopyrightText: 2026 Kevin Ottens <[email protected]>
+
+    SPDX-License-Identifier: LGPL-2.0-or-later
+*/
+
+#pragma once
+
+#include "kdav_export.h"
+
+#include <memory>
+
+#include <QList>
+
+class QNetworkReply;
+class QSslError;
+
+namespace KDAV
+{
+/*!
+ * \class KDAV::DavSslUiProxy
+ * \inmodule KDAV
+ * \inheaderfile KDAV/DavSslUiProxy
+ *
+ * \brief Interface to display SSL errors and requesting user input.
+ * \since 6.29
+ */
+class KDAV_EXPORT DavSslUiProxy
+{
+public:
+    /*!
+     * Set an implementation for the DavSslUiProxy interface.
+     *
+     * If none has been positioned, any SSL error will be automatically
+     * rejected and fail the corresponding job. Position one to avoid
+     * this behavior or be able to ask the user what to do.
+     */
+    static void setDefaultProxy(std::unique_ptr<DavSslUiProxy> &&proxy);
+
+    virtual ~DavSslUiProxy();
+
+    /*!
+     * Show an SSL error and ask the user whether it should be ignored or not.
+     * The recommended KDE UI is the following:
+     * \code
+     * #include <KSslErrorUiData>
+     * #include <KIO/SslUi>
+     * class UiProxy: public DavSslUiProxy
+     * {
+     * public:
+     *     bool ignoreSslErrors(QNetworkReply *reply, const QList<QSslError> &sslErrors) override
+     *     {
+     *         KSslErrorUiData errorData(reply, sslErrors);
+     *         if (KIO::SslUi::askIgnoreSslErrors(errorData)) {
+     *             return true;
+     *         } else {
+     *             return false;
+     *         }
+     *     }
+     * };
+     * [...]
+     * auto proxy = std::make_unique<UiProxy>();
+     * DavSslUiProxy::setDefaultProxy(std::move(proxy));
+     * \endcode
+     *
+     * \a reply is the request which got errors
+     * \a sslErrors contains details about the encountered SSL errors.
+     *
+     * Returns \c true if the error can be ignored
+     */
+    virtual bool ignoreSslErrors(QNetworkReply *reply, const QList<QSslError> &sslErrors) = 0;
+};
+
+}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.