File indexing completed on 2024-05-12 05:25:39

0001 /*
0002    SPDX-FileCopyrightText: 2013-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "serversievesettings.h"
0008 #include "sieveeditor_debug.h"
0009 #include "ui_serversievesettings.h"
0010 #include <KAuthorized>
0011 #include <KLocalizedString>
0012 #include <KMessageBox>
0013 #include <MailTransport/ServerTest>
0014 #include <MailTransport/Transport>
0015 
0016 /** static helper functions **/
0017 static QString authenticationModeString(MailTransport::Transport::EnumAuthenticationType mode)
0018 {
0019     switch (mode) {
0020     case MailTransport::Transport::EnumAuthenticationType::LOGIN:
0021         return QStringLiteral("LOGIN");
0022     case MailTransport::Transport::EnumAuthenticationType::PLAIN:
0023         return QStringLiteral("PLAIN");
0024     case MailTransport::Transport::EnumAuthenticationType::CRAM_MD5:
0025         return QStringLiteral("CRAM-MD5");
0026     case MailTransport::Transport::EnumAuthenticationType::DIGEST_MD5:
0027         return QStringLiteral("DIGEST-MD5");
0028     case MailTransport::Transport::EnumAuthenticationType::GSSAPI:
0029         return QStringLiteral("GSSAPI");
0030     case MailTransport::Transport::EnumAuthenticationType::NTLM:
0031         return QStringLiteral("NTLM");
0032     case MailTransport::Transport::EnumAuthenticationType::CLEAR:
0033         return i18nc("Authentication method", "Clear text");
0034     case MailTransport::Transport::EnumAuthenticationType::ANONYMOUS:
0035         return i18nc("Authentication method", "Anonymous");
0036     default:
0037         break;
0038     }
0039     return {};
0040 }
0041 
0042 static void addAuthenticationItem(QComboBox *authCombo, MailTransport::Transport::EnumAuthenticationType authtype)
0043 {
0044     // qCDebug(SIEVEEDITOR_LOG) << "adding auth item " << authenticationModeString( authtype );
0045     authCombo->addItem(authenticationModeString(authtype), QVariant(authtype));
0046 }
0047 
0048 static MailTransport::Transport::EnumAuthenticationType getCurrentAuthMode(QComboBox *authCombo)
0049 {
0050     auto authtype = static_cast<MailTransport::Transport::EnumAuthenticationType>(authCombo->itemData(authCombo->currentIndex()).toInt());
0051     // qCDebug(SIEVEEDITOR_LOG) << "current auth mode: " << authenticationModeString( authtype );
0052     return authtype;
0053 }
0054 
0055 static void setCurrentAuthMode(QComboBox *authCombo, MailTransport::Transport::EnumAuthenticationType authtype)
0056 {
0057     // qCDebug(SIEVEEDITOR_LOG) << "setting authcombo: " << authenticationModeString( authtype );
0058     int index = authCombo->findData(authtype);
0059     if (index == -1) {
0060         qCWarning(SIEVEEDITOR_LOG) << "desired authmode not in the combo";
0061     }
0062     // qCDebug(SIEVEEDITOR_LOG) << "found corresponding index: " << index << "with data" << authenticationModeString(
0063     // (MailTransport::Transport::EnumAuthenticationType) authCombo->itemData( index ).toInt() );
0064     authCombo->setCurrentIndex(index);
0065     MailTransport::Transport::EnumAuthenticationType t =
0066         static_cast<MailTransport::Transport::EnumAuthenticationType>(authCombo->itemData(authCombo->currentIndex()).toInt());
0067     // qCDebug(SIEVEEDITOR_LOG) << "selected auth mode:" << authenticationModeString( t );
0068     Q_ASSERT(t == authtype);
0069 }
0070 
0071 ServerSieveSettings::ServerSieveSettings(QWidget *parent)
0072     : QWidget(parent)
0073     , ui(new Ui::ServerSieveSettings)
0074 {
0075     ui->setupUi(this);
0076     ui->serversievelabel->setMinimumSize(ui->serversievelabel->sizeHint());
0077     ui->testInfo->clear();
0078     ui->testInfo->hide();
0079     ui->testProgress->hide();
0080     ui->password->setRevealPasswordAvailable(KAuthorized::authorize(QStringLiteral("lineedit_reveal_password")));
0081     ui->imapPassword->setRevealPasswordAvailable(KAuthorized::authorize(QStringLiteral("lineedit_reveal_password")));
0082 
0083     ui->safeImapGroup->setId(ui->noRadio, KSieveCore::SieveImapAccountSettings::Unencrypted);
0084     ui->safeImapGroup->setId(ui->sslRadio, KSieveCore::SieveImapAccountSettings::SSLorTLS);
0085     ui->safeImapGroup->setId(ui->tlsRadio, KSieveCore::SieveImapAccountSettings::STARTTLS);
0086 
0087     connect(ui->testButton, &QPushButton::pressed, this, &ServerSieveSettings::slotTest);
0088 
0089     populateDefaultComboBoxAuthenticationOptions();
0090     connect(ui->serverName, &QLineEdit::textChanged, this, &ServerSieveSettings::slotUserServerNameChanged);
0091     connect(ui->userName, &QLineEdit::textChanged, this, &ServerSieveSettings::slotUserServerNameChanged);
0092 }
0093 
0094 ServerSieveSettings::~ServerSieveSettings()
0095 {
0096     delete ui;
0097 }
0098 
0099 void ServerSieveSettings::populateDefaultComboBoxAuthenticationOptions()
0100 {
0101     populateDefaultAuthenticationOptions(ui->authenticationCombo);
0102     populateDefaultAuthenticationOptions(ui->imapAuthenticationCombo);
0103 }
0104 
0105 void ServerSieveSettings::populateDefaultAuthenticationOptions(QComboBox *combobox)
0106 {
0107     combobox->clear();
0108     addAuthenticationItem(combobox, MailTransport::Transport::EnumAuthenticationType::CLEAR);
0109     addAuthenticationItem(combobox, MailTransport::Transport::EnumAuthenticationType::LOGIN);
0110     addAuthenticationItem(combobox, MailTransport::Transport::EnumAuthenticationType::PLAIN);
0111     addAuthenticationItem(combobox, MailTransport::Transport::EnumAuthenticationType::CRAM_MD5);
0112     addAuthenticationItem(combobox, MailTransport::Transport::EnumAuthenticationType::DIGEST_MD5);
0113     addAuthenticationItem(combobox, MailTransport::Transport::EnumAuthenticationType::NTLM);
0114     addAuthenticationItem(combobox, MailTransport::Transport::EnumAuthenticationType::GSSAPI);
0115     addAuthenticationItem(combobox, MailTransport::Transport::EnumAuthenticationType::ANONYMOUS);
0116 }
0117 
0118 void ServerSieveSettings::slotUserServerNameChanged()
0119 {
0120     Q_EMIT enableOkButton(!ui->userName->text().trimmed().isEmpty() && !ui->serverName->text().trimmed().isEmpty());
0121 }
0122 
0123 QString ServerSieveSettings::serverName() const
0124 {
0125     return ui->serverName->text().trimmed();
0126 }
0127 
0128 void ServerSieveSettings::setServerName(const QString &name)
0129 {
0130     ui->serverName->setText(name);
0131 }
0132 
0133 int ServerSieveSettings::port() const
0134 {
0135     return ui->port->value();
0136 }
0137 
0138 void ServerSieveSettings::setPort(int value)
0139 {
0140     ui->port->setValue(value);
0141 }
0142 
0143 QString ServerSieveSettings::userName() const
0144 {
0145     return ui->userName->text().trimmed();
0146 }
0147 
0148 void ServerSieveSettings::setUserName(const QString &name)
0149 {
0150     ui->userName->setText(name);
0151 }
0152 
0153 QString ServerSieveSettings::password() const
0154 {
0155     return ui->password->password();
0156 }
0157 
0158 void ServerSieveSettings::setPassword(const QString &pass)
0159 {
0160     ui->password->setPassword(pass);
0161 }
0162 
0163 QString ServerSieveSettings::imapServerName() const
0164 {
0165     return ui->imapServerName->text().trimmed();
0166 }
0167 
0168 void ServerSieveSettings::setImapServerName(const QString &name)
0169 {
0170     ui->imapServerName->setText(name);
0171 }
0172 
0173 int ServerSieveSettings::imapPort() const
0174 {
0175     return ui->imapPort->value();
0176 }
0177 
0178 void ServerSieveSettings::setImapPort(int value)
0179 {
0180     ui->imapPort->setValue(value);
0181 }
0182 
0183 QString ServerSieveSettings::imapUserName() const
0184 {
0185     return ui->imapUserName->text().trimmed();
0186 }
0187 
0188 void ServerSieveSettings::setImapUserName(const QString &name)
0189 {
0190     ui->imapUserName->setText(name);
0191 }
0192 
0193 QString ServerSieveSettings::imapPassword() const
0194 {
0195     return ui->imapPassword->password();
0196 }
0197 
0198 void ServerSieveSettings::setImapPassword(const QString &pass)
0199 {
0200     ui->imapPassword->setPassword(pass);
0201 }
0202 
0203 void ServerSieveSettings::setAuthenticationType(KSieveCore::SieveImapAccountSettings::AuthenticationMode type)
0204 {
0205     setCurrentAuthMode(ui->imapAuthenticationCombo, static_cast<MailTransport::Transport::EnumAuthenticationType>(type));
0206 }
0207 
0208 KSieveCore::SieveImapAccountSettings::AuthenticationMode ServerSieveSettings::authenticationType() const
0209 {
0210     return static_cast<KSieveCore::SieveImapAccountSettings::AuthenticationMode>(getCurrentAuthMode(ui->imapAuthenticationCombo));
0211 }
0212 
0213 void ServerSieveSettings::setServerSieveConfig(const SieveEditorUtil::SieveServerConfig &conf)
0214 {
0215     setPassword(conf.sieveSettings.password);
0216     setPort(conf.sieveSettings.port);
0217     setServerName(conf.sieveSettings.serverName);
0218     setUserName(conf.sieveSettings.userName);
0219     setCurrentAuthMode(ui->authenticationCombo, conf.sieveSettings.authenticationType);
0220     ui->alternateServer->setChecked(conf.useImapCustomServer);
0221     if (conf.useImapCustomServer) {
0222         setImapPassword(conf.sieveImapAccountSettings.password());
0223         setImapUserName(conf.sieveImapAccountSettings.userName());
0224         setImapServerName(conf.sieveImapAccountSettings.serverName());
0225     }
0226     setImapPort(conf.sieveImapAccountSettings.port());
0227     setAuthenticationType(conf.sieveImapAccountSettings.authenticationType());
0228 
0229     ui->safeImap->setChecked(conf.sieveImapAccountSettings.isValid());
0230     QAbstractButton *safetyButton = ui->safeImapGroup->button(conf.sieveImapAccountSettings.encryptionMode());
0231     if (safetyButton) {
0232         safetyButton->setChecked(true);
0233     }
0234 }
0235 
0236 SieveEditorUtil::SieveServerConfig ServerSieveSettings::serverSieveConfig() const
0237 {
0238     SieveEditorUtil::SieveServerConfig conf;
0239     conf.sieveSettings.password = password();
0240     conf.sieveSettings.port = port();
0241     conf.sieveSettings.serverName = serverName();
0242     conf.sieveSettings.userName = userName();
0243     const MailTransport::Transport::EnumAuthenticationType authtype = getCurrentAuthMode(ui->authenticationCombo);
0244     conf.sieveSettings.authenticationType = authtype;
0245 
0246     conf.useImapCustomServer = ui->alternateServer->isChecked();
0247     if (ui->alternateServer->isChecked()) {
0248         conf.sieveImapAccountSettings.setPassword(imapPassword());
0249         conf.sieveImapAccountSettings.setUserName(imapUserName());
0250         conf.sieveImapAccountSettings.setServerName(imapServerName());
0251     } else {
0252         conf.sieveImapAccountSettings.setPassword(password());
0253         conf.sieveImapAccountSettings.setUserName(userName());
0254         conf.sieveImapAccountSettings.setServerName(serverName());
0255     }
0256     if (ui->safeImap->isChecked()) {
0257         conf.sieveImapAccountSettings.setPort(imapPort());
0258         conf.sieveImapAccountSettings.setAuthenticationType(authenticationType());
0259         conf.sieveImapAccountSettings.setEncryptionMode(static_cast<KSieveCore::SieveImapAccountSettings::EncryptionMode>(ui->safeImapGroup->checkedId()));
0260     }
0261     return conf;
0262 }
0263 
0264 void ServerSieveSettings::slotTest()
0265 {
0266     const QString server = imapServerName().isEmpty() ? serverName() : imapServerName();
0267     if (server.isEmpty()) {
0268         KMessageBox::error(this, i18n("Server is not defined"), i18nc("@title:window", "Check Server"));
0269         return;
0270     }
0271     // qCDebug(SIEVEEDITOR_LOG) << ui->imapServer->text();
0272     ui->testButton->setEnabled(false);
0273     ui->safeImap->setEnabled(false);
0274     ui->imapAuthenticationCombo->setEnabled(false);
0275 
0276     ui->testInfo->clear();
0277     ui->testInfo->hide();
0278 
0279     delete mServerTest;
0280     mServerTest = new MailTransport::ServerTest(this);
0281 #ifndef QT_NO_CURSOR
0282     qApp->setOverrideCursor(Qt::BusyCursor);
0283 #endif
0284 
0285     const int portValue = ui->imapPort->value();
0286     qCDebug(SIEVEEDITOR_LOG) << "server: " << server << "port: " << portValue;
0287 
0288     mServerTest->setServer(server);
0289 
0290     if (portValue != 143 && portValue != 993) {
0291         mServerTest->setPort(MailTransport::Transport::EnumEncryption::None, portValue);
0292         mServerTest->setPort(MailTransport::Transport::EnumEncryption::SSL, portValue);
0293     }
0294 
0295     mServerTest->setProtocol(QStringLiteral("imap"));
0296     mServerTest->setProgressBar(ui->testProgress);
0297     connect(mServerTest, &MailTransport::ServerTest::finished, this, &ServerSieveSettings::slotFinished);
0298     mServerTest->start();
0299 }
0300 
0301 void ServerSieveSettings::slotFinished(const QList<int> &testResult)
0302 {
0303     qCDebug(SIEVEEDITOR_LOG) << testResult;
0304 
0305 #ifndef QT_NO_CURSOR
0306     qApp->restoreOverrideCursor();
0307 #endif
0308     using namespace MailTransport;
0309 
0310     if (!mServerTest->isNormalPossible() && !mServerTest->isSecurePossible()) {
0311         KMessageBox::error(this, i18n("Unable to connect to the server, please verify the server address."));
0312     }
0313 
0314     ui->testInfo->show();
0315 
0316     ui->sslRadio->setEnabled(testResult.contains(Transport::EnumEncryption::SSL));
0317     ui->tlsRadio->setEnabled(testResult.contains(Transport::EnumEncryption::TLS));
0318     ui->noRadio->setEnabled(testResult.contains(Transport::EnumEncryption::None));
0319 
0320     QString text;
0321     if (testResult.contains(Transport::EnumEncryption::TLS)) {
0322         ui->tlsRadio->setChecked(true);
0323         text = i18n("<qt><b>TLS is supported and recommended.</b></qt>");
0324     } else if (testResult.contains(Transport::EnumEncryption::SSL)) {
0325         ui->sslRadio->setChecked(true);
0326         text = i18n("<qt><b>SSL is supported and recommended.</b></qt>");
0327     } else if (testResult.contains(Transport::EnumEncryption::None)) {
0328         ui->noRadio->setChecked(true);
0329         text = i18n(
0330             "<qt><b>No security is supported. It is not "
0331             "recommended to connect to this server.</b></qt>");
0332     } else {
0333         text = i18n("<qt><b>It is not possible to use this server.</b></qt>");
0334     }
0335     ui->testInfo->setText(text);
0336 
0337     ui->testButton->setEnabled(true);
0338     ui->safeImap->setEnabled(true);
0339     ui->imapAuthenticationCombo->setEnabled(true);
0340     slotEncryptionRadioChanged();
0341     slotSafetyChanged();
0342 }
0343 
0344 void ServerSieveSettings::slotEncryptionRadioChanged()
0345 {
0346     switch (ui->safeImapGroup->checkedId()) {
0347     case KSieveCore::SieveImapAccountSettings::Unencrypted:
0348     case KSieveCore::SieveImapAccountSettings::STARTTLS:
0349         ui->imapPort->setValue(143);
0350         break;
0351     case KSieveCore::SieveImapAccountSettings::SSLorTLS:
0352         ui->imapPort->setValue(993);
0353         break;
0354     default:
0355         qFatal("Shouldn't happen");
0356     }
0357 }
0358 
0359 void ServerSieveSettings::slotSafetyChanged()
0360 {
0361     if (mServerTest == nullptr) {
0362         qCDebug(SIEVEEDITOR_LOG) << "serverTest null";
0363         ui->noRadio->setEnabled(true);
0364         ui->sslRadio->setEnabled(true);
0365         ui->tlsRadio->setEnabled(true);
0366 
0367         ui->imapAuthenticationCombo->setEnabled(true);
0368         return;
0369     }
0370 
0371     QList<int> protocols;
0372 
0373     switch (ui->safeImapGroup->checkedId()) {
0374     case KSieveCore::SieveImapAccountSettings::Unencrypted:
0375         qCDebug(SIEVEEDITOR_LOG) << "safeImapGroup: unencrypted";
0376         protocols = mServerTest->normalProtocols();
0377         break;
0378     case KSieveCore::SieveImapAccountSettings::SSLorTLS:
0379         protocols = mServerTest->secureProtocols();
0380         qCDebug(SIEVEEDITOR_LOG) << "safeImapGroup: SSL";
0381         break;
0382     case KSieveCore::SieveImapAccountSettings::STARTTLS:
0383         protocols = mServerTest->tlsProtocols();
0384         qCDebug(SIEVEEDITOR_LOG) << "safeImapGroup: starttls";
0385         break;
0386     default:
0387         qFatal("Shouldn't happen");
0388     }
0389 
0390     ui->imapAuthenticationCombo->clear();
0391     addAuthenticationItem(ui->imapAuthenticationCombo, MailTransport::Transport::EnumAuthenticationType::CLEAR);
0392     for (int prot : std::as_const(protocols)) {
0393         addAuthenticationItem(ui->imapAuthenticationCombo, static_cast<MailTransport::Transport::EnumAuthenticationType>(prot));
0394     }
0395     if (protocols.isEmpty()) {
0396         qCDebug(SIEVEEDITOR_LOG) << "no authmodes found";
0397     } else {
0398         setCurrentAuthMode(ui->imapAuthenticationCombo, static_cast<MailTransport::Transport::EnumAuthenticationType>(protocols.constFirst()));
0399     }
0400     mServerTest->deleteLater();
0401     mServerTest = nullptr;
0402 }
0403 
0404 #include "moc_serversievesettings.cpp"