14#include "smtpconfigwidget.h"
17#include "ui_smtpsettings.h"
20#include "mailtransportplugin_smtp_debug.h"
21#include "servertest.h"
23#include "transportmanager.h"
24#include "widgets/transportactivitiesabstractplugin.h"
25#include "widgets/transportconfigwidget_p.h"
27#include <QAbstractButton>
28#include <QButtonGroup>
31#include <KLocalizedString>
33#include <KPluginFactory>
34#include <KPluginMetaData>
35#include <KProtocolInfo>
37using namespace MailTransport;
39class MailTransport::SMTPConfigWidgetPrivate :
public TransportConfigWidgetPrivate
42 ::Ui::SMTPSettings ui;
44 ServerTest *serverTest =
nullptr;
45 QButtonGroup *encryptionGroup =
nullptr;
48 QList<int> noEncCapa, sslCapa, tlsCapa;
50 bool serverTestFailed;
52 static void addAuthenticationItem(QComboBox *combo,
int authenticationType)
57 void resetAuthCapabilities()
60 noEncCapa << Transport::EnumAuthenticationType::LOGIN << Transport::EnumAuthenticationType::PLAIN << Transport::EnumAuthenticationType::CRAM_MD5
61 << Transport::EnumAuthenticationType::DIGEST_MD5 << Transport::EnumAuthenticationType::NTLM << Transport::EnumAuthenticationType::GSSAPI
62 << Transport::EnumAuthenticationType::XOAUTH2;
63 sslCapa = tlsCapa = noEncCapa;
64 updateAuthCapbilities();
67 void enablePasswordLine()
69 ui.password->setEnabled(ui.kcfg_storePassword->isChecked() && ui.kcfg_requiresAuthentication->isChecked());
72 void updateAuthCapbilities()
74 if (serverTestFailed) {
78 QList<int> capa = noEncCapa;
79 if (ui.encryptionSsl->isChecked()) {
81 }
else if (ui.encryptionTls->isChecked()) {
85 ui.authCombo->clear();
86 for (
int authType : std::as_const(capa)) {
87 addAuthenticationItem(ui.authCombo, authType);
90 if (transport->isValid()) {
91 const int idx = ui.authCombo->findData(transport->authenticationType());
94 ui.authCombo->setCurrentIndex(idx);
99 ui.noAuthPossible->setVisible(
true);
100 ui.kcfg_requiresAuthentication->setChecked(
false);
101 ui.kcfg_requiresAuthentication->setEnabled(
false);
102 ui.kcfg_requiresAuthentication->setVisible(
false);
103 ui.authCombo->setEnabled(
false);
104 ui.authLabel->setEnabled(
false);
106 ui.noAuthPossible->setVisible(
false);
107 ui.kcfg_requiresAuthentication->setEnabled(
true);
108 ui.kcfg_requiresAuthentication->setVisible(
true);
109 ui.authCombo->setEnabled(
true);
110 ui.authLabel->setEnabled(
true);
111 enablePasswordLine();
122static void checkHighestEnabledButton(
QButtonGroup *group)
126 for (
int i = group->
buttons().count() - 1; i >= 0; --i) {
135void SMTPConfigWidget::init()
137 Q_D(SMTPConfigWidget);
138 d->serverTest =
nullptr;
142 d->serverTestFailed =
false;
145 d->ui.tabWidget->tabBar()->setExpanding(
true);
146 d->ui.password->setRevealPasswordMode(
KAuthorized::authorize(QStringLiteral(
"lineedit_reveal_password")) ? KPassword::RevealMode::OnlyNew
147 : KPassword::RevealMode::Never);
148 d->manager->addWidget(
this);
149 d->manager->updateWidgets();
151 d->ui.password->setWhatsThis(
i18n(
"The password to send to the server for authorization."));
153 d->ui.kcfg_userName->setClearButtonEnabled(
true);
154 d->encryptionGroup =
new QButtonGroup(
this);
155 d->encryptionGroup->addButton(d->ui.encryptionNone, Transport::EnumEncryption::None);
156 d->encryptionGroup->addButton(d->ui.encryptionSsl, Transport::EnumEncryption::SSL);
157 d->encryptionGroup->addButton(d->ui.encryptionTls, Transport::EnumEncryption::TLS);
159 d->ui.encryptionNone->setChecked(d->transport->encryption() == Transport::EnumEncryption::None);
160 d->ui.encryptionSsl->setChecked(d->transport->encryption() == Transport::EnumEncryption::SSL);
161 d->ui.encryptionTls->setChecked(d->transport->encryption() == Transport::EnumEncryption::TLS);
163 d->ui.checkCapabilitiesProgress->setFormat(
i18nc(
"Percent value; %p is the value, % is the percent sign",
"%p%"));
165 d->resetAuthCapabilities();
167 if (!KProtocolInfo::capabilities(SMTP_PROTOCOL).contains(
"SASL"_L1)) {
168 d->ui.authCombo->removeItem(d->ui.authCombo->findData(Transport::EnumAuthenticationType::NTLM));
169 d->ui.authCombo->removeItem(d->ui.authCombo->findData(Transport::EnumAuthenticationType::GSSAPI));
178 if (!d->transport->isValid()) {
179 checkHighestEnabledButton(d->encryptionGroup);
183 d->transport->updatePasswordState();
184 if (d->transport->isComplete()) {
185 d->ui.password->setRevealPasswordMode(
KAuthorized::authorize(QStringLiteral(
"lineedit_reveal_password")) ? KPassword::RevealMode::Always
186 : KPassword::RevealMode::Never);
187 d->ui.password->setPassword(d->transport->password());
189 if (d->transport->requiresAuthentication()) {
194 hostNameChanged(d->transport->host());
196 const KPluginMetaData editWidgetPlugin(QStringLiteral(
"pim6/mailtransportactivities/kmailtransportactivitiesplugin"));
198 const auto result = KPluginFactory::instantiatePlugin<MailTransport::TransportActivitiesAbstractPlugin>(editWidgetPlugin);
200 mTransportActivitiesPlugin = result.plugin;
202 if (mTransportActivitiesPlugin) {
203 d->ui.tabWidget->addTab(mTransportActivitiesPlugin,
i18n(
"Activities"));
204 TransportActivitiesAbstractPlugin::ActivitySettings settings{
205 d->transport->activities(),
206 d->transport->activitiesEnabled(),
208 mTransportActivitiesPlugin->setActivitiesSettings(settings);
212void SMTPConfigWidget::enablePasswordLine()
214 Q_D(SMTPConfigWidget);
215 d->enablePasswordLine();
218void SMTPConfigWidget::checkSmtpCapabilities()
220 Q_D(SMTPConfigWidget);
222 d->serverTest =
new ServerTest(
this);
223 d->serverTest->setProtocol(SMTP_PROTOCOL);
224 d->serverTest->setServer(d->ui.kcfg_host->text().trimmed());
225 if (d->ui.kcfg_specifyHostname->isChecked()) {
226 d->serverTest->setFakeHostname(d->ui.kcfg_localHostname->text());
228 QAbstractButton *encryptionChecked = d->encryptionGroup->checkedButton();
229 if (encryptionChecked == d->ui.encryptionNone) {
230 d->serverTest->setPort(Transport::EnumEncryption::None, d->ui.kcfg_port->value());
231 }
else if (encryptionChecked == d->ui.encryptionSsl) {
232 d->serverTest->setPort(Transport::EnumEncryption::SSL, d->ui.kcfg_port->value());
234 d->serverTest->setProgressBar(d->ui.checkCapabilitiesProgress);
235 d->ui.checkCapabilitiesStack->setCurrentIndex(1);
240 qApp->restoreOverrideCursor();
242 d->ui.checkCapabilities->setEnabled(
false);
243 d->serverTest->start();
244 d->serverTestFailed =
false;
249 Q_D(SMTPConfigWidget);
250 Q_ASSERT(d->manager);
251 d->manager->updateSettings();
252 if (!d->ui.kcfg_storePassword->isChecked() && d->ui.kcfg_requiresAuthentication->isChecked()) {
256 d->transport->setPassword(d->ui.password->password());
258 KConfigGroup group(d->transport->config(), d->transport->currentGroup());
259 const int index = d->ui.authCombo->currentIndex();
261 group.
writeEntry(
"authtype", d->ui.authCombo->itemData(index).toInt());
264 if (d->ui.encryptionNone->isChecked()) {
265 d->transport->setEncryption(Transport::EnumEncryption::None);
266 }
else if (d->ui.encryptionSsl->isChecked()) {
267 d->transport->setEncryption(Transport::EnumEncryption::SSL);
268 }
else if (d->ui.encryptionTls->isChecked()) {
269 d->transport->setEncryption(Transport::EnumEncryption::TLS);
272 if (mTransportActivitiesPlugin) {
273 const TransportActivitiesAbstractPlugin::ActivitySettings settings = mTransportActivitiesPlugin->activitiesSettings();
274 d->transport->setActivities(settings.activities);
275 d->transport->setActivitiesEnabled(settings.enabled);
281void SMTPConfigWidget::passwordsLoaded()
286 d->transport->updatePasswordState();
288 if (d->ui.password->password().isEmpty()) {
289 d->ui.password->setPassword(d->transport->password());
293void SMTPConfigWidget::slotTestFinished(
const QList<int> &results)
295 Q_D(SMTPConfigWidget);
297 d->ui.checkCapabilitiesStack->setCurrentIndex(0);
299 d->ui.checkCapabilities->setEnabled(
true);
300 d->serverTest->deleteLater();
306 i18n(
"Failed to check capabilities. Please verify port and authentication mode."),
307 i18nc(
"@title:window",
"Check Capabilities Failed"));
308 d->serverTestFailed =
true;
309 d->serverTest->deleteLater();
314 d->ui.encryptionNone->setEnabled(results.
contains(Transport::EnumEncryption::None));
315 d->ui.encryptionSsl->setEnabled(results.
contains(Transport::EnumEncryption::SSL));
316 d->ui.encryptionTls->setEnabled(results.
contains(Transport::EnumEncryption::TLS));
317 checkHighestEnabledButton(d->encryptionGroup);
319 d->noEncCapa = d->serverTest->normalProtocols();
320 if (d->ui.encryptionTls->isEnabled()) {
321 d->tlsCapa = d->serverTest->tlsProtocols();
325 d->sslCapa = d->serverTest->secureProtocols();
326 d->updateAuthCapbilities();
328 if (d->ui.encryptionSsl->isEnabled()) {
329 const int portValue = d->serverTest->port(Transport::EnumEncryption::SSL);
330 d->ui.kcfg_port->setValue(portValue == -1 ? SMTPS_PORT : portValue);
331 }
else if (d->ui.encryptionNone->isEnabled()) {
332 const int portValue = d->serverTest->port(Transport::EnumEncryption::None);
333 d->ui.kcfg_port->setValue(portValue == -1 ? SMTP_PORT : portValue);
335 d->serverTest->deleteLater();
338void SMTPConfigWidget::hostNameChanged(
const QString &text)
342 Q_D(SMTPConfigWidget);
345 const int pos = d->ui.kcfg_host->cursorPosition();
346 d->ui.kcfg_host->blockSignals(
true);
347 d->ui.kcfg_host->setText(text.
trimmed());
348 d->ui.kcfg_host->blockSignals(
false);
349 d->ui.kcfg_host->setCursorPosition(
pos);
351 d->resetAuthCapabilities();
352 if (d->encryptionGroup) {
353 for (
int i = 0; i < d->encryptionGroup->buttons().count(); ++i) {
354 d->encryptionGroup->buttons().at(i)->setEnabled(
true);
359void SMTPConfigWidget::ensureValidAuthSelection()
361 Q_D(SMTPConfigWidget);
364 d->updateAuthCapbilities();
365 d->enablePasswordLine();
368void SMTPConfigWidget::encryptionAbstractButtonChanged(QAbstractButton *button)
370 Q_D(SMTPConfigWidget);
372 encryptionChanged(d->encryptionGroup->id(button));
376void SMTPConfigWidget::encryptionChanged(
int enc)
378 Q_D(SMTPConfigWidget);
379 qCDebug(MAILTRANSPORT_SMTP_LOG) << enc;
382 if (enc == Transport::EnumEncryption::SSL) {
383 if (d->ui.kcfg_port->value() == SMTP_PORT) {
384 d->ui.kcfg_port->setValue(SMTPS_PORT);
387 if (d->ui.kcfg_port->value() == SMTPS_PORT) {
388 d->ui.kcfg_port->setValue(SMTP_PORT);
392 ensureValidAuthSelection();
395#include "moc_smtpconfigwidget.cpp"
static Q_INVOKABLE bool authorize(const QString &action)
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
void finished(const QList< int > &)
This will be emitted when the test is done.
void loadPasswordsAsync()
Tries to load passwords asynchronously from KWallet if needed.
void passwordsChanged()
Emitted when passwords have been loaded from the wallet.
static TransportManager * self()
Returns the TransportManager instance.
Represents the settings of a specific mail transport.
QString authenticationTypeString() const
Returns a string representation of the authentication type.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
Internal file containing constant definitions etc.
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
void addItem(const QIcon &icon, const QString &text, const QVariant &userData)
void textChanged(const QString &text)
bool contains(const AT &value) const const
bool isEmpty() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString trimmed() const const