File indexing completed on 2025-02-16 04:50:21
0001 /* 0002 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com> 0003 SPDX-FileContributor: Kevin Ottens <kevin@kdab.com> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "settingspasswordrequester.h" 0009 0010 #include <KLocalizedString> 0011 #include <KMessageBox> 0012 0013 #include "imapresource_debug.h" 0014 #include "imapresourcebase.h" 0015 #include "settings.h" 0016 #include <KAuthorized> 0017 #include <KPasswordDialog> 0018 #include <QDialogButtonBox> 0019 #include <QPushButton> 0020 #include <kwindowsystem.h> 0021 #include <mailtransport/transportbase.h> 0022 0023 SettingsPasswordRequester::SettingsPasswordRequester(ImapResourceBase *resource, QObject *parent) 0024 : PasswordRequesterInterface(parent) 0025 , m_resource(resource) 0026 { 0027 } 0028 0029 SettingsPasswordRequester::~SettingsPasswordRequester() 0030 { 0031 cancelPasswordRequests(); 0032 } 0033 0034 void SettingsPasswordRequester::requestPassword(RequestType request, const QString &serverError) 0035 { 0036 if (request == WrongPasswordRequest) { 0037 QMetaObject::invokeMethod(this, "askUserInput", Qt::QueuedConnection, Q_ARG(QString, serverError)); 0038 } else { 0039 connect(m_resource->settings(), &Settings::passwordRequestCompleted, this, &SettingsPasswordRequester::onPasswordRequestCompleted); 0040 m_resource->settings()->requestPassword(); 0041 } 0042 } 0043 0044 void SettingsPasswordRequester::askUserInput(const QString &serverError) 0045 { 0046 // the credentials were not ok, allow to retry or change password 0047 if (m_requestDialog) { 0048 qCDebug(IMAPRESOURCE_LOG) << "Password request dialog is already open"; 0049 return; 0050 } 0051 QWidget *parent = QWidget::find(m_resource->winIdForDialogs()); 0052 const QString text = i18n( 0053 "The server for account \"%2\" refused the supplied username and password.\n" 0054 "Do you want to go to the settings, have another attempt " 0055 "at logging in, or do nothing?\n\n" 0056 "%1", 0057 serverError, 0058 m_resource->name()); 0059 auto dialog = new QDialog(parent, Qt::Dialog); 0060 dialog->setWindowTitle(i18nc("@title:window", "Could Not Authenticate")); 0061 auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::No | QDialogButtonBox::Yes, dialog); 0062 buttonBox->button(QDialogButtonBox::Yes)->setDefault(true); 0063 0064 buttonBox->button(QDialogButtonBox::Yes)->setText(i18n("Account Settings")); 0065 buttonBox->button(QDialogButtonBox::No)->setText(i18nc("Input username/password manually and not store them", "Try Again")); 0066 dialog->setAttribute(Qt::WA_DeleteOnClose); 0067 connect(buttonBox->button(QDialogButtonBox::Yes), &QPushButton::clicked, this, &SettingsPasswordRequester::slotYesClicked); 0068 connect(buttonBox->button(QDialogButtonBox::No), &QPushButton::clicked, this, &SettingsPasswordRequester::slotNoClicked); 0069 connect(buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &SettingsPasswordRequester::slotCancelClicked); 0070 0071 connect(dialog, &QDialog::destroyed, this, &SettingsPasswordRequester::onDialogDestroyed); 0072 m_requestDialog = dialog; 0073 dialog->setAttribute(Qt::WA_NativeWindow, true); 0074 KWindowSystem::setMainWindow(dialog->windowHandle(), m_resource->winIdForDialogs()); 0075 bool checkboxResult = false; 0076 KMessageBox::createKMessageBox(dialog, buttonBox, QMessageBox::Information, text, QStringList(), QString(), &checkboxResult, KMessageBox::NoExec); 0077 dialog->show(); 0078 } 0079 0080 void SettingsPasswordRequester::onDialogDestroyed() 0081 { 0082 m_requestDialog = nullptr; 0083 } 0084 0085 void SettingsPasswordRequester::slotNoClicked() 0086 { 0087 connect(m_resource->settings(), &Settings::passwordRequestCompleted, this, &SettingsPasswordRequester::onPasswordRequestCompleted); 0088 requestManualAuth(nullptr); 0089 m_requestDialog = nullptr; 0090 } 0091 0092 void SettingsPasswordRequester::slotYesClicked() 0093 { 0094 if (!m_settingsDialog) { 0095 QDialog *dialog = m_resource->createConfigureDialog(m_resource->winIdForDialogs()); 0096 connect(dialog, &QDialog::finished, this, &SettingsPasswordRequester::onSettingsDialogFinished); 0097 m_settingsDialog = dialog; 0098 dialog->show(); 0099 } 0100 m_requestDialog = nullptr; 0101 } 0102 0103 void SettingsPasswordRequester::slotCancelClicked() 0104 { 0105 Q_EMIT done(UserRejected); 0106 m_requestDialog = nullptr; 0107 } 0108 0109 void SettingsPasswordRequester::onSettingsDialogFinished(int result) 0110 { 0111 m_settingsDialog = nullptr; 0112 if (result == QDialog::Accepted) { 0113 Q_EMIT done(ReconnectNeeded); 0114 } else { 0115 Q_EMIT done(UserRejected); 0116 } 0117 } 0118 0119 void SettingsPasswordRequester::cancelPasswordRequests() 0120 { 0121 if (m_requestDialog) { 0122 if (m_requestDialog->close()) { 0123 m_requestDialog = nullptr; 0124 } 0125 } 0126 } 0127 0128 void SettingsPasswordRequester::onPasswordRequestCompleted(const QString &password, bool userRejected) 0129 { 0130 disconnect(m_resource->settings(), &Settings::passwordRequestCompleted, this, &SettingsPasswordRequester::onPasswordRequestCompleted); 0131 0132 QString pwd = password; 0133 if (userRejected || pwd.isEmpty()) { 0134 pwd = requestManualAuth(&userRejected); 0135 } 0136 0137 if (userRejected) { 0138 Q_EMIT done(UserRejected); 0139 } else if (password.isEmpty() && (m_resource->settings()->authentication() != MailTransport::Transport::EnumAuthenticationType::GSSAPI)) { 0140 Q_EMIT done(EmptyPasswordEntered); 0141 } else { 0142 Q_EMIT done(PasswordRetrieved, password); 0143 } 0144 } 0145 0146 QString SettingsPasswordRequester::requestManualAuth(bool *userRejected) 0147 { 0148 QScopedPointer<KPasswordDialog> dlg(new KPasswordDialog(nullptr)); 0149 dlg->setModal(true); 0150 dlg->setPrompt(i18n("Please enter password for user '%1' on IMAP server '%2'.", m_resource->settings()->userName(), m_resource->settings()->imapServer())); 0151 dlg->setPassword(m_resource->settings()->password()); 0152 dlg->setRevealPasswordAvailable(KAuthorized::authorize(QStringLiteral("lineedit_reveal_password"))); 0153 if (dlg->exec()) { 0154 if (userRejected) { 0155 *userRejected = false; 0156 } 0157 m_resource->settings()->setPassword(dlg->password()); 0158 return dlg->password(); 0159 } else { 0160 if (userRejected) { 0161 *userRejected = true; 0162 } 0163 return {}; 0164 } 0165 } 0166 0167 #include "moc_settingspasswordrequester.cpp"