File indexing completed on 2024-10-06 04:35:36
0001 /* 0002 The configuration page for the authentication settings of Smb4K 0003 0004 SPDX-FileCopyrightText: 2003-2023 Alexander Reinholdt <alexander.reinholdt@kdemail.net> 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 // application specific includes 0009 #include "smb4kconfigpageauthentication.h" 0010 #include "core/smb4ksettings.h" 0011 #include "core/smb4kwalletmanager.h" 0012 0013 // Qt includes 0014 #include <QDialogButtonBox> 0015 #include <QGroupBox> 0016 #include <QHBoxLayout> 0017 #include <QListWidgetItem> 0018 #include <QMouseEvent> 0019 #include <QVBoxLayout> 0020 0021 // KDE includes 0022 #include <KIconLoader> 0023 #include <KLocalizedString> 0024 #include <KPasswordDialog> 0025 0026 Smb4KConfigPageAuthentication::Smb4KConfigPageAuthentication(QWidget *parent) 0027 : QWidget(parent) 0028 { 0029 m_entriesLoaded = false; 0030 0031 QVBoxLayout *layout = new QVBoxLayout(this); 0032 0033 QGroupBox *settingsBox = new QGroupBox(i18n("Settings"), this); 0034 QVBoxLayout *settingsBoxLayout = new QVBoxLayout(settingsBox); 0035 0036 QCheckBox *useWallet = new QCheckBox(Smb4KSettings::self()->useWalletItem()->label(), settingsBox); 0037 useWallet->setObjectName(QStringLiteral("kcfg_UseWallet")); 0038 0039 connect(useWallet, &QCheckBox::toggled, this, &Smb4KConfigPageAuthentication::slotKWalletButtonToggled); 0040 0041 settingsBoxLayout->addWidget(useWallet); 0042 0043 m_useDefaultLogin = new QCheckBox(Smb4KSettings::self()->useDefaultLoginItem()->label(), settingsBox); 0044 m_useDefaultLogin->setObjectName(QStringLiteral("kcfg_UseDefaultLogin")); 0045 m_useDefaultLogin->setEnabled(false); 0046 0047 connect(m_useDefaultLogin, &QCheckBox::toggled, this, &Smb4KConfigPageAuthentication::slotDefaultLoginToggled); 0048 0049 settingsBoxLayout->addWidget(m_useDefaultLogin); 0050 0051 layout->addWidget(settingsBox); 0052 0053 QGroupBox *walletEntriesBox = new QGroupBox(i18n("Wallet Entries"), this); 0054 QVBoxLayout *walletEntriesBoxLayout = new QVBoxLayout(walletEntriesBox); 0055 0056 m_walletEntriesEditor = new QWidget(walletEntriesBox); 0057 m_walletEntriesEditor->setEnabled(false); 0058 QHBoxLayout *walletEntriesEditorLayout = new QHBoxLayout(m_walletEntriesEditor); 0059 walletEntriesEditorLayout->setContentsMargins(0, 0, 0, 0); 0060 0061 m_walletEntriesWidget = new QListWidget(m_walletEntriesEditor); 0062 m_walletEntriesWidget->setDragDropMode(QListWidget::NoDragDrop); 0063 m_walletEntriesWidget->setSelectionMode(QListWidget::SingleSelection); 0064 m_walletEntriesWidget->setContextMenuPolicy(Qt::ActionsContextMenu); 0065 m_walletEntriesWidget->viewport()->installEventFilter(this); 0066 0067 connect(m_walletEntriesWidget, &QListWidget::itemDoubleClicked, this, &Smb4KConfigPageAuthentication::slotWalletItemDoubleClicked); 0068 0069 walletEntriesEditorLayout->addWidget(m_walletEntriesWidget); 0070 0071 QDialogButtonBox *buttonBox = new QDialogButtonBox(Qt::Vertical, m_walletEntriesEditor); 0072 0073 m_loadButton = buttonBox->addButton(i18n("Load"), QDialogButtonBox::ActionRole); 0074 m_loadButton->setIcon(KDE::icon(QStringLiteral("document-open"))); 0075 0076 connect(m_loadButton, &QPushButton::clicked, this, &Smb4KConfigPageAuthentication::slotLoadButtonClicked); 0077 0078 m_saveButton = buttonBox->addButton(i18n("Save"), QDialogButtonBox::ActionRole); 0079 m_saveButton->setIcon(KDE::icon(QStringLiteral("document-save-all"))); 0080 m_saveButton->setEnabled(false); 0081 0082 connect(m_saveButton, &QPushButton::clicked, this, &Smb4KConfigPageAuthentication::slotSaveButtonClicked); 0083 0084 m_editButton = buttonBox->addButton(i18n("Edit"), QDialogButtonBox::ActionRole); 0085 m_editButton->setIcon(KDE::icon(QStringLiteral("edit-rename"))); 0086 m_editButton->setEnabled(false); 0087 0088 connect(m_editButton, &QPushButton::clicked, this, &Smb4KConfigPageAuthentication::slotEditButtonClicked); 0089 0090 m_removeButton = buttonBox->addButton(i18n("Remove"), QDialogButtonBox::ActionRole); 0091 m_removeButton->setIcon(KDE::icon(QStringLiteral("edit-delete"))); 0092 m_removeButton->setEnabled(false); 0093 0094 connect(m_removeButton, &QPushButton::clicked, this, &Smb4KConfigPageAuthentication::slotRemoveButtonClicked); 0095 0096 m_clearButton = buttonBox->addButton(i18n("Clear"), QDialogButtonBox::ActionRole); 0097 m_clearButton->setIcon(KDE::icon(QStringLiteral("edit-clear-list"))); 0098 m_clearButton->setEnabled(false); 0099 0100 connect(m_clearButton, &QPushButton::clicked, this, &Smb4KConfigPageAuthentication::slotClearButtonClicked); 0101 0102 m_resetButton = buttonBox->addButton(QDialogButtonBox::Reset); 0103 m_resetButton->setEnabled(false); 0104 0105 connect(m_resetButton, &QPushButton::clicked, this, &Smb4KConfigPageAuthentication::slotResetButtonClicked); 0106 0107 walletEntriesEditorLayout->addWidget(buttonBox); 0108 0109 walletEntriesBoxLayout->addWidget(m_walletEntriesEditor); 0110 0111 layout->addWidget(walletEntriesBox); 0112 0113 connect(this, &Smb4KConfigPageAuthentication::walletEntriesModified, this, &Smb4KConfigPageAuthentication::slotEnableResetButton); 0114 } 0115 0116 Smb4KConfigPageAuthentication::~Smb4KConfigPageAuthentication() 0117 { 0118 } 0119 0120 void Smb4KConfigPageAuthentication::loadLoginCredentials() 0121 { 0122 m_entriesList = Smb4KWalletManager::self()->loginCredentialsList(); 0123 0124 Q_EMIT walletEntriesModified(); 0125 0126 m_walletEntriesWidget->clear(); 0127 0128 for (Smb4KAuthInfo *authInfo : qAsConst(m_entriesList)) { 0129 switch (authInfo->type()) { 0130 case UnknownNetworkItem: { 0131 QListWidgetItem *item = new QListWidgetItem(KDE::icon(QStringLiteral("dialog-password")), i18n("Default Login"), m_walletEntriesWidget); 0132 item->setData(Qt::UserRole, authInfo->url()); 0133 break; 0134 } 0135 default: { 0136 QListWidgetItem *item = new QListWidgetItem(KDE::icon(QStringLiteral("dialog-password")), authInfo->displayString(), m_walletEntriesWidget); 0137 item->setData(Qt::UserRole, authInfo->url()); 0138 break; 0139 } 0140 } 0141 } 0142 0143 m_walletEntriesWidget->sortItems(); 0144 0145 m_entriesLoaded = true; 0146 0147 m_saveButton->setEnabled(m_walletEntriesWidget->count() != 0); 0148 m_clearButton->setEnabled(m_walletEntriesWidget->count() != 0); 0149 } 0150 0151 void Smb4KConfigPageAuthentication::saveLoginCredentials() 0152 { 0153 if (loginCredentialsChanged()) { 0154 Smb4KWalletManager::self()->writeLoginCredentialsList(m_entriesList); 0155 0156 // Do not emit walletEntriesModified() signal, because we do not 0157 // want to enable/disable the "Apply" button as well. 0158 slotEnableResetButton(); 0159 } 0160 } 0161 0162 bool Smb4KConfigPageAuthentication::loginCredentialsLoaded() 0163 { 0164 return m_entriesLoaded; 0165 } 0166 0167 bool Smb4KConfigPageAuthentication::loginCredentialsChanged() 0168 { 0169 bool changed = false; 0170 0171 if (m_entriesLoaded) { 0172 QList<Smb4KAuthInfo *> savedLoginCredentials = Smb4KWalletManager::self()->loginCredentialsList(); 0173 0174 if (savedLoginCredentials.size() != m_entriesList.size()) { 0175 changed = true; 0176 } else { 0177 for (Smb4KAuthInfo *oldEntry : qAsConst(savedLoginCredentials)) { 0178 for (Smb4KAuthInfo *newEntry : qAsConst(m_entriesList)) { 0179 if (oldEntry->url().matches(newEntry->url(), QUrl::RemoveUserInfo | QUrl::RemovePort)) { 0180 changed = (oldEntry->url().userInfo() != newEntry->url().userInfo()); 0181 break; 0182 } 0183 } 0184 0185 if (changed) { 0186 break; 0187 } 0188 } 0189 } 0190 } 0191 0192 return changed; 0193 } 0194 0195 bool Smb4KConfigPageAuthentication::eventFilter(QObject *object, QEvent *e) 0196 { 0197 if (object == m_walletEntriesWidget->viewport()) { 0198 // If the user clicked on the viewport of the entries view, clear 0199 // the details widget and the "Details" button, if no item 0200 // is under the mouse. 0201 if (e->type() == QEvent::MouseButtonPress) { 0202 QMouseEvent *event = static_cast<QMouseEvent *>(e); 0203 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 0204 QPointF pos = m_walletEntriesWidget->mapFromGlobal(event->globalPosition()); 0205 QListWidgetItem *item = m_walletEntriesWidget->itemAt(pos.toPoint()); 0206 #else 0207 QPoint pos = m_walletEntriesWidget->mapFromGlobal(event->globalPos()); 0208 QListWidgetItem *item = m_walletEntriesWidget->itemAt(pos); 0209 #endif 0210 0211 m_editButton->setEnabled(item != nullptr); 0212 m_removeButton->setEnabled(item != nullptr); 0213 0214 if (!item) { 0215 m_walletEntriesWidget->clearSelection(); 0216 } 0217 } 0218 } 0219 0220 return QWidget::eventFilter(object, e); 0221 } 0222 0223 ///////////////////////////////////////////////////////////////////////////// 0224 // SLOT IMPLEMENTATIONS 0225 ///////////////////////////////////////////////////////////////////////////// 0226 0227 void Smb4KConfigPageAuthentication::slotKWalletButtonToggled(bool checked) 0228 { 0229 m_useDefaultLogin->setEnabled(checked); 0230 m_walletEntriesEditor->setEnabled(checked); 0231 } 0232 0233 void Smb4KConfigPageAuthentication::slotDefaultLoginToggled(bool checked) 0234 { 0235 if (checked && !Smb4KSettings::useDefaultLogin()) { 0236 if (!Smb4KWalletManager::self()->hasDefaultCredentials()) { 0237 Smb4KAuthInfo authInfo; 0238 // If there are no default credentials, we do not need to read them. 0239 KPasswordDialog dlg(this, KPasswordDialog::ShowUsernameLine); 0240 dlg.setPrompt(i18n("Enter the default login information.")); 0241 dlg.setUsername(authInfo.userName()); 0242 dlg.setPassword(authInfo.password()); 0243 0244 if (dlg.exec() == KPasswordDialog::Accepted) { 0245 authInfo.setUserName(dlg.username()); 0246 authInfo.setPassword(dlg.password()); 0247 0248 Smb4KWalletManager::self()->writeLoginCredentials(&authInfo); 0249 0250 if (m_entriesLoaded) { 0251 loadLoginCredentials(); 0252 } 0253 } else { 0254 m_useDefaultLogin->setChecked(false); 0255 } 0256 } 0257 } 0258 } 0259 0260 void Smb4KConfigPageAuthentication::slotLoadButtonClicked(bool checked) 0261 { 0262 Q_UNUSED(checked); 0263 0264 if (!m_entriesLoaded) { 0265 loadLoginCredentials(); 0266 } 0267 0268 m_loadButton->setEnabled(false); 0269 m_walletEntriesWidget->setFocus(); 0270 } 0271 0272 void Smb4KConfigPageAuthentication::slotSaveButtonClicked(bool checked) 0273 { 0274 Q_UNUSED(checked); 0275 0276 if (m_entriesLoaded) { 0277 saveLoginCredentials(); 0278 } 0279 0280 m_editButton->setEnabled(false); 0281 m_removeButton->setEnabled(false); 0282 m_clearButton->setEnabled((m_walletEntriesWidget->count() != 0)); 0283 0284 m_walletEntriesWidget->clearSelection(); 0285 0286 Q_EMIT walletEntriesModified(); 0287 } 0288 0289 void Smb4KConfigPageAuthentication::slotEditButtonClicked(bool checked) 0290 { 0291 Q_UNUSED(checked); 0292 0293 KPasswordDialog dlg(this, KPasswordDialog::ShowUsernameLine); 0294 0295 if (m_walletEntriesWidget->currentItem()) { 0296 Smb4KAuthInfo *authInfo = nullptr; 0297 0298 for (Smb4KAuthInfo *walletEntry : qAsConst(m_entriesList)) { 0299 // The following check also finds the default login, because it has an empty URL. 0300 if (m_walletEntriesWidget->currentItem()->data(Qt::UserRole).toUrl() == walletEntry->url()) { 0301 if (walletEntry->type() != Smb4KGlobal::UnknownNetworkItem) { 0302 dlg.setPrompt(i18n("Set the username and password for wallet entry %1.", walletEntry->displayString())); 0303 } else { 0304 dlg.setPrompt(i18n("Set the username and password for the default login.")); 0305 } 0306 dlg.setUsername(walletEntry->userName()); 0307 dlg.setPassword(walletEntry->password()); 0308 0309 authInfo = walletEntry; 0310 0311 break; 0312 } 0313 } 0314 0315 if (authInfo) { 0316 if (dlg.exec() == KPasswordDialog::Accepted) { 0317 authInfo->setUserName(dlg.username()); 0318 authInfo->setPassword(dlg.password()); 0319 0320 Q_EMIT walletEntriesModified(); 0321 } 0322 } 0323 } 0324 } 0325 0326 void Smb4KConfigPageAuthentication::slotRemoveButtonClicked(bool checked) 0327 { 0328 Q_UNUSED(checked); 0329 0330 for (int i = 0; i < m_entriesList.size(); ++i) { 0331 // The following check also finds the default login, because it has an empty URL. 0332 if (m_walletEntriesWidget->currentItem()->data(Qt::UserRole).toUrl() == m_entriesList.at(i)->url()) { 0333 switch (m_entriesList.at(i)->type()) { 0334 case UnknownNetworkItem: { 0335 m_useDefaultLogin->setChecked(false); 0336 break; 0337 } 0338 default: { 0339 break; 0340 } 0341 } 0342 0343 delete m_entriesList.takeAt(i); 0344 break; 0345 } else { 0346 continue; 0347 } 0348 } 0349 0350 delete m_walletEntriesWidget->currentItem(); 0351 0352 m_clearButton->setEnabled((m_walletEntriesWidget->count() != 0)); 0353 0354 Q_EMIT walletEntriesModified(); 0355 } 0356 0357 void Smb4KConfigPageAuthentication::slotClearButtonClicked(bool checked) 0358 { 0359 Q_UNUSED(checked); 0360 0361 while (m_walletEntriesWidget->count() != 0) { 0362 delete m_walletEntriesWidget->item(0); 0363 } 0364 0365 while (!m_entriesList.isEmpty()) { 0366 delete m_entriesList.takeFirst(); 0367 } 0368 0369 m_clearButton->setEnabled(false); 0370 0371 m_useDefaultLogin->setChecked(false); 0372 0373 Q_EMIT walletEntriesModified(); 0374 } 0375 0376 void Smb4KConfigPageAuthentication::slotResetButtonClicked(bool checked) 0377 { 0378 Q_UNUSED(checked); 0379 0380 if (m_entriesLoaded) { 0381 loadLoginCredentials(); 0382 } 0383 0384 Q_EMIT walletEntriesModified(); 0385 0386 m_clearButton->setEnabled((m_walletEntriesWidget->count() != 0)); 0387 } 0388 0389 void Smb4KConfigPageAuthentication::slotEnableResetButton() 0390 { 0391 bool changed = loginCredentialsChanged(); 0392 m_resetButton->setEnabled(changed); 0393 } 0394 0395 void Smb4KConfigPageAuthentication::slotWalletItemDoubleClicked(QListWidgetItem *item) 0396 { 0397 Q_UNUSED(item); 0398 0399 slotEditButtonClicked(false); 0400 }