File indexing completed on 2024-10-06 10:50:31

0001 /*
0002     SPDX-FileCopyrightText: 2010 Omat Holding B.V. <info@omat.nl>
0003     SPDX-FileCopyrightText: 2014 Sandro Knauß <knauss@kolabsys.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 // This code was taken from kmail-account-wizard
0009 
0010 #pragma once
0011 
0012 #include <QObject>
0013 
0014 #include <KIO/Job>
0015 #include <KMime/HeaderParsing>
0016 #include <QUrl>
0017 
0018 class QDomElement;
0019 class QDomDocument;
0020 
0021 struct Server;
0022 struct identity;
0023 
0024 /**
0025   This class will search in Mozilla's database for an xml file
0026   describing the isp data belonging to that address. This class
0027   searches and wraps the result for further usage. References:
0028     https://wiki.mozilla.org/Thunderbird:Autoconfiguration
0029     https://developer.mozilla.org/en/Thunderbird/Autoconfiguration
0030     https://ispdb.mozillamessaging.com/
0031 */
0032 class Ispdb : public QObject
0033 {
0034     Q_OBJECT
0035 public:
0036     enum socketType { None = 0, SSL, StartTLS };
0037 
0038     /**
0039      Ispdb uses custom authtyps, hence the enum here.
0040      @see https://wiki.mozilla.org/Thunderbird:Autoconfiguration:ConfigFileFormat
0041      In particular, note that Ispdb's Plain represents both Cleartext and AUTH Plain
0042      We will always treat it as Cleartext
0043      */
0044     enum authType { Plain = 0, CramMD5, NTLM, GSSAPI, ClientIP, NoAuth, Basic, OAuth2 };
0045     enum length { Long = 0, Short };
0046 
0047     /** Constructor */
0048     explicit Ispdb(QObject *parent = nullptr);
0049 
0050     /** Destructor */
0051     ~Ispdb() override;
0052 
0053     /** After finished() has been emitted you can
0054         retrieve the domains that are covered by these
0055         settings */
0056     QStringList relevantDomains() const;
0057 
0058     /** After finished() has been emitted you can
0059         get the name of the provider, you can get a long
0060         name and a short one */
0061     QString name(length) const;
0062 
0063     /** After finished() has been emitted you can
0064         get a list of imap servers available for this provider */
0065     QVector<Server> imapServers() const;
0066 
0067     /** After finished() has been emitted you can
0068         get a list of pop3 servers available for this provider */
0069     QVector<Server> pop3Servers() const;
0070 
0071     /** After finished() has been emitted you can
0072         get a list of smtp servers available for this provider */
0073     QVector<Server> smtpServers() const;
0074 
0075     QVector<identity> identities() const;
0076 
0077     int defaultIdentity() const;
0078 public Q_SLOTS:
0079     /** Sets the emailaddress you want to servers for */
0080     void setEmail(const QString &);
0081 
0082     /** Sets the password for login */
0083     void setPassword(const QString &);
0084     /** Starts looking up the servers which belong to the e-mailaddress */
0085     void start();
0086 
0087 private:
0088     void slotResult(KJob *);
0089 
0090 Q_SIGNALS:
0091     /** emitted when done. **/
0092     void finished(bool);
0093     void searchType(const QString &type);
0094 
0095 protected:
0096     /** search types, where to search for autoconfig
0097         @see lookupUrl to generate a url base on this type
0098      */
0099     enum searchServerType {
0100         IspAutoConfig = 0, /**< http://autoconfig.example.com/mail/config-v1.1.xml */
0101         IspWellKnow, /**< http://example.com/.well-known/autoconfig/mail/config-v1.1.xml */
0102         DataBase /**< https://autoconfig.thunderbird.net/v1.1/example.com */
0103     };
0104 
0105     /** let's request the autoconfig server */
0106     virtual void startJob(const QUrl &url);
0107 
0108     /** generate url and start job afterwards */
0109     virtual void lookupInDb(bool auth, bool crypt);
0110 
0111     /** an valid xml document is available, parse it and create all the objects
0112         should run createServer, createIdentity, ...
0113      */
0114     virtual void parseResult(const QDomDocument &document);
0115 
0116     /** create a server object out of an element */
0117     virtual Server createServer(const QDomElement &n);
0118 
0119     /** create a identity object out of an element */
0120     virtual identity createIdentity(const QDomElement &n);
0121 
0122     /** get standard urls for autoconfig
0123         @return the standard url for autoconfig depends on serverType
0124         @param type of request (ex. "mail")
0125         @param version of the file (example for mail "1.1")
0126         @param auth use authentication with username & password to access autoconfig file
0127                     (username is the emailaddress)
0128         @param crypt use https
0129      */
0130     QUrl lookupUrl(const QString &type, const QString &version, bool auth, bool crypt);
0131 
0132     /** setter for serverType */
0133     void setServerType(Ispdb::searchServerType type);
0134 
0135     /** getter for serverType */
0136     Ispdb::searchServerType serverType() const;
0137 
0138     /** replaces %EMAILLOCALPART%, %EMAILADDRESS% and %EMAILDOMAIN% with the
0139         parts of the emailaddress */
0140     QString replacePlaceholders(const QString &);
0141 
0142     QByteArray mData; /** storage of incoming data from kio */
0143 protected Q_SLOTS:
0144 
0145     /** slot for TransferJob to dump data */
0146     void dataArrived(KIO::Job *, const QByteArray &data);
0147 
0148 private:
0149     KMime::Types::AddrSpec mAddr; // emailaddress
0150     QString mPassword;
0151 
0152     // storage of the results
0153     QStringList mDomains;
0154     QString mDisplayName;
0155     QString mDisplayShortName;
0156     QVector<Server> mImapServers;
0157     QVector<Server> mPop3Servers;
0158     QVector<Server> mSmtpServers;
0159     QVector<identity> mIdentities;
0160 
0161     int mDefaultIdentity = -1;
0162     Ispdb::searchServerType mServerType;
0163     bool mStart = true;
0164 };
0165 
0166 struct Server {
0167     Server() = default;
0168 
0169     bool isValid() const
0170     {
0171         return port != -1;
0172     }
0173 
0174     Ispdb::authType authentication = Ispdb::Plain;
0175     Ispdb::socketType socketType = Ispdb::None;
0176     QString hostname;
0177     QString username;
0178     int port = -1;
0179 };
0180 QDebug operator<<(QDebug d, const Server &t);
0181 
0182 struct identity {
0183     identity() = default;
0184 
0185     bool isValid() const
0186     {
0187         return !name.isEmpty();
0188     }
0189 
0190     bool isDefault() const
0191     {
0192         return mDefault;
0193     }
0194 
0195     QString email;
0196     QString name;
0197     QString organization;
0198     QString signature;
0199     bool mDefault = false;
0200 };
0201 QDebug operator<<(QDebug d, const identity &t);
0202