setupserver.cpp 32.1 KB
Newer Older
1
/* This file is part of the KDE project
2
3
4
5
6

   Copyright (c) 2010 Klarälvdalens Datakonsult AB,
                      a KDAB Group company <info@kdab.com>
   Author: Kevin Ottens <kevin@kdab.com>

7
8
   Copyright (C) 2010 Casey Link <unnamedrambler@gmail.com>
   Copyright (c) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
9
   Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
   Copyright (C) 2006-2008 Omat Holding B.V. <info@omat.nl>
   Copyright (C) 2006 Frode M. Døving <frode@lnix.net>

   Original copied from showfoto:
    Copyright 2005 by Gilles Caulier <caulier.gilles@free.fr>

   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 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, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

#include "setupserver.h"
32
#include "settings.h"
33
#include "imapresource.h"
Laurent Montel's avatar
Laurent Montel committed
34
#include "serverinfodialog.h"
Laurent Montel's avatar
Laurent Montel committed
35
#include "folderarchivesettingpage.h"
36
#include "utils.h"
37

Laurent Montel's avatar
Laurent Montel committed
38
39
#include <mailtransport/transport.h>
#include <mailtransport/servertest.h>
40

Laurent Montel's avatar
Laurent Montel committed
41
#include <kmime/kmime_message.h>
42

43
#include <collectionfetchjob.h>
44
45
#include <Akonadi/KMime/SpecialMailCollections>
#include <Akonadi/KMime/SpecialMailCollectionsRequestJob>
46
47
#include <resourcesettings.h>
#include <entitydisplayattribute.h>
Laurent Montel's avatar
Laurent Montel committed
48
#include <CollectionModifyJob>
49
#include <kemailsettings.h>
Laurent Montel's avatar
Laurent Montel committed
50
#include <KLocalizedString>
Laurent Montel's avatar
Laurent Montel committed
51
#include <qpushbutton.h>
52
#include <kmessagebox.h>
53
#include <kuser.h>
Laurent Montel's avatar
Laurent Montel committed
54
#include "imapresource_debug.h"
Laurent Montel's avatar
Laurent Montel committed
55
#include <QNetworkConfigurationManager>
56

Laurent Montel's avatar
Laurent Montel committed
57
58
#include <kidentitymanagement/identitymanager.h>
#include <kidentitymanagement/identitycombo.h>
Laurent Montel's avatar
Laurent Montel committed
59
#include <QVBoxLayout>
60

61
62
63
#include "imapaccount.h"
#include "subscriptiondialog.h"

64
#include "ui_setupserverview_desktop.h"
65

66
/** static helper functions **/
Laurent Montel's avatar
Laurent Montel committed
67
static QString authenticationModeString(MailTransport::Transport::EnumAuthenticationType::type mode)
68
{
Laurent Montel's avatar
Laurent Montel committed
69
    switch (mode) {
70
    case  MailTransport::Transport::EnumAuthenticationType::LOGIN:
Laurent Montel's avatar
Laurent Montel committed
71
        return QStringLiteral("LOGIN");
72
    case MailTransport::Transport::EnumAuthenticationType::PLAIN:
Laurent Montel's avatar
Laurent Montel committed
73
        return QStringLiteral("PLAIN");
74
    case MailTransport::Transport::EnumAuthenticationType::CRAM_MD5:
Laurent Montel's avatar
Laurent Montel committed
75
        return QStringLiteral("CRAM-MD5");
76
    case MailTransport::Transport::EnumAuthenticationType::DIGEST_MD5:
Laurent Montel's avatar
Laurent Montel committed
77
        return QStringLiteral("DIGEST-MD5");
78
    case MailTransport::Transport::EnumAuthenticationType::GSSAPI:
Laurent Montel's avatar
Laurent Montel committed
79
        return QStringLiteral("GSSAPI");
80
    case MailTransport::Transport::EnumAuthenticationType::NTLM:
Laurent Montel's avatar
Laurent Montel committed
81
        return QStringLiteral("NTLM");
82
    case MailTransport::Transport::EnumAuthenticationType::CLEAR:
Laurent Montel's avatar
Laurent Montel committed
83
        return i18nc("Authentication method", "Clear text");
84
    case MailTransport::Transport::EnumAuthenticationType::ANONYMOUS:
Laurent Montel's avatar
Laurent Montel committed
85
        return i18nc("Authentication method", "Anonymous");
86
87
    case MailTransport::Transport::EnumAuthenticationType::XOAUTH2:
        return i18nc("Authentication method", "Gmail");
88
    default:
Laurent Montel's avatar
Laurent Montel committed
89
90
91
        break;
    }
    return QString();
92
93
}

Laurent Montel's avatar
Laurent Montel committed
94
static void setCurrentAuthMode(QComboBox *authCombo, MailTransport::Transport::EnumAuthenticationType::type authtype)
95
{
Laurent Montel's avatar
Laurent Montel committed
96
97
98
99
100
101
102
103
104
105
    qCDebug(IMAPRESOURCE_LOG) << "setting authcombo: " << authenticationModeString(authtype);
    int index = authCombo->findData(authtype);
    if (index == -1) {
        qCWarning(IMAPRESOURCE_LOG) << "desired authmode not in the combo";
    }
    qCDebug(IMAPRESOURCE_LOG) << "found corresponding index: " << index << "with data" << authenticationModeString((MailTransport::Transport::EnumAuthenticationType::type) authCombo->itemData(index).toInt());
    authCombo->setCurrentIndex(index);
    MailTransport::Transport::EnumAuthenticationType::type t = (MailTransport::Transport::EnumAuthenticationType::type) authCombo->itemData(authCombo->currentIndex()).toInt();
    qCDebug(IMAPRESOURCE_LOG) << "selected auth mode:" << authenticationModeString(t);
    Q_ASSERT(t == authtype);
106
107
}

Laurent Montel's avatar
Laurent Montel committed
108
static MailTransport::Transport::EnumAuthenticationType::type getCurrentAuthMode(QComboBox *authCombo)
109
{
Laurent Montel's avatar
Laurent Montel committed
110
111
112
    MailTransport::Transport::EnumAuthenticationType::type authtype = (MailTransport::Transport::EnumAuthenticationType::type) authCombo->itemData(authCombo->currentIndex()).toInt();
    qCDebug(IMAPRESOURCE_LOG) << "current auth mode: " << authenticationModeString(authtype);
    return authtype;
113
114
}

Laurent Montel's avatar
Laurent Montel committed
115
static void addAuthenticationItem(QComboBox *authCombo, MailTransport::Transport::EnumAuthenticationType::type authtype)
116
{
Laurent Montel's avatar
Laurent Montel committed
117
118
    qCDebug(IMAPRESOURCE_LOG) << "adding auth item " << authenticationModeString(authtype);
    authCombo->addItem(authenticationModeString(authtype), QVariant(authtype));
119
120
}

Laurent Montel's avatar
Laurent Montel committed
121
SetupServer::SetupServer(ImapResourceBase *parentResource, WId parent)
Laurent Montel's avatar
Laurent Montel committed
122
    : QDialog(), m_parentResource(parentResource), m_ui(new Ui::SetupServerView), m_serverTest(nullptr),
Laurent Montel's avatar
Laurent Montel committed
123
      m_subscriptionsChanged(false), m_shouldClearCache(false), mValidator(this)
124
{
Laurent Montel's avatar
Laurent Montel committed
125
126
    QNetworkConfigurationManager *networkConfigMgr = new QNetworkConfigurationManager(QCoreApplication::instance());

Laurent Montel's avatar
Laurent Montel committed
127
128
    m_parentResource->settings()->setWinId(parent);
    QWidget *mainWidget = new QWidget(this);
Laurent Montel's avatar
Laurent Montel committed
129
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
Laurent Montel's avatar
Laurent Montel committed
130
    mainLayout->addWidget(mainWidget);
Laurent Montel's avatar
Laurent Montel committed
131
    QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
Laurent Montel's avatar
Laurent Montel committed
132
133
134
    mOkButton = buttonBox->button(QDialogButtonBox::Ok);
    mOkButton->setDefault(true);
    mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return);
135
    connect(mOkButton, &QPushButton::clicked, this, &SetupServer::applySettings);
Laurent Montel's avatar
Laurent Montel committed
136
137
138
139
140
    connect(buttonBox, &QDialogButtonBox::rejected, this, &SetupServer::reject);
    mainLayout->addWidget(buttonBox);

    m_ui->setupUi(mainWidget);
    m_folderArchiveSettingPage = new FolderArchiveSettingPage(m_parentResource->identifier());
Laurent Montel's avatar
Laurent Montel committed
141
    m_ui->tabWidget->addTab(m_folderArchiveSettingPage, i18n("Archive Folder"));
Laurent Montel's avatar
Laurent Montel committed
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    m_ui->safeImapGroup->setId(m_ui->noRadio, KIMAP::LoginJob::Unencrypted);
    m_ui->safeImapGroup->setId(m_ui->sslRadio, KIMAP::LoginJob::AnySslVersion);
    m_ui->safeImapGroup->setId(m_ui->tlsRadio, KIMAP::LoginJob::TlsV1);

    connect(m_ui->noRadio, &QRadioButton::toggled, this, &SetupServer::slotSafetyChanged);
    connect(m_ui->sslRadio, &QRadioButton::toggled, this, &SetupServer::slotSafetyChanged);
    connect(m_ui->tlsRadio, &QRadioButton::toggled, this, &SetupServer::slotSafetyChanged);

    m_ui->testInfo->hide();
    m_ui->testProgress->hide();
    m_ui->accountName->setFocus();
    m_ui->checkInterval->setSuffix(ki18np(" minute", " minutes"));
    m_ui->checkInterval->setMinimum(Akonadi::ResourceSettings::self()->minimumCheckInterval());
    m_ui->checkInterval->setMaximum(10000);
    m_ui->checkInterval->setSingleStep(1);

    // regex for evaluating a valid server name/ip
Laurent Montel's avatar
Laurent Montel committed
159
    mValidator.setRegExp(QRegExp(QLatin1String("[A-Za-z0-9-_:.]*")));
Laurent Montel's avatar
Laurent Montel committed
160
161
162
163
164
165
166
167
168
169
170
171
172
173
    m_ui->imapServer->setValidator(&mValidator);

    m_ui->folderRequester->setMimeTypeFilter(
        QStringList() << KMime::Message::mimeType());
    m_ui->folderRequester->setAccessRightsFilter(Akonadi::Collection::CanChangeItem | Akonadi::Collection::CanCreateItem | Akonadi::Collection::CanDeleteItem);
    m_ui->folderRequester->changeCollectionDialogOptions(Akonadi::CollectionDialog::AllowToCreateNewChildCollection);
    m_identityManager = new KIdentityManagement::IdentityManager(false, this, "mIdentityManager");
    m_identityCombobox = new KIdentityManagement::IdentityCombo(m_identityManager, this);
    m_ui->identityLabel->setBuddy(m_identityCombobox);
    m_ui->identityLayout->addWidget(m_identityCombobox, 1);
    m_ui->identityLabel->setBuddy(m_identityCombobox);

    connect(m_ui->testButton, &QPushButton::pressed, this, &SetupServer::slotTest);

174
    connect(m_ui->imapServer, &KLineEdit::textChanged, this, &SetupServer::slotServerChanged);
Laurent Montel's avatar
Laurent Montel committed
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
    connect(m_ui->imapServer, &KLineEdit::textChanged, this, &SetupServer::slotTestChanged);
    connect(m_ui->imapServer, &KLineEdit::textChanged, this, &SetupServer::slotComplete);
    connect(m_ui->userName, &KLineEdit::textChanged, this, &SetupServer::slotComplete);
    connect(m_ui->subscriptionEnabled, &QCheckBox::toggled, this, &SetupServer::slotSubcriptionCheckboxChanged);
    connect(m_ui->subscriptionButton, &QPushButton::pressed, this, &SetupServer::slotManageSubscriptions);

    connect(m_ui->managesieveCheck, &QCheckBox::toggled, this, &SetupServer::slotEnableWidgets);
    connect(m_ui->sameConfigCheck, &QCheckBox::toggled, this, &SetupServer::slotEnableWidgets);

    connect(m_ui->useDefaultIdentityCheck, &QCheckBox::toggled, this, &SetupServer::slotIdentityCheckboxChanged);
    connect(m_ui->enableMailCheckBox, &QCheckBox::toggled, this, &SetupServer::slotMailCheckboxChanged);
    connect(m_ui->safeImapGroup, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked), this, &SetupServer::slotEncryptionRadioChanged);
    connect(m_ui->customSieveGroup, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked), this, &SetupServer::slotCustomSieveChanged);
    connect(m_ui->showServerInfo, &QPushButton::pressed, this, &SetupServer::slotShowServerInfo);

    readSettings();
    slotTestChanged();
    slotComplete();
    slotCustomSieveChanged();
Laurent Montel's avatar
Laurent Montel committed
194
195
    connect(networkConfigMgr, &QNetworkConfigurationManager::onlineStateChanged,
            this, &SetupServer::slotTestChanged);
196
197
198
199
}

SetupServer::~SetupServer()
{
Laurent Montel's avatar
Laurent Montel committed
200
    delete m_ui;
201
202
}

203
204
bool SetupServer::shouldClearCache() const
{
Laurent Montel's avatar
Laurent Montel committed
205
    return m_shouldClearCache;
206
207
}

208
209
void SetupServer::slotSubcriptionCheckboxChanged()
{
Laurent Montel's avatar
Laurent Montel committed
210
    m_ui->subscriptionButton->setEnabled(m_ui->subscriptionEnabled->isChecked());
211
212
}

213
214
void SetupServer::slotIdentityCheckboxChanged()
{
Laurent Montel's avatar
Laurent Montel committed
215
    m_identityCombobox->setEnabled(!m_ui->useDefaultIdentityCheck->isChecked());
216
217
}

218
219
void SetupServer::slotMailCheckboxChanged()
{
Laurent Montel's avatar
Laurent Montel committed
220
    m_ui->checkInterval->setEnabled(m_ui->enableMailCheckBox->isChecked());
221
222
223
224
}

void SetupServer::slotEncryptionRadioChanged()
{
Laurent Montel's avatar
Laurent Montel committed
225
226
    // TODO these really should be defined somewhere else
    switch (m_ui->safeImapGroup->checkedId()) {
227
    case KIMAP::LoginJob::Unencrypted:
Laurent Montel's avatar
Laurent Montel committed
228
    case KIMAP::LoginJob::TlsV1:
Laurent Montel's avatar
Laurent Montel committed
229
230
        m_ui->portSpin->setValue(143);
        break;
231
    case KIMAP::LoginJob::AnySslVersion:
Laurent Montel's avatar
Laurent Montel committed
232
233
234
235
236
        m_ui->portSpin->setValue(993);
        break;
    default:
        qFatal("Shouldn't happen");
    }
237
}
238

239
240
241
242
243
void SetupServer::slotCustomSieveChanged()
{
    QAbstractButton *checkedButton = m_ui->customSieveGroup->checkedButton();

    if (checkedButton == m_ui->imapUserPassword ||
Laurent Montel's avatar
Laurent Montel committed
244
            checkedButton == m_ui->noAuthentification) {
245
246
247
248
249
250
        m_ui->customUsername->setEnabled(false);
        m_ui->customPassword->setEnabled(false);
    } else if (checkedButton == m_ui->customUserPassword) {
        m_ui->customUsername->setEnabled(true);
        m_ui->customPassword->setEnabled(true);
    }
251
252
}

253
254
void SetupServer::applySettings()
{
255
256
    if (!m_parentResource->settings()->imapServer().isEmpty()
        && m_ui->imapServer->text() != m_parentResource->settings()->imapServer()) {
257
258
259
260
261
262
263
264
        if (KMessageBox::warningContinueCancel(
                this, i18n("You have changed the address of the server. Even if this is the same server as before "
                           "we will have to re-download all your emails from this account again. "
                           "Are you sure you want to proceed?"),
                i18n("Server address change")) == KMessageBox::Cancel) {
            return;
        }
    }
265
    if (!m_parentResource->settings()->userName().isEmpty()
266
        && m_ui->userName->text() != m_parentResource->settings()->userName()) {
267
        if (KMessageBox::warningContinueCancel(
Yuri Chornoivan's avatar
Yuri Chornoivan committed
268
                this, i18n("You have changed the user name. Even if this is a user name for the same account as before "
269
270
271
272
273
274
275
                           "we will have to re-download all your emails from this account again. "
                           "Are you sure you want to proceed?"),
                i18n("User name change")) == KMessageBox::Cancel) {
            return;
        }
    }

Laurent Montel's avatar
Laurent Montel committed
276
277
278
279
280
281
282
283
284
285
286
287
    m_folderArchiveSettingPage->writeSettings();
    m_shouldClearCache = (m_parentResource->settings()->imapServer() != m_ui->imapServer->text())
                         || (m_parentResource->settings()->userName() != m_ui->userName->text());

    m_parentResource->setName(m_ui->accountName->text());

    m_parentResource->settings()->setImapServer(m_ui->imapServer->text());
    m_parentResource->settings()->setImapPort(m_ui->portSpin->value());
    m_parentResource->settings()->setUserName(m_ui->userName->text());
    QString encryption;
    switch (m_ui->safeImapGroup->checkedId()) {
    case KIMAP::LoginJob::Unencrypted :
288
        encryption = QStringLiteral("None");
Laurent Montel's avatar
Laurent Montel committed
289
290
        break;
    case KIMAP::LoginJob::AnySslVersion:
291
        encryption = QStringLiteral("SSL");
Laurent Montel's avatar
Laurent Montel committed
292
293
        break;
    case KIMAP::LoginJob::TlsV1:
294
        encryption = QStringLiteral("STARTTLS");
Laurent Montel's avatar
Laurent Montel committed
295
296
297
298
299
300
301
302
303
304
305
306
307
        break;
    default:
        qFatal("Shouldn't happen");
    }
    m_parentResource->settings()->setSafety(encryption);
    MailTransport::Transport::EnumAuthenticationType::type authtype = getCurrentAuthMode(m_ui->authenticationCombo);
    qCDebug(IMAPRESOURCE_LOG) << "saving IMAP auth mode: " << authenticationModeString(authtype);
    m_parentResource->settings()->setAuthentication(authtype);
    m_parentResource->settings()->setPassword(m_ui->password->text());
    m_parentResource->settings()->setSubscriptionEnabled(m_ui->subscriptionEnabled->isChecked());
    m_parentResource->settings()->setIntervalCheckTime(m_ui->checkInterval->value());
    m_parentResource->settings()->setDisconnectedModeEnabled(m_ui->disconnectedModeEnabled->isChecked());

308
309
310
    MailTransport::Transport::EnumAuthenticationType::type alternateAuthtype = getCurrentAuthMode(m_ui->authenticationAlternateCombo);
    qCDebug(IMAPRESOURCE_LOG) << "saving Alternate server sieve auth mode: " << authenticationModeString(alternateAuthtype);
    m_parentResource->settings()->setAlternateAuthentication(alternateAuthtype);
Laurent Montel's avatar
Laurent Montel committed
311
312
313
314
315
316
317
318
319
    m_parentResource->settings()->setSieveSupport(m_ui->managesieveCheck->isChecked());
    m_parentResource->settings()->setSieveReuseConfig(m_ui->sameConfigCheck->isChecked());
    m_parentResource->settings()->setSievePort(m_ui->sievePortSpin->value());
    m_parentResource->settings()->setSieveAlternateUrl(m_ui->alternateURL->text());
    m_parentResource->settings()->setSieveVacationFilename(m_vacationFileName);

    m_parentResource->settings()->setTrashCollection(m_ui->folderRequester->collection().id());
    Akonadi::Collection trash = m_ui->folderRequester->collection();
    Akonadi::SpecialMailCollections::self()->registerCollection(Akonadi::SpecialMailCollections::Trash, trash);
320
    Akonadi::EntityDisplayAttribute *attribute =  trash.attribute<Akonadi::EntityDisplayAttribute>(Akonadi::Collection::AddIfMissing);
321
    attribute->setIconName(QStringLiteral("user-trash"));
Laurent Montel's avatar
Laurent Montel committed
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
    new Akonadi::CollectionModifyJob(trash);
    if (mOldTrash != trash) {
        Akonadi::SpecialMailCollections::self()->unregisterCollection(mOldTrash);
    }

    m_parentResource->settings()->setAutomaticExpungeEnabled(m_ui->autoExpungeCheck->isChecked());
    m_parentResource->settings()->setUseDefaultIdentity(m_ui->useDefaultIdentityCheck->isChecked());

    if (!m_ui->useDefaultIdentityCheck->isChecked()) {
        m_parentResource->settings()->setAccountIdentity(m_identityCombobox->currentIdentity());
    }

    m_parentResource->settings()->setIntervalCheckEnabled(m_ui->enableMailCheckBox->isChecked());
    if (m_ui->enableMailCheckBox->isChecked()) {
        m_parentResource->settings()->setIntervalCheckTime(m_ui->checkInterval->value());
    }

    m_parentResource->settings()->setSieveCustomUsername(m_ui->customUsername->text());

    QAbstractButton *checkedButton = m_ui->customSieveGroup->checkedButton();

    if (checkedButton == m_ui->imapUserPassword) {
344
        m_parentResource->settings()->setSieveCustomAuthentification(QStringLiteral("ImapUserPassword"));
Laurent Montel's avatar
Laurent Montel committed
345
    } else if (checkedButton == m_ui->noAuthentification) {
346
        m_parentResource->settings()->setSieveCustomAuthentification(QStringLiteral("NoAuthentification"));
Laurent Montel's avatar
Laurent Montel committed
347
    } else if (checkedButton == m_ui->customUserPassword) {
348
        m_parentResource->settings()->setSieveCustomAuthentification(QStringLiteral("CustomUserPassword"));
Laurent Montel's avatar
Laurent Montel committed
349
350
351
352
353
354
355
356
357
358
    }

    m_parentResource->settings()->setSieveCustomPassword(m_ui->customPassword->text());

    m_parentResource->settings()->save();
    qCDebug(IMAPRESOURCE_LOG) << "wrote" << m_ui->imapServer->text() << m_ui->userName->text() << m_ui->safeImapGroup->checkedId();

    if (m_oldResourceName != m_ui->accountName->text() && !m_ui->accountName->text().isEmpty()) {
        m_parentResource->settings()->renameRootCollection(m_ui->accountName->text());
    }
359
360

    accept();
361
362
363
364
}

void SetupServer::readSettings()
{
Laurent Montel's avatar
Laurent Montel committed
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
    m_folderArchiveSettingPage->loadSettings();
    m_ui->accountName->setText(m_parentResource->name());
    m_oldResourceName = m_ui->accountName->text();

    KUser *currentUser = new KUser();
    KEMailSettings esetting;

    m_ui->imapServer->setText(
        !m_parentResource->settings()->imapServer().isEmpty() ? m_parentResource->settings()->imapServer() :
        esetting.getSetting(KEMailSettings::InServer));

    m_ui->portSpin->setValue(m_parentResource->settings()->imapPort());

    m_ui->userName->setText(
        !m_parentResource->settings()->userName().isEmpty() ? m_parentResource->settings()->userName() :
        currentUser->loginName());

    const QString safety = m_parentResource->settings()->safety();
    int i = 0;
    if (safety == QLatin1String("SSL")) {
        i = KIMAP::LoginJob::AnySslVersion;
    } else if (safety == QLatin1String("STARTTLS")) {
        i = KIMAP::LoginJob::TlsV1;
    } else {
        i = KIMAP::LoginJob::Unencrypted;
    }

    QAbstractButton *safetyButton = m_ui->safeImapGroup->button(i);
    if (safetyButton) {
        safetyButton->setChecked(true);
    }

    populateDefaultAuthenticationOptions();
    i = m_parentResource->settings()->authentication();
    qCDebug(IMAPRESOURCE_LOG) << "read IMAP auth mode: " << authenticationModeString((MailTransport::Transport::EnumAuthenticationType::type) i);
    setCurrentAuthMode(m_ui->authenticationCombo, (MailTransport::Transport::EnumAuthenticationType::type) i);

402
403
404
    i = m_parentResource->settings()->alternateAuthentication();
    setCurrentAuthMode(m_ui->authenticationAlternateCombo, (MailTransport::Transport::EnumAuthenticationType::type) i);

Laurent Montel's avatar
Laurent Montel committed
405
406
407
408
    bool rejected = false;
    const QString password = m_parentResource->settings()->password(&rejected);
    if (rejected) {
        m_ui->password->setEnabled(false);
Laurent Montel's avatar
Laurent Montel committed
409
        KMessageBox::information(nullptr, i18n("Could not access KWallet. "
Laurent Montel's avatar
Laurent Montel committed
410
411
412
413
                                 "If you want to store the password permanently then you have to "
                                 "activate it. If you do not "
                                 "want to use KWallet, check the box below, but note that you will be "
                                 "prompted for your password when needed."),
Laurent Montel's avatar
Laurent Montel committed
414
                                 i18n("Do not use KWallet"), QStringLiteral("warning_kwallet_disabled"));
Laurent Montel's avatar
Laurent Montel committed
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
    } else {
        m_ui->password->insert(password);
    }

    m_ui->subscriptionEnabled->setChecked(m_parentResource->settings()->subscriptionEnabled());

    m_ui->checkInterval->setValue(m_parentResource->settings()->intervalCheckTime());
    m_ui->disconnectedModeEnabled->setChecked(m_parentResource->settings()->disconnectedModeEnabled());

    m_ui->managesieveCheck->setChecked(m_parentResource->settings()->sieveSupport());
    m_ui->sameConfigCheck->setChecked(m_parentResource->settings()->sieveReuseConfig());
    m_ui->sievePortSpin->setValue(m_parentResource->settings()->sievePort());
    m_ui->alternateURL->setText(m_parentResource->settings()->sieveAlternateUrl());
    m_vacationFileName = m_parentResource->settings()->sieveVacationFilename();

    Akonadi::Collection trashCollection(m_parentResource->settings()->trashCollection());
    if (trashCollection.isValid()) {
        Akonadi::CollectionFetchJob *fetchJob = new Akonadi::CollectionFetchJob(trashCollection, Akonadi::CollectionFetchJob::Base, this);
        connect(fetchJob, &Akonadi::CollectionFetchJob::collectionsReceived, this, &SetupServer::targetCollectionReceived);
    } else {
        Akonadi::SpecialMailCollectionsRequestJob *requestJob = new Akonadi::SpecialMailCollectionsRequestJob(this);
        connect(requestJob, &Akonadi::SpecialMailCollectionsRequestJob::result, this, &SetupServer::localFolderRequestJobFinished);
        requestJob->requestDefaultCollection(Akonadi::SpecialMailCollections::Trash);
        requestJob->start();
    }

    m_ui->useDefaultIdentityCheck->setChecked(m_parentResource->settings()->useDefaultIdentity());
    if (!m_ui->useDefaultIdentityCheck->isChecked()) {
        m_identityCombobox->setCurrentIdentity(m_parentResource->settings()->accountIdentity());
    }

    m_ui->enableMailCheckBox->setChecked(m_parentResource->settings()->intervalCheckEnabled());
    if (m_ui->enableMailCheckBox->isChecked()) {
        m_ui->checkInterval->setValue(m_parentResource->settings()->intervalCheckTime());
    } else {
        m_ui->checkInterval->setEnabled(false);
    }

    m_ui->autoExpungeCheck->setChecked(m_parentResource->settings()->automaticExpungeEnabled());

    if (m_vacationFileName.isEmpty()) {
456
        m_vacationFileName = QStringLiteral("kmail-vacation.siv");
Laurent Montel's avatar
Laurent Montel committed
457
458
459
460
    }

    m_ui->customUsername->setText(m_parentResource->settings()->sieveCustomUsername());

Laurent Montel's avatar
Laurent Montel committed
461
462
463
464
    rejected = false;
    const QString customPassword = m_parentResource->settings()->sieveCustomPassword(&rejected);
    if (rejected) {
        m_ui->customPassword->setEnabled(false);
Laurent Montel's avatar
Laurent Montel committed
465
        KMessageBox::information(nullptr, i18n("Could not access KWallet. "
Laurent Montel's avatar
Laurent Montel committed
466
467
468
469
470
471
472
473
                                 "If you want to store the password permanently then you have to "
                                 "activate it. If you do not "
                                 "want to use KWallet, check the box below, but note that you will be "
                                 "prompted for your password when needed."),
                                 i18n("Do not use KWallet"), QStringLiteral("warning_kwallet_disabled"));
    } else {
        m_ui->customPassword->insert(customPassword);
    }
Laurent Montel's avatar
Laurent Montel committed
474
475
476
477
478
479
480
481
482
483
484

    const QString sieverCustomAuth(m_parentResource->settings()->sieveCustomAuthentification());
    if (sieverCustomAuth == QLatin1String("ImapUserPassword")) {
        m_ui->imapUserPassword->setChecked(true);
    } else if (sieverCustomAuth == QLatin1String("NoAuthentification")) {
        m_ui->noAuthentification->setChecked(true);
    } else if (sieverCustomAuth == QLatin1String("CustomUserPassword")) {
        m_ui->customUserPassword->setChecked(true);
    }

    delete currentUser;
485
486
487
488
}

void SetupServer::slotTest()
{
Laurent Montel's avatar
Laurent Montel committed
489
    qCDebug(IMAPRESOURCE_LOG) << m_ui->imapServer->text();
490

Laurent Montel's avatar
Laurent Montel committed
491
492
493
    m_ui->testButton->setEnabled(false);
    m_ui->safeImap->setEnabled(false);
    m_ui->authenticationCombo->setEnabled(false);
494

Laurent Montel's avatar
Laurent Montel committed
495
496
    m_ui->testInfo->clear();
    m_ui->testInfo->hide();
497

Laurent Montel's avatar
Laurent Montel committed
498
499
    delete m_serverTest;
    m_serverTest = new MailTransport::ServerTest(this);
500
#ifndef QT_NO_CURSOR
Laurent Montel's avatar
Laurent Montel committed
501
    qApp->setOverrideCursor(Qt::BusyCursor);
502
#endif
503

Laurent Montel's avatar
Laurent Montel committed
504
505
506
    const QString server = m_ui->imapServer->text();
    const int port = m_ui->portSpin->value();
    qCDebug(IMAPRESOURCE_LOG) << "server: " << server << "port: " << port;
507

Laurent Montel's avatar
Laurent Montel committed
508
    m_serverTest->setServer(server);
509

Laurent Montel's avatar
Laurent Montel committed
510
511
512
513
    if (port != 143 && port != 993) {
        m_serverTest->setPort(MailTransport::Transport::EnumEncryption::None, port);
        m_serverTest->setPort(MailTransport::Transport::EnumEncryption::SSL, port);
    }
514

515
    m_serverTest->setProtocol(QStringLiteral("imap"));
Laurent Montel's avatar
Laurent Montel committed
516
517
518
519
    m_serverTest->setProgressBar(m_ui->testProgress);
    connect(m_serverTest, &MailTransport::ServerTest::finished, this, &SetupServer::slotFinished);
    mOkButton->setEnabled(false);
    m_serverTest->start();
520
521
}

522
void SetupServer::slotFinished(const QVector<int> &testResult)
523
{
Laurent Montel's avatar
Laurent Montel committed
524
    qCDebug(IMAPRESOURCE_LOG) << testResult;
525

526
#ifndef QT_NO_CURSOR
Laurent Montel's avatar
Laurent Montel committed
527
    qApp->restoreOverrideCursor();
528
#endif
Laurent Montel's avatar
Laurent Montel committed
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
    mOkButton->setEnabled(true);

    using namespace MailTransport;

    if (!m_serverTest->isNormalPossible() && !m_serverTest->isSecurePossible()) {
        KMessageBox::sorry(this, i18n("Unable to connect to the server, please verify the server address."));
    }

    m_ui->testInfo->show();

    m_ui->sslRadio->setEnabled(testResult.contains(Transport::EnumEncryption::SSL));
    m_ui->tlsRadio->setEnabled(testResult.contains(Transport::EnumEncryption::TLS));
    m_ui->noRadio->setEnabled(testResult.contains(Transport::EnumEncryption::None));

    QString text;
    if (testResult.contains(Transport::EnumEncryption::TLS)) {
        m_ui->tlsRadio->setChecked(true);
        text = i18n("<qt><b>TLS is supported and recommended.</b></qt>");
    } else if (testResult.contains(Transport::EnumEncryption::SSL)) {
        m_ui->sslRadio->setChecked(true);
        text = i18n("<qt><b>SSL is supported and recommended.</b></qt>");
    } else if (testResult.contains(Transport::EnumEncryption::None)) {
        m_ui->noRadio->setChecked(true);
        text = i18n("<qt><b>No security is supported. It is not "
                    "recommended to connect to this server.</b></qt>");
    } else {
        text = i18n("<qt><b>It is not possible to use this server.</b></qt>");
    }
    m_ui->testInfo->setText(text);

    m_ui->testButton->setEnabled(true);
    m_ui->safeImap->setEnabled(true);
    m_ui->authenticationCombo->setEnabled(true);
    slotEncryptionRadioChanged();
    slotSafetyChanged();
564
565
566
567
}

void SetupServer::slotTestChanged()
{
Laurent Montel's avatar
Laurent Montel committed
568
    delete m_serverTest;
Laurent Montel's avatar
Laurent Montel committed
569
    m_serverTest = nullptr;
Laurent Montel's avatar
Laurent Montel committed
570
    slotSafetyChanged();
571

Laurent Montel's avatar
Laurent Montel committed
572
    // do not use imapConnectionPossible, as the data is not yet saved.
573
574
575
    const bool isGmail = Utils::isGmail(m_ui->imapServer->text());
    m_ui->testButton->setEnabled(!isGmail /* TODO && Global::connectionPossible() ||
                                                m_ui->imapServer->text() == "localhost"*/);
576
577
}

578
579
void SetupServer::slotEnableWidgets()
{
Laurent Montel's avatar
Laurent Montel committed
580
581
    const bool haveSieve = m_ui->managesieveCheck->isChecked();
    const bool reuseConfig = m_ui->sameConfigCheck->isChecked();
582

Laurent Montel's avatar
Laurent Montel committed
583
    m_ui->sameConfigCheck->setEnabled(haveSieve);
584
    m_ui->sievePortSpin->setEnabled(haveSieve);
Laurent Montel's avatar
Laurent Montel committed
585
586
    m_ui->alternateURL->setEnabled(haveSieve && !reuseConfig);
    m_ui->authentification->setEnabled(haveSieve && !reuseConfig);
587
588
}

589
590
void SetupServer::slotComplete()
{
Laurent Montel's avatar
Laurent Montel committed
591
592
    const bool ok =  !m_ui->imapServer->text().isEmpty() && !m_ui->userName->text().isEmpty();
    mOkButton->setEnabled(ok);
593
594
595
596
}

void SetupServer::slotSafetyChanged()
{
Laurent Montel's avatar
Laurent Montel committed
597
    if (m_serverTest == nullptr) {
598
        const bool isGmail = Utils::isGmail(m_ui->imapServer->text());
Laurent Montel's avatar
Laurent Montel committed
599
        qCDebug(IMAPRESOURCE_LOG) << "serverTest null";
600
601
602
        m_ui->noRadio->setEnabled(!isGmail);
        m_ui->sslRadio->setEnabled(!isGmail);
        m_ui->tlsRadio->setEnabled(!isGmail);
Laurent Montel's avatar
Laurent Montel committed
603

604
        m_ui->authenticationCombo->setEnabled(!isGmail);
Laurent Montel's avatar
Laurent Montel committed
605
606
607
        return;
    }

608
    QVector<int> protocols;
Laurent Montel's avatar
Laurent Montel committed
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631

    switch (m_ui->safeImapGroup->checkedId()) {
    case KIMAP::LoginJob::Unencrypted :
        qCDebug(IMAPRESOURCE_LOG) << "safeImapGroup: unencrypted";
        protocols = m_serverTest->normalProtocols();
        break;
    case KIMAP::LoginJob::AnySslVersion:
        protocols = m_serverTest->secureProtocols();
        qCDebug(IMAPRESOURCE_LOG) << "safeImapGroup: SSL";
        break;
    case KIMAP::LoginJob::TlsV1:
        protocols = m_serverTest->tlsProtocols();
        qCDebug(IMAPRESOURCE_LOG) << "safeImapGroup: starttls";
        break;
    default:
        qFatal("Shouldn't happen");
    }

    m_ui->authenticationCombo->clear();
    addAuthenticationItem(m_ui->authenticationCombo, MailTransport::Transport::EnumAuthenticationType::CLEAR);
    foreach (int prot, protocols) {
        addAuthenticationItem(m_ui->authenticationCombo, (MailTransport::Transport::EnumAuthenticationType::type) prot);
    }
Laurent Montel's avatar
Laurent Montel committed
632
    if (protocols.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
633
        qCDebug(IMAPRESOURCE_LOG) << "no authmodes found";
Laurent Montel's avatar
Laurent Montel committed
634
635
    } else {
        setCurrentAuthMode(m_ui->authenticationCombo, (MailTransport::Transport::EnumAuthenticationType::type) protocols.first());
Laurent Montel's avatar
Laurent Montel committed
636
    }
637
638
}

639
640
void SetupServer::slotManageSubscriptions()
{
Laurent Montel's avatar
Laurent Montel committed
641
642
    qCDebug(IMAPRESOURCE_LOG) << "manage subscripts";
    ImapAccount account;
643

Laurent Montel's avatar
Laurent Montel committed
644
645
    account.setServer(m_ui->imapServer->text());
    account.setPort(m_ui->portSpin->value());
646

Laurent Montel's avatar
Laurent Montel committed
647
648
    account.setUserName(m_ui->userName->text());
    account.setSubscriptionEnabled(m_ui->subscriptionEnabled->isChecked());
649

Laurent Montel's avatar
Laurent Montel committed
650
651
652
    account.setEncryptionMode(
        static_cast<KIMAP::LoginJob::EncryptionMode>(m_ui->safeImapGroup->checkedId())
    );
653

Laurent Montel's avatar
Laurent Montel committed
654
    account.setAuthenticationMode(Settings::mapTransportAuthToKimap(getCurrentAuthMode(m_ui->authenticationCombo)));
655

Laurent Montel's avatar
Laurent Montel committed
656
657
    QPointer<SubscriptionDialog> subscriptions = new SubscriptionDialog(this);
    subscriptions->setWindowTitle(i18n("Serverside Subscription"));
Laurent Montel's avatar
Laurent Montel committed
658
    subscriptions->setWindowIcon(QIcon::fromTheme(QStringLiteral("network-server")));
Laurent Montel's avatar
Laurent Montel committed
659
660
    subscriptions->connectAccount(account, m_ui->password->text());
    m_subscriptionsChanged = subscriptions->isSubscriptionChanged();
661

Laurent Montel's avatar
Laurent Montel committed
662
663
    subscriptions->exec();
    delete subscriptions;
664

Laurent Montel's avatar
Laurent Montel committed
665
    m_ui->subscriptionEnabled->setChecked(account.isSubscriptionEnabled());
666
667
}

668
669
void SetupServer::slotShowServerInfo()
{
Laurent Montel's avatar
Laurent Montel committed
670
671
    ServerInfoDialog *dialog = new ServerInfoDialog(m_parentResource, this);
    dialog->show();
672
}
673

Laurent Montel's avatar
Laurent Montel committed
674
void SetupServer::targetCollectionReceived(const Akonadi::Collection::List &collections)
675
{
Laurent Montel's avatar
Laurent Montel committed
676
677
    m_ui->folderRequester->setCollection(collections.first());
    mOldTrash = collections.first();
678
679
}

Laurent Montel's avatar
Laurent Montel committed
680
void SetupServer::localFolderRequestJobFinished(KJob *job)
681
{
Laurent Montel's avatar
Laurent Montel committed
682
683
684
685
686
687
    if (!job->error()) {
        Akonadi::Collection targetCollection = Akonadi::SpecialMailCollections::self()->defaultCollection(Akonadi::SpecialMailCollections::Trash);
        Q_ASSERT(targetCollection.isValid());
        m_ui->folderRequester->setCollection(targetCollection);
        mOldTrash = targetCollection;
    }
688
689
}

690
691
void SetupServer::populateDefaultAuthenticationOptions()
{
692
693
    populateDefaultAuthenticationOptions(m_ui->authenticationCombo);
    populateDefaultAuthenticationOptions(m_ui->authenticationAlternateCombo);
694
695
}

696
697
698
699
700
701
702
703
704
705
706
void SetupServer::populateDefaultAuthenticationOptions(QComboBox *combo)
{
    combo->clear();
    addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::CLEAR);
    addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::LOGIN);
    addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::PLAIN);
    addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::CRAM_MD5);
    addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::DIGEST_MD5);
    addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::NTLM);
    addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::GSSAPI);
    addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::ANONYMOUS);
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
    if (Utils::isGmail(m_ui->imapServer->text())) {
        addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::XOAUTH2);
    }
}

void SetupServer::slotServerChanged()
{
    const bool isGmail = Utils::isGmail(m_ui->imapServer->text());
    const bool wasGmail = !m_ui->password->isEnabled();

    if (isGmail == wasGmail) {
        return;
    }

    m_ui->password->setEnabled(!isGmail);
    m_ui->managesieveCheck->setChecked(m_ui->managesieveCheck->isChecked() && !isGmail);
    m_ui->managesieveCheck->setEnabled(!isGmail);
    m_ui->testButton->setEnabled(!isGmail);
    m_ui->sslRadio->setChecked(m_ui->sslRadio->isChecked() || isGmail);
    m_ui->noRadio->setEnabled(!isGmail);
    m_ui->sslRadio->setEnabled(!isGmail);
    m_ui->tlsRadio->setEnabled(!isGmail);
    m_ui->portSpin->setValue(isGmail ? 993 : m_ui->portSpin->value());
    m_ui->portSpin->setEnabled(!isGmail);
    populateDefaultAuthenticationOptions(m_ui->authenticationCombo);
    if (isGmail) {
        setCurrentAuthMode(m_ui->authenticationCombo, MailTransport::Transport::EnumAuthenticationType::XOAUTH2);
    }
    m_ui->authenticationCombo->setEnabled(!isGmail);
736
}