1 /* This file is part of the KDE project
2
3 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
4 SPDX-FileContributor: Kevin Ottens <kevin@kdab.com>
5
6 SPDX-FileCopyrightText: 2010 Casey Link <unnamedrambler@gmail.com>
7 SPDX-FileCopyrightText: 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
8 SPDX-FileCopyrightText: 2009 Kevin Ottens <ervin@kde.org>
9 SPDX-FileCopyrightText: 2006-2008 Omat Holding B.V. <info@omat.nl>
10 SPDX-FileCopyrightText: 2006 Frode M. Døving <frode@lnix.net>
11
12 Original copied from showfoto:
13 SPDX-FileCopyrightText: 2005 Gilles Caulier <caulier.gilles@free.fr>
14
15 SPDX-License-Identifier: GPL-2.0-or-later
16 */
17
18 #include "setupserver.h"
19 #include "folderarchivesettingpage.h"
20 #include "imapresource.h"
21 #include "serverinfodialog.h"
22 #include "settings.h"
23 #include "utils.h"
24 #include <config-imap.h>
25
26 #include <Libkdepim/LineEditCatchReturnKey>
27 #include <MailTransport/ServerTest>
28 #include <MailTransport/Transport>
29
30 #include <KMime/Message>
31
32 #include "imapresource_debug.h"
33 #include <Akonadi/CollectionFetchJob>
34 #include <Akonadi/CollectionModifyJob>
35 #include <Akonadi/EntityDisplayAttribute>
36 #include <Akonadi/KMime/SpecialMailCollections>
37 #include <Akonadi/KMime/SpecialMailCollectionsRequestJob>
38 #include <Akonadi/ResourceSettings>
39 #include <KAuthorized>
40 #include <KEMailSettings>
41 #include <KLocalizedString>
42 #include <KMessageBox>
43 #include <KUser>
44 #include <QNetworkConfigurationManager>
45 #include <QPushButton>
46
47 #include <KIdentityManagement/IdentityCombo>
48 #include <KIdentityManagement/IdentityManager>
49 #include <QFontDatabase>
50 #include <QPointer>
51 #include <QVBoxLayout>
52
53 #include "imapaccount.h"
54 #include "subscriptiondialog.h"
55
56 #include "ui_setupserverview_desktop.h"
57
58 /** static helper functions **/
authenticationModeString(MailTransport::Transport::EnumAuthenticationType::type mode)59 static QString authenticationModeString(MailTransport::Transport::EnumAuthenticationType::type mode)
60 {
61 switch (mode) {
62 case MailTransport::Transport::EnumAuthenticationType::LOGIN:
63 return QStringLiteral("LOGIN");
64 case MailTransport::Transport::EnumAuthenticationType::PLAIN:
65 return QStringLiteral("PLAIN");
66 case MailTransport::Transport::EnumAuthenticationType::CRAM_MD5:
67 return QStringLiteral("CRAM-MD5");
68 case MailTransport::Transport::EnumAuthenticationType::DIGEST_MD5:
69 return QStringLiteral("DIGEST-MD5");
70 case MailTransport::Transport::EnumAuthenticationType::GSSAPI:
71 return QStringLiteral("GSSAPI");
72 case MailTransport::Transport::EnumAuthenticationType::NTLM:
73 return QStringLiteral("NTLM");
74 case MailTransport::Transport::EnumAuthenticationType::CLEAR:
75 return i18nc("Authentication method", "Clear text");
76 case MailTransport::Transport::EnumAuthenticationType::ANONYMOUS:
77 return i18nc("Authentication method", "Anonymous");
78 case MailTransport::Transport::EnumAuthenticationType::XOAUTH2:
79 return i18nc("Authentication method", "Gmail");
80 default:
81 break;
82 }
83 return QString();
84 }
85
setCurrentAuthMode(QComboBox * authCombo,MailTransport::Transport::EnumAuthenticationType::type authtype)86 static void setCurrentAuthMode(QComboBox *authCombo, MailTransport::Transport::EnumAuthenticationType::type authtype)
87 {
88 qCDebug(IMAPRESOURCE_LOG) << "setting authcombo: " << authenticationModeString(authtype);
89 int index = authCombo->findData(authtype);
90 if (index == -1) {
91 qCWarning(IMAPRESOURCE_LOG) << "desired authmode not in the combo";
92 }
93 qCDebug(IMAPRESOURCE_LOG) << "found corresponding index: " << index << "with data"
94 << authenticationModeString((MailTransport::Transport::EnumAuthenticationType::type)authCombo->itemData(index).toInt());
95 authCombo->setCurrentIndex(index);
96 MailTransport::Transport::EnumAuthenticationType::type t =
97 (MailTransport::Transport::EnumAuthenticationType::type)authCombo->itemData(authCombo->currentIndex()).toInt();
98 qCDebug(IMAPRESOURCE_LOG) << "selected auth mode:" << authenticationModeString(t);
99 Q_ASSERT(t == authtype);
100 }
101
getCurrentAuthMode(QComboBox * authCombo)102 static MailTransport::Transport::EnumAuthenticationType::type getCurrentAuthMode(QComboBox *authCombo)
103 {
104 MailTransport::Transport::EnumAuthenticationType::type authtype =
105 (MailTransport::Transport::EnumAuthenticationType::type)authCombo->itemData(authCombo->currentIndex()).toInt();
106 qCDebug(IMAPRESOURCE_LOG) << "current auth mode: " << authenticationModeString(authtype);
107 return authtype;
108 }
109
addAuthenticationItem(QComboBox * authCombo,MailTransport::Transport::EnumAuthenticationType::type authtype)110 static void addAuthenticationItem(QComboBox *authCombo, MailTransport::Transport::EnumAuthenticationType::type authtype)
111 {
112 qCDebug(IMAPRESOURCE_LOG) << "adding auth item " << authenticationModeString(authtype);
113 authCombo->addItem(authenticationModeString(authtype), QVariant(authtype));
114 }
115
SetupServer(ImapResourceBase * parentResource,WId parent)116 SetupServer::SetupServer(ImapResourceBase *parentResource, WId parent)
117 : QDialog()
118 , m_parentResource(parentResource)
119 , m_ui(new Ui::SetupServerView)
120 , mValidator(this)
121 {
122 auto networkConfigMgr = new QNetworkConfigurationManager(QCoreApplication::instance());
123
124 m_parentResource->settings()->setWinId(parent);
125 auto mainWidget = new QWidget(this);
126 auto mainLayout = new QVBoxLayout(this);
127 mainLayout->addWidget(mainWidget);
128 auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
129 mOkButton = buttonBox->button(QDialogButtonBox::Ok);
130 mOkButton->setDefault(true);
131 mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return);
132 connect(mOkButton, &QPushButton::clicked, this, &SetupServer::applySettings);
133 connect(buttonBox, &QDialogButtonBox::rejected, this, &SetupServer::reject);
134 mainLayout->addWidget(buttonBox);
135
136 m_ui->setupUi(mainWidget);
137 m_ui->password->setRevealPasswordAvailable(KAuthorized::authorize(QStringLiteral("lineedit_reveal_password")));
138 m_ui->customPassword->setRevealPasswordAvailable(KAuthorized::authorize(QStringLiteral("lineedit_reveal_password")));
139 new KPIM::LineEditCatchReturnKey(m_ui->accountName, this);
140 new KPIM::LineEditCatchReturnKey(m_ui->imapServer, this);
141 new KPIM::LineEditCatchReturnKey(m_ui->userName, this);
142 new KPIM::LineEditCatchReturnKey(m_ui->alternateURL, this);
143 new KPIM::LineEditCatchReturnKey(m_ui->customUsername, this);
144
145 m_folderArchiveSettingPage = new FolderArchiveSettingPage(m_parentResource->identifier());
146 m_ui->tabWidget->addTab(m_folderArchiveSettingPage, i18n("Archive Folder"));
147 m_ui->safeImapGroup->setId(m_ui->noRadio, KIMAP::LoginJob::Unencrypted);
148 m_ui->safeImapGroup->setId(m_ui->sslRadio, KIMAP::LoginJob::SSLorTLS);
149 m_ui->safeImapGroup->setId(m_ui->tlsRadio, KIMAP::LoginJob::STARTTLS);
150
151 connect(m_ui->noRadio, &QRadioButton::toggled, this, &SetupServer::slotSafetyChanged);
152 connect(m_ui->sslRadio, &QRadioButton::toggled, this, &SetupServer::slotSafetyChanged);
153 connect(m_ui->tlsRadio, &QRadioButton::toggled, this, &SetupServer::slotSafetyChanged);
154
155 m_ui->testInfo->hide();
156 m_ui->testProgress->hide();
157 m_ui->accountName->setFocus();
158 m_ui->checkInterval->setSuffix(ki18np(" minute", " minutes"));
159 m_ui->checkInterval->setMinimum(Akonadi::ResourceSettings::self()->minimumCheckInterval());
160 m_ui->checkInterval->setMaximum(10000);
161 m_ui->checkInterval->setSingleStep(1);
162 m_ui->imapInfo->setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
163
164 // regex for evaluating a valid server name/ip
165 mValidator.setRegularExpression(QRegularExpression(QStringLiteral("[A-Za-z0-9_:.-]*")));
166 m_ui->imapServer->setValidator(&mValidator);
167
168 m_ui->folderRequester->setMimeTypeFilter(QStringList() << KMime::Message::mimeType());
169 m_ui->folderRequester->setAccessRightsFilter(Akonadi::Collection::CanChangeItem | Akonadi::Collection::CanCreateItem | Akonadi::Collection::CanDeleteItem);
170 m_ui->folderRequester->changeCollectionDialogOptions(Akonadi::CollectionDialog::AllowToCreateNewChildCollection);
171 m_identityCombobox = new KIdentityManagement::IdentityCombo(KIdentityManagement::IdentityManager::self(), this);
172 m_identityCombobox->setShowDefault(true);
173 m_ui->formLayoutAdvanced->insertRow(3, i18n("Identity:"), m_identityCombobox);
174
175 connect(m_ui->testButton, &QPushButton::pressed, this, &SetupServer::slotTest);
176
177 connect(m_ui->imapServer, &QLineEdit::textChanged, this, &SetupServer::slotServerChanged);
178 connect(m_ui->imapServer, &QLineEdit::textChanged, this, &SetupServer::slotTestChanged);
179 connect(m_ui->imapServer, &QLineEdit::textChanged, this, &SetupServer::slotComplete);
180 connect(m_ui->userName, &QLineEdit::textChanged, this, &SetupServer::slotComplete);
181 connect(m_ui->subscriptionEnabled, &QCheckBox::toggled, this, &SetupServer::slotSubcriptionCheckboxChanged);
182 connect(m_ui->subscriptionButton, &QPushButton::pressed, this, &SetupServer::slotManageSubscriptions);
183
184 connect(m_ui->managesieveCheck, &QCheckBox::toggled, this, &SetupServer::slotEnableWidgets);
185 connect(m_ui->sameConfigCheck, &QCheckBox::toggled, this, &SetupServer::slotEnableWidgets);
186
187 connect(m_ui->enableMailCheckBox, &QCheckBox::toggled, this, &SetupServer::slotMailCheckboxChanged);
188 connect(m_ui->safeImapGroup, qOverload<QAbstractButton *>(&QButtonGroup::buttonClicked), this, &SetupServer::slotEncryptionRadioChanged);
189 connect(m_ui->customSieveGroup, qOverload<QAbstractButton *>(&QButtonGroup::buttonClicked), this, &SetupServer::slotCustomSieveChanged);
190 connect(m_ui->showServerInfo, &QPushButton::pressed, this, &SetupServer::slotShowServerInfo);
191
192 readSettings();
193 slotTestChanged();
194 slotComplete();
195 slotCustomSieveChanged();
196 connect(networkConfigMgr, &QNetworkConfigurationManager::onlineStateChanged, this, &SetupServer::slotTestChanged);
197 }
198
~SetupServer()199 SetupServer::~SetupServer()
200 {
201 delete m_ui;
202 }
203
shouldClearCache() const204 bool SetupServer::shouldClearCache() const
205 {
206 return m_shouldClearCache;
207 }
208
slotSubcriptionCheckboxChanged()209 void SetupServer::slotSubcriptionCheckboxChanged()
210 {
211 m_ui->subscriptionButton->setEnabled(m_ui->subscriptionEnabled->isChecked());
212 }
213
slotMailCheckboxChanged()214 void SetupServer::slotMailCheckboxChanged()
215 {
216 m_ui->checkInterval->setEnabled(m_ui->enableMailCheckBox->isChecked());
217 }
218
slotEncryptionRadioChanged()219 void SetupServer::slotEncryptionRadioChanged()
220 {
221 // TODO these really should be defined somewhere else
222 switch (m_ui->safeImapGroup->checkedId()) {
223 case KIMAP::LoginJob::Unencrypted:
224 case KIMAP::LoginJob::STARTTLS:
225 m_ui->portSpin->setValue(143);
226 break;
227 case KIMAP::LoginJob::SSLorTLS:
228 m_ui->portSpin->setValue(993);
229 break;
230 default:
231 qFatal("Shouldn't happen");
232 }
233 }
234
slotCustomSieveChanged()235 void SetupServer::slotCustomSieveChanged()
236 {
237 QAbstractButton *checkedButton = m_ui->customSieveGroup->checkedButton();
238
239 if (checkedButton == m_ui->imapUserPassword || checkedButton == m_ui->noAuthentification) {
240 m_ui->customUsername->setEnabled(false);
241 m_ui->customPassword->setEnabled(false);
242 } else if (checkedButton == m_ui->customUserPassword) {
243 m_ui->customUsername->setEnabled(true);
244 m_ui->customPassword->setEnabled(true);
245 }
246 }
247
applySettings()248 void SetupServer::applySettings()
249 {
250 if (!m_parentResource->settings()->imapServer().isEmpty() && m_ui->imapServer->text() != m_parentResource->settings()->imapServer()) {
251 if (KMessageBox::warningContinueCancel(this,
252 i18n("You have changed the address of the server. Even if this is the same server as before "
253 "we will have to re-download all your emails from this account again. "
254 "Are you sure you want to proceed?"),
255 i18n("Server address change"))
256 == KMessageBox::Cancel) {
257 return;
258 }
259 }
260 if (!m_parentResource->settings()->userName().isEmpty() && m_ui->userName->text() != m_parentResource->settings()->userName()) {
261 if (KMessageBox::warningContinueCancel(this,
262 i18n("You have changed the user name. Even if this is a user name for the same account as before "
263 "we will have to re-download all your emails from this account again. "
264 "Are you sure you want to proceed?"),
265 i18n("User name change"))
266 == KMessageBox::Cancel) {
267 return;
268 }
269 }
270
271 m_folderArchiveSettingPage->writeSettings();
272 m_shouldClearCache =
273 (m_parentResource->settings()->imapServer() != m_ui->imapServer->text()) || (m_parentResource->settings()->userName() != m_ui->userName->text());
274
275 const MailTransport::Transport::EnumAuthenticationType::type authtype = getCurrentAuthMode(m_ui->authenticationCombo);
276 if (!m_ui->userName->text().contains(QLatin1Char('@')) && authtype == MailTransport::Transport::EnumAuthenticationType::XOAUTH2
277 && m_ui->imapServer->text().contains(QLatin1String("gmail.com"))) {
278 // Normalize gmail username so that it matches the JSON account info returned by GMail authentication.
279 // If we don't do this, we will look up cached auth without @gmail.com and save it with @gmail.com => very frequent auth dialog popping up.
280 qCDebug(IMAPRESOURCE_LOG) << "Fixing up username" << m_ui->userName->text() << "by adding @gmail.com";
281 m_ui->userName->setText(m_ui->userName->text() + QLatin1String("@gmail.com"));
282 }
283
284 m_parentResource->setName(m_ui->accountName->text());
285
286 m_parentResource->settings()->setImapServer(m_ui->imapServer->text());
287 m_parentResource->settings()->setImapPort(m_ui->portSpin->value());
288 m_parentResource->settings()->setUserName(m_ui->userName->text());
289 QString encryption;
290 switch (m_ui->safeImapGroup->checkedId()) {
291 case KIMAP::LoginJob::Unencrypted:
292 encryption = QStringLiteral("None");
293 break;
294 case KIMAP::LoginJob::SSLorTLS:
295 encryption = QStringLiteral("SSL");
296 break;
297 case KIMAP::LoginJob::STARTTLS:
298 encryption = QStringLiteral("STARTTLS");
299 break;
300 default:
301 qFatal("Shouldn't happen");
302 }
303 m_parentResource->settings()->setSafety(encryption);
304
305 qCDebug(IMAPRESOURCE_LOG) << "saving IMAP auth mode: " << authenticationModeString(authtype);
306 m_parentResource->settings()->setAuthentication(authtype);
307 m_parentResource->settings()->setPassword(m_ui->password->password());
308 m_parentResource->settings()->setSubscriptionEnabled(m_ui->subscriptionEnabled->isChecked());
309 m_parentResource->settings()->setIntervalCheckTime(m_ui->checkInterval->value());
310 m_parentResource->settings()->setDisconnectedModeEnabled(m_ui->disconnectedModeEnabled->isChecked());
311 m_parentResource->settings()->setUseProxy(m_ui->useProxyCheck->isChecked());
312
313 MailTransport::Transport::EnumAuthenticationType::type alternateAuthtype = getCurrentAuthMode(m_ui->authenticationAlternateCombo);
314 qCDebug(IMAPRESOURCE_LOG) << "saving Alternate server sieve auth mode: " << authenticationModeString(alternateAuthtype);
315 m_parentResource->settings()->setAlternateAuthentication(alternateAuthtype);
316 m_parentResource->settings()->setSieveSupport(m_ui->managesieveCheck->isChecked());
317 m_parentResource->settings()->setSieveReuseConfig(m_ui->sameConfigCheck->isChecked());
318 m_parentResource->settings()->setSievePort(m_ui->sievePortSpin->value());
319 m_parentResource->settings()->setSieveAlternateUrl(m_ui->alternateURL->text());
320 m_parentResource->settings()->setSieveVacationFilename(m_vacationFileName);
321
322 m_parentResource->settings()->setTrashCollection(m_ui->folderRequester->collection().id());
323 Akonadi::Collection trash = m_ui->folderRequester->collection();
324 Akonadi::SpecialMailCollections::self()->registerCollection(Akonadi::SpecialMailCollections::Trash, trash);
325 auto attribute = trash.attribute<Akonadi::EntityDisplayAttribute>(Akonadi::Collection::AddIfMissing);
326 attribute->setIconName(QStringLiteral("user-trash"));
327 new Akonadi::CollectionModifyJob(trash);
328 if (mOldTrash != trash) {
329 Akonadi::SpecialMailCollections::self()->unregisterCollection(mOldTrash);
330 }
331
332 m_parentResource->settings()->setAutomaticExpungeEnabled(m_ui->autoExpungeCheck->isChecked());
333 m_parentResource->settings()->setUseDefaultIdentity(m_identityCombobox->isDefaultIdentity());
334
335 if (!m_identityCombobox->isDefaultIdentity()) {
336 m_parentResource->settings()->setAccountIdentity(m_identityCombobox->currentIdentity());
337 }
338
339 m_parentResource->settings()->setIntervalCheckEnabled(m_ui->enableMailCheckBox->isChecked());
340 if (m_ui->enableMailCheckBox->isChecked()) {
341 m_parentResource->settings()->setIntervalCheckTime(m_ui->checkInterval->value());
342 }
343
344 m_parentResource->settings()->setSieveCustomUsername(m_ui->customUsername->text());
345
346 QAbstractButton *checkedButton = m_ui->customSieveGroup->checkedButton();
347
348 if (checkedButton == m_ui->imapUserPassword) {
349 m_parentResource->settings()->setSieveCustomAuthentification(QStringLiteral("ImapUserPassword"));
350 } else if (checkedButton == m_ui->noAuthentification) {
351 m_parentResource->settings()->setSieveCustomAuthentification(QStringLiteral("NoAuthentification"));
352 } else if (checkedButton == m_ui->customUserPassword) {
353 m_parentResource->settings()->setSieveCustomAuthentification(QStringLiteral("CustomUserPassword"));
354 }
355
356 m_parentResource->settings()->setSieveCustomPassword(m_ui->customPassword->password());
357
358 m_parentResource->settings()->save();
359 qCDebug(IMAPRESOURCE_LOG) << "wrote" << m_ui->imapServer->text() << m_ui->userName->text() << m_ui->safeImapGroup->checkedId();
360
361 if (m_oldResourceName != m_ui->accountName->text() && !m_ui->accountName->text().isEmpty()) {
362 m_parentResource->settings()->renameRootCollection(m_ui->accountName->text());
363 }
364
365 accept();
366 }
367
readSettings()368 void SetupServer::readSettings()
369 {
370 m_folderArchiveSettingPage->loadSettings();
371 m_ui->accountName->setText(m_parentResource->name());
372 m_oldResourceName = m_ui->accountName->text();
373
374 auto currentUser = new KUser();
375 KEMailSettings esetting;
376
377 m_ui->imapServer->setText(!m_parentResource->settings()->imapServer().isEmpty() ? m_parentResource->settings()->imapServer()
378 : esetting.getSetting(KEMailSettings::InServer));
379
380 m_ui->portSpin->setValue(m_parentResource->settings()->imapPort());
381
382 m_ui->userName->setText(!m_parentResource->settings()->userName().isEmpty() ? m_parentResource->settings()->userName() : currentUser->loginName());
383
384 const QString safety = m_parentResource->settings()->safety();
385 int i = 0;
386 if (safety == QLatin1String("SSL")) {
387 i = KIMAP::LoginJob::SSLorTLS;
388 } else if (safety == QLatin1String("STARTTLS")) {
389 i = KIMAP::LoginJob::STARTTLS;
390 } else {
391 i = KIMAP::LoginJob::Unencrypted;
392 }
393
394 QAbstractButton *safetyButton = m_ui->safeImapGroup->button(i);
395 if (safetyButton) {
396 safetyButton->setChecked(true);
397 }
398
399 populateDefaultAuthenticationOptions();
400 i = m_parentResource->settings()->authentication();
401 qCDebug(IMAPRESOURCE_LOG) << "read IMAP auth mode: " << authenticationModeString(static_cast<MailTransport::Transport::EnumAuthenticationType::type>(i));
402 setCurrentAuthMode(m_ui->authenticationCombo, (MailTransport::Transport::EnumAuthenticationType::type)i);
403
404 i = m_parentResource->settings()->alternateAuthentication();
405 setCurrentAuthMode(m_ui->authenticationAlternateCombo, static_cast<MailTransport::Transport::EnumAuthenticationType::type>(i));
406
407 bool rejected = false;
408 const QString password = m_parentResource->settings()->password(&rejected);
409 if (rejected) {
410 m_ui->password->setEnabled(false);
411 KMessageBox::information(nullptr,
412 i18n("Could not access KWallet. "
413 "If you want to store the password permanently then you have to "
414 "activate it. If you do not "
415 "want to use KWallet, check the box below, but note that you will be "
416 "prompted for your password when needed."),
417 i18n("Do not use KWallet"),
418 QStringLiteral("warning_kwallet_disabled"));
419 } else {
420 m_ui->password->lineEdit()->insert(password);
421 }
422
423 m_ui->subscriptionEnabled->setChecked(m_parentResource->settings()->subscriptionEnabled());
424
425 m_ui->checkInterval->setValue(m_parentResource->settings()->intervalCheckTime());
426 m_ui->disconnectedModeEnabled->setChecked(m_parentResource->settings()->disconnectedModeEnabled());
427 m_ui->useProxyCheck->setChecked(m_parentResource->settings()->useProxy());
428
429 m_ui->managesieveCheck->setChecked(m_parentResource->settings()->sieveSupport());
430 m_ui->sameConfigCheck->setChecked(m_parentResource->settings()->sieveReuseConfig());
431 m_ui->sievePortSpin->setValue(m_parentResource->settings()->sievePort());
432 m_ui->alternateURL->setText(m_parentResource->settings()->sieveAlternateUrl());
433 m_vacationFileName = m_parentResource->settings()->sieveVacationFilename();
434
435 Akonadi::Collection trashCollection(m_parentResource->settings()->trashCollection());
436 if (trashCollection.isValid()) {
437 auto fetchJob = new Akonadi::CollectionFetchJob(trashCollection, Akonadi::CollectionFetchJob::Base, this);
438 connect(fetchJob, &Akonadi::CollectionFetchJob::collectionsReceived, this, &SetupServer::targetCollectionReceived);
439 } else {
440 auto requestJob = new Akonadi::SpecialMailCollectionsRequestJob(this);
441 connect(requestJob, &Akonadi::SpecialMailCollectionsRequestJob::result, this, &SetupServer::localFolderRequestJobFinished);
442 requestJob->requestDefaultCollection(Akonadi::SpecialMailCollections::Trash);
443 requestJob->start();
444 }
445
446 m_identityCombobox->setCurrentIdentity(m_parentResource->settings()->accountIdentity());
447
448 m_ui->enableMailCheckBox->setChecked(m_parentResource->settings()->intervalCheckEnabled());
449 if (m_ui->enableMailCheckBox->isChecked()) {
450 m_ui->checkInterval->setValue(m_parentResource->settings()->intervalCheckTime());
451 } else {
452 m_ui->checkInterval->setEnabled(false);
453 }
454
455 m_ui->autoExpungeCheck->setChecked(m_parentResource->settings()->automaticExpungeEnabled());
456
457 if (m_vacationFileName.isEmpty()) {
458 m_vacationFileName = QStringLiteral("kmail-vacation.siv");
459 }
460
461 m_ui->customUsername->setText(m_parentResource->settings()->sieveCustomUsername());
462
463 rejected = false;
464 const QString customPassword = m_parentResource->settings()->sieveCustomPassword(&rejected);
465 if (rejected) {
466 m_ui->customPassword->setEnabled(false);
467 KMessageBox::information(nullptr,
468 i18n("Could not access KWallet. "
469 "If you want to store the password permanently then you have to "
470 "activate it. If you do not "
471 "want to use KWallet, check the box below, but note that you will be "
472 "prompted for your password when needed."),
473 i18n("Do not use KWallet"),
474 QStringLiteral("warning_kwallet_disabled"));
475 } else {
476 m_ui->customPassword->lineEdit()->insert(customPassword);
477 }
478
479 const QString sieverCustomAuth(m_parentResource->settings()->sieveCustomAuthentification());
480 if (sieverCustomAuth == QLatin1String("ImapUserPassword")) {
481 m_ui->imapUserPassword->setChecked(true);
482 } else if (sieverCustomAuth == QLatin1String("NoAuthentification")) {
483 m_ui->noAuthentification->setChecked(true);
484 } else if (sieverCustomAuth == QLatin1String("CustomUserPassword")) {
485 m_ui->customUserPassword->setChecked(true);
486 }
487
488 delete currentUser;
489 }
490
slotTest()491 void SetupServer::slotTest()
492 {
493 qCDebug(IMAPRESOURCE_LOG) << m_ui->imapServer->text();
494
495 m_ui->testButton->setEnabled(false);
496 m_ui->advancedTab->setEnabled(false);
497 m_ui->authenticationCombo->setEnabled(false);
498
499 m_ui->testInfo->clear();
500 m_ui->testInfo->hide();
501
502 delete m_serverTest;
503 m_serverTest = new MailTransport::ServerTest(this);
504 #ifndef QT_NO_CURSOR
505 qApp->setOverrideCursor(Qt::BusyCursor);
506 #endif
507
508 const QString server = m_ui->imapServer->text();
509 const int port = m_ui->portSpin->value();
510 qCDebug(IMAPRESOURCE_LOG) << "server: " << server << "port: " << port;
511
512 m_serverTest->setServer(server);
513
514 if (port != 143 && port != 993) {
515 m_serverTest->setPort(MailTransport::Transport::EnumEncryption::None, port);
516 m_serverTest->setPort(MailTransport::Transport::EnumEncryption::SSL, port);
517 }
518
519 m_serverTest->setProtocol(QStringLiteral("imap"));
520 m_serverTest->setProgressBar(m_ui->testProgress);
521 connect(m_serverTest, &MailTransport::ServerTest::finished, this, &SetupServer::slotFinished);
522 mOkButton->setEnabled(false);
523 m_serverTest->start();
524 }
525
slotFinished(const QVector<int> & testResult)526 void SetupServer::slotFinished(const QVector<int> &testResult)
527 {
528 qCDebug(IMAPRESOURCE_LOG) << testResult;
529
530 #ifndef QT_NO_CURSOR
531 qApp->restoreOverrideCursor();
532 #endif
533 mOkButton->setEnabled(true);
534
535 using namespace MailTransport;
536
537 if (!m_serverTest->isNormalPossible() && !m_serverTest->isSecurePossible()) {
538 KMessageBox::sorry(this, i18n("Unable to connect to the server, please verify the server address."));
539 }
540
541 m_ui->testInfo->show();
542
543 m_ui->sslRadio->setEnabled(testResult.contains(Transport::EnumEncryption::SSL));
544 m_ui->tlsRadio->setEnabled(testResult.contains(Transport::EnumEncryption::TLS));
545 m_ui->noRadio->setEnabled(testResult.contains(Transport::EnumEncryption::None));
546
547 QString text;
548 if (testResult.contains(Transport::EnumEncryption::TLS)) {
549 m_ui->tlsRadio->setChecked(true);
550 text = i18n("<qt><b>STARTTLS is supported and recommended.</b></qt>");
551 } else if (testResult.contains(Transport::EnumEncryption::SSL)) {
552 m_ui->sslRadio->setChecked(true);
553 text = i18n("<qt><b>SSL/TLS is supported and recommended.</b></qt>");
554 } else if (testResult.contains(Transport::EnumEncryption::None)) {
555 m_ui->noRadio->setChecked(true);
556 text = i18n(
557 "<qt><b>No security is supported. It is not "
558 "recommended to connect to this server.</b></qt>");
559 } else {
560 text = i18n("<qt><b>It is not possible to use this server.</b></qt>");
561 }
562 m_ui->testInfo->setText(text);
563
564 m_ui->testButton->setEnabled(true);
565 m_ui->advancedTab->setEnabled(true);
566 m_ui->authenticationCombo->setEnabled(true);
567 slotEncryptionRadioChanged();
568 slotSafetyChanged();
569 }
570
slotTestChanged()571 void SetupServer::slotTestChanged()
572 {
573 delete m_serverTest;
574 m_serverTest = nullptr;
575 slotSafetyChanged();
576
577 // do not use imapConnectionPossible, as the data is not yet saved.
578 m_ui->testButton->setEnabled(true /* TODO && Global::connectionPossible() ||
579 m_ui->imapServer->text() == "localhost"*/);
580 }
581
slotEnableWidgets()582 void SetupServer::slotEnableWidgets()
583 {
584 const bool haveSieve = m_ui->managesieveCheck->isChecked();
585 const bool reuseConfig = m_ui->sameConfigCheck->isChecked();
586
587 m_ui->sameConfigCheck->setEnabled(haveSieve);
588 m_ui->sievePortSpin->setEnabled(haveSieve);
589 m_ui->alternateURL->setEnabled(haveSieve && !reuseConfig);
590 m_ui->authentication->setEnabled(haveSieve && !reuseConfig);
591 }
592
slotComplete()593 void SetupServer::slotComplete()
594 {
595 const bool ok = !m_ui->imapServer->text().isEmpty() && !m_ui->userName->text().isEmpty();
596 mOkButton->setEnabled(ok);
597 }
598
slotSafetyChanged()599 void SetupServer::slotSafetyChanged()
600 {
601 if (m_serverTest == nullptr) {
602 return;
603 }
604 QVector<int> protocols;
605
606 switch (m_ui->safeImapGroup->checkedId()) {
607 case KIMAP::LoginJob::Unencrypted:
608 qCDebug(IMAPRESOURCE_LOG) << "safeImapGroup: unencrypted";
609 protocols = m_serverTest->normalProtocols();
610 break;
611 case KIMAP::LoginJob::SSLorTLS:
612 protocols = m_serverTest->secureProtocols();
613 qCDebug(IMAPRESOURCE_LOG) << "safeImapGroup: SSL";
614 break;
615 case KIMAP::LoginJob::STARTTLS:
616 protocols = m_serverTest->tlsProtocols();
617 qCDebug(IMAPRESOURCE_LOG) << "safeImapGroup: starttls";
618 break;
619 default:
620 qFatal("Shouldn't happen");
621 }
622
623 m_ui->authenticationCombo->clear();
624 addAuthenticationItem(m_ui->authenticationCombo, MailTransport::Transport::EnumAuthenticationType::CLEAR);
625 for (int prot : std::as_const(protocols)) {
626 addAuthenticationItem(m_ui->authenticationCombo, (MailTransport::Transport::EnumAuthenticationType::type)prot);
627 }
628 if (protocols.isEmpty()) {
629 qCDebug(IMAPRESOURCE_LOG) << "no authmodes found";
630 } else {
631 setCurrentAuthMode(m_ui->authenticationCombo, (MailTransport::Transport::EnumAuthenticationType::type)protocols.first());
632 }
633 }
634
slotManageSubscriptions()635 void SetupServer::slotManageSubscriptions()
636 {
637 qCDebug(IMAPRESOURCE_LOG) << "manage subscripts";
638 ImapAccount account;
639
640 account.setServer(m_ui->imapServer->text());
641 account.setPort(m_ui->portSpin->value());
642
643 account.setUserName(m_ui->userName->text());
644 account.setSubscriptionEnabled(m_ui->subscriptionEnabled->isChecked());
645
646 account.setEncryptionMode(static_cast<KIMAP::LoginJob::EncryptionMode>(m_ui->safeImapGroup->checkedId()));
647
648 account.setAuthenticationMode(Settings::mapTransportAuthToKimap(getCurrentAuthMode(m_ui->authenticationCombo)));
649
650 QPointer<SubscriptionDialog> subscriptions = new SubscriptionDialog(this);
651 subscriptions->setWindowTitle(i18nc("@title:window", "Serverside Subscription"));
652 subscriptions->setWindowIcon(QIcon::fromTheme(QStringLiteral("network-server")));
653 subscriptions->connectAccount(account, m_ui->password->password());
654 m_subscriptionsChanged = subscriptions->isSubscriptionChanged();
655
656 subscriptions->exec();
657 delete subscriptions;
658
659 m_ui->subscriptionEnabled->setChecked(account.isSubscriptionEnabled());
660 }
661
slotShowServerInfo()662 void SetupServer::slotShowServerInfo()
663 {
664 auto dialog = new ServerInfoDialog(m_parentResource, this);
665 dialog->show();
666 }
667
targetCollectionReceived(const Akonadi::Collection::List & collections)668 void SetupServer::targetCollectionReceived(const Akonadi::Collection::List &collections)
669 {
670 m_ui->folderRequester->setCollection(collections.first());
671 mOldTrash = collections.first();
672 }
673
localFolderRequestJobFinished(KJob * job)674 void SetupServer::localFolderRequestJobFinished(KJob *job)
675 {
676 if (!job->error()) {
677 Akonadi::Collection targetCollection = Akonadi::SpecialMailCollections::self()->defaultCollection(Akonadi::SpecialMailCollections::Trash);
678 Q_ASSERT(targetCollection.isValid());
679 m_ui->folderRequester->setCollection(targetCollection);
680 mOldTrash = targetCollection;
681 }
682 }
683
populateDefaultAuthenticationOptions()684 void SetupServer::populateDefaultAuthenticationOptions()
685 {
686 populateDefaultAuthenticationOptions(m_ui->authenticationCombo);
687 populateDefaultAuthenticationOptions(m_ui->authenticationAlternateCombo);
688 }
689
populateDefaultAuthenticationOptions(QComboBox * combo)690 void SetupServer::populateDefaultAuthenticationOptions(QComboBox *combo)
691 {
692 combo->clear();
693 addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::CLEAR);
694 addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::LOGIN);
695 addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::PLAIN);
696 addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::CRAM_MD5);
697 addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::DIGEST_MD5);
698 addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::NTLM);
699 addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::GSSAPI);
700 addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::ANONYMOUS);
701 addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::XOAUTH2);
702 }
703
slotServerChanged()704 void SetupServer::slotServerChanged()
705 {
706 populateDefaultAuthenticationOptions(m_ui->authenticationCombo);
707 }
708