File indexing completed on 2025-02-02 05:08:36

0001 // SPDX-FileCopyrightText: 2010 Omat Holding B.V. <info@omat.nl>
0002 // SPDX-FileCopyrightText: 2014 Sandro Knauß <knauss@kolabsys.com>
0003 // SPDX-FileCopyrightText: 2023 Carl Schwan <carl@carlschwan.eu>
0004 // SPDX-FileCopyrightText: 2023-2024 Laurent Montel <montel.org>
0005 // SPDX-License-Identifier: LGPL-2.0-or-later
0006 
0007 #include "ispdbservice.h"
0008 
0009 #include "accountwizard_debug.h"
0010 
0011 #include <KLocalizedString>
0012 #include <QDomDocument>
0013 #include <QNetworkAccessManager>
0014 #include <QNetworkReply>
0015 #include <QNetworkRequest>
0016 #include <qdom.h>
0017 
0018 IspdbService::IspdbService(QObject *parent)
0019     : QObject(parent)
0020     , mNetworkAccessManager(new QNetworkAccessManager(this))
0021 {
0022 }
0023 
0024 void IspdbService::start(const KMime::Types::AddrSpec &addrSpec)
0025 {
0026     requestConfig(addrSpec, DataBase);
0027 }
0028 
0029 void IspdbService::requestConfig(const KMime::Types::AddrSpec &addrSpec, const SearchServerType searchServerType)
0030 {
0031     const QString domain = addrSpec.domain;
0032     QUrl url;
0033     const QString path = QStringLiteral("/mail/config-v1.1.xml");
0034     switch (searchServerType) {
0035     case IspAutoConfig:
0036         url = QUrl(QStringLiteral("http://autoconfig.") + domain.toLower() + path);
0037         break;
0038     case IspWellKnow:
0039         url = QUrl(QStringLiteral("http://") + domain.toLower() + QStringLiteral("/.well-known/autoconfig") + path);
0040         break;
0041     case DataBase:
0042         url = QUrl(QStringLiteral("https://autoconfig.thunderbird.net/v1.1/") + domain.toLower());
0043     }
0044 
0045     qCDebug(ACCOUNTWIZARD_LOG) << " url " << url;
0046     QNetworkRequest request(url);
0047     Q_EMIT requestedConfigFromUrl(url);
0048     auto reply = mNetworkAccessManager->get(request);
0049 
0050     connect(reply, &QNetworkReply::finished, this, [this, addrSpec, reply, searchServerType]() {
0051         reply->deleteLater();
0052         if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) != 200) {
0053             qCDebug(ACCOUNTWIZARD_LOG) << "Fetching failed" << searchServerType << reply->errorString();
0054 
0055             switch (searchServerType) {
0056             case IspAutoConfig:
0057                 requestConfig(addrSpec, IspWellKnow);
0058                 break;
0059             case IspWellKnow:
0060                 break;
0061             case DataBase:
0062                 requestConfig(addrSpec, IspAutoConfig);
0063                 break;
0064             }
0065         }
0066 
0067         handleReply(reply, addrSpec, searchServerType);
0068     });
0069 }
0070 
0071 void IspdbService::handleReply(QNetworkReply *const reply, const KMime::Types::AddrSpec &addrSpec, const SearchServerType searchServerType)
0072 {
0073     const auto data = reply->readAll();
0074     QDomDocument document;
0075     const QDomDocument::ParseResult result = document.setContent(data);
0076     if (!result) {
0077         qCDebug(ACCOUNTWIZARD_LOG) << "Could not parse xml" << data;
0078         if (searchServerType == IspWellKnow) { // Last one
0079             Q_EMIT notConfigFound();
0080         }
0081         return;
0082     }
0083 
0084     const QDomElement docElem = document.documentElement();
0085     const QDomNodeList emailProviders = docElem.elementsByTagName(QStringLiteral("emailProvider"));
0086 
0087     if (emailProviders.isEmpty()) {
0088         return;
0089     }
0090 
0091     EmailProvider emailProvider;
0092 
0093     QDomNode emailProviderNode = emailProviders.at(0).firstChild();
0094     while (!emailProviderNode.isNull()) {
0095         const QDomElement element = emailProviderNode.toElement();
0096         if (element.isNull()) {
0097             emailProviderNode = emailProviderNode.nextSibling();
0098             continue;
0099         }
0100 
0101         const QString tagName(element.tagName());
0102         if (tagName == QLatin1StringView("domain")) {
0103             emailProvider.domains << element.text();
0104         } else if (tagName == QLatin1StringView("displayName")) {
0105             emailProvider.displayName = element.text();
0106         } else if (tagName == QLatin1StringView("displayShortName")) {
0107             emailProvider.shortDisplayName = element.text();
0108         } else if (tagName == QLatin1StringView("incomingServer") && element.attribute(QStringLiteral("type")) == QLatin1StringView("imap")) {
0109             auto server = Server::fromDomElement(element, addrSpec);
0110             if (server) {
0111                 server->type = Server::Type::IMAP;
0112                 emailProvider.imapServers.append(*server);
0113             }
0114         } else if (tagName == QLatin1StringView("incomingServer") && element.attribute(QStringLiteral("type")) == QLatin1StringView("pop3")) {
0115             auto server = Server::fromDomElement(element, addrSpec);
0116             if (server) {
0117                 server->type = Server::Type::POP3;
0118                 emailProvider.popServers.append(*server);
0119             }
0120         } else if (tagName == QLatin1StringView("outgoingServer") && element.attribute(QStringLiteral("type")) == QLatin1StringView("smtp")) {
0121             auto server = Server::fromDomElement(element, addrSpec);
0122             if (server) {
0123                 server->type = Server::Type::SMTP;
0124                 emailProvider.smtpServers.append(*server);
0125             }
0126         }
0127 
0128         emailProviderNode = emailProviderNode.nextSibling();
0129     }
0130     QString foundInServerTypeMessage;
0131     switch (searchServerType) {
0132     case IspAutoConfig:
0133         foundInServerTypeMessage = i18n("Configuration found auto config file.");
0134         break;
0135     case IspWellKnow:
0136         foundInServerTypeMessage = i18n("Configuration found in well-known file.");
0137         break;
0138     case DataBase:
0139         foundInServerTypeMessage = i18n("Configuration found in Mozilla FAI Database.");
0140         break;
0141     }
0142 
0143     Q_EMIT finished(emailProvider, foundInServerTypeMessage);
0144 }
0145 
0146 #include "moc_ispdbservice.cpp"