diff --git a/src/global.cpp b/src/global.cpp index 24e6155..734e144 100644 --- a/src/global.cpp +++ b/src/global.cpp @@ -1,134 +1,133 @@ /* Copyright (c) 2009 Volker Krause This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "global.h" #include "accountwizard_debug.h" #include #include #include -#include #include class GlobalPrivate { public: QStringList filter; QString assistant; QString poFileName; }; Q_GLOBAL_STATIC(GlobalPrivate, sInstance) QString Global::assistant() { return sInstance->assistant; } void Global::setAssistant(const QString &assistant) { const QFileInfo info(assistant); if (info.isAbsolute()) { sInstance->assistant = assistant; return; } QStringList list; const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("akonadi/accountwizard/"), QStandardPaths::LocateDirectory); for (const QString &dir : dirs) { const QStringList directories = QDir(dir).entryList(QDir::AllDirs); for (const QString &directory : directories) { const QString fullPath = dir + QLatin1Char('/') + directory; const QStringList fileNames = QDir(fullPath).entryList(QStringList() << QStringLiteral("*.desktop")); list.reserve(fileNames.count()); for (const QString &file : fileNames) { list.append(fullPath + QLatin1Char('/') + file); } } } foreach (const QString &entry, list) { const QFileInfo info(entry); const QDir dir(info.absolutePath()); if (dir.dirName() == assistant) { sInstance->assistant = entry; return; } } sInstance->assistant.clear(); } QStringList Global::typeFilter() { return sInstance->filter; } void Global::setTypeFilter(const QStringList &filter) { sInstance->filter = filter; } QString Global::assistantBasePath() { const QFileInfo info(assistant()); if (info.isAbsolute()) { return info.absolutePath() + QDir::separator(); } return QString(); } QString Global::unpackAssistant(const QUrl &remotePackageUrl) { QString localPackageFile; if (remotePackageUrl.scheme() == QLatin1String("file")) { localPackageFile = remotePackageUrl.path(); } else { QString remoteFileName = QFileInfo(remotePackageUrl.path()).fileName(); localPackageFile = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1String("/accountwizard/") + remoteFileName; KIO::Job *job = KIO::copy(remotePackageUrl, QUrl::fromLocalFile(localPackageFile), KIO::Overwrite | KIO::HideProgressInfo); qCDebug(ACCOUNTWIZARD_LOG) << "downloading remote URL" << remotePackageUrl << "to" << localPackageFile; if (!job->exec()) { return QString(); } } const QUrl file(QLatin1String("tar://") + localPackageFile); const QFileInfo fi(localPackageFile); const QString assistant = fi.baseName(); const QString dest = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + QLatin1Char('/'); QDir().mkpath(dest + file.fileName()); KIO::Job *getJob = KIO::copy(file, QUrl::fromLocalFile(dest), KIO::Overwrite | KIO::HideProgressInfo); if (getJob->exec()) { qCDebug(ACCOUNTWIZARD_LOG) << "worked, unpacked in " << dest; return dest + file.fileName() + QLatin1Char('/') + assistant + QLatin1Char('/') + assistant + QLatin1String(".desktop"); } else { qCDebug(ACCOUNTWIZARD_LOG) << "failed" << getJob->errorString(); return QString(); } } void Global::setPoFileName(const QString &poFileName) { sInstance->poFileName = poFileName; } QString Global::poFileName() { return sInstance->poFileName; } diff --git a/src/inprocess-main.cpp b/src/inprocess-main.cpp index 19744b2..dc89b84 100644 --- a/src/inprocess-main.cpp +++ b/src/inprocess-main.cpp @@ -1,39 +1,39 @@ /* Copyright (c) 2010 Volker Krause This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "dialog.h" #include "inprocess-main.h" +#include "dialog.h" #include "global.h" #include #include AccountWizard::AccountWizard(QObject *parent) : QObject(parent) { } void AccountWizard::run(const QStringList &types, QWidget *parent) { if (!types.isEmpty()) { Global::setTypeFilter(types); } Dialog dlg(parent); dlg.exec(); } diff --git a/src/inprocess-main.h b/src/inprocess-main.h index c570251..7b9fd3f 100644 --- a/src/inprocess-main.h +++ b/src/inprocess-main.h @@ -1,36 +1,41 @@ /* Copyright (c) 2010 Volker Krause This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#ifndef INPROCESS_MAIN_H +#define INPROCESS_MAIN_H + #include "dialog.h" #include "global.h" #include #include class AccountWizard : public QObject { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kde.akonadi.AccountWizard") public: explicit AccountWizard(QObject *parent = nullptr); public Q_SLOTS: void run(const QStringList &types, QWidget *parent); }; + +#endif diff --git a/src/ispdb/autoconfigkolabldap.cpp b/src/ispdb/autoconfigkolabldap.cpp index 37521c1..15056a8 100644 --- a/src/ispdb/autoconfigkolabldap.cpp +++ b/src/ispdb/autoconfigkolabldap.cpp @@ -1,135 +1,134 @@ /* * Copyright (C) 2014 Sandro Knauß * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version cense as published by * the Free Software Foundation, either version 2: of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "autoconfigkolabldap.h" #include AutoconfigKolabLdap::AutoconfigKolabLdap(QObject *parent) : AutoconfigKolabMail(parent) { } void AutoconfigKolabLdap::lookupInDb(bool auth, bool crypt) { if (serverType() == DataBase) { setServerType(IspAutoConfig); } startJob(lookupUrl(QStringLiteral("ldap"), QStringLiteral("1.0"), auth, crypt)); } void AutoconfigKolabLdap::parseResult(const QDomDocument &document) { const QDomElement docElem = document.documentElement(); const QDomNodeList l = docElem.elementsByTagName(QStringLiteral("ldapProvider")); if (l.isEmpty()) { Q_EMIT finished(false); return; } for (int i = 0; i < l.count(); ++i) { QDomElement e = l.at(i).toElement(); ldapServer s = createLdapServer(e); if (s.isValid()) { mLdapServers[e.attribute(QStringLiteral("id"))] = s; } } Q_EMIT finished(true); } ldapServer AutoconfigKolabLdap::createLdapServer(const QDomElement &n) { QDomNode o = n.firstChild(); ldapServer s; while (!o.isNull()) { QDomElement f = o.toElement(); if (!f.isNull()) { const QString tagName(f.tagName()); if (tagName == QLatin1String("hostname")) { s.hostname = replacePlaceholders(f.text()); } else if (tagName == QLatin1String("port")) { s.port = f.text().toInt(); } else if (tagName == QLatin1String("socketType")) { const QString type(f.text()); if (type == QLatin1String("plain")) { s.socketType = KLDAP::LdapServer::None; } else if (type == QLatin1String("SSL")) { s.socketType = KLDAP::LdapServer::SSL; } else if (type == QLatin1String("TLS")) { s.socketType = KLDAP::LdapServer::TLS; } } else if (tagName == QLatin1String("authentication")) { const QString type(f.text()); if (type == QLatin1String("anonyoum")) { s.authentication = KLDAP::LdapServer::Anonymous; } else if (type == QLatin1String("simple")) { s.authentication = KLDAP::LdapServer::Simple; } else if (type == QLatin1String("sasl")) { s.authentication = KLDAP::LdapServer::SASL; } } else if (tagName == QLatin1String("bindDn")) { s.bindDn = f.text(); } else if (tagName == QLatin1String("sasl-mech")) { s.saslMech = f.text(); } else if (tagName == QLatin1String("username")) { s.username = f.text(); } else if (tagName == QLatin1String("password")) { s.password = f.text(); } else if (tagName == QLatin1String("realm")) { s.realm = f.text(); } else if (tagName == QLatin1String("dn")) { s.dn = f.text(); } else if (tagName == QLatin1String("ldapVersion")) { s.ldapVersion = f.text().toInt(); } else if (tagName == QLatin1String("filter")) { s.filter = f.text(); } else if (tagName == QLatin1String("pagesize")) { s.pageSize = f.text().toInt(); if (s.pageSize < 1 || s.pageSize > 9999999) { s.pageSize = -1; } } else if (tagName == QLatin1String("timelimit")) { s.timeLimit = f.text().toInt(); if (s.timeLimit < 1 || s.timeLimit > 9999999) { s.timeLimit = -1; } } else if (tagName == QLatin1String("sizelimit")) { s.sizeLimit = f.text().toInt(); if (s.sizeLimit < 1 || s.sizeLimit > 9999999) { s.sizeLimit = -1; } } } o = o.nextSibling(); } return s; } QHash< QString, ldapServer > AutoconfigKolabLdap::ldapServers() const { return mLdapServers; } bool ldapServer::isValid() const { return port != -1; } diff --git a/src/ispdb/ispdb.h b/src/ispdb/ispdb.h index bc86dba..b3fff33 100644 --- a/src/ispdb/ispdb.h +++ b/src/ispdb/ispdb.h @@ -1,223 +1,223 @@ /* Copyright (c) 2010 Omat Holding B.V. Copyright (c) 2014 Sandro Knauß This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef ISPDB_H #define ISPDB_H #include #include #include #include class QDomElement; class QDomDocument; struct Server; struct identity; /** This class will search in Mozilla's database for an xml file describing the isp data belonging to that address. This class searches and wraps the result for further usage. References: https://wiki.mozilla.org/Thunderbird:Autoconfiguration https://developer.mozilla.org/en/Thunderbird/Autoconfiguration https://ispdb.mozillamessaging.com/ */ class Ispdb : public QObject { Q_OBJECT public: enum socketType { None = 0, SSL, StartTLS }; /** Ispdb uses custom authtyps, hence the enum here. @see https://wiki.mozilla.org/Thunderbird:Autoconfiguration:ConfigFileFormat In particular, note that Ispdb's Plain represents both Cleartext and AUTH Plain We will always treat it as Cleartext */ enum authType { Plain = 0, CramMD5, NTLM, GSSAPI, ClientIP, NoAuth, Basic, OAuth2 }; enum length { Long = 0, Short }; /** Constructor */ explicit Ispdb(QObject *parent = nullptr); /** Destructor */ ~Ispdb(); /** After finished() has been emitted you can retrieve the domains that are covered by these settings */ QStringList relevantDomains() const; /** After finished() has been emitted you can get the name of the provider, you can get a long name and a short one */ QString name(length) const; /** After finished() has been emitted you can get a list of imap servers available for this provider */ QVector< Server > imapServers() const; /** After finished() has been emitted you can get a list of pop3 servers available for this provider */ QVector pop3Servers() const; /** After finished() has been emitted you can get a list of smtp servers available for this provider */ QVector< Server > smtpServers() const; QVector< identity > identities() const; int defaultIdentity() const; public Q_SLOTS: /** Sets the emailaddress you want to servers for */ void setEmail(const QString &); /** Sets the password for login */ void setPassword(const QString &); /** Starts looking up the servers which belong to the e-mailaddress */ void start(); private: void slotResult(KJob *); Q_SIGNALS: /** emitted when done. **/ void finished(bool); void searchType(const QString &type); protected: /** search types, where to search for autoconfig @see lookupUrl to geneerate a url base on this type */ enum searchServerType { IspAutoConfig = 0, /**< http://autoconfig.example.com/mail/config-v1.1.xml */ IspWellKnow, /**< http://example.com/.well-known/autoconfig/mail/config-v1.1.xml */ DataBase /**< https://autoconfig.thunderbird.net/v1.1/example.com */ }; /** let's request the autoconfig server */ virtual void startJob(const QUrl &url); /** generate url and start job afterwards */ virtual void lookupInDb(bool auth, bool crypt); /** an valid xml document is available, parse it and create all the objects should run createServer, createIdentity, ... */ virtual void parseResult(const QDomDocument &document); /** create a server object out of an element */ virtual Server createServer(const QDomElement &n); /** create a identity object out of an element */ virtual identity createIdentity(const QDomElement &n); /** get standard urls for autoconfig @return the standard url for autoconfig depends on serverType @param type of request (ex. "mail") @param version of the file (example for mail "1.1") - @param auth use authentification with username & password to access autoconfig file + @param auth use authentication with username & password to access autoconfig file (username is the emailaddress) @param crypt use https */ QUrl lookupUrl(const QString &type, const QString &version, bool auth, bool crypt); /** setter for serverType */ void setServerType(Ispdb::searchServerType type); /** getter for serverType */ Ispdb::searchServerType serverType() const; /** replaces %EMAILLOCALPART%, %EMAILADDRESS% and %EMAILDOMAIN% with the parts of the emailaddress */ QString replacePlaceholders(const QString &); QByteArray mData; /** storage of incoming data from kio */ protected Q_SLOTS: /** slot for TransferJob to dump data */ void dataArrived(KIO::Job *, const QByteArray &data); private: KMime::Types::AddrSpec mAddr; // emailaddress QString mPassword; // storage of the results QStringList mDomains; QString mDisplayName; QString mDisplayShortName; QVector< Server > mImapServers; QVector< Server > mPop3Servers; QVector< Server > mSmtpServers; QVector< identity > mIdentities; int mDefaultIdentity = -1; Ispdb::searchServerType mServerType; bool mStart = true; }; struct Server { Server() { } bool isValid() const { return port != -1; } Ispdb::authType authentication = Ispdb::Plain; Ispdb::socketType socketType = Ispdb::None; QString hostname; QString username; int port = -1; }; struct identity { identity() { } bool isValid() const { return !name.isEmpty(); } bool isDefault() const { return mDefault; } QString email; QString name; QString organization; QString signature; bool mDefault = false; }; #endif diff --git a/src/personaldatapage.cpp b/src/personaldatapage.cpp index 3963cae..0d0842f 100644 --- a/src/personaldatapage.cpp +++ b/src/personaldatapage.cpp @@ -1,329 +1,329 @@ /* Copyright (c) 2009 Volker Krause Copyright (c) 2010 Tom Albers Copyright (C) 2012-2018 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "personaldatapage.h" -#include "config-enterprise.h" +#include #include "global.h" #include "dialog.h" #include "transport.h" #include "resource.h" #include "ispdb/ispdb.h" #include #include #include #include "accountwizard_debug.h" QString accountName(Ispdb *ispdb, QString username) { const int pos(username.indexOf(QLatin1Char('@'))); username = username.left(pos); return ispdb->name(Ispdb::Long) + QStringLiteral(" (%1)").arg(username); } PersonalDataPage::PersonalDataPage(Dialog *parent) : Page(parent) , mIspdb(nullptr) , mSetupManager(parent->setupManager()) { QWidget *pageParent = this; ui.setupUi(pageParent); KPIM::EmailValidator *emailValidator = new KPIM::EmailValidator(this); ui.emailEdit->setValidator(emailValidator); // KEmailSettings defaults ui.nameEdit->setText(mSetupManager->name()); ui.emailEdit->setText(mSetupManager->email()); slotTextChanged(); connect(ui.emailEdit, &QLineEdit::textChanged, this, &PersonalDataPage::slotTextChanged); connect(ui.nameEdit, &QLineEdit::textChanged, this, &PersonalDataPage::slotTextChanged); connect(ui.createAccountPb, &QPushButton::clicked, this, &PersonalDataPage::slotCreateAccountClicked); connect(ui.buttonGroup, QOverload::of(&QButtonGroup::buttonClicked), this, &PersonalDataPage::slotRadioButtonClicked); #ifdef KDEPIM_ENTERPRISE_BUILD ui.checkOnlineGroupBox->setChecked(false); #endif } void PersonalDataPage::setHideOptionInternetSearch(bool hide) { ui.checkOnlineGroupBox->setChecked(!hide); ui.checkOnlineGroupBox->setVisible(!hide); } void PersonalDataPage::slotRadioButtonClicked(QAbstractButton *button) { QString smptHostname; if (!mIspdb->smtpServers().isEmpty()) { Server s = mIspdb->smtpServers().at(0); smptHostname = s.hostname; } ui.outgoingLabel->setText(i18n("SMTP, %1", smptHostname)); if (button == ui.imapAccount) { Server simap = mIspdb->imapServers().at(0); // should be ok. ui.incommingLabel->setText(i18n("IMAP, %1", simap.hostname)); ui.usernameLabel->setText(simap.username); } else if (button == ui.pop3Account) { Server spop3 = mIspdb->pop3Servers().at(0); // should be ok. ui.incommingLabel->setText(i18n("POP3, %1", spop3.hostname)); ui.usernameLabel->setText(spop3.username); } } void PersonalDataPage::slotCreateAccountClicked() { configureSmtpAccount(); if (ui.imapAccount->isChecked()) { configureImapAccount(); } else { configurePop3Account(); } Q_EMIT leavePageNextOk(); // go to the next page mSetupManager->execute(); } void PersonalDataPage::slotTextChanged() { // Ignore the password field, as that can be empty when auth is based on ip-address. setValid(!ui.emailEdit->text().isEmpty() && !ui.nameEdit->text().isEmpty() && KEmailAddress::isValidSimpleAddress(ui.emailEdit->text())); } void PersonalDataPage::leavePageNext() { ui.stackedPage->setCurrentIndex(0); ui.imapAccount->setChecked(true); mSetupManager->setPersonalDataAvailable(true); mSetupManager->setName(ui.nameEdit->text()); mSetupManager->setPassword(ui.passwordEdit->text()); mSetupManager->setEmail(ui.emailEdit->text().trimmed()); if (ui.checkOnlineGroupBox->isChecked()) { // since the user can go back and forth, explicitly disable the man page Q_EMIT manualWanted(false); setCursor(Qt::BusyCursor); ui.mProgress->start(); qCDebug(ACCOUNTWIZARD_LOG) << "Searching on internet"; delete mIspdb; mIspdb = new Ispdb(this); connect(mIspdb, &Ispdb::searchType, this, &PersonalDataPage::slotSearchType); mIspdb->setEmail(ui.emailEdit->text()); mIspdb->start(); connect(mIspdb, &Ispdb::finished, this, &PersonalDataPage::ispdbSearchFinished); } else { Q_EMIT manualWanted(true); // enable the manual page Q_EMIT leavePageNextOk(); // go to the next page } } void PersonalDataPage::ispdbSearchFinished(bool ok) { qCDebug(ACCOUNTWIZARD_LOG) << ok; unsetCursor(); ui.mProgress->stop(); if (ok) { if (!mIspdb->imapServers().isEmpty() && !mIspdb->pop3Servers().isEmpty()) { ui.stackedPage->setCurrentIndex(1); slotRadioButtonClicked(ui.imapAccount); } else { automaticConfigureAccount(); } } else { Q_EMIT manualWanted(true); // enable the manual page Q_EMIT leavePageNextOk(); } } void PersonalDataPage::slotSearchType(const QString &type) { ui.mProgress->setActiveLabel(type); } void PersonalDataPage::configureSmtpAccount() { if (!mIspdb->smtpServers().isEmpty()) { Server s = mIspdb->smtpServers().at(0); // should be ok. qCDebug(ACCOUNTWIZARD_LOG) << "Configuring transport for" << s.hostname; QObject *object = mSetupManager->createTransport(QStringLiteral("smtp")); Transport *t = qobject_cast(object); t->setName(accountName(mIspdb, s.username)); t->setHost(s.hostname); t->setPort(s.port); t->setUsername(s.username); t->setPassword(ui.passwordEdit->text()); switch (s.authentication) { case Ispdb::Plain: t->setAuthenticationType(QStringLiteral("plain")); break; case Ispdb::CramMD5: t->setAuthenticationType(QStringLiteral("cram-md5")); break; case Ispdb::NTLM: t->setAuthenticationType(QStringLiteral("ntlm")); break; case Ispdb::GSSAPI: t->setAuthenticationType(QStringLiteral("gssapi")); break; case Ispdb::ClientIP: break; case Ispdb::NoAuth: break; default: break; } switch (s.socketType) { case Ispdb::None: t->setEncryption(QStringLiteral("none")); break; case Ispdb::SSL: t->setEncryption(QStringLiteral("ssl")); break; case Ispdb::StartTLS: t->setEncryption(QStringLiteral("tls")); break; default: break; } } else { qCDebug(ACCOUNTWIZARD_LOG) << "No transport to be created...."; } } void PersonalDataPage::configureImapAccount() { if (!mIspdb->imapServers().isEmpty()) { Server s = mIspdb->imapServers().at(0); // should be ok. qCDebug(ACCOUNTWIZARD_LOG) << "Configuring imap for" << s.hostname; QObject *object = mSetupManager->createResource(QStringLiteral("akonadi_imap_resource")); Resource *t = qobject_cast(object); t->setName(accountName(mIspdb, s.username)); t->setOption(QStringLiteral("ImapServer"), s.hostname); t->setOption(QStringLiteral("ImapPort"), s.port); t->setOption(QStringLiteral("UserName"), s.username); t->setOption(QStringLiteral("Password"), ui.passwordEdit->text()); switch (s.authentication) { case Ispdb::Plain: t->setOption(QStringLiteral("Authentication"), MailTransport::Transport::EnumAuthenticationType::CLEAR); break; case Ispdb::CramMD5: t->setOption(QStringLiteral("Authentication"), MailTransport::Transport::EnumAuthenticationType::CRAM_MD5); break; case Ispdb::NTLM: t->setOption(QStringLiteral("Authentication"), MailTransport::Transport::EnumAuthenticationType::NTLM); break; case Ispdb::GSSAPI: t->setOption(QStringLiteral("Authentication"), MailTransport::Transport::EnumAuthenticationType::GSSAPI); break; case Ispdb::ClientIP: break; case Ispdb::NoAuth: break; case Ispdb::OAuth2: t->setOption(QStringLiteral("Authentication"), MailTransport::Transport::EnumAuthenticationType::XOAUTH2); break; default: break; } switch (s.socketType) { case Ispdb::None: t->setOption(QStringLiteral("Safety"), QStringLiteral("None")); break; case Ispdb::SSL: t->setOption(QStringLiteral("Safety"), QStringLiteral("SSL")); break; case Ispdb::StartTLS: t->setOption(QStringLiteral("Safety"), QStringLiteral("STARTTLS")); break; default: break; } } } void PersonalDataPage::configurePop3Account() { if (!mIspdb->pop3Servers().isEmpty()) { Server s = mIspdb->pop3Servers().at(0); // should be ok. qCDebug(ACCOUNTWIZARD_LOG) << "No Imap to be created, configuring pop3 for" << s.hostname; QObject *object = mSetupManager->createResource(QStringLiteral("akonadi_pop3_resource")); Resource *t = qobject_cast(object); t->setName(accountName(mIspdb, s.username)); t->setOption(QStringLiteral("Host"), s.hostname); t->setOption(QStringLiteral("Port"), s.port); t->setOption(QStringLiteral("Login"), s.username); t->setOption(QStringLiteral("Password"), ui.passwordEdit->text()); switch (s.authentication) { case Ispdb::Plain: t->setOption(QStringLiteral("AuthenticationMethod"), MailTransport::Transport::EnumAuthenticationType::PLAIN); break; case Ispdb::CramMD5: t->setOption(QStringLiteral("AuthenticationMethod"), MailTransport::Transport::EnumAuthenticationType::CRAM_MD5); break; case Ispdb::NTLM: t->setOption(QStringLiteral("AuthenticationMethod"), MailTransport::Transport::EnumAuthenticationType::NTLM); break; case Ispdb::GSSAPI: t->setOption(QStringLiteral("AuthenticationMethod"), MailTransport::Transport::EnumAuthenticationType::GSSAPI); break; case Ispdb::ClientIP: case Ispdb::NoAuth: default: t->setOption(QStringLiteral("AuthenticationMethod"), MailTransport::Transport::EnumAuthenticationType::CLEAR); break; } switch (s.socketType) { case Ispdb::SSL: t->setOption(QStringLiteral("UseSSL"), 1); break; case Ispdb::StartTLS: t->setOption(QStringLiteral("UseTLS"), 1); break; case Ispdb::None: default: t->setOption(QStringLiteral("UseTLS"), 1); break; } } } void PersonalDataPage::automaticConfigureAccount() { configureSmtpAccount(); configureImapAccount(); configurePop3Account(); Q_EMIT leavePageNextOk(); // go to the next page mSetupManager->execute(); } void PersonalDataPage::leavePageNextRequested() { // override base class with doing nothing... } diff --git a/src/resource.cpp b/src/resource.cpp index 07ff210..7fcf63a 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -1,187 +1,187 @@ /* Copyright (c) 2009 Volker Krause This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "resource.h" #include #include #include #include "accountwizard_debug.h" #include #include #include -#include -#include +#include +#include using namespace Akonadi; static QVariant::Type argumentType(const QMetaObject *mo, const QString &method) { QMetaMethod m; const int numberOfMethod(mo->methodCount()); for (int i = 0; i < numberOfMethod; ++i) { const QString signature = QLatin1String(mo->method(i).methodSignature()); if (signature.contains(method + QLatin1Char('('))) { m = mo->method(i); break; } } if (m.methodSignature().isEmpty()) { qCWarning(ACCOUNTWIZARD_LOG) << "Did not find D-Bus method: " << method << " available methods are:"; const int numberOfMethod(mo->methodCount()); for (int i = 0; i < numberOfMethod; ++i) { qCWarning(ACCOUNTWIZARD_LOG) << mo->method(i).methodSignature(); } return QVariant::Invalid; } const QList argTypes = m.parameterTypes(); if (argTypes.count() != 1) { return QVariant::Invalid; } return QVariant::nameToType(argTypes.first().constData()); } Resource::Resource(const QString &type, QObject *parent) : SetupObject(parent) , m_typeIdentifier(type) , m_editMode(false) { } void Resource::setOption(const QString &key, const QVariant &value) { m_settings.insert(key, value); } void Resource::setName(const QString &name) { m_name = name; } void Resource::create() { const AgentType type = AgentManager::self()->type(m_typeIdentifier); if (!type.isValid()) { Q_EMIT error(i18n("Resource type '%1' is not available.", m_typeIdentifier)); return; } // check if unique instance already exists qCDebug(ACCOUNTWIZARD_LOG) << type.capabilities(); if (type.capabilities().contains(QLatin1String("Unique"))) { const Akonadi::AgentInstance::List lstAgent = AgentManager::self()->instances(); for (const AgentInstance &instance : lstAgent) { qCDebug(ACCOUNTWIZARD_LOG) << instance.type().identifier() << (instance.type() == type); if (instance.type() == type) { if (m_editMode) { edit(); } Q_EMIT finished(i18n("Resource '%1' is already set up.", type.name())); return; } } } Q_EMIT info(i18n("Creating resource instance for '%1'...", type.name())); AgentInstanceCreateJob *job = new AgentInstanceCreateJob(type, this); connect(job, &AgentInstanceCreateJob::result, this, &Resource::instanceCreateResult); job->start(); } void Resource::instanceCreateResult(KJob *job) { if (job->error()) { Q_EMIT error(i18n("Failed to create resource instance: %1", job->errorText())); return; } m_instance = qobject_cast(job)->instance(); if (!m_settings.isEmpty()) { Q_EMIT info(i18n("Configuring resource instance...")); QDBusInterface iface(QStringLiteral("org.freedesktop.Akonadi.Resource.") + m_instance.identifier(), QStringLiteral("/Settings")); if (!iface.isValid()) { Q_EMIT error(i18n("Unable to configure resource instance.")); return; } // configure resource if (!m_name.isEmpty()) { m_instance.setName(m_name); } QMap::const_iterator end(m_settings.constEnd()); for (QMap::const_iterator it = m_settings.constBegin(); it != end; ++it) { qCDebug(ACCOUNTWIZARD_LOG) << "Setting up " << it.key() << " for agent " << m_instance.identifier(); const QString methodName = QStringLiteral("set%1").arg(it.key()); QVariant arg = it.value(); const QVariant::Type targetType = argumentType(iface.metaObject(), methodName); if (!arg.canConvert(targetType)) { Q_EMIT error(i18n("Could not convert value of setting '%1' to required type %2.", it.key(), QLatin1String(QVariant::typeToName(targetType)))); return; } arg.convert(targetType); QDBusReply reply = iface.call(methodName, arg); if (!reply.isValid()) { Q_EMIT error(i18n("Could not set setting '%1': %2", it.key(), reply.error().message())); return; } } m_instance.reconfigure(); } if (m_editMode) { edit(); } Q_EMIT finished(i18n("Resource setup completed.")); } void Resource::edit() { if (m_instance.isValid()) { m_instance.configure(); } } void Resource::destroy() { if (m_instance.isValid()) { AgentManager::self()->removeInstance(m_instance); Q_EMIT info(i18n("Removed resource instance for '%1'.", m_instance.type().name())); } } QString Resource::identifier() { return m_instance.identifier(); } void Resource::reconfigure() { m_instance.reconfigure(); } void Resource::setEditMode(const bool editMode) { m_editMode = editMode; } diff --git a/src/setupispdb.cpp b/src/setupispdb.cpp index b6d5314..403ee9d 100644 --- a/src/setupispdb.cpp +++ b/src/setupispdb.cpp @@ -1,180 +1,180 @@ /* Copyright (c) 2014 Sandro Knauß This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "setupispdb.h" #include "ispdb/ispdb.h" #include "identity.h" #include "resource.h" #include "transport.h" #include "ldap.h" #include "configfile.h" #include SetupIspdb::SetupIspdb(QObject *parent) : SetupObject(parent) { mIspdb = new Ispdb(this); connect(mIspdb, &Ispdb::finished, this, &SetupIspdb::onIspdbFinished); } SetupIspdb::~SetupIspdb() { delete mIspdb; } QStringList SetupIspdb::relevantDomains() const { return mIspdb->relevantDomains(); } QString SetupIspdb::name(int l) const { return mIspdb->name(static_cast(l)); } int SetupIspdb::defaultIdentity() const { return mIspdb->defaultIdentity(); } int SetupIspdb::countIdentities() const { return mIspdb->identities().count(); } void SetupIspdb::fillIdentity(int i, QObject *o) const { identity isp = mIspdb->identities().at(i); Identity *id = qobject_cast(o); id->setIdentityName(isp.name); id->setRealName(isp.name); id->setEmail(isp.email); id->setOrganization(isp.organization); id->setSignature(isp.signature); } void SetupIspdb::fillImapServer(int i, QObject *o) const { if (mIspdb->imapServers().isEmpty()) { return; } Server isp = mIspdb->imapServers().at(i); Resource *imapRes = qobject_cast(o); imapRes->setName(isp.hostname); imapRes->setOption(QStringLiteral("ImapServer"), isp.hostname); imapRes->setOption(QStringLiteral("UserName"), isp.username); imapRes->setOption(QStringLiteral("ImapPort"), isp.port); - imapRes->setOption(QStringLiteral("Authentication"), isp.authentication); //TODO: setup with right authentification + imapRes->setOption(QStringLiteral("Authentication"), isp.authentication); //TODO: setup with right authentication if (isp.socketType == Ispdb::None) { imapRes->setOption(QStringLiteral("Safety"), QStringLiteral("NONE")); } else if (isp.socketType == Ispdb::SSL) { imapRes->setOption(QStringLiteral("Safety"), QStringLiteral("SSL")); } else { imapRes->setOption(QStringLiteral("Safety"), QStringLiteral("STARTTLS")); } } int SetupIspdb::countImapServers() const { return mIspdb->imapServers().count(); } void SetupIspdb::fillSmtpServer(int i, QObject *o) const { Server isp = mIspdb->smtpServers().at(i); Transport *smtpRes = qobject_cast(o); smtpRes->setName(isp.hostname); smtpRes->setHost(isp.hostname); smtpRes->setPort(isp.port); smtpRes->setUsername(isp.username); switch (isp.authentication) { case Ispdb::Plain: smtpRes->setAuthenticationType(QStringLiteral("plain")); break; case Ispdb::CramMD5: smtpRes->setAuthenticationType(QStringLiteral("cram-md5")); break; case Ispdb::NTLM: smtpRes->setAuthenticationType(QStringLiteral("ntlm")); break; case Ispdb::GSSAPI: smtpRes->setAuthenticationType(QStringLiteral("gssapi")); break; case Ispdb::ClientIP: case Ispdb::NoAuth: default: break; } switch (isp.socketType) { case Ispdb::None: smtpRes->setEncryption(QStringLiteral("none")); break; case Ispdb::SSL: smtpRes->setEncryption(QStringLiteral("ssl")); break; case Ispdb::StartTLS: smtpRes->setEncryption(QStringLiteral("tls")); break; } } int SetupIspdb::countSmtpServers() const { return mIspdb->smtpServers().count(); } void SetupIspdb::start() { mIspdb->start(); Q_EMIT info(i18n("Searching for autoconfiguration...")); } void SetupIspdb::setEmail(const QString &email) { mIspdb->setEmail(email); } void SetupIspdb::setPassword(const QString &password) { mIspdb->setPassword(password); } void SetupIspdb::create() { } void SetupIspdb::destroy() { } void SetupIspdb::onIspdbFinished(bool status) { Q_EMIT ispdbFinished(status); if (status) { Q_EMIT info(i18n("Autoconfiguration found.")); } else { Q_EMIT info(i18n("Autoconfiguration failed.")); } } diff --git a/src/setupmanager.cpp b/src/setupmanager.cpp index af784fa..050d1a4 100644 --- a/src/setupmanager.cpp +++ b/src/setupmanager.cpp @@ -1,331 +1,331 @@ /* Copyright (c) 2009 Volker Krause This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "setupmanager.h" #include "resource.h" #include "setuppage.h" #include "transport.h" #include "configfile.h" #include "ldap.h" #include "identity.h" #include "setupispdb.h" #include "setupautoconfigkolabmail.h" #include "setupautoconfigkolabldap.h" #include "setupautoconfigkolabfreebusy.h" #include "key.h" #include #include #include #include SetupManager::SetupManager(QWidget *parent) : QObject(parent) , m_currentSetupObject(nullptr) , m_page(nullptr) , m_wallet(nullptr) , m_keyPublishingMethod(Key::NoPublishing) , m_personalDataAvailable(false) , m_rollbackRequested(false) , m_pgpAutoSign(false) , m_pgpAutoEncrypt(false) { KEMailSettings e; m_name = e.getSetting(KEMailSettings::RealName); m_email = e.getSetting(KEMailSettings::EmailAddress); } SetupManager::~SetupManager() { delete m_wallet; } void SetupManager::setSetupPage(SetupPage *page) { m_page = page; } QObject *SetupManager::createResource(const QString &type) { return connectObject(new Resource(type, this)); } QObject *SetupManager::createTransport(const QString &type) { return connectObject(new Transport(type, this)); } QObject *SetupManager::createConfigFile(const QString &fileName) { return connectObject(new ConfigFile(fileName, this)); } QObject *SetupManager::createLdap() { return connectObject(new Ldap(this)); } QObject *SetupManager::createIdentity() { Identity *identity = new Identity(this); identity->setEmail(m_email); identity->setRealName(m_name); identity->setPgpAutoSign(m_pgpAutoSign); identity->setPgpAutoEncrypt(m_pgpAutoEncrypt); identity->setKey(m_key.protocol(), m_key.primaryFingerprint()); return connectObject(identity); } QObject *SetupManager::createKey() { Key *key = new Key(this); key->setKey(m_key); key->setMailBox(m_email); key->setPublishingMethod(m_keyPublishingMethod); return connectObject(key); } QList SetupManager::objectsToSetup() const { return m_objectToSetup; } QList SetupManager::setupObjects() const { return m_setupObjects; } static bool dependencyCompare(SetupObject *left, SetupObject *right) { if (!left->dependsOn() && right->dependsOn()) { return true; } return false; } void SetupManager::execute() { if (m_keyPublishingMethod != Key::NoPublishing) { auto key = qobject_cast(createKey()); auto it = std::find_if(m_setupObjects.cbegin(), m_setupObjects.cend(), [](SetupObject *obj) -> bool { return qobject_cast(obj); }); if (it != m_setupObjects.cend()) { key->setDependsOn(*it); } } m_page->setStatus(i18n("Setting up account...")); m_page->setValid(false); m_page->assistantDialog()->backButton()->setEnabled(false); // ### FIXME this is a bad over-simplification and would need a real topological sort // but for current usage it is good enough std::stable_sort(m_objectToSetup.begin(), m_objectToSetup.end(), dependencyCompare); setupNext(); } void SetupManager::setupSucceeded(const QString &msg) { Q_ASSERT(m_page); m_page->addMessage(SetupPage::Success, msg); if (m_currentSetupObject) { Q_EMIT setupFinished(m_currentSetupObject); m_setupObjects.append(m_currentSetupObject); m_currentSetupObject = nullptr; } setupNext(); } void SetupManager::setupFailed(const QString &msg) { Q_ASSERT(m_page); m_page->addMessage(SetupPage::Error, msg); if (m_currentSetupObject) { m_setupObjects.append(m_currentSetupObject); m_currentSetupObject = nullptr; } rollback(); } void SetupManager::setupInfo(const QString &msg) { Q_ASSERT(m_page); m_page->addMessage(SetupPage::Info, msg); } void SetupManager::setupNext() { - // user canceld during the previous setup step + // user canceled during the previous setup step if (m_rollbackRequested) { rollback(); return; } if (m_objectToSetup.isEmpty()) { m_page->setStatus(i18n("Setup complete.")); m_page->setProgress(100); m_page->setValid(true); m_page->assistantDialog()->backButton()->setEnabled(false); } else { const int setupObjectCount = m_objectToSetup.size() + m_setupObjects.size(); const int remainingObjectCount = setupObjectCount - m_objectToSetup.size(); m_page->setProgress((remainingObjectCount * 100) / setupObjectCount); m_currentSetupObject = m_objectToSetup.takeFirst(); m_currentSetupObject->create(); } } void SetupManager::rollback() { m_page->setStatus(i18n("Failed to set up account, rolling back...")); const int setupObjectCount = m_objectToSetup.size() + m_setupObjects.size(); int remainingObjectCount = m_setupObjects.size(); foreach (SetupObject *obj, m_setupObjects) { m_page->setProgress((remainingObjectCount * 100) / setupObjectCount); if (obj) { obj->destroy(); m_objectToSetup.prepend(obj); } } m_setupObjects.clear(); m_page->setProgress(0); m_page->setStatus(i18n("Failed to set up account.")); m_page->setValid(true); m_rollbackRequested = false; Q_EMIT rollbackComplete(); } SetupObject *SetupManager::connectObject(SetupObject *obj) { connect(obj, &SetupObject::finished, this, &SetupManager::setupSucceeded); connect(obj, &SetupObject::info, this, &SetupManager::setupInfo); connect(obj, &SetupObject::error, this, &SetupManager::setupFailed); m_objectToSetup.append(obj); return obj; } void SetupManager::setName(const QString &name) { m_name = name; } QString SetupManager::name() { return m_name; } void SetupManager::setEmail(const QString &email) { m_email = email; } QString SetupManager::email() { return m_email; } void SetupManager::setPassword(const QString &password) { m_password = password; } QString SetupManager::password() { return m_password; } QString SetupManager::country() { return QLocale::countryToString(QLocale().country()); } void SetupManager::setPgpAutoEncrypt(bool autoencrypt) { m_pgpAutoEncrypt = autoencrypt; } void SetupManager::setPgpAutoSign(bool autosign) { m_pgpAutoSign = autosign; } void SetupManager::setKey(const GpgME::Key &key) { m_key = key; } void SetupManager::setKeyPublishingMethod(Key::PublishingMethod method) { m_keyPublishingMethod = method; } void SetupManager::openWallet() { using namespace KWallet; if (Wallet::isOpen(Wallet::NetworkWallet())) { return; } Q_ASSERT(parent()->isWidgetType()); m_wallet = Wallet::openWallet(Wallet::NetworkWallet(), qobject_cast(parent())->effectiveWinId(), Wallet::Asynchronous); QEventLoop loop; connect(m_wallet, &KWallet::Wallet::walletOpened, &loop, &QEventLoop::quit); loop.exec(); } bool SetupManager::personalDataAvailable() { return m_personalDataAvailable; } void SetupManager::setPersonalDataAvailable(bool available) { m_personalDataAvailable = available; } QObject *SetupManager::ispDB(const QString &type) { const QString t = type.toLower(); if (t == QLatin1String("autoconfigkolabmail")) { return new SetupAutoconfigKolabMail(this); } else if (t == QLatin1String("autoconfigkolabldap")) { return new SetupAutoconfigKolabLdap(this); } else if (t == QLatin1String("autoconfigkolabfreebusy")) { return new SetupAutoconfigKolabFreebusy(this); } else if (t == QLatin1String("ispdb")) { return new SetupIspdb(this); } else { return new SetupIspdb(this); } } void SetupManager::requestRollback() { if (m_setupObjects.isEmpty()) { Q_EMIT rollbackComplete(); } else { m_rollbackRequested = true; if (!m_currentSetupObject) { rollback(); } } }