File indexing completed on 2024-12-22 05:07:42

0001 /*
0002     SPDX-FileCopyrightText: 2009 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 // this code was taken from kmail-account-wizard
0008 
0009 #include "setupmanager.h"
0010 #include "configfile.h"
0011 #include "identity.h"
0012 #include "ldap.h"
0013 #include "resource.h"
0014 #include "setupautoconfigkolabfreebusy.h"
0015 #include "setupautoconfigkolabldap.h"
0016 #include "setupautoconfigkolabmail.h"
0017 #include "setupispdb.h"
0018 #include "transport.h"
0019 
0020 #include <KAssistantDialog>
0021 #include <KEMailSettings>
0022 #include <KWallet>
0023 
0024 #include <QLocale>
0025 
0026 SetupManager::SetupManager(QObject *parent)
0027     : QObject(parent)
0028     , m_keyPublishingMethod(Key::NoPublishing)
0029 {
0030     KEMailSettings e;
0031     m_name = e.getSetting(KEMailSettings::RealName);
0032     m_email = e.getSetting(KEMailSettings::EmailAddress);
0033 }
0034 
0035 SetupManager::~SetupManager()
0036 {
0037     delete m_wallet;
0038 }
0039 
0040 QObject *SetupManager::createResource(const QString &type)
0041 {
0042     return connectObject(new Resource(type, this));
0043 }
0044 
0045 QObject *SetupManager::createTransport(const QString &type)
0046 {
0047     return connectObject(new Transport(type, this));
0048 }
0049 
0050 QObject *SetupManager::createConfigFile(const QString &fileName)
0051 {
0052     return connectObject(new ConfigFile(fileName, this));
0053 }
0054 
0055 QObject *SetupManager::createLdap()
0056 {
0057     return connectObject(new Ldap(this));
0058 }
0059 
0060 QObject *SetupManager::createIdentity()
0061 {
0062     auto *identity = new Identity(this);
0063     identity->setEmail(m_email);
0064     identity->setRealName(m_name);
0065     identity->setPgpAutoSign(m_pgpAutoSign);
0066     identity->setPgpAutoEncrypt(m_pgpAutoEncrypt);
0067     identity->setKey(m_key.protocol(), m_key.primaryFingerprint());
0068     return connectObject(identity);
0069 }
0070 
0071 QObject *SetupManager::createKey()
0072 {
0073     Key *key = new Key(this);
0074     key->setKey(m_key);
0075     key->setMailBox(m_email);
0076     key->setPublishingMethod(m_keyPublishingMethod);
0077     return connectObject(key);
0078 }
0079 
0080 QVector<SetupObject *> SetupManager::objectsToSetup() const
0081 {
0082     return m_objectToSetup;
0083 }
0084 
0085 QVector<SetupObject *> SetupManager::setupObjects() const
0086 {
0087     return m_setupObjects;
0088 }
0089 
0090 static bool dependencyCompare(SetupObject *left, SetupObject *right)
0091 {
0092     if (!left->dependsOn() && right->dependsOn()) {
0093         return true;
0094     }
0095     return false;
0096 }
0097 
0098 void SetupManager::execute()
0099 {
0100     if (m_keyPublishingMethod != Key::NoPublishing) {
0101         auto key = qobject_cast<Key *>(createKey());
0102         auto it = std::find_if(m_setupObjects.cbegin(), m_setupObjects.cend(), [](SetupObject *obj) -> bool {
0103             return qobject_cast<Transport *>(obj);
0104         });
0105         if (it != m_setupObjects.cend()) {
0106             key->setDependsOn(*it);
0107         }
0108     }
0109 
0110     // ### FIXME this is a bad over-simplification and would need a real topological sort
0111     // but for current usage it is good enough
0112     std::stable_sort(m_objectToSetup.begin(), m_objectToSetup.end(), dependencyCompare);
0113     
0114     while (!m_objectToSetup.isEmpty()) {
0115         m_currentSetupObject = m_objectToSetup.takeFirst();
0116         m_currentSetupObject->create();
0117     }
0118 }
0119 
0120 void SetupManager::setupSuccessSlot(const QString &msg)
0121 {
0122     Q_EMIT setupSucceeded(msg);
0123     if (m_currentSetupObject) {
0124         Q_EMIT setupFinished(m_currentSetupObject);
0125         m_setupObjects.append(m_currentSetupObject);
0126         m_currentSetupObject = nullptr;
0127     }
0128     setupNext();
0129 }
0130 
0131 void SetupManager::setupFailedSlot(const QString &msg)
0132 {
0133     Q_EMIT setupFailed(msg);
0134     if (m_currentSetupObject) {
0135         m_setupObjects.append(m_currentSetupObject);
0136         m_currentSetupObject = nullptr;
0137     }
0138     rollback();
0139 }
0140 
0141 void SetupManager::setupInfoSlot(const QString &msg)
0142 {
0143     Q_EMIT setupInfo(msg);
0144 }
0145 
0146 void SetupManager::setupNext()
0147 {
0148     // user canceled during the previous setup step
0149     if (m_rollbackRequested) {
0150         rollback();
0151         return;
0152     }
0153 
0154     if (!m_objectToSetup.isEmpty()) {
0155         m_currentSetupObject = m_objectToSetup.takeFirst();
0156         m_currentSetupObject->create();
0157     }
0158 }
0159 
0160 void SetupManager::rollback()
0161 {
0162     const auto setupObjectsList = m_setupObjects;
0163     for (int i = 0; i < setupObjectsList.count(); ++i) {
0164         auto obj = m_setupObjects.at(i);
0165         if (obj) {
0166             obj->destroy();
0167             m_objectToSetup.prepend(obj);
0168         }
0169     }
0170     m_setupObjects.clear();
0171     m_rollbackRequested = false;
0172     Q_EMIT rollbackComplete();
0173 }
0174 
0175 SetupObject *SetupManager::connectObject(SetupObject *obj)
0176 {
0177     connect(obj, &SetupObject::finished, this, &SetupManager::setupSuccessSlot);
0178     connect(obj, &SetupObject::finished, this, [](const QString &msg) { qDebug() << msg; });
0179     connect(obj, &SetupObject::info, this, &SetupManager::setupInfo);
0180     connect(obj, &SetupObject::info, this, [](const QString &msg) { qDebug() << msg; });
0181     connect(obj, &SetupObject::error, this, &SetupManager::setupFailedSlot);
0182     connect(obj, &SetupObject::error, this, [](const QString &msg) { qDebug() << msg; });
0183     m_objectToSetup.append(obj);
0184     return obj;
0185 }
0186 
0187 void SetupManager::setName(const QString &name)
0188 {
0189     m_name = name;
0190 }
0191 
0192 QString SetupManager::name() const
0193 {
0194     return m_name;
0195 }
0196 
0197 void SetupManager::setEmail(const QString &email)
0198 {
0199     m_email = email;
0200 }
0201 
0202 QString SetupManager::email() const
0203 {
0204     return m_email;
0205 }
0206 
0207 void SetupManager::setPassword(const QString &password)
0208 {
0209     m_password = password;
0210 }
0211 
0212 QString SetupManager::password() const
0213 {
0214     return m_password;
0215 }
0216 
0217 QString SetupManager::country() const
0218 {
0219     return QLocale::countryToString(QLocale().country());
0220 }
0221 
0222 void SetupManager::setPgpAutoEncrypt(bool autoencrypt)
0223 {
0224     m_pgpAutoEncrypt = autoencrypt;
0225 }
0226 
0227 void SetupManager::setPgpAutoSign(bool autosign)
0228 {
0229     m_pgpAutoSign = autosign;
0230 }
0231 
0232 void SetupManager::setKey(const GpgME::Key &key)
0233 {
0234     m_key = key;
0235 }
0236 
0237 void SetupManager::setKeyPublishingMethod(Key::PublishingMethod method)
0238 {
0239     m_keyPublishingMethod = method;
0240 }
0241 
0242 void SetupManager::openWallet()
0243 {
0244     // Remove it we need to update qt5keychain
0245     using namespace KWallet;
0246     if (Wallet::isOpen(Wallet::NetworkWallet())) {
0247         return;
0248     }
0249 
0250     Q_ASSERT(parent()->isWidgetType());
0251     m_wallet = Wallet::openWallet(Wallet::NetworkWallet(), qobject_cast<QWidget *>(parent())->effectiveWinId(), Wallet::Asynchronous);
0252     QEventLoop loop;
0253     connect(m_wallet, &KWallet::Wallet::walletOpened, &loop, &QEventLoop::quit);
0254     loop.exec();
0255 }
0256 
0257 bool SetupManager::personalDataAvailable() const
0258 {
0259     return m_personalDataAvailable;
0260 }
0261 
0262 void SetupManager::setPersonalDataAvailable(bool available)
0263 {
0264     m_personalDataAvailable = available;
0265 }
0266 
0267 QObject *SetupManager::ispDB(const QString &type)
0268 {
0269     const QString t = type.toLower();
0270     if (t == QLatin1String("autoconfigkolabmail")) {
0271         return new SetupAutoconfigKolabMail(this);
0272     } else if (t == QLatin1String("autoconfigkolabldap")) {
0273         return new SetupAutoconfigKolabLdap(this);
0274     } else if (t == QLatin1String("autoconfigkolabfreebusy")) {
0275         return new SetupAutoconfigKolabFreebusy(this);
0276     } else {
0277         return new SetupIspdb(this);
0278     }
0279 }
0280 
0281 void SetupManager::requestRollback()
0282 {
0283     if (m_setupObjects.isEmpty()) {
0284         Q_EMIT rollbackComplete();
0285     } else {
0286         m_rollbackRequested = true;
0287         if (!m_currentSetupObject) {
0288             rollback();
0289         }
0290     }
0291 }
0292