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"